blob: c85a3a2a37bf36d5f60b07735cf8a716d7de9618 [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 Martineaud1de6d42012-05-17 20:53:55 -070060bool disable_ertm;
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 Padovanee556f62012-05-18 20:22:38 -0300552 switch(chan->mode) {
553 case L2CAP_MODE_BASIC:
554 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300555
Gustavo Padovanee556f62012-05-18 20:22:38 -0300556 case L2CAP_MODE_ERTM:
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -0300557 __clear_retrans_timer(chan);
558 __clear_monitor_timer(chan);
559 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300560
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -0300561 skb_queue_purge(&chan->srej_q);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300562
Mat Martineau3c588192012-04-11 10:48:42 -0700563 l2cap_seq_list_free(&chan->srej_list);
564 l2cap_seq_list_free(&chan->retrans_list);
Gustavo Padovanee556f62012-05-18 20:22:38 -0300565
566 /* fall through */
567
568 case L2CAP_MODE_STREAMING:
569 skb_queue_purge(&chan->tx_q);
570 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300571 }
Gustavo Padovanee556f62012-05-18 20:22:38 -0300572
573 return;
Marcel Holtmann01394182006-07-03 10:02:46 +0200574}
575
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300576static void l2cap_chan_cleanup_listen(struct sock *parent)
577{
578 struct sock *sk;
579
580 BT_DBG("parent %p", parent);
581
582 /* Close not yet accepted channels */
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300583 while ((sk = bt_accept_dequeue(parent, NULL))) {
Gustavo F. Padovanba3bd0e2011-05-16 18:23:24 -0300584 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200585
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200586 l2cap_chan_lock(chan);
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300587 __clear_chan_timer(chan);
Gustavo F. Padovanba3bd0e2011-05-16 18:23:24 -0300588 l2cap_chan_close(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200589 l2cap_chan_unlock(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200590
Gustavo F. Padovanba3bd0e2011-05-16 18:23:24 -0300591 chan->ops->close(chan->data);
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300592 }
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300593}
594
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300595void l2cap_chan_close(struct l2cap_chan *chan, int reason)
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300596{
597 struct l2cap_conn *conn = chan->conn;
598 struct sock *sk = chan->sk;
599
Andrei Emeltchenkoe05dcc32012-02-17 11:40:56 +0200600 BT_DBG("chan %p state %s sk %p", chan,
601 state_to_string(chan->state), sk);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300602
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300603 switch (chan->state) {
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300604 case BT_LISTEN:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200605 lock_sock(sk);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300606 l2cap_chan_cleanup_listen(sk);
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300607
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +0200608 __l2cap_state_change(chan, BT_CLOSED);
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300609 sock_set_flag(sk, SOCK_ZAPPED);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200610 release_sock(sk);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300611 break;
612
613 case BT_CONNECTED:
614 case BT_CONFIG:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300615 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300616 conn->hcon->type == ACL_LINK) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300617 __set_chan_timer(chan, sk->sk_sndtimeo);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300618 l2cap_send_disconn_req(conn, chan, reason);
619 } else
620 l2cap_chan_del(chan, reason);
621 break;
622
623 case BT_CONNECT2:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300624 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300625 conn->hcon->type == ACL_LINK) {
626 struct l2cap_conn_rsp rsp;
627 __u16 result;
628
Gustavo Padovanc5daa682012-05-16 12:17:10 -0300629 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags))
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300630 result = L2CAP_CR_SEC_BLOCK;
631 else
632 result = L2CAP_CR_BAD_PSM;
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300633 l2cap_state_change(chan, BT_DISCONN);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300634
635 rsp.scid = cpu_to_le16(chan->dcid);
636 rsp.dcid = cpu_to_le16(chan->scid);
637 rsp.result = cpu_to_le16(result);
638 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
639 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
640 sizeof(rsp), &rsp);
641 }
642
643 l2cap_chan_del(chan, reason);
644 break;
645
646 case BT_CONNECT:
647 case BT_DISCONN:
648 l2cap_chan_del(chan, reason);
649 break;
650
651 default:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200652 lock_sock(sk);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300653 sock_set_flag(sk, SOCK_ZAPPED);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200654 release_sock(sk);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300655 break;
656 }
657}
658
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300659static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530660{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300661 if (chan->chan_type == L2CAP_CHAN_RAW) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300662 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530663 case BT_SECURITY_HIGH:
664 return HCI_AT_DEDICATED_BONDING_MITM;
665 case BT_SECURITY_MEDIUM:
666 return HCI_AT_DEDICATED_BONDING;
667 default:
668 return HCI_AT_NO_BONDING;
669 }
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300670 } else if (chan->psm == cpu_to_le16(0x0001)) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300671 if (chan->sec_level == BT_SECURITY_LOW)
672 chan->sec_level = BT_SECURITY_SDP;
Johan Hedberg8556edd32011-01-19 12:06:50 +0530673
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300674 if (chan->sec_level == BT_SECURITY_HIGH)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530675 return HCI_AT_NO_BONDING_MITM;
676 else
677 return HCI_AT_NO_BONDING;
678 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300679 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530680 case BT_SECURITY_HIGH:
681 return HCI_AT_GENERAL_BONDING_MITM;
682 case BT_SECURITY_MEDIUM:
683 return HCI_AT_GENERAL_BONDING;
684 default:
685 return HCI_AT_NO_BONDING;
686 }
687 }
688}
689
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200690/* Service level security */
Gustavo F. Padovand45fc422011-11-05 19:54:24 -0200691int l2cap_chan_check_security(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200692{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300693 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100694 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200695
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300696 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100697
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300698 return hci_conn_security(conn->hcon, chan->sec_level, auth_type);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200699}
700
Johannes Bergb5ad8b72011-06-01 08:54:45 +0200701static u8 l2cap_get_ident(struct l2cap_conn *conn)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200702{
703 u8 id;
704
705 /* Get next available identificator.
706 * 1 - 128 are used by kernel.
707 * 129 - 199 are reserved.
708 * 200 - 254 are used by utilities like l2ping, etc.
709 */
710
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200711 spin_lock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200712
713 if (++conn->tx_ident > 128)
714 conn->tx_ident = 1;
715
716 id = conn->tx_ident;
717
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200718 spin_unlock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200719
720 return id;
721}
722
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300723static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200724{
725 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200726 u8 flags;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200727
728 BT_DBG("code 0x%2.2x", code);
729
730 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300731 return;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200732
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200733 if (lmp_no_flush_capable(conn->hcon->hdev))
734 flags = ACL_START_NO_FLUSH;
735 else
736 flags = ACL_START;
737
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700738 bt_cb(skb)->force_active = BT_POWER_FORCE_ACTIVE_ON;
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +0200739 skb->priority = HCI_PRIO_MAX;
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700740
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200741 hci_send_acl(conn->hchan, skb, flags);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200742}
743
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200744static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb)
745{
746 struct hci_conn *hcon = chan->conn->hcon;
747 u16 flags;
748
749 BT_DBG("chan %p, skb %p len %d priority %u", chan, skb, skb->len,
750 skb->priority);
751
752 if (!test_bit(FLAG_FLUSHABLE, &chan->flags) &&
753 lmp_no_flush_capable(hcon->hdev))
754 flags = ACL_START_NO_FLUSH;
755 else
756 flags = ACL_START;
757
758 bt_cb(skb)->force_active = test_bit(FLAG_FORCE_ACTIVE, &chan->flags);
759 hci_send_acl(chan->conn->hchan, skb, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700760}
761
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700762static void __unpack_enhanced_control(u16 enh, struct l2cap_ctrl *control)
763{
764 control->reqseq = (enh & L2CAP_CTRL_REQSEQ) >> L2CAP_CTRL_REQSEQ_SHIFT;
765 control->final = (enh & L2CAP_CTRL_FINAL) >> L2CAP_CTRL_FINAL_SHIFT;
766
767 if (enh & L2CAP_CTRL_FRAME_TYPE) {
768 /* S-Frame */
769 control->sframe = 1;
770 control->poll = (enh & L2CAP_CTRL_POLL) >> L2CAP_CTRL_POLL_SHIFT;
771 control->super = (enh & L2CAP_CTRL_SUPERVISE) >> L2CAP_CTRL_SUPER_SHIFT;
772
773 control->sar = 0;
774 control->txseq = 0;
775 } else {
776 /* I-Frame */
777 control->sframe = 0;
778 control->sar = (enh & L2CAP_CTRL_SAR) >> L2CAP_CTRL_SAR_SHIFT;
779 control->txseq = (enh & L2CAP_CTRL_TXSEQ) >> L2CAP_CTRL_TXSEQ_SHIFT;
780
781 control->poll = 0;
782 control->super = 0;
783 }
784}
785
786static void __unpack_extended_control(u32 ext, struct l2cap_ctrl *control)
787{
788 control->reqseq = (ext & L2CAP_EXT_CTRL_REQSEQ) >> L2CAP_EXT_CTRL_REQSEQ_SHIFT;
789 control->final = (ext & L2CAP_EXT_CTRL_FINAL) >> L2CAP_EXT_CTRL_FINAL_SHIFT;
790
791 if (ext & L2CAP_EXT_CTRL_FRAME_TYPE) {
792 /* S-Frame */
793 control->sframe = 1;
794 control->poll = (ext & L2CAP_EXT_CTRL_POLL) >> L2CAP_EXT_CTRL_POLL_SHIFT;
795 control->super = (ext & L2CAP_EXT_CTRL_SUPERVISE) >> L2CAP_EXT_CTRL_SUPER_SHIFT;
796
797 control->sar = 0;
798 control->txseq = 0;
799 } else {
800 /* I-Frame */
801 control->sframe = 0;
802 control->sar = (ext & L2CAP_EXT_CTRL_SAR) >> L2CAP_EXT_CTRL_SAR_SHIFT;
803 control->txseq = (ext & L2CAP_EXT_CTRL_TXSEQ) >> L2CAP_EXT_CTRL_TXSEQ_SHIFT;
804
805 control->poll = 0;
806 control->super = 0;
807 }
808}
809
810static inline void __unpack_control(struct l2cap_chan *chan,
811 struct sk_buff *skb)
812{
813 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
814 __unpack_extended_control(get_unaligned_le32(skb->data),
815 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700816 skb_pull(skb, L2CAP_EXT_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700817 } else {
818 __unpack_enhanced_control(get_unaligned_le16(skb->data),
819 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700820 skb_pull(skb, L2CAP_ENH_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700821 }
822}
823
824static u32 __pack_extended_control(struct l2cap_ctrl *control)
825{
826 u32 packed;
827
828 packed = control->reqseq << L2CAP_EXT_CTRL_REQSEQ_SHIFT;
829 packed |= control->final << L2CAP_EXT_CTRL_FINAL_SHIFT;
830
831 if (control->sframe) {
832 packed |= control->poll << L2CAP_EXT_CTRL_POLL_SHIFT;
833 packed |= control->super << L2CAP_EXT_CTRL_SUPER_SHIFT;
834 packed |= L2CAP_EXT_CTRL_FRAME_TYPE;
835 } else {
836 packed |= control->sar << L2CAP_EXT_CTRL_SAR_SHIFT;
837 packed |= control->txseq << L2CAP_EXT_CTRL_TXSEQ_SHIFT;
838 }
839
840 return packed;
841}
842
843static u16 __pack_enhanced_control(struct l2cap_ctrl *control)
844{
845 u16 packed;
846
847 packed = control->reqseq << L2CAP_CTRL_REQSEQ_SHIFT;
848 packed |= control->final << L2CAP_CTRL_FINAL_SHIFT;
849
850 if (control->sframe) {
851 packed |= control->poll << L2CAP_CTRL_POLL_SHIFT;
852 packed |= control->super << L2CAP_CTRL_SUPER_SHIFT;
853 packed |= L2CAP_CTRL_FRAME_TYPE;
854 } else {
855 packed |= control->sar << L2CAP_CTRL_SAR_SHIFT;
856 packed |= control->txseq << L2CAP_CTRL_TXSEQ_SHIFT;
857 }
858
859 return packed;
860}
861
862static inline void __pack_control(struct l2cap_chan *chan,
863 struct l2cap_ctrl *control,
864 struct sk_buff *skb)
865{
866 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
867 put_unaligned_le32(__pack_extended_control(control),
868 skb->data + L2CAP_HDR_SIZE);
869 } else {
870 put_unaligned_le16(__pack_enhanced_control(control),
871 skb->data + L2CAP_HDR_SIZE);
872 }
873}
874
Mat Martineaua67d7f62012-05-17 20:53:35 -0700875static struct sk_buff *l2cap_create_sframe_pdu(struct l2cap_chan *chan,
876 u32 control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300877{
878 struct sk_buff *skb;
879 struct l2cap_hdr *lh;
Mat Martineaua67d7f62012-05-17 20:53:35 -0700880 int hlen;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300881
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +0300882 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
883 hlen = L2CAP_EXT_HDR_SIZE;
884 else
885 hlen = L2CAP_ENH_HDR_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300886
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300887 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300888 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300889
Mat Martineaua67d7f62012-05-17 20:53:35 -0700890 skb = bt_skb_alloc(hlen, GFP_KERNEL);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300891
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300892 if (!skb)
Mat Martineaua67d7f62012-05-17 20:53:35 -0700893 return ERR_PTR(-ENOMEM);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300894
895 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300896 lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300897 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +0300898
Mat Martineaua67d7f62012-05-17 20:53:35 -0700899 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
900 put_unaligned_le32(control, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
901 else
902 put_unaligned_le16(control, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300903
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -0300904 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineaua67d7f62012-05-17 20:53:35 -0700905 u16 fcs = crc16(0, (u8 *)skb->data, skb->len);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300906 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300907 }
908
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200909 skb->priority = HCI_PRIO_MAX;
Mat Martineaua67d7f62012-05-17 20:53:35 -0700910 return skb;
911}
912
913static void l2cap_send_sframe(struct l2cap_chan *chan,
914 struct l2cap_ctrl *control)
915{
916 struct sk_buff *skb;
917 u32 control_field;
918
919 BT_DBG("chan %p, control %p", chan, control);
920
921 if (!control->sframe)
922 return;
923
924 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state) &&
925 !control->poll)
926 control->final = 1;
927
928 if (control->super == L2CAP_SUPER_RR)
929 clear_bit(CONN_RNR_SENT, &chan->conn_state);
930 else if (control->super == L2CAP_SUPER_RNR)
931 set_bit(CONN_RNR_SENT, &chan->conn_state);
932
933 if (control->super != L2CAP_SUPER_SREJ) {
934 chan->last_acked_seq = control->reqseq;
935 __clear_ack_timer(chan);
936 }
937
938 BT_DBG("reqseq %d, final %d, poll %d, super %d", control->reqseq,
939 control->final, control->poll, control->super);
940
941 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
942 control_field = __pack_extended_control(control);
943 else
944 control_field = __pack_enhanced_control(control);
945
946 skb = l2cap_create_sframe_pdu(chan, control_field);
947 if (!IS_ERR(skb))
948 l2cap_do_send(chan, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300949}
950
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700951static void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, bool poll)
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300952{
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700953 struct l2cap_ctrl control;
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300954
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700955 BT_DBG("chan %p, poll %d", chan, poll);
956
957 memset(&control, 0, sizeof(control));
958 control.sframe = 1;
959 control.poll = poll;
960
961 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
962 control.super = L2CAP_SUPER_RNR;
963 else
964 control.super = L2CAP_SUPER_RR;
965
966 control.reqseq = chan->buffer_seq;
967 l2cap_send_sframe(chan, &control);
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300968}
969
Gustavo F. Padovanb4450032011-04-12 18:15:09 -0300970static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan)
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300971{
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -0300972 return !test_bit(CONF_CONNECT_PEND, &chan->conf_state);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300973}
974
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +0200975static void l2cap_send_conn_req(struct l2cap_chan *chan)
976{
977 struct l2cap_conn *conn = chan->conn;
978 struct l2cap_conn_req req;
979
980 req.scid = cpu_to_le16(chan->scid);
981 req.psm = chan->psm;
982
983 chan->ident = l2cap_get_ident(conn);
984
985 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
986
987 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, sizeof(req), &req);
988}
989
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -0300990static void l2cap_chan_ready(struct l2cap_chan *chan)
991{
992 struct sock *sk = chan->sk;
993 struct sock *parent;
994
995 lock_sock(sk);
996
997 parent = bt_sk(sk)->parent;
998
999 BT_DBG("sk %p, parent %p", sk, parent);
1000
Mat Martineau28270112012-05-17 21:14:09 -07001001 /* This clears all conf flags, including CONF_NOT_COMPLETE */
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001002 chan->conf_state = 0;
1003 __clear_chan_timer(chan);
1004
1005 __l2cap_state_change(chan, BT_CONNECTED);
1006 sk->sk_state_change(sk);
1007
1008 if (parent)
1009 parent->sk_data_ready(parent, 0);
1010
1011 release_sock(sk);
1012}
1013
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001014static void l2cap_do_start(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001015{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001016 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001017
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001018 if (conn->hcon->type == LE_LINK) {
1019 l2cap_chan_ready(chan);
1020 return;
1021 }
1022
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001023 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01001024 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
1025 return;
1026
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001027 if (l2cap_chan_check_security(chan) &&
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +02001028 __l2cap_no_conn_pending(chan))
1029 l2cap_send_conn_req(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001030 } else {
1031 struct l2cap_info_req req;
1032 req.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
1033
1034 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
1035 conn->info_ident = l2cap_get_ident(conn);
1036
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08001037 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001038
1039 l2cap_send_cmd(conn, conn->info_ident,
1040 L2CAP_INFO_REQ, sizeof(req), &req);
1041 }
1042}
1043
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001044static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
1045{
1046 u32 local_feat_mask = l2cap_feat_mask;
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03001047 if (!disable_ertm)
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001048 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
1049
1050 switch (mode) {
1051 case L2CAP_MODE_ERTM:
1052 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
1053 case L2CAP_MODE_STREAMING:
1054 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
1055 default:
1056 return 0x00;
1057 }
1058}
1059
Gustavo F. Padovan4519de92011-04-28 17:55:53 -03001060static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *chan, int err)
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001061{
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001062 struct sock *sk = chan->sk;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001063 struct l2cap_disconn_req req;
1064
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001065 if (!conn)
1066 return;
1067
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03001068 if (chan->mode == L2CAP_MODE_ERTM) {
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03001069 __clear_retrans_timer(chan);
1070 __clear_monitor_timer(chan);
1071 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001072 }
1073
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001074 req.dcid = cpu_to_le16(chan->dcid);
1075 req.scid = cpu_to_le16(chan->scid);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001076 l2cap_send_cmd(conn, l2cap_get_ident(conn),
1077 L2CAP_DISCONN_REQ, sizeof(req), &req);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001078
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001079 lock_sock(sk);
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001080 __l2cap_state_change(chan, BT_DISCONN);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02001081 __l2cap_chan_set_err(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001082 release_sock(sk);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001083}
1084
Linus Torvalds1da177e2005-04-16 15:20:36 -07001085/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001086static void l2cap_conn_start(struct l2cap_conn *conn)
1087{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001088 struct l2cap_chan *chan, *tmp;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001089
1090 BT_DBG("conn %p", conn);
1091
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001092 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001093
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001094 list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001095 struct sock *sk = chan->sk;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001096
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001097 l2cap_chan_lock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001098
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001099 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001100 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001101 continue;
1102 }
1103
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001104 if (chan->state == BT_CONNECT) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001105 if (!l2cap_chan_check_security(chan) ||
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03001106 !__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001107 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001108 continue;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02001109 }
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001110
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001111 if (!l2cap_mode_supported(chan->mode, conn->feat_mask)
1112 && test_bit(CONF_STATE2_DEVICE,
1113 &chan->conf_state)) {
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001114 l2cap_chan_close(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001115 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001116 continue;
1117 }
1118
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +02001119 l2cap_send_conn_req(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001120
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001121 } else if (chan->state == BT_CONNECT2) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001122 struct l2cap_conn_rsp rsp;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001123 char buf[128];
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001124 rsp.scid = cpu_to_le16(chan->dcid);
1125 rsp.dcid = cpu_to_le16(chan->scid);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001126
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001127 if (l2cap_chan_check_security(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001128 lock_sock(sk);
Gustavo Padovanc5daa682012-05-16 12:17:10 -03001129 if (test_bit(BT_SK_DEFER_SETUP,
1130 &bt_sk(sk)->flags)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001131 struct sock *parent = bt_sk(sk)->parent;
1132 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
1133 rsp.status = cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
Ilia Kolomisnky05e9a2f2011-07-15 18:30:21 +00001134 if (parent)
1135 parent->sk_data_ready(parent, 0);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001136
1137 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001138 __l2cap_state_change(chan, BT_CONFIG);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001139 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
1140 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
1141 }
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001142 release_sock(sk);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001143 } else {
1144 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
1145 rsp.status = cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
1146 }
1147
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001148 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
1149 sizeof(rsp), &rsp);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001150
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001151 if (test_bit(CONF_REQ_SENT, &chan->conf_state) ||
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001152 rsp.result != L2CAP_CR_SUCCESS) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001153 l2cap_chan_unlock(chan);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001154 continue;
1155 }
1156
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001157 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001158 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03001159 l2cap_build_conf_req(chan, buf), buf);
1160 chan->num_conf_req++;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001161 }
1162
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001163 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001164 }
1165
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001166 mutex_unlock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001167}
1168
Ido Yarivc2287682012-04-20 15:46:07 -03001169/* Find socket with cid and source/destination bdaddr.
Ville Tervob62f3282011-02-10 22:38:50 -03001170 * Returns closest match, locked.
1171 */
Andrei Emeltchenkod9b88702012-03-12 12:13:08 +02001172static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid,
Ido Yarivc2287682012-04-20 15:46:07 -03001173 bdaddr_t *src,
1174 bdaddr_t *dst)
Ville Tervob62f3282011-02-10 22:38:50 -03001175{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001176 struct l2cap_chan *c, *c1 = NULL;
Ville Tervob62f3282011-02-10 22:38:50 -03001177
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001178 read_lock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001179
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001180 list_for_each_entry(c, &chan_list, global_l) {
1181 struct sock *sk = c->sk;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001182
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001183 if (state && c->state != state)
Ville Tervob62f3282011-02-10 22:38:50 -03001184 continue;
1185
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001186 if (c->scid == cid) {
Ido Yarivc2287682012-04-20 15:46:07 -03001187 int src_match, dst_match;
1188 int src_any, dst_any;
1189
Ville Tervob62f3282011-02-10 22:38:50 -03001190 /* Exact match. */
Ido Yarivc2287682012-04-20 15:46:07 -03001191 src_match = !bacmp(&bt_sk(sk)->src, src);
1192 dst_match = !bacmp(&bt_sk(sk)->dst, dst);
1193 if (src_match && dst_match) {
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001194 read_unlock(&chan_list_lock);
1195 return c;
1196 }
Ville Tervob62f3282011-02-10 22:38:50 -03001197
1198 /* Closest match */
Ido Yarivc2287682012-04-20 15:46:07 -03001199 src_any = !bacmp(&bt_sk(sk)->src, BDADDR_ANY);
1200 dst_any = !bacmp(&bt_sk(sk)->dst, BDADDR_ANY);
1201 if ((src_match && dst_any) || (src_any && dst_match) ||
1202 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001203 c1 = c;
Ville Tervob62f3282011-02-10 22:38:50 -03001204 }
1205 }
Gustavo F. Padovan280f2942011-04-13 19:01:22 -03001206
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001207 read_unlock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001208
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001209 return c1;
Ville Tervob62f3282011-02-10 22:38:50 -03001210}
1211
1212static void l2cap_le_conn_ready(struct l2cap_conn *conn)
1213{
Gustavo F. Padovanc916fbe2011-04-04 16:00:55 -03001214 struct sock *parent, *sk;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001215 struct l2cap_chan *chan, *pchan;
Ville Tervob62f3282011-02-10 22:38:50 -03001216
1217 BT_DBG("");
1218
1219 /* Check if we have socket listening on cid */
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001220 pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_LE_DATA,
Ido Yarivc2287682012-04-20 15:46:07 -03001221 conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001222 if (!pchan)
Ville Tervob62f3282011-02-10 22:38:50 -03001223 return;
1224
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001225 parent = pchan->sk;
1226
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03001227 lock_sock(parent);
Gustavo F. Padovan62f3a2c2011-04-14 18:34:34 -03001228
Ville Tervob62f3282011-02-10 22:38:50 -03001229 /* Check for backlog size */
1230 if (sk_acceptq_is_full(parent)) {
1231 BT_DBG("backlog full %d", parent->sk_ack_backlog);
1232 goto clean;
1233 }
1234
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001235 chan = pchan->ops->new_connection(pchan->data);
1236 if (!chan)
Ville Tervob62f3282011-02-10 22:38:50 -03001237 goto clean;
1238
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001239 sk = chan->sk;
Gustavo F. Padovan5d41ce12011-04-08 15:40:02 -03001240
Ville Tervob62f3282011-02-10 22:38:50 -03001241 hci_conn_hold(conn->hcon);
1242
Ville Tervob62f3282011-02-10 22:38:50 -03001243 bacpy(&bt_sk(sk)->src, conn->src);
1244 bacpy(&bt_sk(sk)->dst, conn->dst);
1245
Gustavo F. Padovand1010242011-03-25 00:39:48 -03001246 bt_accept_enqueue(parent, sk);
1247
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02001248 l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001249
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001250 __set_chan_timer(chan, sk->sk_sndtimeo);
Ville Tervob62f3282011-02-10 22:38:50 -03001251
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001252 __l2cap_state_change(chan, BT_CONNECTED);
Ville Tervob62f3282011-02-10 22:38:50 -03001253 parent->sk_data_ready(parent, 0);
1254
Ville Tervob62f3282011-02-10 22:38:50 -03001255clean:
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03001256 release_sock(parent);
Ville Tervob62f3282011-02-10 22:38:50 -03001257}
1258
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001259static void l2cap_conn_ready(struct l2cap_conn *conn)
1260{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001261 struct l2cap_chan *chan;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001262
1263 BT_DBG("conn %p", conn);
1264
Ville Tervob62f3282011-02-10 22:38:50 -03001265 if (!conn->hcon->out && conn->hcon->type == LE_LINK)
1266 l2cap_le_conn_ready(conn);
1267
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03001268 if (conn->hcon->out && conn->hcon->type == LE_LINK)
1269 smp_conn_security(conn, conn->hcon->pending_sec_level);
1270
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001271 mutex_lock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001272
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001273 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001274
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001275 l2cap_chan_lock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001276
Vinicius Costa Gomes63128452011-06-17 22:46:26 -03001277 if (conn->hcon->type == LE_LINK) {
Anderson Brigliab501d6a2011-06-07 18:46:31 -03001278 if (smp_conn_security(conn, chan->sec_level))
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02001279 l2cap_chan_ready(chan);
Ville Tervoacd7d372011-02-10 22:38:49 -03001280
Vinicius Costa Gomes63128452011-06-17 22:46:26 -03001281 } else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001282 struct sock *sk = chan->sk;
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001283 __clear_chan_timer(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001284 lock_sock(sk);
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001285 __l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001286 sk->sk_state_change(sk);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001287 release_sock(sk);
Anderson Brigliab501d6a2011-06-07 18:46:31 -03001288
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001289 } else if (chan->state == BT_CONNECT)
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001290 l2cap_do_start(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001291
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001292 l2cap_chan_unlock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001293 }
1294
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001295 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001296}
1297
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001298/* Notify sockets that we cannot guaranty reliability anymore */
1299static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
1300{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001301 struct l2cap_chan *chan;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001302
1303 BT_DBG("conn %p", conn);
1304
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001305 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001306
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001307 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenkoecf61bd2011-10-11 14:04:32 +03001308 if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags))
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02001309 __l2cap_chan_set_err(chan, err);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001310 }
1311
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001312 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001313}
1314
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001315static void l2cap_info_timeout(struct work_struct *work)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001316{
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001317 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo F. Padovan030013d2011-12-20 10:57:28 -02001318 info_timer.work);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001319
Marcel Holtmann984947d2009-02-06 23:35:19 +01001320 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01001321 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01001322
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001323 l2cap_conn_start(conn);
1324}
1325
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001326static void l2cap_conn_del(struct hci_conn *hcon, int err)
1327{
1328 struct l2cap_conn *conn = hcon->l2cap_data;
1329 struct l2cap_chan *chan, *l;
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001330
1331 if (!conn)
1332 return;
1333
1334 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
1335
1336 kfree_skb(conn->rx_skb);
1337
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001338 mutex_lock(&conn->chan_lock);
1339
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001340 /* Kill channels */
1341 list_for_each_entry_safe(chan, l, &conn->chan_l, list) {
Mat Martineau61d6ef32012-04-27 16:50:50 -07001342 l2cap_chan_hold(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001343 l2cap_chan_lock(chan);
1344
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001345 l2cap_chan_del(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001346
1347 l2cap_chan_unlock(chan);
1348
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001349 chan->ops->close(chan->data);
Mat Martineau61d6ef32012-04-27 16:50:50 -07001350 l2cap_chan_put(chan);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001351 }
1352
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001353 mutex_unlock(&conn->chan_lock);
1354
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001355 hci_chan_del(conn->hchan);
1356
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001357 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
Ulisses Furquim127074b2012-01-30 18:26:29 -02001358 cancel_delayed_work_sync(&conn->info_timer);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001359
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001360 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) {
Ulisses Furquim127074b2012-01-30 18:26:29 -02001361 cancel_delayed_work_sync(&conn->security_timer);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -03001362 smp_chan_destroy(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001363 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001364
1365 hcon->l2cap_data = NULL;
1366 kfree(conn);
1367}
1368
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001369static void security_timeout(struct work_struct *work)
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001370{
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001371 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
1372 security_timer.work);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001373
1374 l2cap_conn_del(conn->hcon, ETIMEDOUT);
1375}
1376
Linus Torvalds1da177e2005-04-16 15:20:36 -07001377static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
1378{
Marcel Holtmann01394182006-07-03 10:02:46 +02001379 struct l2cap_conn *conn = hcon->l2cap_data;
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001380 struct hci_chan *hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001381
Marcel Holtmann01394182006-07-03 10:02:46 +02001382 if (conn || status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001383 return conn;
1384
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001385 hchan = hci_chan_create(hcon);
1386 if (!hchan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001387 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001388
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001389 conn = kzalloc(sizeof(struct l2cap_conn), GFP_ATOMIC);
1390 if (!conn) {
1391 hci_chan_del(hchan);
1392 return NULL;
1393 }
1394
Linus Torvalds1da177e2005-04-16 15:20:36 -07001395 hcon->l2cap_data = conn;
1396 conn->hcon = hcon;
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001397 conn->hchan = hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001398
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001399 BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan);
Marcel Holtmann01394182006-07-03 10:02:46 +02001400
Ville Tervoacd7d372011-02-10 22:38:49 -03001401 if (hcon->hdev->le_mtu && hcon->type == LE_LINK)
1402 conn->mtu = hcon->hdev->le_mtu;
1403 else
1404 conn->mtu = hcon->hdev->acl_mtu;
1405
Linus Torvalds1da177e2005-04-16 15:20:36 -07001406 conn->src = &hcon->hdev->bdaddr;
1407 conn->dst = &hcon->dst;
1408
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001409 conn->feat_mask = 0;
1410
Linus Torvalds1da177e2005-04-16 15:20:36 -07001411 spin_lock_init(&conn->lock);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001412 mutex_init(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001413
1414 INIT_LIST_HEAD(&conn->chan_l);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001415
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001416 if (hcon->type == LE_LINK)
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001417 INIT_DELAYED_WORK(&conn->security_timer, security_timeout);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001418 else
Gustavo F. Padovan030013d2011-12-20 10:57:28 -02001419 INIT_DELAYED_WORK(&conn->info_timer, l2cap_info_timeout);
Dave Young45054dc2009-10-18 20:28:30 +00001420
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001421 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01001422
Linus Torvalds1da177e2005-04-16 15:20:36 -07001423 return conn;
1424}
1425
Linus Torvalds1da177e2005-04-16 15:20:36 -07001426/* ---- Socket interface ---- */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001427
Ido Yarivc2287682012-04-20 15:46:07 -03001428/* Find socket with psm and source / destination bdaddr.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001429 * Returns closest match.
1430 */
Ido Yarivc2287682012-04-20 15:46:07 -03001431static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
1432 bdaddr_t *src,
1433 bdaddr_t *dst)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001434{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001435 struct l2cap_chan *c, *c1 = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001436
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001437 read_lock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001438
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001439 list_for_each_entry(c, &chan_list, global_l) {
1440 struct sock *sk = c->sk;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001441
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001442 if (state && c->state != state)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001443 continue;
1444
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001445 if (c->psm == psm) {
Ido Yarivc2287682012-04-20 15:46:07 -03001446 int src_match, dst_match;
1447 int src_any, dst_any;
1448
Linus Torvalds1da177e2005-04-16 15:20:36 -07001449 /* Exact match. */
Ido Yarivc2287682012-04-20 15:46:07 -03001450 src_match = !bacmp(&bt_sk(sk)->src, src);
1451 dst_match = !bacmp(&bt_sk(sk)->dst, dst);
1452 if (src_match && dst_match) {
Johannes Berga7567b22011-06-01 08:29:54 +02001453 read_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001454 return c;
1455 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001456
1457 /* Closest match */
Ido Yarivc2287682012-04-20 15:46:07 -03001458 src_any = !bacmp(&bt_sk(sk)->src, BDADDR_ANY);
1459 dst_any = !bacmp(&bt_sk(sk)->dst, BDADDR_ANY);
1460 if ((src_match && dst_any) || (src_any && dst_match) ||
1461 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001462 c1 = c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001463 }
1464 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001465
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001466 read_unlock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001467
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001468 return c1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001469}
1470
Andre Guedes8e9f9892012-04-24 21:02:55 -03001471int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
1472 bdaddr_t *dst, u8 dst_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001473{
Gustavo F. Padovan5d41ce12011-04-08 15:40:02 -03001474 struct sock *sk = chan->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001475 bdaddr_t *src = &bt_sk(sk)->src;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001476 struct l2cap_conn *conn;
1477 struct hci_conn *hcon;
1478 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001479 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +02001480 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001481
Andre Guedes8e9f9892012-04-24 21:02:55 -03001482 BT_DBG("%s -> %s (type %u) psm 0x%2.2x", batostr(src), batostr(dst),
1483 dst_type, __le16_to_cpu(chan->psm));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001484
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001485 hdev = hci_get_route(dst, src);
1486 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001487 return -EHOSTUNREACH;
1488
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001489 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001490
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001491 l2cap_chan_lock(chan);
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001492
1493 /* PSM must be odd and lsb of upper byte must be 0 */
1494 if ((__le16_to_cpu(psm) & 0x0101) != 0x0001 && !cid &&
1495 chan->chan_type != L2CAP_CHAN_RAW) {
1496 err = -EINVAL;
1497 goto done;
1498 }
1499
1500 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && !(psm || cid)) {
1501 err = -EINVAL;
1502 goto done;
1503 }
1504
1505 switch (chan->mode) {
1506 case L2CAP_MODE_BASIC:
1507 break;
1508 case L2CAP_MODE_ERTM:
1509 case L2CAP_MODE_STREAMING:
1510 if (!disable_ertm)
1511 break;
1512 /* fall through */
1513 default:
1514 err = -ENOTSUPP;
1515 goto done;
1516 }
1517
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001518 lock_sock(sk);
1519
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001520 switch (sk->sk_state) {
1521 case BT_CONNECT:
1522 case BT_CONNECT2:
1523 case BT_CONFIG:
1524 /* Already connecting */
1525 err = 0;
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001526 release_sock(sk);
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001527 goto done;
1528
1529 case BT_CONNECTED:
1530 /* Already connected */
1531 err = -EISCONN;
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001532 release_sock(sk);
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001533 goto done;
1534
1535 case BT_OPEN:
1536 case BT_BOUND:
1537 /* Can connect */
1538 break;
1539
1540 default:
1541 err = -EBADFD;
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001542 release_sock(sk);
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001543 goto done;
1544 }
1545
1546 /* Set destination address and psm */
Gustavo F. Padovan9219b2a2012-01-02 20:08:04 -02001547 bacpy(&bt_sk(sk)->dst, dst);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001548
1549 release_sock(sk);
1550
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001551 chan->psm = psm;
1552 chan->dcid = cid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001553
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001554 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001555
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001556 if (chan->dcid == L2CAP_CID_LE_DATA)
Andre Guedes8e9f9892012-04-24 21:02:55 -03001557 hcon = hci_connect(hdev, LE_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001558 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001559 else
Andre Guedes8e9f9892012-04-24 21:02:55 -03001560 hcon = hci_connect(hdev, ACL_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001561 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001562
Ville Tervo30e76272011-02-22 16:10:53 -03001563 if (IS_ERR(hcon)) {
1564 err = PTR_ERR(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001565 goto done;
Ville Tervo30e76272011-02-22 16:10:53 -03001566 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001567
1568 conn = l2cap_conn_add(hcon, 0);
1569 if (!conn) {
1570 hci_conn_put(hcon);
Ville Tervo30e76272011-02-22 16:10:53 -03001571 err = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001572 goto done;
1573 }
1574
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001575 if (hcon->type == LE_LINK) {
1576 err = 0;
1577
1578 if (!list_empty(&conn->chan_l)) {
1579 err = -EBUSY;
1580 hci_conn_put(hcon);
1581 }
1582
1583 if (err)
1584 goto done;
1585 }
1586
Linus Torvalds1da177e2005-04-16 15:20:36 -07001587 /* Update source addr of the socket */
1588 bacpy(src, conn->src);
1589
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001590 l2cap_chan_unlock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001591 l2cap_chan_add(conn, chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001592 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001593
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001594 l2cap_state_change(chan, BT_CONNECT);
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001595 __set_chan_timer(chan, sk->sk_sndtimeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001596
1597 if (hcon->state == BT_CONNECTED) {
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001598 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001599 __clear_chan_timer(chan);
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001600 if (l2cap_chan_check_security(chan))
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001601 l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001602 } else
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001603 l2cap_do_start(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001604 }
1605
Ville Tervo30e76272011-02-22 16:10:53 -03001606 err = 0;
1607
Linus Torvalds1da177e2005-04-16 15:20:36 -07001608done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001609 l2cap_chan_unlock(chan);
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001610 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001611 hci_dev_put(hdev);
1612 return err;
1613}
1614
Gustavo F. Padovandcba0db2011-02-04 03:08:36 -02001615int __l2cap_wait_ack(struct sock *sk)
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001616{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001617 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001618 DECLARE_WAITQUEUE(wait, current);
1619 int err = 0;
1620 int timeo = HZ/5;
1621
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001622 add_wait_queue(sk_sleep(sk), &wait);
Peter Hurleya71a0cf2011-07-25 18:36:26 -04001623 set_current_state(TASK_INTERRUPTIBLE);
1624 while (chan->unacked_frames > 0 && chan->conn) {
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001625 if (!timeo)
1626 timeo = HZ/5;
1627
1628 if (signal_pending(current)) {
1629 err = sock_intr_errno(timeo);
1630 break;
1631 }
1632
1633 release_sock(sk);
1634 timeo = schedule_timeout(timeo);
1635 lock_sock(sk);
Peter Hurleya71a0cf2011-07-25 18:36:26 -04001636 set_current_state(TASK_INTERRUPTIBLE);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001637
1638 err = sock_error(sk);
1639 if (err)
1640 break;
1641 }
1642 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001643 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001644 return err;
1645}
1646
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001647static void l2cap_monitor_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001648{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001649 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001650 monitor_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001651
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03001652 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001653
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001654 l2cap_chan_lock(chan);
1655
Mat Martineau80909e02012-05-17 20:53:50 -07001656 if (!chan->conn) {
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 return;
1660 }
1661
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001662 l2cap_tx(chan, NULL, NULL, L2CAP_EV_MONITOR_TO);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001663
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001664 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001665 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001666}
1667
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001668static void l2cap_retrans_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001669{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001670 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001671 retrans_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001672
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03001673 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001674
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001675 l2cap_chan_lock(chan);
1676
Mat Martineau80909e02012-05-17 20:53:50 -07001677 if (!chan->conn) {
1678 l2cap_chan_unlock(chan);
1679 l2cap_chan_put(chan);
1680 return;
1681 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001682
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001683 l2cap_tx(chan, NULL, NULL, L2CAP_EV_RETRANS_TO);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001684 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001685 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001686}
1687
Mat Martineau37339372012-05-17 20:53:33 -07001688static int l2cap_streaming_send(struct l2cap_chan *chan,
1689 struct sk_buff_head *skbs)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001690{
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001691 struct sk_buff *skb;
Mat Martineau37339372012-05-17 20:53:33 -07001692 struct l2cap_ctrl *control;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001693
Mat Martineau37339372012-05-17 20:53:33 -07001694 BT_DBG("chan %p, skbs %p", chan, skbs);
1695
1696 if (chan->state != BT_CONNECTED)
1697 return -ENOTCONN;
1698
1699 skb_queue_splice_tail_init(skbs, &chan->tx_q);
1700
1701 while (!skb_queue_empty(&chan->tx_q)) {
1702
1703 skb = skb_dequeue(&chan->tx_q);
1704
1705 bt_cb(skb)->control.retries = 1;
1706 control = &bt_cb(skb)->control;
1707
1708 control->reqseq = 0;
1709 control->txseq = chan->next_tx_seq;
1710
1711 __pack_control(chan, control, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001712
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001713 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau37339372012-05-17 20:53:33 -07001714 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
1715 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001716 }
1717
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001718 l2cap_do_send(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001719
Mat Martineau37339372012-05-17 20:53:33 -07001720 BT_DBG("Sent txseq %d", (int)control->txseq);
1721
Andrei Emeltchenko836be932011-10-17 12:19:57 +03001722 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau37339372012-05-17 20:53:33 -07001723 chan->frames_sent++;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001724 }
Mat Martineau37339372012-05-17 20:53:33 -07001725
1726 return 0;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001727}
1728
Szymon Janc67c9e842011-07-28 16:24:33 +02001729static int l2cap_ertm_send(struct l2cap_chan *chan)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001730{
1731 struct sk_buff *skb, *tx_skb;
Mat Martineau18a48e72012-05-17 20:53:34 -07001732 struct l2cap_ctrl *control;
1733 int sent = 0;
1734
1735 BT_DBG("chan %p", chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001736
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001737 if (chan->state != BT_CONNECTED)
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001738 return -ENOTCONN;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001739
Mat Martineau94122bb2012-05-02 09:42:02 -07001740 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1741 return 0;
1742
Mat Martineau18a48e72012-05-17 20:53:34 -07001743 while (chan->tx_send_head &&
1744 chan->unacked_frames < chan->remote_tx_win &&
1745 chan->tx_state == L2CAP_TX_STATE_XMIT) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001746
Mat Martineau18a48e72012-05-17 20:53:34 -07001747 skb = chan->tx_send_head;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001748
Mat Martineau18a48e72012-05-17 20:53:34 -07001749 bt_cb(skb)->control.retries = 1;
1750 control = &bt_cb(skb)->control;
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03001751
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03001752 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
Mat Martineau18a48e72012-05-17 20:53:34 -07001753 control->final = 1;
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03001754
Mat Martineau18a48e72012-05-17 20:53:34 -07001755 control->reqseq = chan->buffer_seq;
1756 chan->last_acked_seq = chan->buffer_seq;
1757 control->txseq = chan->next_tx_seq;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001758
Mat Martineau18a48e72012-05-17 20:53:34 -07001759 __pack_control(chan, control, skb);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001760
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001761 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau18a48e72012-05-17 20:53:34 -07001762 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
1763 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001764 }
1765
Mat Martineau18a48e72012-05-17 20:53:34 -07001766 /* Clone after data has been modified. Data is assumed to be
1767 read-only (for locking purposes) on cloned sk_buffs.
1768 */
1769 tx_skb = skb_clone(skb, GFP_KERNEL);
1770
1771 if (!tx_skb)
1772 break;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001773
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03001774 __set_retrans_timer(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001775
Andrei Emeltchenko836be932011-10-17 12:19:57 +03001776 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau18a48e72012-05-17 20:53:34 -07001777 chan->unacked_frames++;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03001778 chan->frames_sent++;
Mat Martineau18a48e72012-05-17 20:53:34 -07001779 sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001780
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03001781 if (skb_queue_is_last(&chan->tx_q, skb))
1782 chan->tx_send_head = NULL;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001783 else
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03001784 chan->tx_send_head = skb_queue_next(&chan->tx_q, skb);
Mat Martineau18a48e72012-05-17 20:53:34 -07001785
1786 l2cap_do_send(chan, tx_skb);
1787 BT_DBG("Sent txseq %d", (int)control->txseq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001788 }
1789
Mat Martineau18a48e72012-05-17 20:53:34 -07001790 BT_DBG("Sent %d, %d unacked, %d in ERTM queue", sent,
1791 (int) chan->unacked_frames, skb_queue_len(&chan->tx_q));
1792
1793 return sent;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001794}
1795
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001796static void l2cap_ertm_resend(struct l2cap_chan *chan)
1797{
1798 struct l2cap_ctrl control;
1799 struct sk_buff *skb;
1800 struct sk_buff *tx_skb;
1801 u16 seq;
1802
1803 BT_DBG("chan %p", chan);
1804
1805 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1806 return;
1807
1808 while (chan->retrans_list.head != L2CAP_SEQ_LIST_CLEAR) {
1809 seq = l2cap_seq_list_pop(&chan->retrans_list);
1810
1811 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, seq);
1812 if (!skb) {
1813 BT_DBG("Error: Can't retransmit seq %d, frame missing",
1814 seq);
1815 continue;
1816 }
1817
1818 bt_cb(skb)->control.retries++;
1819 control = bt_cb(skb)->control;
1820
1821 if (chan->max_tx != 0 &&
1822 bt_cb(skb)->control.retries > chan->max_tx) {
1823 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
1824 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
1825 l2cap_seq_list_clear(&chan->retrans_list);
1826 break;
1827 }
1828
1829 control.reqseq = chan->buffer_seq;
1830 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
1831 control.final = 1;
1832 else
1833 control.final = 0;
1834
1835 if (skb_cloned(skb)) {
1836 /* Cloned sk_buffs are read-only, so we need a
1837 * writeable copy
1838 */
1839 tx_skb = skb_copy(skb, GFP_ATOMIC);
1840 } else {
1841 tx_skb = skb_clone(skb, GFP_ATOMIC);
1842 }
1843
1844 if (!tx_skb) {
1845 l2cap_seq_list_clear(&chan->retrans_list);
1846 break;
1847 }
1848
1849 /* Update skb contents */
1850 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
1851 put_unaligned_le32(__pack_extended_control(&control),
1852 tx_skb->data + L2CAP_HDR_SIZE);
1853 } else {
1854 put_unaligned_le16(__pack_enhanced_control(&control),
1855 tx_skb->data + L2CAP_HDR_SIZE);
1856 }
1857
1858 if (chan->fcs == L2CAP_FCS_CRC16) {
1859 u16 fcs = crc16(0, (u8 *) tx_skb->data, tx_skb->len);
1860 put_unaligned_le16(fcs, skb_put(tx_skb,
1861 L2CAP_FCS_SIZE));
1862 }
1863
1864 l2cap_do_send(chan, tx_skb);
1865
1866 BT_DBG("Resent txseq %d", control.txseq);
1867
1868 chan->last_acked_seq = chan->buffer_seq;
1869 }
1870}
1871
Mat Martineauf80842a2012-05-17 20:53:46 -07001872static void l2cap_retransmit(struct l2cap_chan *chan,
1873 struct l2cap_ctrl *control)
1874{
1875 BT_DBG("chan %p, control %p", chan, control);
1876
1877 l2cap_seq_list_append(&chan->retrans_list, control->reqseq);
1878 l2cap_ertm_resend(chan);
1879}
1880
Mat Martineaud2a7ac52012-05-17 20:53:42 -07001881static void l2cap_retransmit_all(struct l2cap_chan *chan,
1882 struct l2cap_ctrl *control)
1883{
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001884 struct sk_buff *skb;
1885
1886 BT_DBG("chan %p, control %p", chan, control);
1887
1888 if (control->poll)
1889 set_bit(CONN_SEND_FBIT, &chan->conn_state);
1890
1891 l2cap_seq_list_clear(&chan->retrans_list);
1892
1893 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1894 return;
1895
1896 if (chan->unacked_frames) {
1897 skb_queue_walk(&chan->tx_q, skb) {
1898 if (bt_cb(skb)->control.txseq == control->reqseq ||
1899 skb == chan->tx_send_head)
1900 break;
1901 }
1902
1903 skb_queue_walk_from(&chan->tx_q, skb) {
1904 if (skb == chan->tx_send_head)
1905 break;
1906
1907 l2cap_seq_list_append(&chan->retrans_list,
1908 bt_cb(skb)->control.txseq);
1909 }
1910
1911 l2cap_ertm_resend(chan);
1912 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07001913}
1914
Szymon Jancb17e73b2012-01-11 10:59:47 +01001915static void l2cap_send_ack(struct l2cap_chan *chan)
1916{
Mat Martineau0a0aba42012-05-17 20:53:39 -07001917 struct l2cap_ctrl control;
1918 u16 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
1919 chan->last_acked_seq);
1920 int threshold;
1921
1922 BT_DBG("chan %p last_acked_seq %d buffer_seq %d",
1923 chan, chan->last_acked_seq, chan->buffer_seq);
1924
1925 memset(&control, 0, sizeof(control));
1926 control.sframe = 1;
1927
1928 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
1929 chan->rx_state == L2CAP_RX_STATE_RECV) {
1930 __clear_ack_timer(chan);
1931 control.super = L2CAP_SUPER_RNR;
1932 control.reqseq = chan->buffer_seq;
1933 l2cap_send_sframe(chan, &control);
1934 } else {
1935 if (!test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) {
1936 l2cap_ertm_send(chan);
1937 /* If any i-frames were sent, they included an ack */
1938 if (chan->buffer_seq == chan->last_acked_seq)
1939 frames_to_ack = 0;
1940 }
1941
1942 /* Ack now if the tx window is 3/4ths full.
1943 * Calculate without mul or div
1944 */
1945 threshold = chan->tx_win;
1946 threshold += threshold << 1;
1947 threshold >>= 2;
1948
1949 BT_DBG("frames_to_ack %d, threshold %d", (int)frames_to_ack,
1950 threshold);
1951
1952 if (frames_to_ack >= threshold) {
1953 __clear_ack_timer(chan);
1954 control.super = L2CAP_SUPER_RR;
1955 control.reqseq = chan->buffer_seq;
1956 l2cap_send_sframe(chan, &control);
1957 frames_to_ack = 0;
1958 }
1959
1960 if (frames_to_ack)
1961 __set_ack_timer(chan);
1962 }
Szymon Jancb17e73b2012-01-11 10:59:47 +01001963}
1964
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001965static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
1966 struct msghdr *msg, int len,
1967 int count, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001968{
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02001969 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001970 struct sk_buff **frag;
Gustavo Padovan90338942012-04-06 20:15:47 -03001971 int sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001972
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03001973 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001974 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001975
1976 sent += count;
1977 len -= count;
1978
1979 /* Continuation fragments (no L2CAP header) */
1980 frag = &skb_shinfo(skb)->frag_list;
1981 while (len) {
Gustavo Padovanfbe00702012-05-15 13:22:55 -03001982 struct sk_buff *tmp;
1983
Linus Torvalds1da177e2005-04-16 15:20:36 -07001984 count = min_t(unsigned int, conn->mtu, len);
1985
Gustavo Padovanfbe00702012-05-15 13:22:55 -03001986 tmp = chan->ops->alloc_skb(chan, count,
1987 msg->msg_flags & MSG_DONTWAIT);
1988 if (IS_ERR(tmp))
1989 return PTR_ERR(tmp);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02001990
Gustavo Padovanfbe00702012-05-15 13:22:55 -03001991 *frag = tmp;
1992
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001993 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
1994 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001995
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02001996 (*frag)->priority = skb->priority;
1997
Linus Torvalds1da177e2005-04-16 15:20:36 -07001998 sent += count;
1999 len -= count;
2000
Gustavo Padovan2d0ed3d2012-05-11 13:16:12 -03002001 skb->len += (*frag)->len;
2002 skb->data_len += (*frag)->len;
2003
Linus Torvalds1da177e2005-04-16 15:20:36 -07002004 frag = &(*frag)->next;
2005 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002006
2007 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002008}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002009
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002010static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan,
2011 struct msghdr *msg, size_t len,
2012 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002013{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002014 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002015 struct sk_buff *skb;
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002016 int err, count, hlen = L2CAP_HDR_SIZE + L2CAP_PSMLEN_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002017 struct l2cap_hdr *lh;
2018
Andrei Emeltchenko6d5922b2012-02-06 15:04:01 +02002019 BT_DBG("chan %p len %d priority %u", chan, (int)len, priority);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002020
2021 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002022
2023 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002024 msg->msg_flags & MSG_DONTWAIT);
2025 if (IS_ERR(skb))
2026 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002027
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002028 skb->priority = priority;
2029
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002030 /* Create L2CAP header */
2031 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002032 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenkodaf6a78c2012-05-03 10:55:52 +03002033 lh->len = cpu_to_le16(len + L2CAP_PSMLEN_SIZE);
2034 put_unaligned(chan->psm, skb_put(skb, L2CAP_PSMLEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002035
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002036 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002037 if (unlikely(err < 0)) {
2038 kfree_skb(skb);
2039 return ERR_PTR(err);
2040 }
2041 return skb;
2042}
2043
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002044static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan,
2045 struct msghdr *msg, size_t len,
2046 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002047{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002048 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002049 struct sk_buff *skb;
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002050 int err, count;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002051 struct l2cap_hdr *lh;
2052
Andrei Emeltchenko6d5922b2012-02-06 15:04:01 +02002053 BT_DBG("chan %p len %d", chan, (int)len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002054
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002055 count = min_t(unsigned int, (conn->mtu - L2CAP_HDR_SIZE), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002056
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002057 skb = chan->ops->alloc_skb(chan, count + L2CAP_HDR_SIZE,
Gustavo Padovan90338942012-04-06 20:15:47 -03002058 msg->msg_flags & MSG_DONTWAIT);
2059 if (IS_ERR(skb))
2060 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002061
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002062 skb->priority = priority;
2063
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002064 /* Create L2CAP header */
2065 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002066 lh->cid = cpu_to_le16(chan->dcid);
Gustavo Padovan6ff9b5e2012-05-02 11:56:17 -03002067 lh->len = cpu_to_le16(len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002068
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002069 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002070 if (unlikely(err < 0)) {
2071 kfree_skb(skb);
2072 return ERR_PTR(err);
2073 }
2074 return skb;
2075}
2076
Luiz Augusto von Dentzab0ff762011-09-12 20:00:50 +03002077static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan,
2078 struct msghdr *msg, size_t len,
Mat Martineau94122bb2012-05-02 09:42:02 -07002079 u16 sdulen)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002080{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002081 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002082 struct sk_buff *skb;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002083 int err, count, hlen;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002084 struct l2cap_hdr *lh;
2085
Andrei Emeltchenko6d5922b2012-02-06 15:04:01 +02002086 BT_DBG("chan %p len %d", chan, (int)len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002087
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03002088 if (!conn)
2089 return ERR_PTR(-ENOTCONN);
2090
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002091 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
2092 hlen = L2CAP_EXT_HDR_SIZE;
2093 else
2094 hlen = L2CAP_ENH_HDR_SIZE;
2095
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002096 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002097 hlen += L2CAP_SDULEN_SIZE;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002098
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002099 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002100 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002101
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002102 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002103
2104 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002105 msg->msg_flags & MSG_DONTWAIT);
2106 if (IS_ERR(skb))
2107 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002108
2109 /* Create L2CAP header */
2110 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002111 lh->cid = cpu_to_le16(chan->dcid);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002112 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002113
Mat Martineau18a48e72012-05-17 20:53:34 -07002114 /* Control header is populated later */
2115 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
2116 put_unaligned_le32(0, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
2117 else
2118 put_unaligned_le16(0, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002119
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002120 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002121 put_unaligned_le16(sdulen, skb_put(skb, L2CAP_SDULEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002122
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002123 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002124 if (unlikely(err < 0)) {
2125 kfree_skb(skb);
2126 return ERR_PTR(err);
2127 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002128
Mat Martineau18a48e72012-05-17 20:53:34 -07002129 bt_cb(skb)->control.fcs = chan->fcs;
Mat Martineau3ce35142012-04-25 16:36:14 -07002130 bt_cb(skb)->control.retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002131 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002132}
2133
Mat Martineau94122bb2012-05-02 09:42:02 -07002134static int l2cap_segment_sdu(struct l2cap_chan *chan,
2135 struct sk_buff_head *seg_queue,
2136 struct msghdr *msg, size_t len)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002137{
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002138 struct sk_buff *skb;
Mat Martineau94122bb2012-05-02 09:42:02 -07002139 u16 sdu_len;
2140 size_t pdu_len;
2141 int err = 0;
2142 u8 sar;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002143
Mat Martineau94122bb2012-05-02 09:42:02 -07002144 BT_DBG("chan %p, msg %p, len %d", chan, msg, (int)len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002145
Mat Martineau94122bb2012-05-02 09:42:02 -07002146 /* It is critical that ERTM PDUs fit in a single HCI fragment,
2147 * so fragmented skbs are not used. The HCI layer's handling
2148 * of fragmented skbs is not compatible with ERTM's queueing.
2149 */
2150
2151 /* PDU size is derived from the HCI MTU */
2152 pdu_len = chan->conn->mtu;
2153
2154 pdu_len = min_t(size_t, pdu_len, L2CAP_BREDR_MAX_PAYLOAD);
2155
2156 /* Adjust for largest possible L2CAP overhead. */
2157 pdu_len -= L2CAP_EXT_HDR_SIZE + L2CAP_FCS_SIZE;
2158
2159 /* Remote device may have requested smaller PDUs */
2160 pdu_len = min_t(size_t, pdu_len, chan->remote_mps);
2161
2162 if (len <= pdu_len) {
2163 sar = L2CAP_SAR_UNSEGMENTED;
2164 sdu_len = 0;
2165 pdu_len = len;
2166 } else {
2167 sar = L2CAP_SAR_START;
2168 sdu_len = len;
2169 pdu_len -= L2CAP_SDULEN_SIZE;
2170 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002171
2172 while (len > 0) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002173 skb = l2cap_create_iframe_pdu(chan, msg, pdu_len, sdu_len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002174
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002175 if (IS_ERR(skb)) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002176 __skb_queue_purge(seg_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002177 return PTR_ERR(skb);
2178 }
2179
Mat Martineau94122bb2012-05-02 09:42:02 -07002180 bt_cb(skb)->control.sar = sar;
2181 __skb_queue_tail(seg_queue, skb);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002182
Mat Martineau94122bb2012-05-02 09:42:02 -07002183 len -= pdu_len;
2184 if (sdu_len) {
2185 sdu_len = 0;
2186 pdu_len += L2CAP_SDULEN_SIZE;
2187 }
2188
2189 if (len <= pdu_len) {
2190 sar = L2CAP_SAR_END;
2191 pdu_len = len;
2192 } else {
2193 sar = L2CAP_SAR_CONTINUE;
2194 }
2195 }
2196
2197 return err;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002198}
2199
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002200int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
2201 u32 priority)
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002202{
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002203 struct sk_buff *skb;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002204 int err;
Mat Martineau94122bb2012-05-02 09:42:02 -07002205 struct sk_buff_head seg_queue;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002206
2207 /* Connectionless channel */
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002208 if (chan->chan_type == L2CAP_CHAN_CONN_LESS) {
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002209 skb = l2cap_create_connless_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002210 if (IS_ERR(skb))
2211 return PTR_ERR(skb);
2212
2213 l2cap_do_send(chan, skb);
2214 return len;
2215 }
2216
2217 switch (chan->mode) {
2218 case L2CAP_MODE_BASIC:
2219 /* Check outgoing MTU */
2220 if (len > chan->omtu)
2221 return -EMSGSIZE;
2222
2223 /* Create a basic PDU */
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002224 skb = l2cap_create_basic_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002225 if (IS_ERR(skb))
2226 return PTR_ERR(skb);
2227
2228 l2cap_do_send(chan, skb);
2229 err = len;
2230 break;
2231
2232 case L2CAP_MODE_ERTM:
2233 case L2CAP_MODE_STREAMING:
Mat Martineau94122bb2012-05-02 09:42:02 -07002234 /* Check outgoing MTU */
2235 if (len > chan->omtu) {
2236 err = -EMSGSIZE;
2237 break;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002238 }
2239
Mat Martineau94122bb2012-05-02 09:42:02 -07002240 __skb_queue_head_init(&seg_queue);
2241
2242 /* Do segmentation before calling in to the state machine,
2243 * since it's possible to block while waiting for memory
2244 * allocation.
2245 */
2246 err = l2cap_segment_sdu(chan, &seg_queue, msg, len);
2247
2248 /* The channel could have been closed while segmenting,
2249 * check that it is still connected.
2250 */
2251 if (chan->state != BT_CONNECTED) {
2252 __skb_queue_purge(&seg_queue);
2253 err = -ENOTCONN;
2254 }
2255
2256 if (err)
2257 break;
2258
Mat Martineau37339372012-05-17 20:53:33 -07002259 if (chan->mode == L2CAP_MODE_ERTM)
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002260 err = l2cap_tx(chan, NULL, &seg_queue,
Mat Martineau608bcc62012-05-17 20:53:32 -07002261 L2CAP_EV_DATA_REQUEST);
Mat Martineau37339372012-05-17 20:53:33 -07002262 else
2263 err = l2cap_streaming_send(chan, &seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002264
Mat Martineau608bcc62012-05-17 20:53:32 -07002265 if (!err)
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002266 err = len;
2267
Mat Martineau94122bb2012-05-02 09:42:02 -07002268 /* If the skbs were not queued for sending, they'll still be in
2269 * seg_queue and need to be purged.
2270 */
2271 __skb_queue_purge(&seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002272 break;
2273
2274 default:
2275 BT_DBG("bad state %1.1x", chan->mode);
2276 err = -EBADFD;
2277 }
2278
2279 return err;
2280}
2281
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002282static void l2cap_send_srej(struct l2cap_chan *chan, u16 txseq)
2283{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002284 struct l2cap_ctrl control;
2285 u16 seq;
2286
2287 BT_DBG("chan %p, txseq %d", chan, txseq);
2288
2289 memset(&control, 0, sizeof(control));
2290 control.sframe = 1;
2291 control.super = L2CAP_SUPER_SREJ;
2292
2293 for (seq = chan->expected_tx_seq; seq != txseq;
2294 seq = __next_seq(chan, seq)) {
2295 if (!l2cap_ertm_seq_in_queue(&chan->srej_q, seq)) {
2296 control.reqseq = seq;
2297 l2cap_send_sframe(chan, &control);
2298 l2cap_seq_list_append(&chan->srej_list, seq);
2299 }
2300 }
2301
2302 chan->expected_tx_seq = __next_seq(chan, txseq);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002303}
2304
2305static void l2cap_send_srej_tail(struct l2cap_chan *chan)
2306{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002307 struct l2cap_ctrl control;
2308
2309 BT_DBG("chan %p", chan);
2310
2311 if (chan->srej_list.tail == L2CAP_SEQ_LIST_CLEAR)
2312 return;
2313
2314 memset(&control, 0, sizeof(control));
2315 control.sframe = 1;
2316 control.super = L2CAP_SUPER_SREJ;
2317 control.reqseq = chan->srej_list.tail;
2318 l2cap_send_sframe(chan, &control);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002319}
2320
2321static void l2cap_send_srej_list(struct l2cap_chan *chan, u16 txseq)
2322{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002323 struct l2cap_ctrl control;
2324 u16 initial_head;
2325 u16 seq;
2326
2327 BT_DBG("chan %p, txseq %d", chan, txseq);
2328
2329 memset(&control, 0, sizeof(control));
2330 control.sframe = 1;
2331 control.super = L2CAP_SUPER_SREJ;
2332
2333 /* Capture initial list head to allow only one pass through the list. */
2334 initial_head = chan->srej_list.head;
2335
2336 do {
2337 seq = l2cap_seq_list_pop(&chan->srej_list);
2338 if (seq == txseq || seq == L2CAP_SEQ_LIST_CLEAR)
2339 break;
2340
2341 control.reqseq = seq;
2342 l2cap_send_sframe(chan, &control);
2343 l2cap_seq_list_append(&chan->srej_list, seq);
2344 } while (chan->srej_list.head != initial_head);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002345}
2346
Mat Martineau608bcc62012-05-17 20:53:32 -07002347static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq)
2348{
2349 struct sk_buff *acked_skb;
2350 u16 ackseq;
2351
2352 BT_DBG("chan %p, reqseq %d", chan, reqseq);
2353
2354 if (chan->unacked_frames == 0 || reqseq == chan->expected_ack_seq)
2355 return;
2356
2357 BT_DBG("expected_ack_seq %d, unacked_frames %d",
2358 chan->expected_ack_seq, chan->unacked_frames);
2359
2360 for (ackseq = chan->expected_ack_seq; ackseq != reqseq;
2361 ackseq = __next_seq(chan, ackseq)) {
2362
2363 acked_skb = l2cap_ertm_seq_in_queue(&chan->tx_q, ackseq);
2364 if (acked_skb) {
2365 skb_unlink(acked_skb, &chan->tx_q);
2366 kfree_skb(acked_skb);
2367 chan->unacked_frames--;
2368 }
2369 }
2370
2371 chan->expected_ack_seq = reqseq;
2372
2373 if (chan->unacked_frames == 0)
2374 __clear_retrans_timer(chan);
2375
2376 BT_DBG("unacked_frames %d", (int) chan->unacked_frames);
2377}
2378
2379static void l2cap_abort_rx_srej_sent(struct l2cap_chan *chan)
2380{
2381 BT_DBG("chan %p", chan);
2382
2383 chan->expected_tx_seq = chan->buffer_seq;
2384 l2cap_seq_list_clear(&chan->srej_list);
2385 skb_queue_purge(&chan->srej_q);
2386 chan->rx_state = L2CAP_RX_STATE_RECV;
2387}
2388
2389static int l2cap_tx_state_xmit(struct l2cap_chan *chan,
2390 struct l2cap_ctrl *control,
2391 struct sk_buff_head *skbs, u8 event)
2392{
2393 int err = 0;
2394
2395 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2396 event);
2397
2398 switch (event) {
2399 case L2CAP_EV_DATA_REQUEST:
2400 if (chan->tx_send_head == NULL)
2401 chan->tx_send_head = skb_peek(skbs);
2402
2403 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2404 l2cap_ertm_send(chan);
2405 break;
2406 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2407 BT_DBG("Enter LOCAL_BUSY");
2408 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2409
2410 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2411 /* The SREJ_SENT state must be aborted if we are to
2412 * enter the LOCAL_BUSY state.
2413 */
2414 l2cap_abort_rx_srej_sent(chan);
2415 }
2416
2417 l2cap_send_ack(chan);
2418
2419 break;
2420 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2421 BT_DBG("Exit LOCAL_BUSY");
2422 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2423
2424 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2425 struct l2cap_ctrl local_control;
2426
2427 memset(&local_control, 0, sizeof(local_control));
2428 local_control.sframe = 1;
2429 local_control.super = L2CAP_SUPER_RR;
2430 local_control.poll = 1;
2431 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002432 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002433
2434 chan->retry_count = 1;
2435 __set_monitor_timer(chan);
2436 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2437 }
2438 break;
2439 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2440 l2cap_process_reqseq(chan, control->reqseq);
2441 break;
2442 case L2CAP_EV_EXPLICIT_POLL:
2443 l2cap_send_rr_or_rnr(chan, 1);
2444 chan->retry_count = 1;
2445 __set_monitor_timer(chan);
2446 __clear_ack_timer(chan);
2447 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2448 break;
2449 case L2CAP_EV_RETRANS_TO:
2450 l2cap_send_rr_or_rnr(chan, 1);
2451 chan->retry_count = 1;
2452 __set_monitor_timer(chan);
2453 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2454 break;
2455 case L2CAP_EV_RECV_FBIT:
2456 /* Nothing to process */
2457 break;
2458 default:
2459 break;
2460 }
2461
2462 return err;
2463}
2464
2465static int l2cap_tx_state_wait_f(struct l2cap_chan *chan,
2466 struct l2cap_ctrl *control,
2467 struct sk_buff_head *skbs, u8 event)
2468{
2469 int err = 0;
2470
2471 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2472 event);
2473
2474 switch (event) {
2475 case L2CAP_EV_DATA_REQUEST:
2476 if (chan->tx_send_head == NULL)
2477 chan->tx_send_head = skb_peek(skbs);
2478 /* Queue data, but don't send. */
2479 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2480 break;
2481 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2482 BT_DBG("Enter LOCAL_BUSY");
2483 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2484
2485 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2486 /* The SREJ_SENT state must be aborted if we are to
2487 * enter the LOCAL_BUSY state.
2488 */
2489 l2cap_abort_rx_srej_sent(chan);
2490 }
2491
2492 l2cap_send_ack(chan);
2493
2494 break;
2495 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2496 BT_DBG("Exit LOCAL_BUSY");
2497 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2498
2499 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2500 struct l2cap_ctrl local_control;
2501 memset(&local_control, 0, sizeof(local_control));
2502 local_control.sframe = 1;
2503 local_control.super = L2CAP_SUPER_RR;
2504 local_control.poll = 1;
2505 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002506 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002507
2508 chan->retry_count = 1;
2509 __set_monitor_timer(chan);
2510 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2511 }
2512 break;
2513 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2514 l2cap_process_reqseq(chan, control->reqseq);
2515
2516 /* Fall through */
2517
2518 case L2CAP_EV_RECV_FBIT:
2519 if (control && control->final) {
2520 __clear_monitor_timer(chan);
2521 if (chan->unacked_frames > 0)
2522 __set_retrans_timer(chan);
2523 chan->retry_count = 0;
2524 chan->tx_state = L2CAP_TX_STATE_XMIT;
2525 BT_DBG("recv fbit tx_state 0x2.2%x", chan->tx_state);
2526 }
2527 break;
2528 case L2CAP_EV_EXPLICIT_POLL:
2529 /* Ignore */
2530 break;
2531 case L2CAP_EV_MONITOR_TO:
2532 if (chan->max_tx == 0 || chan->retry_count < chan->max_tx) {
2533 l2cap_send_rr_or_rnr(chan, 1);
2534 __set_monitor_timer(chan);
2535 chan->retry_count++;
2536 } else {
2537 l2cap_send_disconn_req(chan->conn, chan, ECONNABORTED);
2538 }
2539 break;
2540 default:
2541 break;
2542 }
2543
2544 return err;
2545}
2546
2547static int l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
2548 struct sk_buff_head *skbs, u8 event)
2549{
2550 int err = 0;
2551
2552 BT_DBG("chan %p, control %p, skbs %p, event %d, state %d",
2553 chan, control, skbs, event, chan->tx_state);
2554
2555 switch (chan->tx_state) {
2556 case L2CAP_TX_STATE_XMIT:
2557 err = l2cap_tx_state_xmit(chan, control, skbs, event);
2558 break;
2559 case L2CAP_TX_STATE_WAIT_F:
2560 err = l2cap_tx_state_wait_f(chan, control, skbs, event);
2561 break;
2562 default:
2563 /* Ignore event */
2564 break;
2565 }
2566
2567 return err;
2568}
2569
Mat Martineau4b51dae92012-05-17 20:53:37 -07002570static void l2cap_pass_to_tx(struct l2cap_chan *chan,
2571 struct l2cap_ctrl *control)
2572{
2573 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002574 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_REQSEQ_AND_FBIT);
Mat Martineau4b51dae92012-05-17 20:53:37 -07002575}
2576
Mat Martineauf80842a2012-05-17 20:53:46 -07002577static void l2cap_pass_to_tx_fbit(struct l2cap_chan *chan,
2578 struct l2cap_ctrl *control)
2579{
2580 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002581 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_FBIT);
Mat Martineauf80842a2012-05-17 20:53:46 -07002582}
2583
Linus Torvalds1da177e2005-04-16 15:20:36 -07002584/* Copy frame to all raw sockets on that connection */
2585static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2586{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002587 struct sk_buff *nskb;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002588 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002589
2590 BT_DBG("conn %p", conn);
2591
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002592 mutex_lock(&conn->chan_lock);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002593
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002594 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002595 struct sock *sk = chan->sk;
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002596 if (chan->chan_type != L2CAP_CHAN_RAW)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002597 continue;
2598
2599 /* Don't send frame to the socket it came from */
2600 if (skb->sk == sk)
2601 continue;
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002602 nskb = skb_clone(skb, GFP_ATOMIC);
2603 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002604 continue;
2605
Gustavo F. Padovan23070492011-05-16 17:57:22 -03002606 if (chan->ops->recv(chan->data, nskb))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002607 kfree_skb(nskb);
2608 }
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002609
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002610 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002611}
2612
2613/* ---- L2CAP signalling commands ---- */
2614static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
2615 u8 code, u8 ident, u16 dlen, void *data)
2616{
2617 struct sk_buff *skb, **frag;
2618 struct l2cap_cmd_hdr *cmd;
2619 struct l2cap_hdr *lh;
2620 int len, count;
2621
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002622 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d",
2623 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002624
2625 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2626 count = min_t(unsigned int, conn->mtu, len);
2627
2628 skb = bt_skb_alloc(count, GFP_ATOMIC);
2629 if (!skb)
2630 return NULL;
2631
2632 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002633 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002634
2635 if (conn->hcon->type == LE_LINK)
2636 lh->cid = cpu_to_le16(L2CAP_CID_LE_SIGNALING);
2637 else
2638 lh->cid = cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002639
2640 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2641 cmd->code = code;
2642 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002643 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002644
2645 if (dlen) {
2646 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2647 memcpy(skb_put(skb, count), data, count);
2648 data += count;
2649 }
2650
2651 len -= skb->len;
2652
2653 /* Continuation fragments (no L2CAP header) */
2654 frag = &skb_shinfo(skb)->frag_list;
2655 while (len) {
2656 count = min_t(unsigned int, conn->mtu, len);
2657
2658 *frag = bt_skb_alloc(count, GFP_ATOMIC);
2659 if (!*frag)
2660 goto fail;
2661
2662 memcpy(skb_put(*frag, count), data, count);
2663
2664 len -= count;
2665 data += count;
2666
2667 frag = &(*frag)->next;
2668 }
2669
2670 return skb;
2671
2672fail:
2673 kfree_skb(skb);
2674 return NULL;
2675}
2676
2677static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned long *val)
2678{
2679 struct l2cap_conf_opt *opt = *ptr;
2680 int len;
2681
2682 len = L2CAP_CONF_OPT_SIZE + opt->len;
2683 *ptr += len;
2684
2685 *type = opt->type;
2686 *olen = opt->len;
2687
2688 switch (opt->len) {
2689 case 1:
2690 *val = *((u8 *) opt->val);
2691 break;
2692
2693 case 2:
steven miaobfaaeb32010-10-16 18:29:47 -04002694 *val = get_unaligned_le16(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002695 break;
2696
2697 case 4:
steven miaobfaaeb32010-10-16 18:29:47 -04002698 *val = get_unaligned_le32(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002699 break;
2700
2701 default:
2702 *val = (unsigned long) opt->val;
2703 break;
2704 }
2705
2706 BT_DBG("type 0x%2.2x len %d val 0x%lx", *type, opt->len, *val);
2707 return len;
2708}
2709
Linus Torvalds1da177e2005-04-16 15:20:36 -07002710static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2711{
2712 struct l2cap_conf_opt *opt = *ptr;
2713
2714 BT_DBG("type 0x%2.2x len %d val 0x%lx", type, len, val);
2715
2716 opt->type = type;
2717 opt->len = len;
2718
2719 switch (len) {
2720 case 1:
2721 *((u8 *) opt->val) = val;
2722 break;
2723
2724 case 2:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002725 put_unaligned_le16(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002726 break;
2727
2728 case 4:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002729 put_unaligned_le32(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002730 break;
2731
2732 default:
2733 memcpy(opt->val, (void *) val, len);
2734 break;
2735 }
2736
2737 *ptr += L2CAP_CONF_OPT_SIZE + len;
2738}
2739
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002740static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan)
2741{
2742 struct l2cap_conf_efs efs;
2743
Szymon Janc1ec918c2011-11-16 09:32:21 +01002744 switch (chan->mode) {
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002745 case L2CAP_MODE_ERTM:
2746 efs.id = chan->local_id;
2747 efs.stype = chan->local_stype;
2748 efs.msdu = cpu_to_le16(chan->local_msdu);
2749 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
2750 efs.acc_lat = cpu_to_le32(L2CAP_DEFAULT_ACC_LAT);
2751 efs.flush_to = cpu_to_le32(L2CAP_DEFAULT_FLUSH_TO);
2752 break;
2753
2754 case L2CAP_MODE_STREAMING:
2755 efs.id = 1;
2756 efs.stype = L2CAP_SERV_BESTEFFORT;
2757 efs.msdu = cpu_to_le16(chan->local_msdu);
2758 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
2759 efs.acc_lat = 0;
2760 efs.flush_to = 0;
2761 break;
2762
2763 default:
2764 return;
2765 }
2766
2767 l2cap_add_conf_opt(ptr, L2CAP_CONF_EFS, sizeof(efs),
2768 (unsigned long) &efs);
2769}
2770
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002771static void l2cap_ack_timeout(struct work_struct *work)
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002772{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002773 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau03625202012-05-17 20:53:51 -07002774 ack_timer.work);
2775 u16 frames_to_ack;
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002776
Gustavo F. Padovan2fb9b3d2011-12-22 16:56:05 -02002777 BT_DBG("chan %p", chan);
2778
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02002779 l2cap_chan_lock(chan);
2780
Mat Martineau03625202012-05-17 20:53:51 -07002781 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
2782 chan->last_acked_seq);
2783
2784 if (frames_to_ack)
2785 l2cap_send_rr_or_rnr(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02002786
2787 l2cap_chan_unlock(chan);
Szymon Janc09bfb2e2012-01-11 10:59:49 +01002788 l2cap_chan_put(chan);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002789}
2790
Mat Martineau3c588192012-04-11 10:48:42 -07002791static inline int l2cap_ertm_init(struct l2cap_chan *chan)
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002792{
Mat Martineau3c588192012-04-11 10:48:42 -07002793 int err;
2794
Mat Martineau105bdf92012-04-27 16:50:48 -07002795 chan->next_tx_seq = 0;
2796 chan->expected_tx_seq = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03002797 chan->expected_ack_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03002798 chan->unacked_frames = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03002799 chan->buffer_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03002800 chan->frames_sent = 0;
Mat Martineau105bdf92012-04-27 16:50:48 -07002801 chan->last_acked_seq = 0;
2802 chan->sdu = NULL;
2803 chan->sdu_last_frag = NULL;
2804 chan->sdu_len = 0;
2805
Mat Martineaud34c34f2012-05-14 14:49:27 -07002806 skb_queue_head_init(&chan->tx_q);
2807
Mat Martineau105bdf92012-04-27 16:50:48 -07002808 if (chan->mode != L2CAP_MODE_ERTM)
2809 return 0;
2810
2811 chan->rx_state = L2CAP_RX_STATE_RECV;
2812 chan->tx_state = L2CAP_TX_STATE_XMIT;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002813
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002814 INIT_DELAYED_WORK(&chan->retrans_timer, l2cap_retrans_timeout);
2815 INIT_DELAYED_WORK(&chan->monitor_timer, l2cap_monitor_timeout);
2816 INIT_DELAYED_WORK(&chan->ack_timer, l2cap_ack_timeout);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002817
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -03002818 skb_queue_head_init(&chan->srej_q);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002819
Mat Martineau3c588192012-04-11 10:48:42 -07002820 err = l2cap_seq_list_init(&chan->srej_list, chan->tx_win);
2821 if (err < 0)
2822 return err;
2823
Mat Martineau9dc9aff2012-05-17 16:20:14 -07002824 err = l2cap_seq_list_init(&chan->retrans_list, chan->remote_tx_win);
2825 if (err < 0)
2826 l2cap_seq_list_free(&chan->srej_list);
2827
2828 return err;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002829}
2830
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002831static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
2832{
2833 switch (mode) {
2834 case L2CAP_MODE_STREAMING:
2835 case L2CAP_MODE_ERTM:
2836 if (l2cap_mode_supported(mode, remote_feat_mask))
2837 return mode;
2838 /* fall through */
2839 default:
2840 return L2CAP_MODE_BASIC;
2841 }
2842}
2843
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002844static inline bool __l2cap_ews_supported(struct l2cap_chan *chan)
2845{
2846 return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_WINDOW;
2847}
2848
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002849static inline bool __l2cap_efs_supported(struct l2cap_chan *chan)
2850{
2851 return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_FLOW;
2852}
2853
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002854static inline void l2cap_txwin_setup(struct l2cap_chan *chan)
2855{
2856 if (chan->tx_win > L2CAP_DEFAULT_TX_WINDOW &&
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002857 __l2cap_ews_supported(chan)) {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002858 /* use extended control field */
2859 set_bit(FLAG_EXT_CTRL, &chan->flags);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002860 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
2861 } else {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002862 chan->tx_win = min_t(u16, chan->tx_win,
2863 L2CAP_DEFAULT_TX_WINDOW);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002864 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
2865 }
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002866}
2867
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03002868static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002869{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002870 struct l2cap_conf_req *req = data;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002871 struct l2cap_conf_rfc rfc = { .mode = chan->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07002872 void *ptr = req->data;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03002873 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002874
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03002875 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002876
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03002877 if (chan->num_conf_req || chan->num_conf_rsp)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002878 goto done;
2879
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002880 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002881 case L2CAP_MODE_STREAMING:
2882 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03002883 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state))
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03002884 break;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03002885
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002886 if (__l2cap_efs_supported(chan))
2887 set_bit(FLAG_EFS_ENABLE, &chan->flags);
2888
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03002889 /* fall through */
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002890 default:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002891 chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002892 break;
2893 }
2894
2895done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002896 if (chan->imtu != L2CAP_DEFAULT_MTU)
2897 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovan7990681c2011-01-24 16:01:43 -02002898
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002899 switch (chan->mode) {
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002900 case L2CAP_MODE_BASIC:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002901 if (!(chan->conn->feat_mask & L2CAP_FEAT_ERTM) &&
2902 !(chan->conn->feat_mask & L2CAP_FEAT_STREAMING))
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002903 break;
2904
Gustavo F. Padovan62547752010-06-08 20:05:31 -03002905 rfc.mode = L2CAP_MODE_BASIC;
2906 rfc.txwin_size = 0;
2907 rfc.max_transmit = 0;
2908 rfc.retrans_timeout = 0;
2909 rfc.monitor_timeout = 0;
2910 rfc.max_pdu_size = 0;
2911
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002912 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
2913 (unsigned long) &rfc);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002914 break;
2915
2916 case L2CAP_MODE_ERTM:
2917 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002918 rfc.max_transmit = chan->max_tx;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002919 rfc.retrans_timeout = 0;
2920 rfc.monitor_timeout = 0;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03002921
2922 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
2923 L2CAP_EXT_HDR_SIZE -
2924 L2CAP_SDULEN_SIZE -
2925 L2CAP_FCS_SIZE);
2926 rfc.max_pdu_size = cpu_to_le16(size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002927
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002928 l2cap_txwin_setup(chan);
2929
2930 rfc.txwin_size = min_t(u16, chan->tx_win,
2931 L2CAP_DEFAULT_TX_WINDOW);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002932
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002933 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
2934 (unsigned long) &rfc);
2935
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002936 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
2937 l2cap_add_opt_efs(&ptr, chan);
2938
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002939 if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS))
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002940 break;
2941
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002942 if (chan->fcs == L2CAP_FCS_NONE ||
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03002943 test_bit(CONF_NO_FCS_RECV, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002944 chan->fcs = L2CAP_FCS_NONE;
2945 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002946 }
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002947
2948 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
2949 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
2950 chan->tx_win);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002951 break;
2952
2953 case L2CAP_MODE_STREAMING:
Mat Martineau273759e2012-05-17 20:53:53 -07002954 l2cap_txwin_setup(chan);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002955 rfc.mode = L2CAP_MODE_STREAMING;
2956 rfc.txwin_size = 0;
2957 rfc.max_transmit = 0;
2958 rfc.retrans_timeout = 0;
2959 rfc.monitor_timeout = 0;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03002960
2961 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
2962 L2CAP_EXT_HDR_SIZE -
2963 L2CAP_SDULEN_SIZE -
2964 L2CAP_FCS_SIZE);
2965 rfc.max_pdu_size = cpu_to_le16(size);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002966
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002967 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
2968 (unsigned long) &rfc);
2969
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002970 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
2971 l2cap_add_opt_efs(&ptr, chan);
2972
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002973 if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS))
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002974 break;
2975
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002976 if (chan->fcs == L2CAP_FCS_NONE ||
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03002977 test_bit(CONF_NO_FCS_RECV, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002978 chan->fcs = L2CAP_FCS_NONE;
2979 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002980 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002981 break;
2982 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002983
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002984 req->dcid = cpu_to_le16(chan->dcid);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002985 req->flags = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002986
2987 return ptr - data;
2988}
2989
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03002990static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002991{
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002992 struct l2cap_conf_rsp *rsp = data;
2993 void *ptr = rsp->data;
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03002994 void *req = chan->conf_req;
2995 int len = chan->conf_len;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002996 int type, hint, olen;
2997 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002998 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03002999 struct l2cap_conf_efs efs;
3000 u8 remote_efs = 0;
Marcel Holtmann861d6882007-10-20 13:37:06 +02003001 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003002 u16 result = L2CAP_CONF_SUCCESS;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003003 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003004
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003005 BT_DBG("chan %p", chan);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01003006
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003007 while (len >= L2CAP_CONF_OPT_SIZE) {
3008 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003009
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03003010 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003011 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003012
3013 switch (type) {
3014 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02003015 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003016 break;
3017
3018 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003019 chan->flush_to = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003020 break;
3021
3022 case L2CAP_CONF_QOS:
3023 break;
3024
Marcel Holtmann6464f352007-10-20 13:39:51 +02003025 case L2CAP_CONF_RFC:
3026 if (olen == sizeof(rfc))
3027 memcpy(&rfc, (void *) val, olen);
3028 break;
3029
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003030 case L2CAP_CONF_FCS:
3031 if (val == L2CAP_FCS_NONE)
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003032 set_bit(CONF_NO_FCS_RECV, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003033 break;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003034
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003035 case L2CAP_CONF_EFS:
3036 remote_efs = 1;
3037 if (olen == sizeof(efs))
3038 memcpy(&efs, (void *) val, olen);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003039 break;
3040
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003041 case L2CAP_CONF_EWS:
3042 if (!enable_hs)
3043 return -ECONNREFUSED;
3044
3045 set_bit(FLAG_EXT_CTRL, &chan->flags);
3046 set_bit(CONF_EWS_RECV, &chan->conf_state);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003047 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003048 chan->remote_tx_win = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003049 break;
3050
3051 default:
3052 if (hint)
3053 break;
3054
3055 result = L2CAP_CONF_UNKNOWN;
3056 *((u8 *) ptr++) = type;
3057 break;
3058 }
3059 }
3060
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003061 if (chan->num_conf_rsp || chan->num_conf_req > 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003062 goto done;
3063
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003064 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003065 case L2CAP_MODE_STREAMING:
3066 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003067 if (!test_bit(CONF_STATE2_DEVICE, &chan->conf_state)) {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003068 chan->mode = l2cap_select_mode(rfc.mode,
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003069 chan->conn->feat_mask);
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003070 break;
3071 }
3072
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003073 if (remote_efs) {
3074 if (__l2cap_efs_supported(chan))
3075 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3076 else
3077 return -ECONNREFUSED;
3078 }
3079
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003080 if (chan->mode != rfc.mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003081 return -ECONNREFUSED;
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03003082
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003083 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003084 }
3085
3086done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003087 if (chan->mode != rfc.mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003088 result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003089 rfc.mode = chan->mode;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003090
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003091 if (chan->num_conf_rsp == 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003092 return -ECONNREFUSED;
3093
3094 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
3095 sizeof(rfc), (unsigned long) &rfc);
3096 }
3097
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003098 if (result == L2CAP_CONF_SUCCESS) {
3099 /* Configure output options and let the other side know
3100 * which ones we don't like. */
3101
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003102 if (mtu < L2CAP_DEFAULT_MIN_MTU)
3103 result = L2CAP_CONF_UNACCEPT;
3104 else {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003105 chan->omtu = mtu;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003106 set_bit(CONF_MTU_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003107 }
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003108 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003109
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003110 if (remote_efs) {
3111 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
3112 efs.stype != L2CAP_SERV_NOTRAFIC &&
3113 efs.stype != chan->local_stype) {
3114
3115 result = L2CAP_CONF_UNACCEPT;
3116
3117 if (chan->num_conf_req >= 1)
3118 return -ECONNREFUSED;
3119
3120 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003121 sizeof(efs),
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003122 (unsigned long) &efs);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003123 } else {
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003124 /* Send PENDING Conf Rsp */
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003125 result = L2CAP_CONF_PENDING;
3126 set_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003127 }
3128 }
3129
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003130 switch (rfc.mode) {
3131 case L2CAP_MODE_BASIC:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003132 chan->fcs = L2CAP_FCS_NONE;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003133 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003134 break;
3135
3136 case L2CAP_MODE_ERTM:
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003137 if (!test_bit(CONF_EWS_RECV, &chan->conf_state))
3138 chan->remote_tx_win = rfc.txwin_size;
3139 else
3140 rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW;
3141
Gustavo F. Padovan2c03a7a2011-03-25 20:15:28 -03003142 chan->remote_max_tx = rfc.max_transmit;
Mat Martineau86b1b262010-08-05 15:54:22 -07003143
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003144 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
3145 chan->conn->mtu -
3146 L2CAP_EXT_HDR_SIZE -
3147 L2CAP_SDULEN_SIZE -
3148 L2CAP_FCS_SIZE);
3149 rfc.max_pdu_size = cpu_to_le16(size);
3150 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003151
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03003152 rfc.retrans_timeout =
Andrei Emeltchenko4fd21a82012-03-12 12:13:10 +02003153 __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03003154 rfc.monitor_timeout =
Andrei Emeltchenko4fd21a82012-03-12 12:13:10 +02003155 __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003156
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003157 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003158
3159 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
3160 sizeof(rfc), (unsigned long) &rfc);
3161
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003162 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3163 chan->remote_id = efs.id;
3164 chan->remote_stype = efs.stype;
3165 chan->remote_msdu = le16_to_cpu(efs.msdu);
3166 chan->remote_flush_to =
3167 le32_to_cpu(efs.flush_to);
3168 chan->remote_acc_lat =
3169 le32_to_cpu(efs.acc_lat);
3170 chan->remote_sdu_itime =
3171 le32_to_cpu(efs.sdu_itime);
3172 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
3173 sizeof(efs), (unsigned long) &efs);
3174 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003175 break;
3176
3177 case L2CAP_MODE_STREAMING:
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003178 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
3179 chan->conn->mtu -
3180 L2CAP_EXT_HDR_SIZE -
3181 L2CAP_SDULEN_SIZE -
3182 L2CAP_FCS_SIZE);
3183 rfc.max_pdu_size = cpu_to_le16(size);
3184 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003185
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003186 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003187
3188 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
3189 sizeof(rfc), (unsigned long) &rfc);
3190
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003191 break;
3192
3193 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02003194 result = L2CAP_CONF_UNACCEPT;
3195
3196 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003197 rfc.mode = chan->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003198 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003199
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003200 if (result == L2CAP_CONF_SUCCESS)
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003201 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003202 }
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003203 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003204 rsp->result = cpu_to_le16(result);
3205 rsp->flags = cpu_to_le16(0x0000);
3206
3207 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003208}
3209
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03003210static 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 -03003211{
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003212 struct l2cap_conf_req *req = data;
3213 void *ptr = req->data;
3214 int type, olen;
3215 unsigned long val;
Mat Martineau36e999a2011-12-08 17:23:21 -08003216 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003217 struct l2cap_conf_efs efs;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003218
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003219 BT_DBG("chan %p, rsp %p, len %d, req %p", chan, rsp, len, data);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003220
3221 while (len >= L2CAP_CONF_OPT_SIZE) {
3222 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3223
3224 switch (type) {
3225 case L2CAP_CONF_MTU:
3226 if (val < L2CAP_DEFAULT_MIN_MTU) {
3227 *result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003228 chan->imtu = L2CAP_DEFAULT_MIN_MTU;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003229 } else
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003230 chan->imtu = val;
3231 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003232 break;
3233
3234 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003235 chan->flush_to = val;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003236 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003237 2, chan->flush_to);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003238 break;
3239
3240 case L2CAP_CONF_RFC:
3241 if (olen == sizeof(rfc))
3242 memcpy(&rfc, (void *)val, olen);
3243
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003244 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state) &&
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003245 rfc.mode != chan->mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003246 return -ECONNREFUSED;
3247
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003248 chan->fcs = 0;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003249
3250 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
3251 sizeof(rfc), (unsigned long) &rfc);
3252 break;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003253
3254 case L2CAP_CONF_EWS:
3255 chan->tx_win = min_t(u16, val,
3256 L2CAP_DEFAULT_EXT_WINDOW);
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003257 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
3258 chan->tx_win);
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003259 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003260
3261 case L2CAP_CONF_EFS:
3262 if (olen == sizeof(efs))
3263 memcpy(&efs, (void *)val, olen);
3264
3265 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
3266 efs.stype != L2CAP_SERV_NOTRAFIC &&
3267 efs.stype != chan->local_stype)
3268 return -ECONNREFUSED;
3269
3270 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
3271 sizeof(efs), (unsigned long) &efs);
3272 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003273 }
3274 }
3275
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003276 if (chan->mode == L2CAP_MODE_BASIC && chan->mode != rfc.mode)
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003277 return -ECONNREFUSED;
3278
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003279 chan->mode = rfc.mode;
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003280
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003281 if (*result == L2CAP_CONF_SUCCESS || *result == L2CAP_CONF_PENDING) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003282 switch (rfc.mode) {
3283 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003284 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3285 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
3286 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003287
3288 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3289 chan->local_msdu = le16_to_cpu(efs.msdu);
3290 chan->local_sdu_itime =
3291 le32_to_cpu(efs.sdu_itime);
3292 chan->local_acc_lat = le32_to_cpu(efs.acc_lat);
3293 chan->local_flush_to =
3294 le32_to_cpu(efs.flush_to);
3295 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003296 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003297
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003298 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003299 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003300 }
3301 }
3302
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003303 req->dcid = cpu_to_le16(chan->dcid);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003304 req->flags = cpu_to_le16(0x0000);
3305
3306 return ptr - data;
3307}
3308
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003309static int l2cap_build_conf_rsp(struct l2cap_chan *chan, void *data, u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003310{
3311 struct l2cap_conf_rsp *rsp = data;
3312 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003313
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003314 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003315
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003316 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003317 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003318 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003319
3320 return ptr - data;
3321}
3322
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003323void __l2cap_connect_rsp_defer(struct l2cap_chan *chan)
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003324{
3325 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003326 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003327 u8 buf[128];
3328
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003329 rsp.scid = cpu_to_le16(chan->dcid);
3330 rsp.dcid = cpu_to_le16(chan->scid);
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003331 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
3332 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
3333 l2cap_send_cmd(conn, chan->ident,
3334 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
3335
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003336 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003337 return;
3338
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003339 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
3340 l2cap_build_conf_req(chan, buf), buf);
3341 chan->num_conf_req++;
3342}
3343
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003344static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003345{
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003346 int type, olen;
3347 unsigned long val;
3348 struct l2cap_conf_rfc rfc;
3349
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003350 BT_DBG("chan %p, rsp %p, len %d", chan, rsp, len);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003351
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003352 if ((chan->mode != L2CAP_MODE_ERTM) && (chan->mode != L2CAP_MODE_STREAMING))
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003353 return;
3354
3355 while (len >= L2CAP_CONF_OPT_SIZE) {
3356 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3357
3358 switch (type) {
3359 case L2CAP_CONF_RFC:
3360 if (olen == sizeof(rfc))
3361 memcpy(&rfc, (void *)val, olen);
3362 goto done;
3363 }
3364 }
3365
Mat Martineau36e999a2011-12-08 17:23:21 -08003366 /* Use sane default values in case a misbehaving remote device
3367 * did not send an RFC option.
3368 */
3369 rfc.mode = chan->mode;
3370 rfc.retrans_timeout = cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
3371 rfc.monitor_timeout = cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
3372 rfc.max_pdu_size = cpu_to_le16(chan->imtu);
3373
3374 BT_ERR("Expected RFC option was not found, using defaults");
3375
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003376done:
3377 switch (rfc.mode) {
3378 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003379 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3380 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
3381 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003382 break;
3383 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003384 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003385 }
3386}
3387
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003388static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3389{
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003390 struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003391
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003392 if (rej->reason != L2CAP_REJ_NOT_UNDERSTOOD)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003393 return 0;
3394
3395 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
3396 cmd->ident == conn->info_ident) {
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02003397 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01003398
3399 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003400 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003401
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003402 l2cap_conn_start(conn);
3403 }
3404
3405 return 0;
3406}
3407
Linus Torvalds1da177e2005-04-16 15:20:36 -07003408static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3409{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003410 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
3411 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003412 struct l2cap_chan *chan = NULL, *pchan;
Nathan Holsteind793fe82010-10-15 11:54:02 -04003413 struct sock *parent, *sk = NULL;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003414 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003415
3416 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003417 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003418
Andrei Emeltchenko097db762012-03-09 14:16:17 +02003419 BT_DBG("psm 0x%2.2x scid 0x%4.4x", __le16_to_cpu(psm), scid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003420
3421 /* Check if we have socket listening on psm */
Ido Yarivc2287682012-04-20 15:46:07 -03003422 pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003423 if (!pchan) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003424 result = L2CAP_CR_BAD_PSM;
3425 goto sendresp;
3426 }
3427
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003428 parent = pchan->sk;
3429
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003430 mutex_lock(&conn->chan_lock);
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003431 lock_sock(parent);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00003432
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003433 /* Check if the ACL is secure enough (if not SDP) */
3434 if (psm != cpu_to_le16(0x0001) &&
3435 !hci_conn_check_link_mode(conn->hcon)) {
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003436 conn->disc_reason = HCI_ERROR_AUTH_FAILURE;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003437 result = L2CAP_CR_SEC_BLOCK;
3438 goto response;
3439 }
3440
Linus Torvalds1da177e2005-04-16 15:20:36 -07003441 result = L2CAP_CR_NO_MEM;
3442
3443 /* Check for backlog size */
3444 if (sk_acceptq_is_full(parent)) {
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09003445 BT_DBG("backlog full %d", parent->sk_ack_backlog);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003446 goto response;
3447 }
3448
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003449 chan = pchan->ops->new_connection(pchan->data);
3450 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003451 goto response;
3452
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003453 sk = chan->sk;
3454
Linus Torvalds1da177e2005-04-16 15:20:36 -07003455 /* Check if we already have channel with that dcid */
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03003456 if (__l2cap_get_chan_by_dcid(conn, scid)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003457 sock_set_flag(sk, SOCK_ZAPPED);
Gustavo F. Padovanba3bd0e2011-05-16 18:23:24 -03003458 chan->ops->close(chan->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003459 goto response;
3460 }
3461
3462 hci_conn_hold(conn->hcon);
3463
Linus Torvalds1da177e2005-04-16 15:20:36 -07003464 bacpy(&bt_sk(sk)->src, conn->src);
3465 bacpy(&bt_sk(sk)->dst, conn->dst);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003466 chan->psm = psm;
3467 chan->dcid = scid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003468
Gustavo F. Padovand1010242011-03-25 00:39:48 -03003469 bt_accept_enqueue(parent, sk);
3470
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003471 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003472
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003473 dcid = chan->scid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003474
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03003475 __set_chan_timer(chan, sk->sk_sndtimeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003476
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003477 chan->ident = cmd->ident;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003478
Marcel Holtmann984947d2009-02-06 23:35:19 +01003479 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02003480 if (l2cap_chan_check_security(chan)) {
Gustavo Padovanc5daa682012-05-16 12:17:10 -03003481 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003482 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003483 result = L2CAP_CR_PEND;
3484 status = L2CAP_CS_AUTHOR_PEND;
3485 parent->sk_data_ready(parent, 0);
3486 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003487 __l2cap_state_change(chan, BT_CONFIG);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003488 result = L2CAP_CR_SUCCESS;
3489 status = L2CAP_CS_NO_INFO;
3490 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003491 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003492 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003493 result = L2CAP_CR_PEND;
3494 status = L2CAP_CS_AUTHEN_PEND;
3495 }
3496 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003497 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003498 result = L2CAP_CR_PEND;
3499 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003500 }
3501
Linus Torvalds1da177e2005-04-16 15:20:36 -07003502response:
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003503 release_sock(parent);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003504 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003505
3506sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003507 rsp.scid = cpu_to_le16(scid);
3508 rsp.dcid = cpu_to_le16(dcid);
3509 rsp.result = cpu_to_le16(result);
3510 rsp.status = cpu_to_le16(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003511 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003512
3513 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
3514 struct l2cap_info_req info;
3515 info.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
3516
3517 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
3518 conn->info_ident = l2cap_get_ident(conn);
3519
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08003520 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003521
3522 l2cap_send_cmd(conn, conn->info_ident,
3523 L2CAP_INFO_REQ, sizeof(info), &info);
3524 }
3525
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003526 if (chan && !test_bit(CONF_REQ_SENT, &chan->conf_state) &&
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003527 result == L2CAP_CR_SUCCESS) {
3528 u8 buf[128];
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003529 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003530 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003531 l2cap_build_conf_req(chan, buf), buf);
3532 chan->num_conf_req++;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003533 }
3534
Linus Torvalds1da177e2005-04-16 15:20:36 -07003535 return 0;
3536}
3537
3538static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3539{
3540 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
3541 u16 scid, dcid, result, status;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003542 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003543 u8 req[128];
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003544 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003545
3546 scid = __le16_to_cpu(rsp->scid);
3547 dcid = __le16_to_cpu(rsp->dcid);
3548 result = __le16_to_cpu(rsp->result);
3549 status = __le16_to_cpu(rsp->status);
3550
Andrei Emeltchenko1b009c92012-02-21 12:54:54 +02003551 BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x",
3552 dcid, scid, result, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003553
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003554 mutex_lock(&conn->chan_lock);
3555
Linus Torvalds1da177e2005-04-16 15:20:36 -07003556 if (scid) {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003557 chan = __l2cap_get_chan_by_scid(conn, scid);
3558 if (!chan) {
3559 err = -EFAULT;
3560 goto unlock;
3561 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003562 } else {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003563 chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
3564 if (!chan) {
3565 err = -EFAULT;
3566 goto unlock;
3567 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003568 }
3569
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003570 err = 0;
3571
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003572 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003573
Linus Torvalds1da177e2005-04-16 15:20:36 -07003574 switch (result) {
3575 case L2CAP_CR_SUCCESS:
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03003576 l2cap_state_change(chan, BT_CONFIG);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003577 chan->ident = 0;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003578 chan->dcid = dcid;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003579 clear_bit(CONF_CONNECT_PEND, &chan->conf_state);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003580
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003581 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003582 break;
3583
Linus Torvalds1da177e2005-04-16 15:20:36 -07003584 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003585 l2cap_build_conf_req(chan, req), req);
3586 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003587 break;
3588
3589 case L2CAP_CR_PEND:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003590 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003591 break;
3592
3593 default:
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003594 l2cap_chan_del(chan, ECONNREFUSED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003595 break;
3596 }
3597
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003598 l2cap_chan_unlock(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003599
3600unlock:
3601 mutex_unlock(&conn->chan_lock);
3602
3603 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003604}
3605
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003606static inline void set_default_fcs(struct l2cap_chan *chan)
Mat Martineau8c462b62010-08-24 15:35:42 -07003607{
3608 /* FCS is enabled only in ERTM or streaming mode, if one or both
3609 * sides request it.
3610 */
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003611 if (chan->mode != L2CAP_MODE_ERTM && chan->mode != L2CAP_MODE_STREAMING)
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003612 chan->fcs = L2CAP_FCS_NONE;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003613 else if (!test_bit(CONF_NO_FCS_RECV, &chan->conf_state))
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003614 chan->fcs = L2CAP_FCS_CRC16;
Mat Martineau8c462b62010-08-24 15:35:42 -07003615}
3616
Al Viro88219a02007-07-29 00:17:25 -07003617static 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 -07003618{
3619 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
3620 u16 dcid, flags;
3621 u8 rsp[64];
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003622 struct l2cap_chan *chan;
Mat Martineau3c588192012-04-11 10:48:42 -07003623 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003624
3625 dcid = __le16_to_cpu(req->dcid);
3626 flags = __le16_to_cpu(req->flags);
3627
3628 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
3629
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03003630 chan = l2cap_get_chan_by_scid(conn, dcid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003631 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003632 return -ENOENT;
3633
David S. Miller033b1142011-07-21 13:38:42 -07003634 if (chan->state != BT_CONFIG && chan->state != BT_CONNECT2) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003635 struct l2cap_cmd_rej_cid rej;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003636
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003637 rej.reason = cpu_to_le16(L2CAP_REJ_INVALID_CID);
3638 rej.scid = cpu_to_le16(chan->scid);
3639 rej.dcid = cpu_to_le16(chan->dcid);
3640
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003641 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
3642 sizeof(rej), &rej);
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003643 goto unlock;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003644 }
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003645
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003646 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07003647 len = cmd_len - sizeof(*req);
Dan Rosenberg7ac28812011-06-24 08:38:05 -04003648 if (len < 0 || chan->conf_len + len > sizeof(chan->conf_req)) {
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003649 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003650 l2cap_build_conf_rsp(chan, rsp,
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003651 L2CAP_CONF_REJECT, flags), rsp);
3652 goto unlock;
3653 }
3654
3655 /* Store config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003656 memcpy(chan->conf_req + chan->conf_len, req->data, len);
3657 chan->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003658
3659 if (flags & 0x0001) {
3660 /* Incomplete config. Send empty response. */
3661 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003662 l2cap_build_conf_rsp(chan, rsp,
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003663 L2CAP_CONF_SUCCESS, 0x0001), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003664 goto unlock;
3665 }
3666
3667 /* Complete config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003668 len = l2cap_parse_conf_req(chan, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003669 if (len < 0) {
Gustavo F. Padovane92c8e72011-04-01 00:53:45 -03003670 l2cap_send_disconn_req(conn, chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003671 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003672 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003673
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003674 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003675 chan->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003676
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003677 /* Reset config buffer. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003678 chan->conf_len = 0;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003679
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003680 if (!test_bit(CONF_OUTPUT_DONE, &chan->conf_state))
Marcel Holtmann876d9482007-10-20 13:35:42 +02003681 goto unlock;
3682
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003683 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003684 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003685
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03003686 l2cap_state_change(chan, BT_CONNECTED);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003687
Mat Martineau105bdf92012-04-27 16:50:48 -07003688 if (chan->mode == L2CAP_MODE_ERTM ||
3689 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07003690 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003691
Mat Martineau3c588192012-04-11 10:48:42 -07003692 if (err < 0)
3693 l2cap_send_disconn_req(chan->conn, chan, -err);
3694 else
3695 l2cap_chan_ready(chan);
3696
Marcel Holtmann876d9482007-10-20 13:35:42 +02003697 goto unlock;
3698 }
3699
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003700 if (!test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003701 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003702 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003703 l2cap_build_conf_req(chan, buf), buf);
3704 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003705 }
3706
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003707 /* Got Conf Rsp PENDING from remote side and asume we sent
3708 Conf Rsp PENDING in the code above */
3709 if (test_bit(CONF_REM_CONF_PEND, &chan->conf_state) &&
3710 test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
3711
3712 /* check compatibility */
3713
3714 clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
3715 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
3716
3717 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003718 l2cap_build_conf_rsp(chan, rsp,
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003719 L2CAP_CONF_SUCCESS, 0x0000), rsp);
3720 }
3721
Linus Torvalds1da177e2005-04-16 15:20:36 -07003722unlock:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003723 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07003724 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003725}
3726
3727static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3728{
3729 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
3730 u16 scid, flags, result;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003731 struct l2cap_chan *chan;
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02003732 int len = le16_to_cpu(cmd->len) - sizeof(*rsp);
Mat Martineau3c588192012-04-11 10:48:42 -07003733 int err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003734
3735 scid = __le16_to_cpu(rsp->scid);
3736 flags = __le16_to_cpu(rsp->flags);
3737 result = __le16_to_cpu(rsp->result);
3738
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02003739 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x len %d", scid, flags,
3740 result, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003741
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03003742 chan = l2cap_get_chan_by_scid(conn, scid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003743 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003744 return 0;
3745
3746 switch (result) {
3747 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003748 l2cap_conf_rfc_get(chan, rsp->data, len);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003749 clear_bit(CONF_REM_CONF_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003750 break;
3751
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003752 case L2CAP_CONF_PENDING:
3753 set_bit(CONF_REM_CONF_PEND, &chan->conf_state);
3754
3755 if (test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
3756 char buf[64];
3757
3758 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
3759 buf, &result);
3760 if (len < 0) {
3761 l2cap_send_disconn_req(conn, chan, ECONNRESET);
3762 goto done;
3763 }
3764
3765 /* check compatibility */
3766
3767 clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
3768 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
3769
3770 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003771 l2cap_build_conf_rsp(chan, buf,
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003772 L2CAP_CONF_SUCCESS, 0x0000), buf);
3773 }
3774 goto done;
3775
Linus Torvalds1da177e2005-04-16 15:20:36 -07003776 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003777 if (chan->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003778 char req[64];
3779
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02003780 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
Gustavo F. Padovane92c8e72011-04-01 00:53:45 -03003781 l2cap_send_disconn_req(conn, chan, ECONNRESET);
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02003782 goto done;
3783 }
3784
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003785 /* throw out any old stored conf requests */
3786 result = L2CAP_CONF_SUCCESS;
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03003787 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
3788 req, &result);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003789 if (len < 0) {
Gustavo F. Padovane92c8e72011-04-01 00:53:45 -03003790 l2cap_send_disconn_req(conn, chan, ECONNRESET);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003791 goto done;
3792 }
3793
3794 l2cap_send_cmd(conn, l2cap_get_ident(conn),
3795 L2CAP_CONF_REQ, len, req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003796 chan->num_conf_req++;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003797 if (result != L2CAP_CONF_SUCCESS)
3798 goto done;
3799 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003800 }
3801
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09003802 default:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003803 l2cap_chan_set_err(chan, ECONNRESET);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02003804
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08003805 __set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT);
Gustavo F. Padovane92c8e72011-04-01 00:53:45 -03003806 l2cap_send_disconn_req(conn, chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003807 goto done;
3808 }
3809
3810 if (flags & 0x01)
3811 goto done;
3812
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003813 set_bit(CONF_INPUT_DONE, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003814
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003815 if (test_bit(CONF_OUTPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003816 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003817
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03003818 l2cap_state_change(chan, BT_CONNECTED);
Mat Martineau105bdf92012-04-27 16:50:48 -07003819 if (chan->mode == L2CAP_MODE_ERTM ||
3820 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07003821 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003822
Mat Martineau3c588192012-04-11 10:48:42 -07003823 if (err < 0)
3824 l2cap_send_disconn_req(chan->conn, chan, -err);
3825 else
3826 l2cap_chan_ready(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003827 }
3828
3829done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003830 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07003831 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003832}
3833
3834static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3835{
3836 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
3837 struct l2cap_disconn_rsp rsp;
3838 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003839 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003840 struct sock *sk;
3841
3842 scid = __le16_to_cpu(req->scid);
3843 dcid = __le16_to_cpu(req->dcid);
3844
3845 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
3846
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003847 mutex_lock(&conn->chan_lock);
3848
3849 chan = __l2cap_get_chan_by_scid(conn, dcid);
3850 if (!chan) {
3851 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003852 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003853 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003854
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003855 l2cap_chan_lock(chan);
3856
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003857 sk = chan->sk;
3858
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003859 rsp.dcid = cpu_to_le16(chan->scid);
3860 rsp.scid = cpu_to_le16(chan->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003861 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
3862
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003863 lock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003864 sk->sk_shutdown = SHUTDOWN_MASK;
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003865 release_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003866
Mat Martineau61d6ef32012-04-27 16:50:50 -07003867 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003868 l2cap_chan_del(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003869
3870 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003871
Gustavo F. Padovanba3bd0e2011-05-16 18:23:24 -03003872 chan->ops->close(chan->data);
Mat Martineau61d6ef32012-04-27 16:50:50 -07003873 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003874
3875 mutex_unlock(&conn->chan_lock);
3876
Linus Torvalds1da177e2005-04-16 15:20:36 -07003877 return 0;
3878}
3879
3880static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3881{
3882 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
3883 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003884 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003885
3886 scid = __le16_to_cpu(rsp->scid);
3887 dcid = __le16_to_cpu(rsp->dcid);
3888
3889 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
3890
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003891 mutex_lock(&conn->chan_lock);
3892
3893 chan = __l2cap_get_chan_by_scid(conn, scid);
3894 if (!chan) {
3895 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003896 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003897 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003898
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003899 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003900
Mat Martineau61d6ef32012-04-27 16:50:50 -07003901 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003902 l2cap_chan_del(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003903
3904 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003905
Gustavo F. Padovanba3bd0e2011-05-16 18:23:24 -03003906 chan->ops->close(chan->data);
Mat Martineau61d6ef32012-04-27 16:50:50 -07003907 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003908
3909 mutex_unlock(&conn->chan_lock);
3910
Linus Torvalds1da177e2005-04-16 15:20:36 -07003911 return 0;
3912}
3913
3914static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3915{
3916 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003917 u16 type;
3918
3919 type = __le16_to_cpu(req->type);
3920
3921 BT_DBG("type 0x%4.4x", type);
3922
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003923 if (type == L2CAP_IT_FEAT_MASK) {
3924 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003925 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003926 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
3927 rsp->type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
3928 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03003929 if (!disable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003930 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
3931 | L2CAP_FEAT_FCS;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03003932 if (enable_hs)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003933 feat_mask |= L2CAP_FEAT_EXT_FLOW
3934 | L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03003935
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03003936 put_unaligned_le32(feat_mask, rsp->data);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003937 l2cap_send_cmd(conn, cmd->ident,
3938 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003939 } else if (type == L2CAP_IT_FIXED_CHAN) {
3940 u8 buf[12];
3941 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Mat Martineau50a147c2011-11-02 16:18:34 -07003942
3943 if (enable_hs)
3944 l2cap_fixed_chan[0] |= L2CAP_FC_A2MP;
3945 else
3946 l2cap_fixed_chan[0] &= ~L2CAP_FC_A2MP;
3947
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003948 rsp->type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3949 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
Andrei Emeltchenkoc6337ea2011-10-20 17:02:44 +03003950 memcpy(rsp->data, l2cap_fixed_chan, sizeof(l2cap_fixed_chan));
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003951 l2cap_send_cmd(conn, cmd->ident,
3952 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003953 } else {
3954 struct l2cap_info_rsp rsp;
3955 rsp.type = cpu_to_le16(type);
3956 rsp.result = cpu_to_le16(L2CAP_IR_NOTSUPP);
3957 l2cap_send_cmd(conn, cmd->ident,
3958 L2CAP_INFO_RSP, sizeof(rsp), &rsp);
3959 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003960
3961 return 0;
3962}
3963
3964static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3965{
3966 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
3967 u16 type, result;
3968
3969 type = __le16_to_cpu(rsp->type);
3970 result = __le16_to_cpu(rsp->result);
3971
3972 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
3973
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02003974 /* L2CAP Info req/rsp are unbound to channels, add extra checks */
3975 if (cmd->ident != conn->info_ident ||
3976 conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)
3977 return 0;
3978
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02003979 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003980
Ville Tervoadb08ed2010-08-04 09:43:33 +03003981 if (result != L2CAP_IR_SUCCESS) {
3982 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
3983 conn->info_ident = 0;
3984
3985 l2cap_conn_start(conn);
3986
3987 return 0;
3988 }
3989
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02003990 switch (type) {
3991 case L2CAP_IT_FEAT_MASK:
Harvey Harrison83985312008-05-02 16:25:46 -07003992 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003993
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003994 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003995 struct l2cap_info_req req;
3996 req.type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3997
3998 conn->info_ident = l2cap_get_ident(conn);
3999
4000 l2cap_send_cmd(conn, conn->info_ident,
4001 L2CAP_INFO_REQ, sizeof(req), &req);
4002 } else {
4003 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4004 conn->info_ident = 0;
4005
4006 l2cap_conn_start(conn);
4007 }
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004008 break;
4009
4010 case L2CAP_IT_FIXED_CHAN:
4011 conn->fixed_chan_mask = rsp->data[0];
Marcel Holtmann984947d2009-02-06 23:35:19 +01004012 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004013 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004014
4015 l2cap_conn_start(conn);
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004016 break;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004017 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004018
Linus Torvalds1da177e2005-04-16 15:20:36 -07004019 return 0;
4020}
4021
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004022static inline int l2cap_create_channel_req(struct l2cap_conn *conn,
4023 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4024 void *data)
4025{
4026 struct l2cap_create_chan_req *req = data;
4027 struct l2cap_create_chan_rsp rsp;
4028 u16 psm, scid;
4029
4030 if (cmd_len != sizeof(*req))
4031 return -EPROTO;
4032
4033 if (!enable_hs)
4034 return -EINVAL;
4035
4036 psm = le16_to_cpu(req->psm);
4037 scid = le16_to_cpu(req->scid);
4038
4039 BT_DBG("psm %d, scid %d, amp_id %d", psm, scid, req->amp_id);
4040
4041 /* Placeholder: Always reject */
4042 rsp.dcid = 0;
4043 rsp.scid = cpu_to_le16(scid);
Andrei Emeltchenko8ce0c492012-03-12 12:13:09 +02004044 rsp.result = __constant_cpu_to_le16(L2CAP_CR_NO_MEM);
4045 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004046
4047 l2cap_send_cmd(conn, cmd->ident, L2CAP_CREATE_CHAN_RSP,
4048 sizeof(rsp), &rsp);
4049
4050 return 0;
4051}
4052
4053static inline int l2cap_create_channel_rsp(struct l2cap_conn *conn,
4054 struct l2cap_cmd_hdr *cmd, void *data)
4055{
4056 BT_DBG("conn %p", conn);
4057
4058 return l2cap_connect_rsp(conn, cmd, data);
4059}
4060
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004061static void l2cap_send_move_chan_rsp(struct l2cap_conn *conn, u8 ident,
4062 u16 icid, u16 result)
4063{
4064 struct l2cap_move_chan_rsp rsp;
4065
4066 BT_DBG("icid %d, result %d", icid, result);
4067
4068 rsp.icid = cpu_to_le16(icid);
4069 rsp.result = cpu_to_le16(result);
4070
4071 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_RSP, sizeof(rsp), &rsp);
4072}
4073
4074static void l2cap_send_move_chan_cfm(struct l2cap_conn *conn,
4075 struct l2cap_chan *chan, u16 icid, u16 result)
4076{
4077 struct l2cap_move_chan_cfm cfm;
4078 u8 ident;
4079
4080 BT_DBG("icid %d, result %d", icid, result);
4081
4082 ident = l2cap_get_ident(conn);
4083 if (chan)
4084 chan->ident = ident;
4085
4086 cfm.icid = cpu_to_le16(icid);
4087 cfm.result = cpu_to_le16(result);
4088
4089 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM, sizeof(cfm), &cfm);
4090}
4091
4092static void l2cap_send_move_chan_cfm_rsp(struct l2cap_conn *conn, u8 ident,
4093 u16 icid)
4094{
4095 struct l2cap_move_chan_cfm_rsp rsp;
4096
4097 BT_DBG("icid %d", icid);
4098
4099 rsp.icid = cpu_to_le16(icid);
4100 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM_RSP, sizeof(rsp), &rsp);
4101}
4102
4103static inline int l2cap_move_channel_req(struct l2cap_conn *conn,
4104 struct l2cap_cmd_hdr *cmd, u16 cmd_len, void *data)
4105{
4106 struct l2cap_move_chan_req *req = data;
4107 u16 icid = 0;
4108 u16 result = L2CAP_MR_NOT_ALLOWED;
4109
4110 if (cmd_len != sizeof(*req))
4111 return -EPROTO;
4112
4113 icid = le16_to_cpu(req->icid);
4114
4115 BT_DBG("icid %d, dest_amp_id %d", icid, req->dest_amp_id);
4116
4117 if (!enable_hs)
4118 return -EINVAL;
4119
4120 /* Placeholder: Always refuse */
4121 l2cap_send_move_chan_rsp(conn, cmd->ident, icid, result);
4122
4123 return 0;
4124}
4125
4126static inline int l2cap_move_channel_rsp(struct l2cap_conn *conn,
4127 struct l2cap_cmd_hdr *cmd, u16 cmd_len, void *data)
4128{
4129 struct l2cap_move_chan_rsp *rsp = data;
4130 u16 icid, result;
4131
4132 if (cmd_len != sizeof(*rsp))
4133 return -EPROTO;
4134
4135 icid = le16_to_cpu(rsp->icid);
4136 result = le16_to_cpu(rsp->result);
4137
4138 BT_DBG("icid %d, result %d", icid, result);
4139
4140 /* Placeholder: Always unconfirmed */
4141 l2cap_send_move_chan_cfm(conn, NULL, icid, L2CAP_MC_UNCONFIRMED);
4142
4143 return 0;
4144}
4145
4146static inline int l2cap_move_channel_confirm(struct l2cap_conn *conn,
4147 struct l2cap_cmd_hdr *cmd, u16 cmd_len, void *data)
4148{
4149 struct l2cap_move_chan_cfm *cfm = data;
4150 u16 icid, result;
4151
4152 if (cmd_len != sizeof(*cfm))
4153 return -EPROTO;
4154
4155 icid = le16_to_cpu(cfm->icid);
4156 result = le16_to_cpu(cfm->result);
4157
4158 BT_DBG("icid %d, result %d", icid, result);
4159
4160 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
4161
4162 return 0;
4163}
4164
4165static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn,
4166 struct l2cap_cmd_hdr *cmd, u16 cmd_len, void *data)
4167{
4168 struct l2cap_move_chan_cfm_rsp *rsp = data;
4169 u16 icid;
4170
4171 if (cmd_len != sizeof(*rsp))
4172 return -EPROTO;
4173
4174 icid = le16_to_cpu(rsp->icid);
4175
4176 BT_DBG("icid %d", icid);
4177
4178 return 0;
4179}
4180
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03004181static inline int l2cap_check_conn_param(u16 min, u16 max, u16 latency,
Claudio Takahaside731152011-02-11 19:28:55 -02004182 u16 to_multiplier)
4183{
4184 u16 max_latency;
4185
4186 if (min > max || min < 6 || max > 3200)
4187 return -EINVAL;
4188
4189 if (to_multiplier < 10 || to_multiplier > 3200)
4190 return -EINVAL;
4191
4192 if (max >= to_multiplier * 8)
4193 return -EINVAL;
4194
4195 max_latency = (to_multiplier * 8 / max) - 1;
4196 if (latency > 499 || latency > max_latency)
4197 return -EINVAL;
4198
4199 return 0;
4200}
4201
4202static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
4203 struct l2cap_cmd_hdr *cmd, u8 *data)
4204{
4205 struct hci_conn *hcon = conn->hcon;
4206 struct l2cap_conn_param_update_req *req;
4207 struct l2cap_conn_param_update_rsp rsp;
4208 u16 min, max, latency, to_multiplier, cmd_len;
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02004209 int err;
Claudio Takahaside731152011-02-11 19:28:55 -02004210
4211 if (!(hcon->link_mode & HCI_LM_MASTER))
4212 return -EINVAL;
4213
4214 cmd_len = __le16_to_cpu(cmd->len);
4215 if (cmd_len != sizeof(struct l2cap_conn_param_update_req))
4216 return -EPROTO;
4217
4218 req = (struct l2cap_conn_param_update_req *) data;
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03004219 min = __le16_to_cpu(req->min);
4220 max = __le16_to_cpu(req->max);
Claudio Takahaside731152011-02-11 19:28:55 -02004221 latency = __le16_to_cpu(req->latency);
4222 to_multiplier = __le16_to_cpu(req->to_multiplier);
4223
4224 BT_DBG("min 0x%4.4x max 0x%4.4x latency: 0x%4.4x Timeout: 0x%4.4x",
4225 min, max, latency, to_multiplier);
4226
4227 memset(&rsp, 0, sizeof(rsp));
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02004228
4229 err = l2cap_check_conn_param(min, max, latency, to_multiplier);
4230 if (err)
Claudio Takahaside731152011-02-11 19:28:55 -02004231 rsp.result = cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
4232 else
4233 rsp.result = cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED);
4234
4235 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP,
4236 sizeof(rsp), &rsp);
4237
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02004238 if (!err)
4239 hci_le_conn_update(hcon, min, max, latency, to_multiplier);
4240
Claudio Takahaside731152011-02-11 19:28:55 -02004241 return 0;
4242}
4243
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004244static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
4245 struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
4246{
4247 int err = 0;
4248
4249 switch (cmd->code) {
4250 case L2CAP_COMMAND_REJ:
4251 l2cap_command_rej(conn, cmd, data);
4252 break;
4253
4254 case L2CAP_CONN_REQ:
4255 err = l2cap_connect_req(conn, cmd, data);
4256 break;
4257
4258 case L2CAP_CONN_RSP:
4259 err = l2cap_connect_rsp(conn, cmd, data);
4260 break;
4261
4262 case L2CAP_CONF_REQ:
4263 err = l2cap_config_req(conn, cmd, cmd_len, data);
4264 break;
4265
4266 case L2CAP_CONF_RSP:
4267 err = l2cap_config_rsp(conn, cmd, data);
4268 break;
4269
4270 case L2CAP_DISCONN_REQ:
4271 err = l2cap_disconnect_req(conn, cmd, data);
4272 break;
4273
4274 case L2CAP_DISCONN_RSP:
4275 err = l2cap_disconnect_rsp(conn, cmd, data);
4276 break;
4277
4278 case L2CAP_ECHO_REQ:
4279 l2cap_send_cmd(conn, cmd->ident, L2CAP_ECHO_RSP, cmd_len, data);
4280 break;
4281
4282 case L2CAP_ECHO_RSP:
4283 break;
4284
4285 case L2CAP_INFO_REQ:
4286 err = l2cap_information_req(conn, cmd, data);
4287 break;
4288
4289 case L2CAP_INFO_RSP:
4290 err = l2cap_information_rsp(conn, cmd, data);
4291 break;
4292
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004293 case L2CAP_CREATE_CHAN_REQ:
4294 err = l2cap_create_channel_req(conn, cmd, cmd_len, data);
4295 break;
4296
4297 case L2CAP_CREATE_CHAN_RSP:
4298 err = l2cap_create_channel_rsp(conn, cmd, data);
4299 break;
4300
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004301 case L2CAP_MOVE_CHAN_REQ:
4302 err = l2cap_move_channel_req(conn, cmd, cmd_len, data);
4303 break;
4304
4305 case L2CAP_MOVE_CHAN_RSP:
4306 err = l2cap_move_channel_rsp(conn, cmd, cmd_len, data);
4307 break;
4308
4309 case L2CAP_MOVE_CHAN_CFM:
4310 err = l2cap_move_channel_confirm(conn, cmd, cmd_len, data);
4311 break;
4312
4313 case L2CAP_MOVE_CHAN_CFM_RSP:
4314 err = l2cap_move_channel_confirm_rsp(conn, cmd, cmd_len, data);
4315 break;
4316
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004317 default:
4318 BT_ERR("Unknown BR/EDR signaling command 0x%2.2x", cmd->code);
4319 err = -EINVAL;
4320 break;
4321 }
4322
4323 return err;
4324}
4325
4326static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn,
4327 struct l2cap_cmd_hdr *cmd, u8 *data)
4328{
4329 switch (cmd->code) {
4330 case L2CAP_COMMAND_REJ:
4331 return 0;
4332
4333 case L2CAP_CONN_PARAM_UPDATE_REQ:
Claudio Takahaside731152011-02-11 19:28:55 -02004334 return l2cap_conn_param_update_req(conn, cmd, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004335
4336 case L2CAP_CONN_PARAM_UPDATE_RSP:
4337 return 0;
4338
4339 default:
4340 BT_ERR("Unknown LE signaling command 0x%2.2x", cmd->code);
4341 return -EINVAL;
4342 }
4343}
4344
4345static inline void l2cap_sig_channel(struct l2cap_conn *conn,
4346 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004347{
4348 u8 *data = skb->data;
4349 int len = skb->len;
4350 struct l2cap_cmd_hdr cmd;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004351 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004352
4353 l2cap_raw_recv(conn, skb);
4354
4355 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07004356 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004357 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
4358 data += L2CAP_CMD_HDR_SIZE;
4359 len -= L2CAP_CMD_HDR_SIZE;
4360
Al Viro88219a02007-07-29 00:17:25 -07004361 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004362
Al Viro88219a02007-07-29 00:17:25 -07004363 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 -07004364
Al Viro88219a02007-07-29 00:17:25 -07004365 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004366 BT_DBG("corrupted command");
4367 break;
4368 }
4369
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004370 if (conn->hcon->type == LE_LINK)
4371 err = l2cap_le_sig_cmd(conn, &cmd, data);
4372 else
4373 err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004374
4375 if (err) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03004376 struct l2cap_cmd_rej_unk rej;
Gustavo F. Padovan2c6d1a22011-03-23 14:38:32 -03004377
4378 BT_ERR("Wrong link type (%d)", err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004379
4380 /* FIXME: Map err to a valid reason */
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03004381 rej.reason = cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004382 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
4383 }
4384
Al Viro88219a02007-07-29 00:17:25 -07004385 data += cmd_len;
4386 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004387 }
4388
4389 kfree_skb(skb);
4390}
4391
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004392static int l2cap_check_fcs(struct l2cap_chan *chan, struct sk_buff *skb)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004393{
4394 u16 our_fcs, rcv_fcs;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03004395 int hdr_size;
4396
4397 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
4398 hdr_size = L2CAP_EXT_HDR_SIZE;
4399 else
4400 hdr_size = L2CAP_ENH_HDR_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004401
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004402 if (chan->fcs == L2CAP_FCS_CRC16) {
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03004403 skb_trim(skb, skb->len - L2CAP_FCS_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004404 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
4405 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
4406
4407 if (our_fcs != rcv_fcs)
João Paulo Rechi Vita7a560e52010-06-22 13:56:27 -03004408 return -EBADMSG;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004409 }
4410 return 0;
4411}
4412
Mat Martineau6ea00482012-05-17 20:53:52 -07004413static void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan)
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004414{
Mat Martineaue31f7632012-05-17 20:53:41 -07004415 struct l2cap_ctrl control;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004416
Mat Martineaue31f7632012-05-17 20:53:41 -07004417 BT_DBG("chan %p", chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004418
Mat Martineaue31f7632012-05-17 20:53:41 -07004419 memset(&control, 0, sizeof(control));
4420 control.sframe = 1;
4421 control.final = 1;
4422 control.reqseq = chan->buffer_seq;
4423 set_bit(CONN_SEND_FBIT, &chan->conn_state);
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 control.super = L2CAP_SUPER_RNR;
4427 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004428 }
4429
Mat Martineaue31f7632012-05-17 20:53:41 -07004430 if (test_and_clear_bit(CONN_REMOTE_BUSY, &chan->conn_state) &&
4431 chan->unacked_frames > 0)
4432 __set_retrans_timer(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004433
Mat Martineaue31f7632012-05-17 20:53:41 -07004434 /* Send pending iframes */
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03004435 l2cap_ertm_send(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004436
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03004437 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
Mat Martineaue31f7632012-05-17 20:53:41 -07004438 test_bit(CONN_SEND_FBIT, &chan->conn_state)) {
4439 /* F-bit wasn't sent in an s-frame or i-frame yet, so
4440 * send it now.
4441 */
4442 control.super = L2CAP_SUPER_RR;
4443 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004444 }
4445}
4446
Mat Martineau84084a32011-07-22 14:54:00 -07004447static void append_skb_frag(struct sk_buff *skb,
4448 struct sk_buff *new_frag, struct sk_buff **last_frag)
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004449{
Mat Martineau84084a32011-07-22 14:54:00 -07004450 /* skb->len reflects data in skb as well as all fragments
4451 * skb->data_len reflects only data in fragments
4452 */
4453 if (!skb_has_frag_list(skb))
4454 skb_shinfo(skb)->frag_list = new_frag;
4455
4456 new_frag->next = NULL;
4457
4458 (*last_frag)->next = new_frag;
4459 *last_frag = new_frag;
4460
4461 skb->len += new_frag->len;
4462 skb->data_len += new_frag->len;
4463 skb->truesize += new_frag->truesize;
4464}
4465
Mat Martineau4b51dae92012-05-17 20:53:37 -07004466static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb,
4467 struct l2cap_ctrl *control)
Mat Martineau84084a32011-07-22 14:54:00 -07004468{
4469 int err = -EINVAL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004470
Mat Martineau4b51dae92012-05-17 20:53:37 -07004471 switch (control->sar) {
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03004472 case L2CAP_SAR_UNSEGMENTED:
Mat Martineau84084a32011-07-22 14:54:00 -07004473 if (chan->sdu)
4474 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004475
Mat Martineau84084a32011-07-22 14:54:00 -07004476 err = chan->ops->recv(chan->data, skb);
4477 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004478
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03004479 case L2CAP_SAR_START:
Mat Martineau84084a32011-07-22 14:54:00 -07004480 if (chan->sdu)
4481 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004482
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03004483 chan->sdu_len = get_unaligned_le16(skb->data);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03004484 skb_pull(skb, L2CAP_SDULEN_SIZE);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004485
Mat Martineau84084a32011-07-22 14:54:00 -07004486 if (chan->sdu_len > chan->imtu) {
4487 err = -EMSGSIZE;
4488 break;
4489 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004490
Mat Martineau84084a32011-07-22 14:54:00 -07004491 if (skb->len >= chan->sdu_len)
4492 break;
4493
4494 chan->sdu = skb;
4495 chan->sdu_last_frag = skb;
4496
4497 skb = NULL;
4498 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004499 break;
4500
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03004501 case L2CAP_SAR_CONTINUE:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03004502 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07004503 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004504
Mat Martineau84084a32011-07-22 14:54:00 -07004505 append_skb_frag(chan->sdu, skb,
4506 &chan->sdu_last_frag);
4507 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004508
Mat Martineau84084a32011-07-22 14:54:00 -07004509 if (chan->sdu->len >= chan->sdu_len)
4510 break;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03004511
Mat Martineau84084a32011-07-22 14:54:00 -07004512 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004513 break;
4514
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03004515 case L2CAP_SAR_END:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03004516 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07004517 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004518
Mat Martineau84084a32011-07-22 14:54:00 -07004519 append_skb_frag(chan->sdu, skb,
4520 &chan->sdu_last_frag);
4521 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004522
Mat Martineau84084a32011-07-22 14:54:00 -07004523 if (chan->sdu->len != chan->sdu_len)
4524 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004525
Mat Martineau84084a32011-07-22 14:54:00 -07004526 err = chan->ops->recv(chan->data, chan->sdu);
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03004527
Mat Martineau84084a32011-07-22 14:54:00 -07004528 if (!err) {
4529 /* Reassembly complete */
4530 chan->sdu = NULL;
4531 chan->sdu_last_frag = NULL;
4532 chan->sdu_len = 0;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004533 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004534 break;
4535 }
4536
Mat Martineau84084a32011-07-22 14:54:00 -07004537 if (err) {
4538 kfree_skb(skb);
4539 kfree_skb(chan->sdu);
4540 chan->sdu = NULL;
4541 chan->sdu_last_frag = NULL;
4542 chan->sdu_len = 0;
4543 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004544
Mat Martineau84084a32011-07-22 14:54:00 -07004545 return err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004546}
4547
Mat Martineaue3281402011-07-07 09:39:02 -07004548void l2cap_chan_busy(struct l2cap_chan *chan, int busy)
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03004549{
Mat Martineau61aa4f52012-05-17 20:53:40 -07004550 u8 event;
4551
4552 if (chan->mode != L2CAP_MODE_ERTM)
4553 return;
4554
4555 event = busy ? L2CAP_EV_LOCAL_BUSY_DETECTED : L2CAP_EV_LOCAL_BUSY_CLEAR;
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03004556 l2cap_tx(chan, NULL, NULL, event);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004557}
4558
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004559static int l2cap_rx_queued_iframes(struct l2cap_chan *chan)
4560{
Mat Martineau63838722012-05-17 20:53:45 -07004561 int err = 0;
4562 /* Pass sequential frames to l2cap_reassemble_sdu()
4563 * until a gap is encountered.
4564 */
4565
4566 BT_DBG("chan %p", chan);
4567
4568 while (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4569 struct sk_buff *skb;
4570 BT_DBG("Searching for skb with txseq %d (queue len %d)",
4571 chan->buffer_seq, skb_queue_len(&chan->srej_q));
4572
4573 skb = l2cap_ertm_seq_in_queue(&chan->srej_q, chan->buffer_seq);
4574
4575 if (!skb)
4576 break;
4577
4578 skb_unlink(skb, &chan->srej_q);
4579 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
4580 err = l2cap_reassemble_sdu(chan, skb, &bt_cb(skb)->control);
4581 if (err)
4582 break;
4583 }
4584
4585 if (skb_queue_empty(&chan->srej_q)) {
4586 chan->rx_state = L2CAP_RX_STATE_RECV;
4587 l2cap_send_ack(chan);
4588 }
4589
4590 return err;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004591}
4592
4593static void l2cap_handle_srej(struct l2cap_chan *chan,
4594 struct l2cap_ctrl *control)
4595{
Mat Martineauf80842a2012-05-17 20:53:46 -07004596 struct sk_buff *skb;
4597
4598 BT_DBG("chan %p, control %p", chan, control);
4599
4600 if (control->reqseq == chan->next_tx_seq) {
4601 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
4602 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
4603 return;
4604 }
4605
4606 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
4607
4608 if (skb == NULL) {
4609 BT_DBG("Seq %d not available for retransmission",
4610 control->reqseq);
4611 return;
4612 }
4613
4614 if (chan->max_tx != 0 && bt_cb(skb)->control.retries >= chan->max_tx) {
4615 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
4616 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
4617 return;
4618 }
4619
4620 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4621
4622 if (control->poll) {
4623 l2cap_pass_to_tx(chan, control);
4624
4625 set_bit(CONN_SEND_FBIT, &chan->conn_state);
4626 l2cap_retransmit(chan, control);
4627 l2cap_ertm_send(chan);
4628
4629 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
4630 set_bit(CONN_SREJ_ACT, &chan->conn_state);
4631 chan->srej_save_reqseq = control->reqseq;
4632 }
4633 } else {
4634 l2cap_pass_to_tx_fbit(chan, control);
4635
4636 if (control->final) {
4637 if (chan->srej_save_reqseq != control->reqseq ||
4638 !test_and_clear_bit(CONN_SREJ_ACT,
4639 &chan->conn_state))
4640 l2cap_retransmit(chan, control);
4641 } else {
4642 l2cap_retransmit(chan, control);
4643 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
4644 set_bit(CONN_SREJ_ACT, &chan->conn_state);
4645 chan->srej_save_reqseq = control->reqseq;
4646 }
4647 }
4648 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004649}
4650
4651static void l2cap_handle_rej(struct l2cap_chan *chan,
4652 struct l2cap_ctrl *control)
4653{
Mat Martineaufcd289d2012-05-17 20:53:47 -07004654 struct sk_buff *skb;
4655
4656 BT_DBG("chan %p, control %p", chan, control);
4657
4658 if (control->reqseq == chan->next_tx_seq) {
4659 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
4660 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
4661 return;
4662 }
4663
4664 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
4665
4666 if (chan->max_tx && skb &&
4667 bt_cb(skb)->control.retries >= chan->max_tx) {
4668 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
4669 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
4670 return;
4671 }
4672
4673 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4674
4675 l2cap_pass_to_tx(chan, control);
4676
4677 if (control->final) {
4678 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state))
4679 l2cap_retransmit_all(chan, control);
4680 } else {
4681 l2cap_retransmit_all(chan, control);
4682 l2cap_ertm_send(chan);
4683 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F)
4684 set_bit(CONN_REJ_ACT, &chan->conn_state);
4685 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004686}
4687
Mat Martineau4b51dae92012-05-17 20:53:37 -07004688static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq)
4689{
4690 BT_DBG("chan %p, txseq %d", chan, txseq);
4691
4692 BT_DBG("last_acked_seq %d, expected_tx_seq %d", chan->last_acked_seq,
4693 chan->expected_tx_seq);
4694
4695 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
4696 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
4697 chan->tx_win) {
4698 /* See notes below regarding "double poll" and
4699 * invalid packets.
4700 */
4701 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
4702 BT_DBG("Invalid/Ignore - after SREJ");
4703 return L2CAP_TXSEQ_INVALID_IGNORE;
4704 } else {
4705 BT_DBG("Invalid - in window after SREJ sent");
4706 return L2CAP_TXSEQ_INVALID;
4707 }
4708 }
4709
4710 if (chan->srej_list.head == txseq) {
4711 BT_DBG("Expected SREJ");
4712 return L2CAP_TXSEQ_EXPECTED_SREJ;
4713 }
4714
4715 if (l2cap_ertm_seq_in_queue(&chan->srej_q, txseq)) {
4716 BT_DBG("Duplicate SREJ - txseq already stored");
4717 return L2CAP_TXSEQ_DUPLICATE_SREJ;
4718 }
4719
4720 if (l2cap_seq_list_contains(&chan->srej_list, txseq)) {
4721 BT_DBG("Unexpected SREJ - not requested");
4722 return L2CAP_TXSEQ_UNEXPECTED_SREJ;
4723 }
4724 }
4725
4726 if (chan->expected_tx_seq == txseq) {
4727 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
4728 chan->tx_win) {
4729 BT_DBG("Invalid - txseq outside tx window");
4730 return L2CAP_TXSEQ_INVALID;
4731 } else {
4732 BT_DBG("Expected");
4733 return L2CAP_TXSEQ_EXPECTED;
4734 }
4735 }
4736
4737 if (__seq_offset(chan, txseq, chan->last_acked_seq) <
4738 __seq_offset(chan, chan->expected_tx_seq,
4739 chan->last_acked_seq)){
4740 BT_DBG("Duplicate - expected_tx_seq later than txseq");
4741 return L2CAP_TXSEQ_DUPLICATE;
4742 }
4743
4744 if (__seq_offset(chan, txseq, chan->last_acked_seq) >= chan->tx_win) {
4745 /* A source of invalid packets is a "double poll" condition,
4746 * where delays cause us to send multiple poll packets. If
4747 * the remote stack receives and processes both polls,
4748 * sequence numbers can wrap around in such a way that a
4749 * resent frame has a sequence number that looks like new data
4750 * with a sequence gap. This would trigger an erroneous SREJ
4751 * request.
4752 *
4753 * Fortunately, this is impossible with a tx window that's
4754 * less than half of the maximum sequence number, which allows
4755 * invalid frames to be safely ignored.
4756 *
4757 * With tx window sizes greater than half of the tx window
4758 * maximum, the frame is invalid and cannot be ignored. This
4759 * causes a disconnect.
4760 */
4761
4762 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
4763 BT_DBG("Invalid/Ignore - txseq outside tx window");
4764 return L2CAP_TXSEQ_INVALID_IGNORE;
4765 } else {
4766 BT_DBG("Invalid - txseq outside tx window");
4767 return L2CAP_TXSEQ_INVALID;
4768 }
4769 } else {
4770 BT_DBG("Unexpected - txseq indicates missing frames");
4771 return L2CAP_TXSEQ_UNEXPECTED;
4772 }
4773}
4774
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004775static int l2cap_rx_state_recv(struct l2cap_chan *chan,
4776 struct l2cap_ctrl *control,
4777 struct sk_buff *skb, u8 event)
4778{
4779 int err = 0;
4780 bool skb_in_use = 0;
4781
4782 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
4783 event);
4784
4785 switch (event) {
4786 case L2CAP_EV_RECV_IFRAME:
4787 switch (l2cap_classify_txseq(chan, control->txseq)) {
4788 case L2CAP_TXSEQ_EXPECTED:
4789 l2cap_pass_to_tx(chan, control);
4790
4791 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4792 BT_DBG("Busy, discarding expected seq %d",
4793 control->txseq);
4794 break;
4795 }
4796
4797 chan->expected_tx_seq = __next_seq(chan,
4798 control->txseq);
4799
4800 chan->buffer_seq = chan->expected_tx_seq;
4801 skb_in_use = 1;
4802
4803 err = l2cap_reassemble_sdu(chan, skb, control);
4804 if (err)
4805 break;
4806
4807 if (control->final) {
4808 if (!test_and_clear_bit(CONN_REJ_ACT,
4809 &chan->conn_state)) {
4810 control->final = 0;
4811 l2cap_retransmit_all(chan, control);
4812 l2cap_ertm_send(chan);
4813 }
4814 }
4815
4816 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
4817 l2cap_send_ack(chan);
4818 break;
4819 case L2CAP_TXSEQ_UNEXPECTED:
4820 l2cap_pass_to_tx(chan, control);
4821
4822 /* Can't issue SREJ frames in the local busy state.
4823 * Drop this frame, it will be seen as missing
4824 * when local busy is exited.
4825 */
4826 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4827 BT_DBG("Busy, discarding unexpected seq %d",
4828 control->txseq);
4829 break;
4830 }
4831
4832 /* There was a gap in the sequence, so an SREJ
4833 * must be sent for each missing frame. The
4834 * current frame is stored for later use.
4835 */
4836 skb_queue_tail(&chan->srej_q, skb);
4837 skb_in_use = 1;
4838 BT_DBG("Queued %p (queue len %d)", skb,
4839 skb_queue_len(&chan->srej_q));
4840
4841 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
4842 l2cap_seq_list_clear(&chan->srej_list);
4843 l2cap_send_srej(chan, control->txseq);
4844
4845 chan->rx_state = L2CAP_RX_STATE_SREJ_SENT;
4846 break;
4847 case L2CAP_TXSEQ_DUPLICATE:
4848 l2cap_pass_to_tx(chan, control);
4849 break;
4850 case L2CAP_TXSEQ_INVALID_IGNORE:
4851 break;
4852 case L2CAP_TXSEQ_INVALID:
4853 default:
4854 l2cap_send_disconn_req(chan->conn, chan,
4855 ECONNRESET);
4856 break;
4857 }
4858 break;
4859 case L2CAP_EV_RECV_RR:
4860 l2cap_pass_to_tx(chan, control);
4861 if (control->final) {
4862 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4863
4864 if (!test_and_clear_bit(CONN_REJ_ACT,
4865 &chan->conn_state)) {
4866 control->final = 0;
4867 l2cap_retransmit_all(chan, control);
4868 }
4869
4870 l2cap_ertm_send(chan);
4871 } else if (control->poll) {
4872 l2cap_send_i_or_rr_or_rnr(chan);
4873 } else {
4874 if (test_and_clear_bit(CONN_REMOTE_BUSY,
4875 &chan->conn_state) &&
4876 chan->unacked_frames)
4877 __set_retrans_timer(chan);
4878
4879 l2cap_ertm_send(chan);
4880 }
4881 break;
4882 case L2CAP_EV_RECV_RNR:
4883 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4884 l2cap_pass_to_tx(chan, control);
4885 if (control && control->poll) {
4886 set_bit(CONN_SEND_FBIT, &chan->conn_state);
4887 l2cap_send_rr_or_rnr(chan, 0);
4888 }
4889 __clear_retrans_timer(chan);
4890 l2cap_seq_list_clear(&chan->retrans_list);
4891 break;
4892 case L2CAP_EV_RECV_REJ:
4893 l2cap_handle_rej(chan, control);
4894 break;
4895 case L2CAP_EV_RECV_SREJ:
4896 l2cap_handle_srej(chan, control);
4897 break;
4898 default:
4899 break;
4900 }
4901
4902 if (skb && !skb_in_use) {
4903 BT_DBG("Freeing %p", skb);
4904 kfree_skb(skb);
4905 }
4906
4907 return err;
4908}
4909
4910static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan,
4911 struct l2cap_ctrl *control,
4912 struct sk_buff *skb, u8 event)
4913{
4914 int err = 0;
4915 u16 txseq = control->txseq;
4916 bool skb_in_use = 0;
4917
4918 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
4919 event);
4920
4921 switch (event) {
4922 case L2CAP_EV_RECV_IFRAME:
4923 switch (l2cap_classify_txseq(chan, txseq)) {
4924 case L2CAP_TXSEQ_EXPECTED:
4925 /* Keep frame for reassembly later */
4926 l2cap_pass_to_tx(chan, control);
4927 skb_queue_tail(&chan->srej_q, skb);
4928 skb_in_use = 1;
4929 BT_DBG("Queued %p (queue len %d)", skb,
4930 skb_queue_len(&chan->srej_q));
4931
4932 chan->expected_tx_seq = __next_seq(chan, txseq);
4933 break;
4934 case L2CAP_TXSEQ_EXPECTED_SREJ:
4935 l2cap_seq_list_pop(&chan->srej_list);
4936
4937 l2cap_pass_to_tx(chan, control);
4938 skb_queue_tail(&chan->srej_q, skb);
4939 skb_in_use = 1;
4940 BT_DBG("Queued %p (queue len %d)", skb,
4941 skb_queue_len(&chan->srej_q));
4942
4943 err = l2cap_rx_queued_iframes(chan);
4944 if (err)
4945 break;
4946
4947 break;
4948 case L2CAP_TXSEQ_UNEXPECTED:
4949 /* Got a frame that can't be reassembled yet.
4950 * Save it for later, and send SREJs to cover
4951 * the missing frames.
4952 */
4953 skb_queue_tail(&chan->srej_q, skb);
4954 skb_in_use = 1;
4955 BT_DBG("Queued %p (queue len %d)", skb,
4956 skb_queue_len(&chan->srej_q));
4957
4958 l2cap_pass_to_tx(chan, control);
4959 l2cap_send_srej(chan, control->txseq);
4960 break;
4961 case L2CAP_TXSEQ_UNEXPECTED_SREJ:
4962 /* This frame was requested with an SREJ, but
4963 * some expected retransmitted frames are
4964 * missing. Request retransmission of missing
4965 * SREJ'd frames.
4966 */
4967 skb_queue_tail(&chan->srej_q, skb);
4968 skb_in_use = 1;
4969 BT_DBG("Queued %p (queue len %d)", skb,
4970 skb_queue_len(&chan->srej_q));
4971
4972 l2cap_pass_to_tx(chan, control);
4973 l2cap_send_srej_list(chan, control->txseq);
4974 break;
4975 case L2CAP_TXSEQ_DUPLICATE_SREJ:
4976 /* We've already queued this frame. Drop this copy. */
4977 l2cap_pass_to_tx(chan, control);
4978 break;
4979 case L2CAP_TXSEQ_DUPLICATE:
4980 /* Expecting a later sequence number, so this frame
4981 * was already received. Ignore it completely.
4982 */
4983 break;
4984 case L2CAP_TXSEQ_INVALID_IGNORE:
4985 break;
4986 case L2CAP_TXSEQ_INVALID:
4987 default:
4988 l2cap_send_disconn_req(chan->conn, chan,
4989 ECONNRESET);
4990 break;
4991 }
4992 break;
4993 case L2CAP_EV_RECV_RR:
4994 l2cap_pass_to_tx(chan, control);
4995 if (control->final) {
4996 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4997
4998 if (!test_and_clear_bit(CONN_REJ_ACT,
4999 &chan->conn_state)) {
5000 control->final = 0;
5001 l2cap_retransmit_all(chan, control);
5002 }
5003
5004 l2cap_ertm_send(chan);
5005 } else if (control->poll) {
5006 if (test_and_clear_bit(CONN_REMOTE_BUSY,
5007 &chan->conn_state) &&
5008 chan->unacked_frames) {
5009 __set_retrans_timer(chan);
5010 }
5011
5012 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5013 l2cap_send_srej_tail(chan);
5014 } else {
5015 if (test_and_clear_bit(CONN_REMOTE_BUSY,
5016 &chan->conn_state) &&
5017 chan->unacked_frames)
5018 __set_retrans_timer(chan);
5019
5020 l2cap_send_ack(chan);
5021 }
5022 break;
5023 case L2CAP_EV_RECV_RNR:
5024 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5025 l2cap_pass_to_tx(chan, control);
5026 if (control->poll) {
5027 l2cap_send_srej_tail(chan);
5028 } else {
5029 struct l2cap_ctrl rr_control;
5030 memset(&rr_control, 0, sizeof(rr_control));
5031 rr_control.sframe = 1;
5032 rr_control.super = L2CAP_SUPER_RR;
5033 rr_control.reqseq = chan->buffer_seq;
5034 l2cap_send_sframe(chan, &rr_control);
5035 }
5036
5037 break;
5038 case L2CAP_EV_RECV_REJ:
5039 l2cap_handle_rej(chan, control);
5040 break;
5041 case L2CAP_EV_RECV_SREJ:
5042 l2cap_handle_srej(chan, control);
5043 break;
5044 }
5045
5046 if (skb && !skb_in_use) {
5047 BT_DBG("Freeing %p", skb);
5048 kfree_skb(skb);
5049 }
5050
5051 return err;
5052}
5053
5054static bool __valid_reqseq(struct l2cap_chan *chan, u16 reqseq)
5055{
5056 /* Make sure reqseq is for a packet that has been sent but not acked */
5057 u16 unacked;
5058
5059 unacked = __seq_offset(chan, chan->next_tx_seq, chan->expected_ack_seq);
5060 return __seq_offset(chan, chan->next_tx_seq, reqseq) <= unacked;
5061}
5062
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005063static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
5064 struct sk_buff *skb, u8 event)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005065{
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005066 int err = 0;
5067
5068 BT_DBG("chan %p, control %p, skb %p, event %d, state %d", chan,
5069 control, skb, event, chan->rx_state);
5070
5071 if (__valid_reqseq(chan, control->reqseq)) {
5072 switch (chan->rx_state) {
5073 case L2CAP_RX_STATE_RECV:
5074 err = l2cap_rx_state_recv(chan, control, skb, event);
5075 break;
5076 case L2CAP_RX_STATE_SREJ_SENT:
5077 err = l2cap_rx_state_srej_sent(chan, control, skb,
5078 event);
5079 break;
5080 default:
5081 /* shut it down */
5082 break;
5083 }
5084 } else {
5085 BT_DBG("Invalid reqseq %d (next_tx_seq %d, expected_ack_seq %d",
5086 control->reqseq, chan->next_tx_seq,
5087 chan->expected_ack_seq);
5088 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
5089 }
5090
5091 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005092}
5093
5094static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
5095 struct sk_buff *skb)
5096{
Mat Martineau4b51dae92012-05-17 20:53:37 -07005097 int err = 0;
5098
5099 BT_DBG("chan %p, control %p, skb %p, state %d", chan, control, skb,
5100 chan->rx_state);
5101
5102 if (l2cap_classify_txseq(chan, control->txseq) ==
5103 L2CAP_TXSEQ_EXPECTED) {
5104 l2cap_pass_to_tx(chan, control);
5105
5106 BT_DBG("buffer_seq %d->%d", chan->buffer_seq,
5107 __next_seq(chan, chan->buffer_seq));
5108
5109 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
5110
5111 l2cap_reassemble_sdu(chan, skb, control);
5112 } else {
5113 if (chan->sdu) {
5114 kfree_skb(chan->sdu);
5115 chan->sdu = NULL;
5116 }
5117 chan->sdu_last_frag = NULL;
5118 chan->sdu_len = 0;
5119
5120 if (skb) {
5121 BT_DBG("Freeing %p", skb);
5122 kfree_skb(skb);
5123 }
5124 }
5125
5126 chan->last_acked_seq = control->txseq;
5127 chan->expected_tx_seq = __next_seq(chan, control->txseq);
5128
5129 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005130}
5131
5132static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
5133{
5134 struct l2cap_ctrl *control = &bt_cb(skb)->control;
5135 u16 len;
5136 u8 event;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005137
Mat Martineaub76bbd62012-04-11 10:48:43 -07005138 __unpack_control(chan, skb);
5139
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005140 len = skb->len;
5141
5142 /*
5143 * We can just drop the corrupted I-frame here.
5144 * Receiver will miss it and start proper recovery
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005145 * procedures and ask for retransmission.
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005146 */
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005147 if (l2cap_check_fcs(chan, skb))
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005148 goto drop;
5149
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005150 if (!control->sframe && control->sar == L2CAP_SAR_START)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005151 len -= L2CAP_SDULEN_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005152
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005153 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005154 len -= L2CAP_FCS_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005155
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005156 if (len > chan->mps) {
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03005157 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005158 goto drop;
5159 }
5160
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005161 if (!control->sframe) {
5162 int err;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005163
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005164 BT_DBG("iframe sar %d, reqseq %d, final %d, txseq %d",
5165 control->sar, control->reqseq, control->final,
5166 control->txseq);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03005167
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005168 /* Validate F-bit - F=0 always valid, F=1 only
5169 * valid in TX WAIT_F
5170 */
5171 if (control->final && chan->tx_state != L2CAP_TX_STATE_WAIT_F)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005172 goto drop;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005173
5174 if (chan->mode != L2CAP_MODE_STREAMING) {
5175 event = L2CAP_EV_RECV_IFRAME;
5176 err = l2cap_rx(chan, control, skb, event);
5177 } else {
5178 err = l2cap_stream_rx(chan, control, skb);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005179 }
5180
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005181 if (err)
5182 l2cap_send_disconn_req(chan->conn, chan,
5183 ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005184 } else {
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005185 const u8 rx_func_to_event[4] = {
5186 L2CAP_EV_RECV_RR, L2CAP_EV_RECV_REJ,
5187 L2CAP_EV_RECV_RNR, L2CAP_EV_RECV_SREJ
5188 };
5189
5190 /* Only I-frames are expected in streaming mode */
5191 if (chan->mode == L2CAP_MODE_STREAMING)
5192 goto drop;
5193
5194 BT_DBG("sframe reqseq %d, final %d, poll %d, super %d",
5195 control->reqseq, control->final, control->poll,
5196 control->super);
5197
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005198 if (len != 0) {
5199 BT_ERR("%d", len);
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03005200 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005201 goto drop;
5202 }
5203
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005204 /* Validate F and P bits */
5205 if (control->final && (control->poll ||
5206 chan->tx_state != L2CAP_TX_STATE_WAIT_F))
5207 goto drop;
5208
5209 event = rx_func_to_event[control->super];
5210 if (l2cap_rx(chan, control, skb, event))
5211 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005212 }
5213
5214 return 0;
5215
5216drop:
5217 kfree_skb(skb);
5218 return 0;
5219}
5220
Linus Torvalds1da177e2005-04-16 15:20:36 -07005221static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk_buff *skb)
5222{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03005223 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005224
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03005225 chan = l2cap_get_chan_by_scid(conn, cid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03005226 if (!chan) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005227 BT_DBG("unknown cid 0x%4.4x", cid);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005228 /* Drop packet and return */
Dan Carpenter33790132012-02-28 09:52:46 +03005229 kfree_skb(skb);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005230 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005231 }
5232
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03005233 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005234
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005235 if (chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005236 goto drop;
5237
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03005238 switch (chan->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005239 case L2CAP_MODE_BASIC:
5240 /* If socket recv buffers overflows we drop data here
5241 * which is *bad* because L2CAP has to be reliable.
5242 * But we don't have any other choice. L2CAP doesn't
5243 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07005244
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03005245 if (chan->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005246 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005247
Gustavo F. Padovan23070492011-05-16 17:57:22 -03005248 if (!chan->ops->recv(chan->data, skb))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005249 goto done;
5250 break;
5251
5252 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03005253 case L2CAP_MODE_STREAMING:
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005254 l2cap_data_rcv(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03005255 goto done;
5256
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005257 default:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03005258 BT_DBG("chan %p: bad mode 0x%2.2x", chan, chan->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005259 break;
5260 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005261
5262drop:
5263 kfree_skb(skb);
5264
5265done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005266 l2cap_chan_unlock(chan);
Marcel Holtmann01394182006-07-03 10:02:46 +02005267
Linus Torvalds1da177e2005-04-16 15:20:36 -07005268 return 0;
5269}
5270
Al Viro8e036fc2007-07-29 00:16:36 -07005271static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005272{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005273 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005274
Ido Yarivc2287682012-04-20 15:46:07 -03005275 chan = l2cap_global_chan_by_psm(0, psm, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005276 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005277 goto drop;
5278
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02005279 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005280
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005281 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005282 goto drop;
5283
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03005284 if (chan->imtu < skb->len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005285 goto drop;
5286
Gustavo F. Padovan23070492011-05-16 17:57:22 -03005287 if (!chan->ops->recv(chan->data, skb))
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02005288 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005289
5290drop:
5291 kfree_skb(skb);
5292
Linus Torvalds1da177e2005-04-16 15:20:36 -07005293 return 0;
5294}
5295
Andrei Emeltchenkod9b88702012-03-12 12:13:08 +02005296static inline int l2cap_att_channel(struct l2cap_conn *conn, u16 cid,
5297 struct sk_buff *skb)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005298{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005299 struct l2cap_chan *chan;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005300
Ido Yarivc2287682012-04-20 15:46:07 -03005301 chan = l2cap_global_chan_by_scid(0, cid, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005302 if (!chan)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005303 goto drop;
5304
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02005305 BT_DBG("chan %p, len %d", chan, skb->len);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005306
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005307 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005308 goto drop;
5309
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03005310 if (chan->imtu < skb->len)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005311 goto drop;
5312
Gustavo F. Padovan23070492011-05-16 17:57:22 -03005313 if (!chan->ops->recv(chan->data, skb))
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02005314 return 0;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005315
5316drop:
5317 kfree_skb(skb);
5318
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005319 return 0;
5320}
5321
Linus Torvalds1da177e2005-04-16 15:20:36 -07005322static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
5323{
5324 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07005325 u16 cid, len;
5326 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005327
5328 skb_pull(skb, L2CAP_HDR_SIZE);
5329 cid = __le16_to_cpu(lh->cid);
5330 len = __le16_to_cpu(lh->len);
5331
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005332 if (len != skb->len) {
5333 kfree_skb(skb);
5334 return;
5335 }
5336
Linus Torvalds1da177e2005-04-16 15:20:36 -07005337 BT_DBG("len %d, cid 0x%4.4x", len, cid);
5338
5339 switch (cid) {
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005340 case L2CAP_CID_LE_SIGNALING:
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03005341 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07005342 l2cap_sig_channel(conn, skb);
5343 break;
5344
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03005345 case L2CAP_CID_CONN_LESS:
Andrei Emeltchenko097db762012-03-09 14:16:17 +02005346 psm = get_unaligned((__le16 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005347 skb_pull(skb, 2);
5348 l2cap_conless_channel(conn, psm, skb);
5349 break;
5350
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005351 case L2CAP_CID_LE_DATA:
5352 l2cap_att_channel(conn, cid, skb);
5353 break;
5354
Anderson Brigliab501d6a2011-06-07 18:46:31 -03005355 case L2CAP_CID_SMP:
5356 if (smp_sig_channel(conn, skb))
5357 l2cap_conn_del(conn->hcon, EACCES);
5358 break;
5359
Linus Torvalds1da177e2005-04-16 15:20:36 -07005360 default:
5361 l2cap_data_channel(conn, cid, skb);
5362 break;
5363 }
5364}
5365
5366/* ---- L2CAP interface with lower layer (HCI) ---- */
5367
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005368int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005369{
5370 int exact = 0, lm1 = 0, lm2 = 0;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005371 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005372
Linus Torvalds1da177e2005-04-16 15:20:36 -07005373 BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
5374
5375 /* Find listening sockets and check their link_mode */
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005376 read_lock(&chan_list_lock);
5377 list_for_each_entry(c, &chan_list, global_l) {
5378 struct sock *sk = c->sk;
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005379
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005380 if (c->state != BT_LISTEN)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005381 continue;
5382
5383 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01005384 lm1 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03005385 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01005386 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005387 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01005388 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
5389 lm2 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03005390 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01005391 lm2 |= HCI_LM_MASTER;
5392 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005393 }
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005394 read_unlock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005395
5396 return exact ? lm1 : lm2;
5397}
5398
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005399int l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005400{
Marcel Holtmann01394182006-07-03 10:02:46 +02005401 struct l2cap_conn *conn;
5402
Linus Torvalds1da177e2005-04-16 15:20:36 -07005403 BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
5404
Linus Torvalds1da177e2005-04-16 15:20:36 -07005405 if (!status) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005406 conn = l2cap_conn_add(hcon, status);
5407 if (conn)
5408 l2cap_conn_ready(conn);
Marcel Holtmann01394182006-07-03 10:02:46 +02005409 } else
Joe Perchese1750722011-06-29 18:18:29 -07005410 l2cap_conn_del(hcon, bt_to_errno(status));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005411
5412 return 0;
5413}
5414
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005415int l2cap_disconn_ind(struct hci_conn *hcon)
Marcel Holtmann2950f212009-02-12 14:02:50 +01005416{
5417 struct l2cap_conn *conn = hcon->l2cap_data;
5418
5419 BT_DBG("hcon %p", hcon);
5420
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005421 if (!conn)
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02005422 return HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01005423 return conn->disc_reason;
5424}
5425
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005426int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005427{
5428 BT_DBG("hcon %p reason %d", hcon, reason);
5429
Joe Perchese1750722011-06-29 18:18:29 -07005430 l2cap_conn_del(hcon, bt_to_errno(reason));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005431 return 0;
5432}
5433
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005434static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
Marcel Holtmannf62e4322009-01-15 21:58:44 +01005435{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03005436 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED)
Marcel Holtmann255c7602009-02-04 21:07:19 +01005437 return;
5438
Marcel Holtmannf62e4322009-01-15 21:58:44 +01005439 if (encrypt == 0x00) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005440 if (chan->sec_level == BT_SECURITY_MEDIUM) {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08005441 __set_chan_timer(chan, L2CAP_ENC_TIMEOUT);
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005442 } else if (chan->sec_level == BT_SECURITY_HIGH)
Gustavo F. Padovan0f852722011-05-04 19:42:50 -03005443 l2cap_chan_close(chan, ECONNREFUSED);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01005444 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005445 if (chan->sec_level == BT_SECURITY_MEDIUM)
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03005446 __clear_chan_timer(chan);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01005447 }
5448}
5449
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005450int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005451{
Marcel Holtmann40be4922008-07-14 20:13:50 +02005452 struct l2cap_conn *conn = hcon->l2cap_data;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03005453 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005454
Marcel Holtmann01394182006-07-03 10:02:46 +02005455 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005456 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02005457
Linus Torvalds1da177e2005-04-16 15:20:36 -07005458 BT_DBG("conn %p", conn);
5459
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03005460 if (hcon->type == LE_LINK) {
Hemant Gupta35d4adcc2012-04-18 14:46:26 +05305461 if (!status && encrypt)
5462 smp_distribute_keys(conn, 0);
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02005463 cancel_delayed_work(&conn->security_timer);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03005464 }
5465
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02005466 mutex_lock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005467
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02005468 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005469 l2cap_chan_lock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005470
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03005471 BT_DBG("chan->scid %d", chan->scid);
5472
5473 if (chan->scid == L2CAP_CID_LE_DATA) {
5474 if (!status && encrypt) {
5475 chan->sec_level = hcon->sec_level;
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02005476 l2cap_chan_ready(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03005477 }
5478
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005479 l2cap_chan_unlock(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03005480 continue;
5481 }
5482
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03005483 if (test_bit(CONF_CONNECT_PEND, &chan->conf_state)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005484 l2cap_chan_unlock(chan);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01005485 continue;
5486 }
5487
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005488 if (!status && (chan->state == BT_CONNECTED ||
5489 chan->state == BT_CONFIG)) {
Gustavo Padovana7d77232012-05-13 03:20:07 -03005490 struct sock *sk = chan->sk;
5491
Gustavo Padovanc5daa682012-05-16 12:17:10 -03005492 clear_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags);
Gustavo Padovana7d77232012-05-13 03:20:07 -03005493 sk->sk_state_change(sk);
5494
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005495 l2cap_check_encryption(chan, encrypt);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005496 l2cap_chan_unlock(chan);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02005497 continue;
5498 }
5499
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005500 if (chan->state == BT_CONNECT) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005501 if (!status) {
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +02005502 l2cap_send_conn_req(chan);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005503 } else {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08005504 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005505 }
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005506 } else if (chan->state == BT_CONNECT2) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005507 struct sock *sk = chan->sk;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005508 struct l2cap_conn_rsp rsp;
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005509 __u16 res, stat;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005510
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005511 lock_sock(sk);
5512
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005513 if (!status) {
Gustavo Padovanc5daa682012-05-16 12:17:10 -03005514 if (test_bit(BT_SK_DEFER_SETUP,
5515 &bt_sk(sk)->flags)) {
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005516 struct sock *parent = bt_sk(sk)->parent;
5517 res = L2CAP_CR_PEND;
5518 stat = L2CAP_CS_AUTHOR_PEND;
Ilia Kolomisnky05e9a2f2011-07-15 18:30:21 +00005519 if (parent)
5520 parent->sk_data_ready(parent, 0);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005521 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02005522 __l2cap_state_change(chan, BT_CONFIG);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005523 res = L2CAP_CR_SUCCESS;
5524 stat = L2CAP_CS_NO_INFO;
5525 }
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005526 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02005527 __l2cap_state_change(chan, BT_DISCONN);
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08005528 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005529 res = L2CAP_CR_SEC_BLOCK;
5530 stat = L2CAP_CS_NO_INFO;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005531 }
5532
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005533 release_sock(sk);
5534
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03005535 rsp.scid = cpu_to_le16(chan->dcid);
5536 rsp.dcid = cpu_to_le16(chan->scid);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005537 rsp.result = cpu_to_le16(res);
5538 rsp.status = cpu_to_le16(stat);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03005539 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
5540 sizeof(rsp), &rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005541 }
5542
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005543 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005544 }
5545
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02005546 mutex_unlock(&conn->chan_lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005547
Linus Torvalds1da177e2005-04-16 15:20:36 -07005548 return 0;
5549}
5550
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005551int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005552{
5553 struct l2cap_conn *conn = hcon->l2cap_data;
5554
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02005555 if (!conn)
5556 conn = l2cap_conn_add(hcon, 0);
5557
5558 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005559 goto drop;
5560
5561 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
5562
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +02005563 if (!(flags & ACL_CONT)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005564 struct l2cap_hdr *hdr;
5565 int len;
5566
5567 if (conn->rx_len) {
5568 BT_ERR("Unexpected start frame (len %d)", skb->len);
5569 kfree_skb(conn->rx_skb);
5570 conn->rx_skb = NULL;
5571 conn->rx_len = 0;
5572 l2cap_conn_unreliable(conn, ECOMM);
5573 }
5574
Andrei Emeltchenkoaae7fe22010-09-15 14:28:43 +03005575 /* Start fragment always begin with Basic L2CAP header */
5576 if (skb->len < L2CAP_HDR_SIZE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005577 BT_ERR("Frame is too short (len %d)", skb->len);
5578 l2cap_conn_unreliable(conn, ECOMM);
5579 goto drop;
5580 }
5581
5582 hdr = (struct l2cap_hdr *) skb->data;
5583 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
5584
5585 if (len == skb->len) {
5586 /* Complete frame received */
5587 l2cap_recv_frame(conn, skb);
5588 return 0;
5589 }
5590
5591 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
5592
5593 if (skb->len > len) {
5594 BT_ERR("Frame is too long (len %d, expected len %d)",
5595 skb->len, len);
5596 l2cap_conn_unreliable(conn, ECOMM);
5597 goto drop;
5598 }
5599
5600 /* Allocate skb for the complete frame (with header) */
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03005601 conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC);
5602 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005603 goto drop;
5604
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03005605 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01005606 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005607 conn->rx_len = len - skb->len;
5608 } else {
5609 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
5610
5611 if (!conn->rx_len) {
5612 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
5613 l2cap_conn_unreliable(conn, ECOMM);
5614 goto drop;
5615 }
5616
5617 if (skb->len > conn->rx_len) {
5618 BT_ERR("Fragment is too long (len %d, expected %d)",
5619 skb->len, conn->rx_len);
5620 kfree_skb(conn->rx_skb);
5621 conn->rx_skb = NULL;
5622 conn->rx_len = 0;
5623 l2cap_conn_unreliable(conn, ECOMM);
5624 goto drop;
5625 }
5626
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03005627 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01005628 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005629 conn->rx_len -= skb->len;
5630
5631 if (!conn->rx_len) {
5632 /* Complete frame received */
5633 l2cap_recv_frame(conn, conn->rx_skb);
5634 conn->rx_skb = NULL;
5635 }
5636 }
5637
5638drop:
5639 kfree_skb(skb);
5640 return 0;
5641}
5642
Marcel Holtmannaef7d972010-03-21 05:27:45 +01005643static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005644{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005645 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005646
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02005647 read_lock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005648
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005649 list_for_each_entry(c, &chan_list, global_l) {
5650 struct sock *sk = c->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005651
Gustavo F. Padovan903d3432011-02-10 14:16:06 -02005652 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 +01005653 batostr(&bt_sk(sk)->src),
5654 batostr(&bt_sk(sk)->dst),
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005655 c->state, __le16_to_cpu(c->psm),
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005656 c->scid, c->dcid, c->imtu, c->omtu,
5657 c->sec_level, c->mode);
Andrei Emeltchenko61e1b4b2012-01-19 11:19:50 +02005658 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005659
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02005660 read_unlock(&chan_list_lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08005661
Marcel Holtmannaef7d972010-03-21 05:27:45 +01005662 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005663}
5664
Marcel Holtmannaef7d972010-03-21 05:27:45 +01005665static int l2cap_debugfs_open(struct inode *inode, struct file *file)
5666{
5667 return single_open(file, l2cap_debugfs_show, inode->i_private);
5668}
5669
5670static const struct file_operations l2cap_debugfs_fops = {
5671 .open = l2cap_debugfs_open,
5672 .read = seq_read,
5673 .llseek = seq_lseek,
5674 .release = single_release,
5675};
5676
5677static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005678
Gustavo F. Padovan64274512011-02-07 20:08:52 -02005679int __init l2cap_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005680{
5681 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08005682
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02005683 err = l2cap_init_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005684 if (err < 0)
5685 return err;
5686
Marcel Holtmannaef7d972010-03-21 05:27:45 +01005687 if (bt_debugfs) {
5688 l2cap_debugfs = debugfs_create_file("l2cap", 0444,
5689 bt_debugfs, NULL, &l2cap_debugfs_fops);
5690 if (!l2cap_debugfs)
5691 BT_ERR("Failed to create L2CAP debug file");
5692 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005693
Linus Torvalds1da177e2005-04-16 15:20:36 -07005694 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005695}
5696
Gustavo F. Padovan64274512011-02-07 20:08:52 -02005697void l2cap_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005698{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01005699 debugfs_remove(l2cap_debugfs);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02005700 l2cap_cleanup_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005701}
5702
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03005703module_param(disable_ertm, bool, 0644);
5704MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode");