blob: a8964db04bfb5cd1d0d348ed96c472e4786f3f44 [file] [log] [blame]
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 BlueZ - Bluetooth protocol stack for Linux
3 Copyright (C) 2000-2001 Qualcomm Incorporated
Gustavo F. Padovance5706b2010-07-13 11:57:11 -03004 Copyright (C) 2009-2010 Gustavo F. Padovan <gustavo@padovan.org>
Gustavo F. Padovan5d8868f2010-07-16 16:18:39 -03005 Copyright (C) 2010 Google Inc.
Gustavo F. Padovan590051d2011-12-18 13:39:33 -02006 Copyright (C) 2011 ProFUSION Embedded Systems
Mat Martineau422e9252012-04-27 16:50:55 -07007 Copyright (c) 2012 Code Aurora Forum. All rights reserved.
Linus Torvalds1da177e2005-04-16 15:20:36 -07008
9 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License version 2 as
13 published by the Free Software Foundation;
14
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
18 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090019 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
20 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
21 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Linus Torvalds1da177e2005-04-16 15:20:36 -070022 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090024 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
25 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
Linus Torvalds1da177e2005-04-16 15:20:36 -070026 SOFTWARE IS DISCLAIMED.
27*/
28
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -020029/* Bluetooth L2CAP core. */
Linus Torvalds1da177e2005-04-16 15:20:36 -070030
Linus Torvalds1da177e2005-04-16 15:20:36 -070031#include <linux/module.h>
32
Marcel Holtmannaef7d972010-03-21 05:27:45 +010033#include <linux/debugfs.h>
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -030034#include <linux/crc16.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070035
36#include <net/bluetooth/bluetooth.h>
37#include <net/bluetooth/hci_core.h>
38#include <net/bluetooth/l2cap.h>
Anderson Brigliab501d6a2011-06-07 18:46:31 -030039#include <net/bluetooth/smp.h>
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +030040#include <net/bluetooth/a2mp.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070041
Mat Martineaud1de6d42012-05-17 20:53:55 -070042bool disable_ertm;
Marcel Holtmannf0709e02007-10-20 13:38:51 +020043
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -070044static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN;
Mat Martineau50a147c2011-11-02 16:18:34 -070045static u8 l2cap_fixed_chan[8] = { L2CAP_FC_L2CAP, };
Linus Torvalds1da177e2005-04-16 15:20:36 -070046
Johannes Bergb5ad8b72011-06-01 08:54:45 +020047static LIST_HEAD(chan_list);
48static DEFINE_RWLOCK(chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -070049
Linus Torvalds1da177e2005-04-16 15:20:36 -070050static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
51 u8 code, u8 ident, u16 dlen, void *data);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -030052static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
53 void *data);
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -030054static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -030055static void l2cap_send_disconn_req(struct l2cap_conn *conn,
Gustavo Padovanc5daa682012-05-16 12:17:10 -030056 struct l2cap_chan *chan, int err);
Linus Torvalds1da177e2005-04-16 15:20:36 -070057
Gustavo Padovand6603662012-05-21 13:58:22 -030058static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
Mat Martineau608bcc62012-05-17 20:53:32 -070059 struct sk_buff_head *skbs, u8 event);
60
Marcel Holtmann01394182006-07-03 10:02:46 +020061/* ---- L2CAP channels ---- */
Gustavo F. Padovan71ba0e52011-05-17 14:34:52 -030062
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030063static struct l2cap_chan *__l2cap_get_chan_by_dcid(struct l2cap_conn *conn, u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +020064{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020065 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030066
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020067 list_for_each_entry(c, &conn->chan_l, list) {
68 if (c->dcid == cid)
69 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +020070 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020071 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +020072}
73
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030074static struct l2cap_chan *__l2cap_get_chan_by_scid(struct l2cap_conn *conn, u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +020075{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020076 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030077
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020078 list_for_each_entry(c, &conn->chan_l, list) {
79 if (c->scid == cid)
80 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +020081 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020082 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +020083}
84
85/* Find channel with given SCID.
Mat Martineauef191ad2012-05-02 09:42:00 -070086 * Returns locked channel. */
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030087static struct l2cap_chan *l2cap_get_chan_by_scid(struct l2cap_conn *conn, u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +020088{
Gustavo F. Padovan48454072011-03-25 00:22:30 -030089 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030090
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020091 mutex_lock(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030092 c = __l2cap_get_chan_by_scid(conn, cid);
Mat Martineauef191ad2012-05-02 09:42:00 -070093 if (c)
94 l2cap_chan_lock(c);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020095 mutex_unlock(&conn->chan_lock);
96
Gustavo F. Padovan48454072011-03-25 00:22:30 -030097 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +020098}
99
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300100static struct l2cap_chan *__l2cap_get_chan_by_ident(struct l2cap_conn *conn, u8 ident)
Marcel Holtmann01394182006-07-03 10:02:46 +0200101{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200102 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300103
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200104 list_for_each_entry(c, &conn->chan_l, list) {
105 if (c->ident == ident)
106 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +0200107 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200108 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200109}
110
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300111static struct l2cap_chan *__l2cap_global_chan_by_addr(__le16 psm, bdaddr_t *src)
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300112{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300113 struct l2cap_chan *c;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300114
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300115 list_for_each_entry(c, &chan_list, global_l) {
116 if (c->sport == psm && !bacmp(&bt_sk(c->sk)->src, src))
Szymon Janc250938c2011-11-16 09:32:22 +0100117 return c;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300118 }
Szymon Janc250938c2011-11-16 09:32:22 +0100119 return NULL;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300120}
121
122int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm)
123{
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300124 int err;
125
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200126 write_lock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300127
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300128 if (psm && __l2cap_global_chan_by_addr(psm, src)) {
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300129 err = -EADDRINUSE;
130 goto done;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300131 }
132
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300133 if (psm) {
134 chan->psm = psm;
135 chan->sport = psm;
136 err = 0;
137 } else {
138 u16 p;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300139
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300140 err = -EINVAL;
141 for (p = 0x1001; p < 0x1100; p += 2)
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300142 if (!__l2cap_global_chan_by_addr(cpu_to_le16(p), src)) {
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300143 chan->psm = cpu_to_le16(p);
144 chan->sport = cpu_to_le16(p);
145 err = 0;
146 break;
147 }
148 }
149
150done:
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200151 write_unlock(&chan_list_lock);
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300152 return err;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300153}
154
155int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid)
156{
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200157 write_lock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300158
159 chan->scid = scid;
160
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200161 write_unlock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300162
163 return 0;
164}
165
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300166static u16 l2cap_alloc_cid(struct l2cap_conn *conn)
Marcel Holtmann01394182006-07-03 10:02:46 +0200167{
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300168 u16 cid = L2CAP_CID_DYN_START;
Marcel Holtmann01394182006-07-03 10:02:46 +0200169
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300170 for (; cid < L2CAP_CID_DYN_END; cid++) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300171 if (!__l2cap_get_chan_by_scid(conn, cid))
Marcel Holtmann01394182006-07-03 10:02:46 +0200172 return cid;
173 }
174
175 return 0;
176}
177
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +0200178static void __l2cap_state_change(struct l2cap_chan *chan, int state)
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300179{
Andrei Emeltchenko42d2d872012-02-17 11:40:57 +0200180 BT_DBG("chan %p %s -> %s", chan, state_to_string(chan->state),
Gustavo F. Padovanbadaaa02011-11-23 20:11:46 -0200181 state_to_string(state));
182
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300183 chan->state = state;
Gustavo Padovan80b98022012-05-27 22:27:51 -0300184 chan->ops->state_change(chan, state);
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300185}
186
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +0200187static void l2cap_state_change(struct l2cap_chan *chan, int state)
188{
189 struct sock *sk = chan->sk;
190
191 lock_sock(sk);
192 __l2cap_state_change(chan, state);
193 release_sock(sk);
194}
195
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +0200196static inline void __l2cap_chan_set_err(struct l2cap_chan *chan, int err)
197{
198 struct sock *sk = chan->sk;
199
200 sk->sk_err = err;
201}
202
203static inline void l2cap_chan_set_err(struct l2cap_chan *chan, int err)
204{
205 struct sock *sk = chan->sk;
206
207 lock_sock(sk);
208 __l2cap_chan_set_err(chan, err);
209 release_sock(sk);
210}
211
Mat Martineau4239d162012-05-17 20:53:49 -0700212static void __set_retrans_timer(struct l2cap_chan *chan)
213{
214 if (!delayed_work_pending(&chan->monitor_timer) &&
215 chan->retrans_timeout) {
216 l2cap_set_timer(chan, &chan->retrans_timer,
217 msecs_to_jiffies(chan->retrans_timeout));
218 }
219}
220
221static void __set_monitor_timer(struct l2cap_chan *chan)
222{
223 __clear_retrans_timer(chan);
224 if (chan->monitor_timeout) {
225 l2cap_set_timer(chan, &chan->monitor_timer,
226 msecs_to_jiffies(chan->monitor_timeout));
227 }
228}
229
Mat Martineau608bcc62012-05-17 20:53:32 -0700230static struct sk_buff *l2cap_ertm_seq_in_queue(struct sk_buff_head *head,
231 u16 seq)
232{
233 struct sk_buff *skb;
234
235 skb_queue_walk(head, skb) {
236 if (bt_cb(skb)->control.txseq == seq)
237 return skb;
238 }
239
240 return NULL;
241}
242
Mat Martineau3c588192012-04-11 10:48:42 -0700243/* ---- L2CAP sequence number lists ---- */
244
245/* For ERTM, ordered lists of sequence numbers must be tracked for
246 * SREJ requests that are received and for frames that are to be
247 * retransmitted. These seq_list functions implement a singly-linked
248 * list in an array, where membership in the list can also be checked
249 * in constant time. Items can also be added to the tail of the list
250 * and removed from the head in constant time, without further memory
251 * allocs or frees.
252 */
253
254static int l2cap_seq_list_init(struct l2cap_seq_list *seq_list, u16 size)
255{
256 size_t alloc_size, i;
257
258 /* Allocated size is a power of 2 to map sequence numbers
259 * (which may be up to 14 bits) in to a smaller array that is
260 * sized for the negotiated ERTM transmit windows.
261 */
262 alloc_size = roundup_pow_of_two(size);
263
264 seq_list->list = kmalloc(sizeof(u16) * alloc_size, GFP_KERNEL);
265 if (!seq_list->list)
266 return -ENOMEM;
267
268 seq_list->mask = alloc_size - 1;
269 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
270 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
271 for (i = 0; i < alloc_size; i++)
272 seq_list->list[i] = L2CAP_SEQ_LIST_CLEAR;
273
274 return 0;
275}
276
277static inline void l2cap_seq_list_free(struct l2cap_seq_list *seq_list)
278{
279 kfree(seq_list->list);
280}
281
282static inline bool l2cap_seq_list_contains(struct l2cap_seq_list *seq_list,
283 u16 seq)
284{
285 /* Constant-time check for list membership */
286 return seq_list->list[seq & seq_list->mask] != L2CAP_SEQ_LIST_CLEAR;
287}
288
289static u16 l2cap_seq_list_remove(struct l2cap_seq_list *seq_list, u16 seq)
290{
291 u16 mask = seq_list->mask;
292
293 if (seq_list->head == L2CAP_SEQ_LIST_CLEAR) {
294 /* In case someone tries to pop the head of an empty list */
295 return L2CAP_SEQ_LIST_CLEAR;
296 } else if (seq_list->head == seq) {
297 /* Head can be removed in constant time */
298 seq_list->head = seq_list->list[seq & mask];
299 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_CLEAR;
300
301 if (seq_list->head == L2CAP_SEQ_LIST_TAIL) {
302 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
303 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
304 }
305 } else {
306 /* Walk the list to find the sequence number */
307 u16 prev = seq_list->head;
308 while (seq_list->list[prev & mask] != seq) {
309 prev = seq_list->list[prev & mask];
310 if (prev == L2CAP_SEQ_LIST_TAIL)
311 return L2CAP_SEQ_LIST_CLEAR;
312 }
313
314 /* Unlink the number from the list and clear it */
315 seq_list->list[prev & mask] = seq_list->list[seq & mask];
316 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_CLEAR;
317 if (seq_list->tail == seq)
318 seq_list->tail = prev;
319 }
320 return seq;
321}
322
323static inline u16 l2cap_seq_list_pop(struct l2cap_seq_list *seq_list)
324{
325 /* Remove the head in constant time */
326 return l2cap_seq_list_remove(seq_list, seq_list->head);
327}
328
329static void l2cap_seq_list_clear(struct l2cap_seq_list *seq_list)
330{
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300331 u16 i;
Mat Martineau3c588192012-04-11 10:48:42 -0700332
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300333 if (seq_list->head == L2CAP_SEQ_LIST_CLEAR)
334 return;
335
336 for (i = 0; i <= seq_list->mask; i++)
337 seq_list->list[i] = L2CAP_SEQ_LIST_CLEAR;
338
339 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
340 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
Mat Martineau3c588192012-04-11 10:48:42 -0700341}
342
343static void l2cap_seq_list_append(struct l2cap_seq_list *seq_list, u16 seq)
344{
345 u16 mask = seq_list->mask;
346
347 /* All appends happen in constant time */
348
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300349 if (seq_list->list[seq & mask] != L2CAP_SEQ_LIST_CLEAR)
350 return;
Mat Martineau3c588192012-04-11 10:48:42 -0700351
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300352 if (seq_list->tail == L2CAP_SEQ_LIST_CLEAR)
353 seq_list->head = seq;
354 else
355 seq_list->list[seq_list->tail & mask] = seq;
356
357 seq_list->tail = seq;
358 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_TAIL;
Mat Martineau3c588192012-04-11 10:48:42 -0700359}
360
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300361static void l2cap_chan_timeout(struct work_struct *work)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300362{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300363 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
364 chan_timer.work);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200365 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300366 int reason;
367
Andrei Emeltchenkoe05dcc32012-02-17 11:40:56 +0200368 BT_DBG("chan %p state %s", chan, state_to_string(chan->state));
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300369
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200370 mutex_lock(&conn->chan_lock);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200371 l2cap_chan_lock(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300372
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300373 if (chan->state == BT_CONNECTED || chan->state == BT_CONFIG)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300374 reason = ECONNREFUSED;
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300375 else if (chan->state == BT_CONNECT &&
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300376 chan->sec_level != BT_SECURITY_SDP)
377 reason = ECONNREFUSED;
378 else
379 reason = ETIMEDOUT;
380
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300381 l2cap_chan_close(chan, reason);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300382
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200383 l2cap_chan_unlock(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300384
Gustavo Padovan80b98022012-05-27 22:27:51 -0300385 chan->ops->close(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200386 mutex_unlock(&conn->chan_lock);
387
Ulisses Furquim371fd832011-12-21 20:02:36 -0200388 l2cap_chan_put(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300389}
390
Gustavo Padovaneef1d9b2012-03-25 13:59:16 -0300391struct l2cap_chan *l2cap_chan_create(void)
Marcel Holtmann01394182006-07-03 10:02:46 +0200392{
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300393 struct l2cap_chan *chan;
Marcel Holtmann01394182006-07-03 10:02:46 +0200394
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300395 chan = kzalloc(sizeof(*chan), GFP_ATOMIC);
396 if (!chan)
397 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200398
Andrei Emeltchenkoc03b3552012-02-21 12:54:56 +0200399 mutex_init(&chan->lock);
400
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200401 write_lock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300402 list_add(&chan->global_l, &chan_list);
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200403 write_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300404
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300405 INIT_DELAYED_WORK(&chan->chan_timer, l2cap_chan_timeout);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300406
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300407 chan->state = BT_OPEN;
408
Gustavo F. Padovan71ba0e52011-05-17 14:34:52 -0300409 atomic_set(&chan->refcnt, 1);
410
Mat Martineau28270112012-05-17 21:14:09 -0700411 /* This flag is cleared in l2cap_chan_ready() */
412 set_bit(CONF_NOT_COMPLETE, &chan->conf_state);
413
Gustavo Padovaneef1d9b2012-03-25 13:59:16 -0300414 BT_DBG("chan %p", chan);
Szymon Jancabc545b2011-11-03 16:05:44 +0100415
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300416 return chan;
Marcel Holtmann01394182006-07-03 10:02:46 +0200417}
418
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300419void l2cap_chan_destroy(struct l2cap_chan *chan)
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300420{
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200421 write_lock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300422 list_del(&chan->global_l);
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200423 write_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300424
Ulisses Furquim371fd832011-12-21 20:02:36 -0200425 l2cap_chan_put(chan);
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300426}
427
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +0300428void l2cap_chan_set_defaults(struct l2cap_chan *chan)
429{
430 chan->fcs = L2CAP_FCS_CRC16;
431 chan->max_tx = L2CAP_DEFAULT_MAX_TX;
432 chan->tx_win = L2CAP_DEFAULT_TX_WINDOW;
433 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
Mat Martineauc20f8e32012-07-10 05:47:07 -0700434 chan->ack_win = L2CAP_DEFAULT_TX_WINDOW;
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +0300435 chan->sec_level = BT_SECURITY_LOW;
436
437 set_bit(FLAG_FORCE_ACTIVE, &chan->flags);
438}
439
Andrei Emeltchenko14a28492012-03-23 16:31:49 +0200440static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Marcel Holtmann01394182006-07-03 10:02:46 +0200441{
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300442 BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
Andrei Emeltchenko097db762012-03-09 14:16:17 +0200443 __le16_to_cpu(chan->psm), chan->dcid);
Marcel Holtmann01394182006-07-03 10:02:46 +0200444
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +0200445 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +0100446
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300447 chan->conn = conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200448
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200449 switch (chan->chan_type) {
450 case L2CAP_CHAN_CONN_ORIENTED:
Ville Tervob62f3282011-02-10 22:38:50 -0300451 if (conn->hcon->type == LE_LINK) {
452 /* LE connection */
Andre Guedes6fcb06a2012-05-31 17:01:33 -0300453 chan->omtu = L2CAP_DEFAULT_MTU;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300454 chan->scid = L2CAP_CID_LE_DATA;
455 chan->dcid = L2CAP_CID_LE_DATA;
Ville Tervob62f3282011-02-10 22:38:50 -0300456 } else {
457 /* Alloc CID for connection-oriented socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300458 chan->scid = l2cap_alloc_cid(conn);
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300459 chan->omtu = L2CAP_DEFAULT_MTU;
Ville Tervob62f3282011-02-10 22:38:50 -0300460 }
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200461 break;
462
463 case L2CAP_CHAN_CONN_LESS:
Marcel Holtmann01394182006-07-03 10:02:46 +0200464 /* Connectionless socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300465 chan->scid = L2CAP_CID_CONN_LESS;
466 chan->dcid = L2CAP_CID_CONN_LESS;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300467 chan->omtu = L2CAP_DEFAULT_MTU;
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200468 break;
469
Andrei Emeltchenko416fa752012-05-29 13:59:16 +0300470 case L2CAP_CHAN_CONN_FIX_A2MP:
471 chan->scid = L2CAP_CID_A2MP;
472 chan->dcid = L2CAP_CID_A2MP;
473 chan->omtu = L2CAP_A2MP_DEFAULT_MTU;
474 chan->imtu = L2CAP_A2MP_DEFAULT_MTU;
475 break;
476
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200477 default:
Marcel Holtmann01394182006-07-03 10:02:46 +0200478 /* Raw socket can send/recv signalling messages only */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300479 chan->scid = L2CAP_CID_SIGNALING;
480 chan->dcid = L2CAP_CID_SIGNALING;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300481 chan->omtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann01394182006-07-03 10:02:46 +0200482 }
483
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300484 chan->local_id = L2CAP_BESTEFFORT_ID;
485 chan->local_stype = L2CAP_SERV_BESTEFFORT;
486 chan->local_msdu = L2CAP_DEFAULT_MAX_SDU_SIZE;
487 chan->local_sdu_itime = L2CAP_DEFAULT_SDU_ITIME;
488 chan->local_acc_lat = L2CAP_DEFAULT_ACC_LAT;
489 chan->local_flush_to = L2CAP_DEFAULT_FLUSH_TO;
490
Ulisses Furquim371fd832011-12-21 20:02:36 -0200491 l2cap_chan_hold(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300492
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200493 list_add(&chan->list, &conn->chan_l);
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200494}
495
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300496void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200497{
498 mutex_lock(&conn->chan_lock);
499 __l2cap_chan_add(conn, chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200500 mutex_unlock(&conn->chan_lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200501}
502
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300503void l2cap_chan_del(struct l2cap_chan *chan, int err)
Marcel Holtmann01394182006-07-03 10:02:46 +0200504{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300505 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200506
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300507 __clear_chan_timer(chan);
Marcel Holtmann01394182006-07-03 10:02:46 +0200508
Gustavo F. Padovan49208c92011-04-04 15:59:54 -0300509 BT_DBG("chan %p, conn %p, err %d", chan, conn, err);
Marcel Holtmann01394182006-07-03 10:02:46 +0200510
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900511 if (conn) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300512 /* Delete from channel list */
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200513 list_del(&chan->list);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -0200514
Ulisses Furquim371fd832011-12-21 20:02:36 -0200515 l2cap_chan_put(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300516
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300517 chan->conn = NULL;
Andrei Emeltchenko3cabbfd2012-05-31 11:01:37 +0300518
519 if (chan->chan_type != L2CAP_CHAN_CONN_FIX_A2MP)
520 hci_conn_put(conn->hcon);
Marcel Holtmann01394182006-07-03 10:02:46 +0200521 }
522
Andrei Emeltchenkoc0df7f62012-05-27 22:27:52 -0300523 if (chan->ops->teardown)
524 chan->ops->teardown(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200525
Mat Martineau28270112012-05-17 21:14:09 -0700526 if (test_bit(CONF_NOT_COMPLETE, &chan->conf_state))
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300527 return;
Gustavo F. Padovan2ead70b2011-04-01 15:13:36 -0300528
Gustavo Padovanee556f62012-05-18 20:22:38 -0300529 switch(chan->mode) {
530 case L2CAP_MODE_BASIC:
531 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300532
Gustavo Padovanee556f62012-05-18 20:22:38 -0300533 case L2CAP_MODE_ERTM:
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -0300534 __clear_retrans_timer(chan);
535 __clear_monitor_timer(chan);
536 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300537
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -0300538 skb_queue_purge(&chan->srej_q);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300539
Mat Martineau3c588192012-04-11 10:48:42 -0700540 l2cap_seq_list_free(&chan->srej_list);
541 l2cap_seq_list_free(&chan->retrans_list);
Gustavo Padovanee556f62012-05-18 20:22:38 -0300542
543 /* fall through */
544
545 case L2CAP_MODE_STREAMING:
546 skb_queue_purge(&chan->tx_q);
547 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300548 }
Gustavo Padovanee556f62012-05-18 20:22:38 -0300549
550 return;
Marcel Holtmann01394182006-07-03 10:02:46 +0200551}
552
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300553void l2cap_chan_close(struct l2cap_chan *chan, int reason)
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300554{
555 struct l2cap_conn *conn = chan->conn;
556 struct sock *sk = chan->sk;
557
Andrei Emeltchenkoe05dcc32012-02-17 11:40:56 +0200558 BT_DBG("chan %p state %s sk %p", chan,
559 state_to_string(chan->state), sk);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300560
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300561 switch (chan->state) {
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300562 case BT_LISTEN:
Andrei Emeltchenkoc0df7f62012-05-27 22:27:52 -0300563 if (chan->ops->teardown)
564 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300565 break;
566
567 case BT_CONNECTED:
568 case BT_CONFIG:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300569 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300570 conn->hcon->type == ACL_LINK) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300571 __set_chan_timer(chan, sk->sk_sndtimeo);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300572 l2cap_send_disconn_req(conn, chan, reason);
573 } else
574 l2cap_chan_del(chan, reason);
575 break;
576
577 case BT_CONNECT2:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300578 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300579 conn->hcon->type == ACL_LINK) {
580 struct l2cap_conn_rsp rsp;
581 __u16 result;
582
Gustavo Padovanc5daa682012-05-16 12:17:10 -0300583 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags))
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300584 result = L2CAP_CR_SEC_BLOCK;
585 else
586 result = L2CAP_CR_BAD_PSM;
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300587 l2cap_state_change(chan, BT_DISCONN);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300588
589 rsp.scid = cpu_to_le16(chan->dcid);
590 rsp.dcid = cpu_to_le16(chan->scid);
591 rsp.result = cpu_to_le16(result);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +0300592 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300593 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
594 sizeof(rsp), &rsp);
595 }
596
597 l2cap_chan_del(chan, reason);
598 break;
599
600 case BT_CONNECT:
601 case BT_DISCONN:
602 l2cap_chan_del(chan, reason);
603 break;
604
605 default:
Andrei Emeltchenkoc0df7f62012-05-27 22:27:52 -0300606 if (chan->ops->teardown)
607 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300608 break;
609 }
610}
611
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300612static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530613{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300614 if (chan->chan_type == L2CAP_CHAN_RAW) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300615 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530616 case BT_SECURITY_HIGH:
617 return HCI_AT_DEDICATED_BONDING_MITM;
618 case BT_SECURITY_MEDIUM:
619 return HCI_AT_DEDICATED_BONDING;
620 default:
621 return HCI_AT_NO_BONDING;
622 }
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +0300623 } else if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_SDP)) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300624 if (chan->sec_level == BT_SECURITY_LOW)
625 chan->sec_level = BT_SECURITY_SDP;
Johan Hedberg8556edd32011-01-19 12:06:50 +0530626
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300627 if (chan->sec_level == BT_SECURITY_HIGH)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530628 return HCI_AT_NO_BONDING_MITM;
629 else
630 return HCI_AT_NO_BONDING;
631 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300632 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530633 case BT_SECURITY_HIGH:
634 return HCI_AT_GENERAL_BONDING_MITM;
635 case BT_SECURITY_MEDIUM:
636 return HCI_AT_GENERAL_BONDING;
637 default:
638 return HCI_AT_NO_BONDING;
639 }
640 }
641}
642
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200643/* Service level security */
Gustavo F. Padovand45fc422011-11-05 19:54:24 -0200644int l2cap_chan_check_security(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200645{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300646 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100647 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200648
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300649 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100650
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300651 return hci_conn_security(conn->hcon, chan->sec_level, auth_type);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200652}
653
Johannes Bergb5ad8b72011-06-01 08:54:45 +0200654static u8 l2cap_get_ident(struct l2cap_conn *conn)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200655{
656 u8 id;
657
658 /* Get next available identificator.
659 * 1 - 128 are used by kernel.
660 * 129 - 199 are reserved.
661 * 200 - 254 are used by utilities like l2ping, etc.
662 */
663
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200664 spin_lock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200665
666 if (++conn->tx_ident > 128)
667 conn->tx_ident = 1;
668
669 id = conn->tx_ident;
670
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200671 spin_unlock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200672
673 return id;
674}
675
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300676static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200677{
678 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200679 u8 flags;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200680
681 BT_DBG("code 0x%2.2x", code);
682
683 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300684 return;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200685
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200686 if (lmp_no_flush_capable(conn->hcon->hdev))
687 flags = ACL_START_NO_FLUSH;
688 else
689 flags = ACL_START;
690
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700691 bt_cb(skb)->force_active = BT_POWER_FORCE_ACTIVE_ON;
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +0200692 skb->priority = HCI_PRIO_MAX;
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700693
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200694 hci_send_acl(conn->hchan, skb, flags);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200695}
696
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200697static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb)
698{
699 struct hci_conn *hcon = chan->conn->hcon;
700 u16 flags;
701
702 BT_DBG("chan %p, skb %p len %d priority %u", chan, skb, skb->len,
703 skb->priority);
704
705 if (!test_bit(FLAG_FLUSHABLE, &chan->flags) &&
706 lmp_no_flush_capable(hcon->hdev))
707 flags = ACL_START_NO_FLUSH;
708 else
709 flags = ACL_START;
710
711 bt_cb(skb)->force_active = test_bit(FLAG_FORCE_ACTIVE, &chan->flags);
712 hci_send_acl(chan->conn->hchan, skb, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700713}
714
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700715static void __unpack_enhanced_control(u16 enh, struct l2cap_ctrl *control)
716{
717 control->reqseq = (enh & L2CAP_CTRL_REQSEQ) >> L2CAP_CTRL_REQSEQ_SHIFT;
718 control->final = (enh & L2CAP_CTRL_FINAL) >> L2CAP_CTRL_FINAL_SHIFT;
719
720 if (enh & L2CAP_CTRL_FRAME_TYPE) {
721 /* S-Frame */
722 control->sframe = 1;
723 control->poll = (enh & L2CAP_CTRL_POLL) >> L2CAP_CTRL_POLL_SHIFT;
724 control->super = (enh & L2CAP_CTRL_SUPERVISE) >> L2CAP_CTRL_SUPER_SHIFT;
725
726 control->sar = 0;
727 control->txseq = 0;
728 } else {
729 /* I-Frame */
730 control->sframe = 0;
731 control->sar = (enh & L2CAP_CTRL_SAR) >> L2CAP_CTRL_SAR_SHIFT;
732 control->txseq = (enh & L2CAP_CTRL_TXSEQ) >> L2CAP_CTRL_TXSEQ_SHIFT;
733
734 control->poll = 0;
735 control->super = 0;
736 }
737}
738
739static void __unpack_extended_control(u32 ext, struct l2cap_ctrl *control)
740{
741 control->reqseq = (ext & L2CAP_EXT_CTRL_REQSEQ) >> L2CAP_EXT_CTRL_REQSEQ_SHIFT;
742 control->final = (ext & L2CAP_EXT_CTRL_FINAL) >> L2CAP_EXT_CTRL_FINAL_SHIFT;
743
744 if (ext & L2CAP_EXT_CTRL_FRAME_TYPE) {
745 /* S-Frame */
746 control->sframe = 1;
747 control->poll = (ext & L2CAP_EXT_CTRL_POLL) >> L2CAP_EXT_CTRL_POLL_SHIFT;
748 control->super = (ext & L2CAP_EXT_CTRL_SUPERVISE) >> L2CAP_EXT_CTRL_SUPER_SHIFT;
749
750 control->sar = 0;
751 control->txseq = 0;
752 } else {
753 /* I-Frame */
754 control->sframe = 0;
755 control->sar = (ext & L2CAP_EXT_CTRL_SAR) >> L2CAP_EXT_CTRL_SAR_SHIFT;
756 control->txseq = (ext & L2CAP_EXT_CTRL_TXSEQ) >> L2CAP_EXT_CTRL_TXSEQ_SHIFT;
757
758 control->poll = 0;
759 control->super = 0;
760 }
761}
762
763static inline void __unpack_control(struct l2cap_chan *chan,
764 struct sk_buff *skb)
765{
766 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
767 __unpack_extended_control(get_unaligned_le32(skb->data),
768 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700769 skb_pull(skb, L2CAP_EXT_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700770 } else {
771 __unpack_enhanced_control(get_unaligned_le16(skb->data),
772 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700773 skb_pull(skb, L2CAP_ENH_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700774 }
775}
776
777static u32 __pack_extended_control(struct l2cap_ctrl *control)
778{
779 u32 packed;
780
781 packed = control->reqseq << L2CAP_EXT_CTRL_REQSEQ_SHIFT;
782 packed |= control->final << L2CAP_EXT_CTRL_FINAL_SHIFT;
783
784 if (control->sframe) {
785 packed |= control->poll << L2CAP_EXT_CTRL_POLL_SHIFT;
786 packed |= control->super << L2CAP_EXT_CTRL_SUPER_SHIFT;
787 packed |= L2CAP_EXT_CTRL_FRAME_TYPE;
788 } else {
789 packed |= control->sar << L2CAP_EXT_CTRL_SAR_SHIFT;
790 packed |= control->txseq << L2CAP_EXT_CTRL_TXSEQ_SHIFT;
791 }
792
793 return packed;
794}
795
796static u16 __pack_enhanced_control(struct l2cap_ctrl *control)
797{
798 u16 packed;
799
800 packed = control->reqseq << L2CAP_CTRL_REQSEQ_SHIFT;
801 packed |= control->final << L2CAP_CTRL_FINAL_SHIFT;
802
803 if (control->sframe) {
804 packed |= control->poll << L2CAP_CTRL_POLL_SHIFT;
805 packed |= control->super << L2CAP_CTRL_SUPER_SHIFT;
806 packed |= L2CAP_CTRL_FRAME_TYPE;
807 } else {
808 packed |= control->sar << L2CAP_CTRL_SAR_SHIFT;
809 packed |= control->txseq << L2CAP_CTRL_TXSEQ_SHIFT;
810 }
811
812 return packed;
813}
814
815static inline void __pack_control(struct l2cap_chan *chan,
816 struct l2cap_ctrl *control,
817 struct sk_buff *skb)
818{
819 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
820 put_unaligned_le32(__pack_extended_control(control),
821 skb->data + L2CAP_HDR_SIZE);
822 } else {
823 put_unaligned_le16(__pack_enhanced_control(control),
824 skb->data + L2CAP_HDR_SIZE);
825 }
826}
827
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300828static inline unsigned int __ertm_hdr_size(struct l2cap_chan *chan)
829{
830 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
831 return L2CAP_EXT_HDR_SIZE;
832 else
833 return L2CAP_ENH_HDR_SIZE;
834}
835
Mat Martineaua67d7f62012-05-17 20:53:35 -0700836static struct sk_buff *l2cap_create_sframe_pdu(struct l2cap_chan *chan,
837 u32 control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300838{
839 struct sk_buff *skb;
840 struct l2cap_hdr *lh;
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300841 int hlen = __ertm_hdr_size(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300842
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300843 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300844 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300845
Mat Martineaua67d7f62012-05-17 20:53:35 -0700846 skb = bt_skb_alloc(hlen, GFP_KERNEL);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300847
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300848 if (!skb)
Mat Martineaua67d7f62012-05-17 20:53:35 -0700849 return ERR_PTR(-ENOMEM);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300850
851 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300852 lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300853 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +0300854
Mat Martineaua67d7f62012-05-17 20:53:35 -0700855 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
856 put_unaligned_le32(control, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
857 else
858 put_unaligned_le16(control, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300859
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -0300860 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineaua67d7f62012-05-17 20:53:35 -0700861 u16 fcs = crc16(0, (u8 *)skb->data, skb->len);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300862 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300863 }
864
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200865 skb->priority = HCI_PRIO_MAX;
Mat Martineaua67d7f62012-05-17 20:53:35 -0700866 return skb;
867}
868
869static void l2cap_send_sframe(struct l2cap_chan *chan,
870 struct l2cap_ctrl *control)
871{
872 struct sk_buff *skb;
873 u32 control_field;
874
875 BT_DBG("chan %p, control %p", chan, control);
876
877 if (!control->sframe)
878 return;
879
880 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state) &&
881 !control->poll)
882 control->final = 1;
883
884 if (control->super == L2CAP_SUPER_RR)
885 clear_bit(CONN_RNR_SENT, &chan->conn_state);
886 else if (control->super == L2CAP_SUPER_RNR)
887 set_bit(CONN_RNR_SENT, &chan->conn_state);
888
889 if (control->super != L2CAP_SUPER_SREJ) {
890 chan->last_acked_seq = control->reqseq;
891 __clear_ack_timer(chan);
892 }
893
894 BT_DBG("reqseq %d, final %d, poll %d, super %d", control->reqseq,
895 control->final, control->poll, control->super);
896
897 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
898 control_field = __pack_extended_control(control);
899 else
900 control_field = __pack_enhanced_control(control);
901
902 skb = l2cap_create_sframe_pdu(chan, control_field);
903 if (!IS_ERR(skb))
904 l2cap_do_send(chan, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300905}
906
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700907static void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, bool poll)
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300908{
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700909 struct l2cap_ctrl control;
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300910
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700911 BT_DBG("chan %p, poll %d", chan, poll);
912
913 memset(&control, 0, sizeof(control));
914 control.sframe = 1;
915 control.poll = poll;
916
917 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
918 control.super = L2CAP_SUPER_RNR;
919 else
920 control.super = L2CAP_SUPER_RR;
921
922 control.reqseq = chan->buffer_seq;
923 l2cap_send_sframe(chan, &control);
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300924}
925
Gustavo F. Padovanb4450032011-04-12 18:15:09 -0300926static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan)
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300927{
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -0300928 return !test_bit(CONF_CONNECT_PEND, &chan->conf_state);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300929}
930
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +0200931static void l2cap_send_conn_req(struct l2cap_chan *chan)
932{
933 struct l2cap_conn *conn = chan->conn;
934 struct l2cap_conn_req req;
935
936 req.scid = cpu_to_le16(chan->scid);
937 req.psm = chan->psm;
938
939 chan->ident = l2cap_get_ident(conn);
940
941 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
942
943 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, sizeof(req), &req);
944}
945
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -0300946static void l2cap_chan_ready(struct l2cap_chan *chan)
947{
Mat Martineau28270112012-05-17 21:14:09 -0700948 /* This clears all conf flags, including CONF_NOT_COMPLETE */
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -0300949 chan->conf_state = 0;
950 __clear_chan_timer(chan);
951
Andrei Emeltchenko54a59aa2012-05-27 22:27:53 -0300952 chan->state = BT_CONNECTED;
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -0300953
Andrei Emeltchenkofd83e2c2012-05-30 09:55:32 +0300954 chan->ops->ready(chan);
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -0300955}
956
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -0300957static void l2cap_do_start(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200958{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300959 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200960
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -0300961 if (conn->hcon->type == LE_LINK) {
962 l2cap_chan_ready(chan);
963 return;
964 }
965
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200966 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +0100967 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
968 return;
969
Gustavo F. Padovand45fc422011-11-05 19:54:24 -0200970 if (l2cap_chan_check_security(chan) &&
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +0200971 __l2cap_no_conn_pending(chan))
972 l2cap_send_conn_req(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200973 } else {
974 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +0300975 req.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200976
977 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
978 conn->info_ident = l2cap_get_ident(conn);
979
Marcel Holtmannba13ccd2012-03-01 14:25:33 -0800980 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200981
982 l2cap_send_cmd(conn, conn->info_ident,
983 L2CAP_INFO_REQ, sizeof(req), &req);
984 }
985}
986
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -0300987static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
988{
989 u32 local_feat_mask = l2cap_feat_mask;
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -0300990 if (!disable_ertm)
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -0300991 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
992
993 switch (mode) {
994 case L2CAP_MODE_ERTM:
995 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
996 case L2CAP_MODE_STREAMING:
997 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
998 default:
999 return 0x00;
1000 }
1001}
1002
Gustavo F. Padovan4519de92011-04-28 17:55:53 -03001003static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *chan, int err)
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001004{
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001005 struct sock *sk = chan->sk;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001006 struct l2cap_disconn_req req;
1007
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001008 if (!conn)
1009 return;
1010
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03001011 if (chan->mode == L2CAP_MODE_ERTM) {
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03001012 __clear_retrans_timer(chan);
1013 __clear_monitor_timer(chan);
1014 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001015 }
1016
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001017 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
1018 __l2cap_state_change(chan, BT_DISCONN);
1019 return;
1020 }
1021
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001022 req.dcid = cpu_to_le16(chan->dcid);
1023 req.scid = cpu_to_le16(chan->scid);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001024 l2cap_send_cmd(conn, l2cap_get_ident(conn),
1025 L2CAP_DISCONN_REQ, sizeof(req), &req);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001026
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001027 lock_sock(sk);
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001028 __l2cap_state_change(chan, BT_DISCONN);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02001029 __l2cap_chan_set_err(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001030 release_sock(sk);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001031}
1032
Linus Torvalds1da177e2005-04-16 15:20:36 -07001033/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001034static void l2cap_conn_start(struct l2cap_conn *conn)
1035{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001036 struct l2cap_chan *chan, *tmp;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001037
1038 BT_DBG("conn %p", conn);
1039
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001040 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001041
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001042 list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001043 struct sock *sk = chan->sk;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001044
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001045 l2cap_chan_lock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001046
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001047 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001048 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001049 continue;
1050 }
1051
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001052 if (chan->state == BT_CONNECT) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001053 if (!l2cap_chan_check_security(chan) ||
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03001054 !__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001055 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001056 continue;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02001057 }
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001058
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001059 if (!l2cap_mode_supported(chan->mode, conn->feat_mask)
1060 && test_bit(CONF_STATE2_DEVICE,
1061 &chan->conf_state)) {
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001062 l2cap_chan_close(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001063 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001064 continue;
1065 }
1066
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +02001067 l2cap_send_conn_req(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001068
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001069 } else if (chan->state == BT_CONNECT2) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001070 struct l2cap_conn_rsp rsp;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001071 char buf[128];
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001072 rsp.scid = cpu_to_le16(chan->dcid);
1073 rsp.dcid = cpu_to_le16(chan->scid);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001074
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001075 if (l2cap_chan_check_security(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001076 lock_sock(sk);
Gustavo Padovanc5daa682012-05-16 12:17:10 -03001077 if (test_bit(BT_SK_DEFER_SETUP,
1078 &bt_sk(sk)->flags)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001079 struct sock *parent = bt_sk(sk)->parent;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001080 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1081 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
Ilia Kolomisnky05e9a2f2011-07-15 18:30:21 +00001082 if (parent)
1083 parent->sk_data_ready(parent, 0);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001084
1085 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001086 __l2cap_state_change(chan, BT_CONFIG);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001087 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
1088 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001089 }
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001090 release_sock(sk);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001091 } else {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001092 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1093 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001094 }
1095
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001096 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
1097 sizeof(rsp), &rsp);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001098
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001099 if (test_bit(CONF_REQ_SENT, &chan->conf_state) ||
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001100 rsp.result != L2CAP_CR_SUCCESS) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001101 l2cap_chan_unlock(chan);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001102 continue;
1103 }
1104
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001105 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001106 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03001107 l2cap_build_conf_req(chan, buf), buf);
1108 chan->num_conf_req++;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001109 }
1110
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001111 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001112 }
1113
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001114 mutex_unlock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001115}
1116
Ido Yarivc2287682012-04-20 15:46:07 -03001117/* Find socket with cid and source/destination bdaddr.
Ville Tervob62f3282011-02-10 22:38:50 -03001118 * Returns closest match, locked.
1119 */
Andrei Emeltchenkod9b88702012-03-12 12:13:08 +02001120static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid,
Ido Yarivc2287682012-04-20 15:46:07 -03001121 bdaddr_t *src,
1122 bdaddr_t *dst)
Ville Tervob62f3282011-02-10 22:38:50 -03001123{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001124 struct l2cap_chan *c, *c1 = NULL;
Ville Tervob62f3282011-02-10 22:38:50 -03001125
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001126 read_lock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001127
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001128 list_for_each_entry(c, &chan_list, global_l) {
1129 struct sock *sk = c->sk;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001130
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001131 if (state && c->state != state)
Ville Tervob62f3282011-02-10 22:38:50 -03001132 continue;
1133
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001134 if (c->scid == cid) {
Ido Yarivc2287682012-04-20 15:46:07 -03001135 int src_match, dst_match;
1136 int src_any, dst_any;
1137
Ville Tervob62f3282011-02-10 22:38:50 -03001138 /* Exact match. */
Ido Yarivc2287682012-04-20 15:46:07 -03001139 src_match = !bacmp(&bt_sk(sk)->src, src);
1140 dst_match = !bacmp(&bt_sk(sk)->dst, dst);
1141 if (src_match && dst_match) {
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001142 read_unlock(&chan_list_lock);
1143 return c;
1144 }
Ville Tervob62f3282011-02-10 22:38:50 -03001145
1146 /* Closest match */
Ido Yarivc2287682012-04-20 15:46:07 -03001147 src_any = !bacmp(&bt_sk(sk)->src, BDADDR_ANY);
1148 dst_any = !bacmp(&bt_sk(sk)->dst, BDADDR_ANY);
1149 if ((src_match && dst_any) || (src_any && dst_match) ||
1150 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001151 c1 = c;
Ville Tervob62f3282011-02-10 22:38:50 -03001152 }
1153 }
Gustavo F. Padovan280f2942011-04-13 19:01:22 -03001154
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001155 read_unlock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001156
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001157 return c1;
Ville Tervob62f3282011-02-10 22:38:50 -03001158}
1159
1160static void l2cap_le_conn_ready(struct l2cap_conn *conn)
1161{
Gustavo F. Padovanc916fbe2011-04-04 16:00:55 -03001162 struct sock *parent, *sk;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001163 struct l2cap_chan *chan, *pchan;
Ville Tervob62f3282011-02-10 22:38:50 -03001164
1165 BT_DBG("");
1166
1167 /* Check if we have socket listening on cid */
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001168 pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_LE_DATA,
Ido Yarivc2287682012-04-20 15:46:07 -03001169 conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001170 if (!pchan)
Ville Tervob62f3282011-02-10 22:38:50 -03001171 return;
1172
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001173 parent = pchan->sk;
1174
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03001175 lock_sock(parent);
Gustavo F. Padovan62f3a2c2011-04-14 18:34:34 -03001176
Gustavo Padovan80b98022012-05-27 22:27:51 -03001177 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001178 if (!chan)
Ville Tervob62f3282011-02-10 22:38:50 -03001179 goto clean;
1180
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001181 sk = chan->sk;
Gustavo F. Padovan5d41ce12011-04-08 15:40:02 -03001182
Ville Tervob62f3282011-02-10 22:38:50 -03001183 hci_conn_hold(conn->hcon);
1184
Ville Tervob62f3282011-02-10 22:38:50 -03001185 bacpy(&bt_sk(sk)->src, conn->src);
1186 bacpy(&bt_sk(sk)->dst, conn->dst);
1187
Gustavo F. Padovand1010242011-03-25 00:39:48 -03001188 bt_accept_enqueue(parent, sk);
1189
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02001190 l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001191
Gustavo Padovan6754e0d2012-05-25 09:30:56 -03001192 l2cap_chan_ready(chan);
Ville Tervob62f3282011-02-10 22:38:50 -03001193
Ville Tervob62f3282011-02-10 22:38:50 -03001194clean:
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03001195 release_sock(parent);
Ville Tervob62f3282011-02-10 22:38:50 -03001196}
1197
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001198static void l2cap_conn_ready(struct l2cap_conn *conn)
1199{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001200 struct l2cap_chan *chan;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001201
1202 BT_DBG("conn %p", conn);
1203
Ville Tervob62f3282011-02-10 22:38:50 -03001204 if (!conn->hcon->out && conn->hcon->type == LE_LINK)
1205 l2cap_le_conn_ready(conn);
1206
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03001207 if (conn->hcon->out && conn->hcon->type == LE_LINK)
1208 smp_conn_security(conn, conn->hcon->pending_sec_level);
1209
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001210 mutex_lock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001211
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001212 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001213
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001214 l2cap_chan_lock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001215
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001216 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
1217 l2cap_chan_unlock(chan);
1218 continue;
1219 }
1220
Vinicius Costa Gomes63128452011-06-17 22:46:26 -03001221 if (conn->hcon->type == LE_LINK) {
Anderson Brigliab501d6a2011-06-07 18:46:31 -03001222 if (smp_conn_security(conn, chan->sec_level))
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02001223 l2cap_chan_ready(chan);
Ville Tervoacd7d372011-02-10 22:38:49 -03001224
Vinicius Costa Gomes63128452011-06-17 22:46:26 -03001225 } else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001226 struct sock *sk = chan->sk;
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001227 __clear_chan_timer(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001228 lock_sock(sk);
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001229 __l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001230 sk->sk_state_change(sk);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001231 release_sock(sk);
Anderson Brigliab501d6a2011-06-07 18:46:31 -03001232
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001233 } else if (chan->state == BT_CONNECT)
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001234 l2cap_do_start(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001235
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001236 l2cap_chan_unlock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001237 }
1238
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001239 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001240}
1241
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001242/* Notify sockets that we cannot guaranty reliability anymore */
1243static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
1244{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001245 struct l2cap_chan *chan;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001246
1247 BT_DBG("conn %p", conn);
1248
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001249 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001250
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001251 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenkoecf61bd2011-10-11 14:04:32 +03001252 if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags))
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02001253 __l2cap_chan_set_err(chan, err);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001254 }
1255
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001256 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001257}
1258
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001259static void l2cap_info_timeout(struct work_struct *work)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001260{
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001261 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo F. Padovan030013d2011-12-20 10:57:28 -02001262 info_timer.work);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001263
Marcel Holtmann984947d2009-02-06 23:35:19 +01001264 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01001265 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01001266
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001267 l2cap_conn_start(conn);
1268}
1269
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001270static void l2cap_conn_del(struct hci_conn *hcon, int err)
1271{
1272 struct l2cap_conn *conn = hcon->l2cap_data;
1273 struct l2cap_chan *chan, *l;
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001274
1275 if (!conn)
1276 return;
1277
1278 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
1279
1280 kfree_skb(conn->rx_skb);
1281
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001282 mutex_lock(&conn->chan_lock);
1283
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001284 /* Kill channels */
1285 list_for_each_entry_safe(chan, l, &conn->chan_l, list) {
Mat Martineau61d6ef32012-04-27 16:50:50 -07001286 l2cap_chan_hold(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001287 l2cap_chan_lock(chan);
1288
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001289 l2cap_chan_del(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001290
1291 l2cap_chan_unlock(chan);
1292
Gustavo Padovan80b98022012-05-27 22:27:51 -03001293 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07001294 l2cap_chan_put(chan);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001295 }
1296
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001297 mutex_unlock(&conn->chan_lock);
1298
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001299 hci_chan_del(conn->hchan);
1300
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001301 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
Ulisses Furquim127074b2012-01-30 18:26:29 -02001302 cancel_delayed_work_sync(&conn->info_timer);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001303
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001304 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) {
Ulisses Furquim127074b2012-01-30 18:26:29 -02001305 cancel_delayed_work_sync(&conn->security_timer);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -03001306 smp_chan_destroy(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001307 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001308
1309 hcon->l2cap_data = NULL;
1310 kfree(conn);
1311}
1312
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001313static void security_timeout(struct work_struct *work)
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001314{
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001315 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
1316 security_timer.work);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001317
Johan Hedbergd06cc412012-06-06 18:44:11 +08001318 BT_DBG("conn %p", conn);
1319
1320 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) {
1321 smp_chan_destroy(conn);
1322 l2cap_conn_del(conn->hcon, ETIMEDOUT);
1323 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001324}
1325
Linus Torvalds1da177e2005-04-16 15:20:36 -07001326static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
1327{
Marcel Holtmann01394182006-07-03 10:02:46 +02001328 struct l2cap_conn *conn = hcon->l2cap_data;
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001329 struct hci_chan *hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001330
Marcel Holtmann01394182006-07-03 10:02:46 +02001331 if (conn || status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001332 return conn;
1333
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001334 hchan = hci_chan_create(hcon);
1335 if (!hchan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001336 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001337
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001338 conn = kzalloc(sizeof(struct l2cap_conn), GFP_ATOMIC);
1339 if (!conn) {
1340 hci_chan_del(hchan);
1341 return NULL;
1342 }
1343
Linus Torvalds1da177e2005-04-16 15:20:36 -07001344 hcon->l2cap_data = conn;
1345 conn->hcon = hcon;
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001346 conn->hchan = hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001347
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001348 BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan);
Marcel Holtmann01394182006-07-03 10:02:46 +02001349
Ville Tervoacd7d372011-02-10 22:38:49 -03001350 if (hcon->hdev->le_mtu && hcon->type == LE_LINK)
1351 conn->mtu = hcon->hdev->le_mtu;
1352 else
1353 conn->mtu = hcon->hdev->acl_mtu;
1354
Linus Torvalds1da177e2005-04-16 15:20:36 -07001355 conn->src = &hcon->hdev->bdaddr;
1356 conn->dst = &hcon->dst;
1357
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001358 conn->feat_mask = 0;
1359
Linus Torvalds1da177e2005-04-16 15:20:36 -07001360 spin_lock_init(&conn->lock);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001361 mutex_init(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001362
1363 INIT_LIST_HEAD(&conn->chan_l);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001364
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001365 if (hcon->type == LE_LINK)
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001366 INIT_DELAYED_WORK(&conn->security_timer, security_timeout);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001367 else
Gustavo F. Padovan030013d2011-12-20 10:57:28 -02001368 INIT_DELAYED_WORK(&conn->info_timer, l2cap_info_timeout);
Dave Young45054dc2009-10-18 20:28:30 +00001369
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001370 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01001371
Linus Torvalds1da177e2005-04-16 15:20:36 -07001372 return conn;
1373}
1374
Linus Torvalds1da177e2005-04-16 15:20:36 -07001375/* ---- Socket interface ---- */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001376
Ido Yarivc2287682012-04-20 15:46:07 -03001377/* Find socket with psm and source / destination bdaddr.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001378 * Returns closest match.
1379 */
Ido Yarivc2287682012-04-20 15:46:07 -03001380static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
1381 bdaddr_t *src,
1382 bdaddr_t *dst)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001383{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001384 struct l2cap_chan *c, *c1 = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001385
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001386 read_lock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001387
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001388 list_for_each_entry(c, &chan_list, global_l) {
1389 struct sock *sk = c->sk;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001390
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001391 if (state && c->state != state)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001392 continue;
1393
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001394 if (c->psm == psm) {
Ido Yarivc2287682012-04-20 15:46:07 -03001395 int src_match, dst_match;
1396 int src_any, dst_any;
1397
Linus Torvalds1da177e2005-04-16 15:20:36 -07001398 /* Exact match. */
Ido Yarivc2287682012-04-20 15:46:07 -03001399 src_match = !bacmp(&bt_sk(sk)->src, src);
1400 dst_match = !bacmp(&bt_sk(sk)->dst, dst);
1401 if (src_match && dst_match) {
Johannes Berga7567b22011-06-01 08:29:54 +02001402 read_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001403 return c;
1404 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001405
1406 /* Closest match */
Ido Yarivc2287682012-04-20 15:46:07 -03001407 src_any = !bacmp(&bt_sk(sk)->src, BDADDR_ANY);
1408 dst_any = !bacmp(&bt_sk(sk)->dst, BDADDR_ANY);
1409 if ((src_match && dst_any) || (src_any && dst_match) ||
1410 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001411 c1 = c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001412 }
1413 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001414
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001415 read_unlock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001416
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001417 return c1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001418}
1419
Andre Guedes8e9f9892012-04-24 21:02:55 -03001420int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
1421 bdaddr_t *dst, u8 dst_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001422{
Gustavo F. Padovan5d41ce12011-04-08 15:40:02 -03001423 struct sock *sk = chan->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001424 bdaddr_t *src = &bt_sk(sk)->src;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001425 struct l2cap_conn *conn;
1426 struct hci_conn *hcon;
1427 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001428 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +02001429 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001430
Andre Guedes8e9f9892012-04-24 21:02:55 -03001431 BT_DBG("%s -> %s (type %u) psm 0x%2.2x", batostr(src), batostr(dst),
1432 dst_type, __le16_to_cpu(chan->psm));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001433
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001434 hdev = hci_get_route(dst, src);
1435 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001436 return -EHOSTUNREACH;
1437
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001438 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001439
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001440 l2cap_chan_lock(chan);
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001441
1442 /* PSM must be odd and lsb of upper byte must be 0 */
1443 if ((__le16_to_cpu(psm) & 0x0101) != 0x0001 && !cid &&
1444 chan->chan_type != L2CAP_CHAN_RAW) {
1445 err = -EINVAL;
1446 goto done;
1447 }
1448
1449 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && !(psm || cid)) {
1450 err = -EINVAL;
1451 goto done;
1452 }
1453
1454 switch (chan->mode) {
1455 case L2CAP_MODE_BASIC:
1456 break;
1457 case L2CAP_MODE_ERTM:
1458 case L2CAP_MODE_STREAMING:
1459 if (!disable_ertm)
1460 break;
1461 /* fall through */
1462 default:
1463 err = -ENOTSUPP;
1464 goto done;
1465 }
1466
Gustavo Padovan0797e012012-05-27 22:27:54 -03001467 switch (chan->state) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001468 case BT_CONNECT:
1469 case BT_CONNECT2:
1470 case BT_CONFIG:
1471 /* Already connecting */
1472 err = 0;
1473 goto done;
1474
1475 case BT_CONNECTED:
1476 /* Already connected */
1477 err = -EISCONN;
1478 goto done;
1479
1480 case BT_OPEN:
1481 case BT_BOUND:
1482 /* Can connect */
1483 break;
1484
1485 default:
1486 err = -EBADFD;
1487 goto done;
1488 }
1489
1490 /* Set destination address and psm */
Gustavo Padovan0797e012012-05-27 22:27:54 -03001491 lock_sock(sk);
Gustavo F. Padovan9219b2a2012-01-02 20:08:04 -02001492 bacpy(&bt_sk(sk)->dst, dst);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001493 release_sock(sk);
1494
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001495 chan->psm = psm;
1496 chan->dcid = cid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001497
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001498 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001499
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001500 if (chan->dcid == L2CAP_CID_LE_DATA)
Andre Guedes8e9f9892012-04-24 21:02:55 -03001501 hcon = hci_connect(hdev, LE_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001502 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001503 else
Andre Guedes8e9f9892012-04-24 21:02:55 -03001504 hcon = hci_connect(hdev, ACL_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001505 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001506
Ville Tervo30e76272011-02-22 16:10:53 -03001507 if (IS_ERR(hcon)) {
1508 err = PTR_ERR(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001509 goto done;
Ville Tervo30e76272011-02-22 16:10:53 -03001510 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001511
1512 conn = l2cap_conn_add(hcon, 0);
1513 if (!conn) {
1514 hci_conn_put(hcon);
Ville Tervo30e76272011-02-22 16:10:53 -03001515 err = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001516 goto done;
1517 }
1518
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001519 if (hcon->type == LE_LINK) {
1520 err = 0;
1521
1522 if (!list_empty(&conn->chan_l)) {
1523 err = -EBUSY;
1524 hci_conn_put(hcon);
1525 }
1526
1527 if (err)
1528 goto done;
1529 }
1530
Linus Torvalds1da177e2005-04-16 15:20:36 -07001531 /* Update source addr of the socket */
1532 bacpy(src, conn->src);
1533
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001534 l2cap_chan_unlock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001535 l2cap_chan_add(conn, chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001536 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001537
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001538 l2cap_state_change(chan, BT_CONNECT);
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001539 __set_chan_timer(chan, sk->sk_sndtimeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001540
1541 if (hcon->state == BT_CONNECTED) {
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001542 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001543 __clear_chan_timer(chan);
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001544 if (l2cap_chan_check_security(chan))
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001545 l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001546 } else
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001547 l2cap_do_start(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001548 }
1549
Ville Tervo30e76272011-02-22 16:10:53 -03001550 err = 0;
1551
Linus Torvalds1da177e2005-04-16 15:20:36 -07001552done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001553 l2cap_chan_unlock(chan);
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001554 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001555 hci_dev_put(hdev);
1556 return err;
1557}
1558
Gustavo F. Padovandcba0db2011-02-04 03:08:36 -02001559int __l2cap_wait_ack(struct sock *sk)
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001560{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001561 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001562 DECLARE_WAITQUEUE(wait, current);
1563 int err = 0;
1564 int timeo = HZ/5;
1565
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001566 add_wait_queue(sk_sleep(sk), &wait);
Peter Hurleya71a0cf2011-07-25 18:36:26 -04001567 set_current_state(TASK_INTERRUPTIBLE);
1568 while (chan->unacked_frames > 0 && chan->conn) {
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001569 if (!timeo)
1570 timeo = HZ/5;
1571
1572 if (signal_pending(current)) {
1573 err = sock_intr_errno(timeo);
1574 break;
1575 }
1576
1577 release_sock(sk);
1578 timeo = schedule_timeout(timeo);
1579 lock_sock(sk);
Peter Hurleya71a0cf2011-07-25 18:36:26 -04001580 set_current_state(TASK_INTERRUPTIBLE);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001581
1582 err = sock_error(sk);
1583 if (err)
1584 break;
1585 }
1586 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001587 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001588 return err;
1589}
1590
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001591static void l2cap_monitor_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001592{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001593 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001594 monitor_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001595
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03001596 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001597
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001598 l2cap_chan_lock(chan);
1599
Mat Martineau80909e02012-05-17 20:53:50 -07001600 if (!chan->conn) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001601 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001602 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001603 return;
1604 }
1605
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001606 l2cap_tx(chan, NULL, NULL, L2CAP_EV_MONITOR_TO);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001607
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001608 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001609 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001610}
1611
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001612static void l2cap_retrans_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001613{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001614 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001615 retrans_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001616
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03001617 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001618
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001619 l2cap_chan_lock(chan);
1620
Mat Martineau80909e02012-05-17 20:53:50 -07001621 if (!chan->conn) {
1622 l2cap_chan_unlock(chan);
1623 l2cap_chan_put(chan);
1624 return;
1625 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001626
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001627 l2cap_tx(chan, NULL, NULL, L2CAP_EV_RETRANS_TO);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001628 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001629 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001630}
1631
Gustavo Padovand6603662012-05-21 13:58:22 -03001632static void l2cap_streaming_send(struct l2cap_chan *chan,
1633 struct sk_buff_head *skbs)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001634{
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001635 struct sk_buff *skb;
Mat Martineau37339372012-05-17 20:53:33 -07001636 struct l2cap_ctrl *control;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001637
Mat Martineau37339372012-05-17 20:53:33 -07001638 BT_DBG("chan %p, skbs %p", chan, skbs);
1639
Mat Martineau37339372012-05-17 20:53:33 -07001640 skb_queue_splice_tail_init(skbs, &chan->tx_q);
1641
1642 while (!skb_queue_empty(&chan->tx_q)) {
1643
1644 skb = skb_dequeue(&chan->tx_q);
1645
1646 bt_cb(skb)->control.retries = 1;
1647 control = &bt_cb(skb)->control;
1648
1649 control->reqseq = 0;
1650 control->txseq = chan->next_tx_seq;
1651
1652 __pack_control(chan, control, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001653
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001654 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau37339372012-05-17 20:53:33 -07001655 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
1656 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001657 }
1658
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001659 l2cap_do_send(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001660
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001661 BT_DBG("Sent txseq %u", control->txseq);
Mat Martineau37339372012-05-17 20:53:33 -07001662
Andrei Emeltchenko836be932011-10-17 12:19:57 +03001663 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau37339372012-05-17 20:53:33 -07001664 chan->frames_sent++;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001665 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001666}
1667
Szymon Janc67c9e842011-07-28 16:24:33 +02001668static int l2cap_ertm_send(struct l2cap_chan *chan)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001669{
1670 struct sk_buff *skb, *tx_skb;
Mat Martineau18a48e72012-05-17 20:53:34 -07001671 struct l2cap_ctrl *control;
1672 int sent = 0;
1673
1674 BT_DBG("chan %p", chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001675
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001676 if (chan->state != BT_CONNECTED)
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001677 return -ENOTCONN;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001678
Mat Martineau94122bb2012-05-02 09:42:02 -07001679 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1680 return 0;
1681
Mat Martineau18a48e72012-05-17 20:53:34 -07001682 while (chan->tx_send_head &&
1683 chan->unacked_frames < chan->remote_tx_win &&
1684 chan->tx_state == L2CAP_TX_STATE_XMIT) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001685
Mat Martineau18a48e72012-05-17 20:53:34 -07001686 skb = chan->tx_send_head;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001687
Mat Martineau18a48e72012-05-17 20:53:34 -07001688 bt_cb(skb)->control.retries = 1;
1689 control = &bt_cb(skb)->control;
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03001690
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03001691 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
Mat Martineau18a48e72012-05-17 20:53:34 -07001692 control->final = 1;
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03001693
Mat Martineau18a48e72012-05-17 20:53:34 -07001694 control->reqseq = chan->buffer_seq;
1695 chan->last_acked_seq = chan->buffer_seq;
1696 control->txseq = chan->next_tx_seq;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001697
Mat Martineau18a48e72012-05-17 20:53:34 -07001698 __pack_control(chan, control, skb);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001699
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001700 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau18a48e72012-05-17 20:53:34 -07001701 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
1702 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001703 }
1704
Mat Martineau18a48e72012-05-17 20:53:34 -07001705 /* Clone after data has been modified. Data is assumed to be
1706 read-only (for locking purposes) on cloned sk_buffs.
1707 */
1708 tx_skb = skb_clone(skb, GFP_KERNEL);
1709
1710 if (!tx_skb)
1711 break;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001712
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03001713 __set_retrans_timer(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001714
Andrei Emeltchenko836be932011-10-17 12:19:57 +03001715 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau18a48e72012-05-17 20:53:34 -07001716 chan->unacked_frames++;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03001717 chan->frames_sent++;
Mat Martineau18a48e72012-05-17 20:53:34 -07001718 sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001719
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03001720 if (skb_queue_is_last(&chan->tx_q, skb))
1721 chan->tx_send_head = NULL;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001722 else
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03001723 chan->tx_send_head = skb_queue_next(&chan->tx_q, skb);
Mat Martineau18a48e72012-05-17 20:53:34 -07001724
1725 l2cap_do_send(chan, tx_skb);
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001726 BT_DBG("Sent txseq %u", control->txseq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001727 }
1728
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001729 BT_DBG("Sent %d, %u unacked, %u in ERTM queue", sent,
1730 chan->unacked_frames, skb_queue_len(&chan->tx_q));
Mat Martineau18a48e72012-05-17 20:53:34 -07001731
1732 return sent;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001733}
1734
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001735static void l2cap_ertm_resend(struct l2cap_chan *chan)
1736{
1737 struct l2cap_ctrl control;
1738 struct sk_buff *skb;
1739 struct sk_buff *tx_skb;
1740 u16 seq;
1741
1742 BT_DBG("chan %p", chan);
1743
1744 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1745 return;
1746
1747 while (chan->retrans_list.head != L2CAP_SEQ_LIST_CLEAR) {
1748 seq = l2cap_seq_list_pop(&chan->retrans_list);
1749
1750 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, seq);
1751 if (!skb) {
1752 BT_DBG("Error: Can't retransmit seq %d, frame missing",
1753 seq);
1754 continue;
1755 }
1756
1757 bt_cb(skb)->control.retries++;
1758 control = bt_cb(skb)->control;
1759
1760 if (chan->max_tx != 0 &&
1761 bt_cb(skb)->control.retries > chan->max_tx) {
1762 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
1763 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
1764 l2cap_seq_list_clear(&chan->retrans_list);
1765 break;
1766 }
1767
1768 control.reqseq = chan->buffer_seq;
1769 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
1770 control.final = 1;
1771 else
1772 control.final = 0;
1773
1774 if (skb_cloned(skb)) {
1775 /* Cloned sk_buffs are read-only, so we need a
1776 * writeable copy
1777 */
1778 tx_skb = skb_copy(skb, GFP_ATOMIC);
1779 } else {
1780 tx_skb = skb_clone(skb, GFP_ATOMIC);
1781 }
1782
1783 if (!tx_skb) {
1784 l2cap_seq_list_clear(&chan->retrans_list);
1785 break;
1786 }
1787
1788 /* Update skb contents */
1789 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
1790 put_unaligned_le32(__pack_extended_control(&control),
1791 tx_skb->data + L2CAP_HDR_SIZE);
1792 } else {
1793 put_unaligned_le16(__pack_enhanced_control(&control),
1794 tx_skb->data + L2CAP_HDR_SIZE);
1795 }
1796
1797 if (chan->fcs == L2CAP_FCS_CRC16) {
1798 u16 fcs = crc16(0, (u8 *) tx_skb->data, tx_skb->len);
1799 put_unaligned_le16(fcs, skb_put(tx_skb,
1800 L2CAP_FCS_SIZE));
1801 }
1802
1803 l2cap_do_send(chan, tx_skb);
1804
1805 BT_DBG("Resent txseq %d", control.txseq);
1806
1807 chan->last_acked_seq = chan->buffer_seq;
1808 }
1809}
1810
Mat Martineauf80842a2012-05-17 20:53:46 -07001811static void l2cap_retransmit(struct l2cap_chan *chan,
1812 struct l2cap_ctrl *control)
1813{
1814 BT_DBG("chan %p, control %p", chan, control);
1815
1816 l2cap_seq_list_append(&chan->retrans_list, control->reqseq);
1817 l2cap_ertm_resend(chan);
1818}
1819
Mat Martineaud2a7ac52012-05-17 20:53:42 -07001820static void l2cap_retransmit_all(struct l2cap_chan *chan,
1821 struct l2cap_ctrl *control)
1822{
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001823 struct sk_buff *skb;
1824
1825 BT_DBG("chan %p, control %p", chan, control);
1826
1827 if (control->poll)
1828 set_bit(CONN_SEND_FBIT, &chan->conn_state);
1829
1830 l2cap_seq_list_clear(&chan->retrans_list);
1831
1832 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1833 return;
1834
1835 if (chan->unacked_frames) {
1836 skb_queue_walk(&chan->tx_q, skb) {
1837 if (bt_cb(skb)->control.txseq == control->reqseq ||
1838 skb == chan->tx_send_head)
1839 break;
1840 }
1841
1842 skb_queue_walk_from(&chan->tx_q, skb) {
1843 if (skb == chan->tx_send_head)
1844 break;
1845
1846 l2cap_seq_list_append(&chan->retrans_list,
1847 bt_cb(skb)->control.txseq);
1848 }
1849
1850 l2cap_ertm_resend(chan);
1851 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07001852}
1853
Szymon Jancb17e73b2012-01-11 10:59:47 +01001854static void l2cap_send_ack(struct l2cap_chan *chan)
1855{
Mat Martineau0a0aba42012-05-17 20:53:39 -07001856 struct l2cap_ctrl control;
1857 u16 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
1858 chan->last_acked_seq);
1859 int threshold;
1860
1861 BT_DBG("chan %p last_acked_seq %d buffer_seq %d",
1862 chan, chan->last_acked_seq, chan->buffer_seq);
1863
1864 memset(&control, 0, sizeof(control));
1865 control.sframe = 1;
1866
1867 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
1868 chan->rx_state == L2CAP_RX_STATE_RECV) {
1869 __clear_ack_timer(chan);
1870 control.super = L2CAP_SUPER_RNR;
1871 control.reqseq = chan->buffer_seq;
1872 l2cap_send_sframe(chan, &control);
1873 } else {
1874 if (!test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) {
1875 l2cap_ertm_send(chan);
1876 /* If any i-frames were sent, they included an ack */
1877 if (chan->buffer_seq == chan->last_acked_seq)
1878 frames_to_ack = 0;
1879 }
1880
Mat Martineauc20f8e32012-07-10 05:47:07 -07001881 /* Ack now if the window is 3/4ths full.
Mat Martineau0a0aba42012-05-17 20:53:39 -07001882 * Calculate without mul or div
1883 */
Mat Martineauc20f8e32012-07-10 05:47:07 -07001884 threshold = chan->ack_win;
Mat Martineau0a0aba42012-05-17 20:53:39 -07001885 threshold += threshold << 1;
1886 threshold >>= 2;
1887
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001888 BT_DBG("frames_to_ack %u, threshold %d", frames_to_ack,
Mat Martineau0a0aba42012-05-17 20:53:39 -07001889 threshold);
1890
1891 if (frames_to_ack >= threshold) {
1892 __clear_ack_timer(chan);
1893 control.super = L2CAP_SUPER_RR;
1894 control.reqseq = chan->buffer_seq;
1895 l2cap_send_sframe(chan, &control);
1896 frames_to_ack = 0;
1897 }
1898
1899 if (frames_to_ack)
1900 __set_ack_timer(chan);
1901 }
Szymon Jancb17e73b2012-01-11 10:59:47 +01001902}
1903
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001904static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
1905 struct msghdr *msg, int len,
1906 int count, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001907{
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02001908 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001909 struct sk_buff **frag;
Gustavo Padovan90338942012-04-06 20:15:47 -03001910 int sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001911
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03001912 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001913 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001914
1915 sent += count;
1916 len -= count;
1917
1918 /* Continuation fragments (no L2CAP header) */
1919 frag = &skb_shinfo(skb)->frag_list;
1920 while (len) {
Gustavo Padovanfbe00702012-05-15 13:22:55 -03001921 struct sk_buff *tmp;
1922
Linus Torvalds1da177e2005-04-16 15:20:36 -07001923 count = min_t(unsigned int, conn->mtu, len);
1924
Gustavo Padovanfbe00702012-05-15 13:22:55 -03001925 tmp = chan->ops->alloc_skb(chan, count,
1926 msg->msg_flags & MSG_DONTWAIT);
1927 if (IS_ERR(tmp))
1928 return PTR_ERR(tmp);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02001929
Gustavo Padovanfbe00702012-05-15 13:22:55 -03001930 *frag = tmp;
1931
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001932 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
1933 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001934
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02001935 (*frag)->priority = skb->priority;
1936
Linus Torvalds1da177e2005-04-16 15:20:36 -07001937 sent += count;
1938 len -= count;
1939
Gustavo Padovan2d0ed3d2012-05-11 13:16:12 -03001940 skb->len += (*frag)->len;
1941 skb->data_len += (*frag)->len;
1942
Linus Torvalds1da177e2005-04-16 15:20:36 -07001943 frag = &(*frag)->next;
1944 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001945
1946 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001947}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001948
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02001949static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001950 struct msghdr *msg, size_t len,
1951 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001952{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001953 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001954 struct sk_buff *skb;
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03001955 int err, count, hlen = L2CAP_HDR_SIZE + L2CAP_PSMLEN_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001956 struct l2cap_hdr *lh;
1957
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001958 BT_DBG("chan %p len %zu priority %u", chan, len, priority);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001959
1960 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02001961
1962 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03001963 msg->msg_flags & MSG_DONTWAIT);
1964 if (IS_ERR(skb))
1965 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001966
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02001967 skb->priority = priority;
1968
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001969 /* Create L2CAP header */
1970 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001971 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenkodaf6a78c2012-05-03 10:55:52 +03001972 lh->len = cpu_to_le16(len + L2CAP_PSMLEN_SIZE);
1973 put_unaligned(chan->psm, skb_put(skb, L2CAP_PSMLEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001974
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02001975 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001976 if (unlikely(err < 0)) {
1977 kfree_skb(skb);
1978 return ERR_PTR(err);
1979 }
1980 return skb;
1981}
1982
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02001983static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001984 struct msghdr *msg, size_t len,
1985 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001986{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001987 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001988 struct sk_buff *skb;
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03001989 int err, count;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001990 struct l2cap_hdr *lh;
1991
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001992 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001993
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03001994 count = min_t(unsigned int, (conn->mtu - L2CAP_HDR_SIZE), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02001995
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03001996 skb = chan->ops->alloc_skb(chan, count + L2CAP_HDR_SIZE,
Gustavo Padovan90338942012-04-06 20:15:47 -03001997 msg->msg_flags & MSG_DONTWAIT);
1998 if (IS_ERR(skb))
1999 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002000
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002001 skb->priority = priority;
2002
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002003 /* Create L2CAP header */
2004 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002005 lh->cid = cpu_to_le16(chan->dcid);
Gustavo Padovan6ff9b5e2012-05-02 11:56:17 -03002006 lh->len = cpu_to_le16(len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002007
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002008 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002009 if (unlikely(err < 0)) {
2010 kfree_skb(skb);
2011 return ERR_PTR(err);
2012 }
2013 return skb;
2014}
2015
Luiz Augusto von Dentzab0ff762011-09-12 20:00:50 +03002016static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002017 struct msghdr *msg, size_t len,
2018 u16 sdulen)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002019{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002020 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002021 struct sk_buff *skb;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002022 int err, count, hlen;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002023 struct l2cap_hdr *lh;
2024
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002025 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002026
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03002027 if (!conn)
2028 return ERR_PTR(-ENOTCONN);
2029
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002030 hlen = __ertm_hdr_size(chan);
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002031
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002032 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002033 hlen += L2CAP_SDULEN_SIZE;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002034
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002035 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002036 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002037
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002038 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002039
2040 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002041 msg->msg_flags & MSG_DONTWAIT);
2042 if (IS_ERR(skb))
2043 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002044
2045 /* Create L2CAP header */
2046 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002047 lh->cid = cpu_to_le16(chan->dcid);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002048 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002049
Mat Martineau18a48e72012-05-17 20:53:34 -07002050 /* Control header is populated later */
2051 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
2052 put_unaligned_le32(0, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
2053 else
2054 put_unaligned_le16(0, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002055
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002056 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002057 put_unaligned_le16(sdulen, skb_put(skb, L2CAP_SDULEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002058
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002059 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002060 if (unlikely(err < 0)) {
2061 kfree_skb(skb);
2062 return ERR_PTR(err);
2063 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002064
Mat Martineau18a48e72012-05-17 20:53:34 -07002065 bt_cb(skb)->control.fcs = chan->fcs;
Mat Martineau3ce35142012-04-25 16:36:14 -07002066 bt_cb(skb)->control.retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002067 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002068}
2069
Mat Martineau94122bb2012-05-02 09:42:02 -07002070static int l2cap_segment_sdu(struct l2cap_chan *chan,
2071 struct sk_buff_head *seg_queue,
2072 struct msghdr *msg, size_t len)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002073{
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002074 struct sk_buff *skb;
Mat Martineau94122bb2012-05-02 09:42:02 -07002075 u16 sdu_len;
2076 size_t pdu_len;
Mat Martineau94122bb2012-05-02 09:42:02 -07002077 u8 sar;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002078
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002079 BT_DBG("chan %p, msg %p, len %zu", chan, msg, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002080
Mat Martineau94122bb2012-05-02 09:42:02 -07002081 /* It is critical that ERTM PDUs fit in a single HCI fragment,
2082 * so fragmented skbs are not used. The HCI layer's handling
2083 * of fragmented skbs is not compatible with ERTM's queueing.
2084 */
2085
2086 /* PDU size is derived from the HCI MTU */
2087 pdu_len = chan->conn->mtu;
2088
2089 pdu_len = min_t(size_t, pdu_len, L2CAP_BREDR_MAX_PAYLOAD);
2090
2091 /* Adjust for largest possible L2CAP overhead. */
Gustavo Padovan35d401d2012-05-25 18:57:05 -03002092 if (chan->fcs)
2093 pdu_len -= L2CAP_FCS_SIZE;
2094
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002095 pdu_len -= __ertm_hdr_size(chan);
Mat Martineau94122bb2012-05-02 09:42:02 -07002096
2097 /* Remote device may have requested smaller PDUs */
2098 pdu_len = min_t(size_t, pdu_len, chan->remote_mps);
2099
2100 if (len <= pdu_len) {
2101 sar = L2CAP_SAR_UNSEGMENTED;
2102 sdu_len = 0;
2103 pdu_len = len;
2104 } else {
2105 sar = L2CAP_SAR_START;
2106 sdu_len = len;
2107 pdu_len -= L2CAP_SDULEN_SIZE;
2108 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002109
2110 while (len > 0) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002111 skb = l2cap_create_iframe_pdu(chan, msg, pdu_len, sdu_len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002112
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002113 if (IS_ERR(skb)) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002114 __skb_queue_purge(seg_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002115 return PTR_ERR(skb);
2116 }
2117
Mat Martineau94122bb2012-05-02 09:42:02 -07002118 bt_cb(skb)->control.sar = sar;
2119 __skb_queue_tail(seg_queue, skb);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002120
Mat Martineau94122bb2012-05-02 09:42:02 -07002121 len -= pdu_len;
2122 if (sdu_len) {
2123 sdu_len = 0;
2124 pdu_len += L2CAP_SDULEN_SIZE;
2125 }
2126
2127 if (len <= pdu_len) {
2128 sar = L2CAP_SAR_END;
2129 pdu_len = len;
2130 } else {
2131 sar = L2CAP_SAR_CONTINUE;
2132 }
2133 }
2134
Gustavo Padovanf0f62792012-05-29 13:29:17 -03002135 return 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002136}
2137
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002138int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
2139 u32 priority)
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002140{
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002141 struct sk_buff *skb;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002142 int err;
Mat Martineau94122bb2012-05-02 09:42:02 -07002143 struct sk_buff_head seg_queue;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002144
2145 /* Connectionless channel */
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002146 if (chan->chan_type == L2CAP_CHAN_CONN_LESS) {
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002147 skb = l2cap_create_connless_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002148 if (IS_ERR(skb))
2149 return PTR_ERR(skb);
2150
2151 l2cap_do_send(chan, skb);
2152 return len;
2153 }
2154
2155 switch (chan->mode) {
2156 case L2CAP_MODE_BASIC:
2157 /* Check outgoing MTU */
2158 if (len > chan->omtu)
2159 return -EMSGSIZE;
2160
2161 /* Create a basic PDU */
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002162 skb = l2cap_create_basic_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002163 if (IS_ERR(skb))
2164 return PTR_ERR(skb);
2165
2166 l2cap_do_send(chan, skb);
2167 err = len;
2168 break;
2169
2170 case L2CAP_MODE_ERTM:
2171 case L2CAP_MODE_STREAMING:
Mat Martineau94122bb2012-05-02 09:42:02 -07002172 /* Check outgoing MTU */
2173 if (len > chan->omtu) {
2174 err = -EMSGSIZE;
2175 break;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002176 }
2177
Mat Martineau94122bb2012-05-02 09:42:02 -07002178 __skb_queue_head_init(&seg_queue);
2179
2180 /* Do segmentation before calling in to the state machine,
2181 * since it's possible to block while waiting for memory
2182 * allocation.
2183 */
2184 err = l2cap_segment_sdu(chan, &seg_queue, msg, len);
2185
2186 /* The channel could have been closed while segmenting,
2187 * check that it is still connected.
2188 */
2189 if (chan->state != BT_CONNECTED) {
2190 __skb_queue_purge(&seg_queue);
2191 err = -ENOTCONN;
2192 }
2193
2194 if (err)
2195 break;
2196
Mat Martineau37339372012-05-17 20:53:33 -07002197 if (chan->mode == L2CAP_MODE_ERTM)
Gustavo Padovand6603662012-05-21 13:58:22 -03002198 l2cap_tx(chan, NULL, &seg_queue, L2CAP_EV_DATA_REQUEST);
Mat Martineau37339372012-05-17 20:53:33 -07002199 else
Gustavo Padovand6603662012-05-21 13:58:22 -03002200 l2cap_streaming_send(chan, &seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002201
Gustavo Padovand6603662012-05-21 13:58:22 -03002202 err = len;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002203
Mat Martineau94122bb2012-05-02 09:42:02 -07002204 /* If the skbs were not queued for sending, they'll still be in
2205 * seg_queue and need to be purged.
2206 */
2207 __skb_queue_purge(&seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002208 break;
2209
2210 default:
2211 BT_DBG("bad state %1.1x", chan->mode);
2212 err = -EBADFD;
2213 }
2214
2215 return err;
2216}
2217
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002218static void l2cap_send_srej(struct l2cap_chan *chan, u16 txseq)
2219{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002220 struct l2cap_ctrl control;
2221 u16 seq;
2222
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002223 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002224
2225 memset(&control, 0, sizeof(control));
2226 control.sframe = 1;
2227 control.super = L2CAP_SUPER_SREJ;
2228
2229 for (seq = chan->expected_tx_seq; seq != txseq;
2230 seq = __next_seq(chan, seq)) {
2231 if (!l2cap_ertm_seq_in_queue(&chan->srej_q, seq)) {
2232 control.reqseq = seq;
2233 l2cap_send_sframe(chan, &control);
2234 l2cap_seq_list_append(&chan->srej_list, seq);
2235 }
2236 }
2237
2238 chan->expected_tx_seq = __next_seq(chan, txseq);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002239}
2240
2241static void l2cap_send_srej_tail(struct l2cap_chan *chan)
2242{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002243 struct l2cap_ctrl control;
2244
2245 BT_DBG("chan %p", chan);
2246
2247 if (chan->srej_list.tail == L2CAP_SEQ_LIST_CLEAR)
2248 return;
2249
2250 memset(&control, 0, sizeof(control));
2251 control.sframe = 1;
2252 control.super = L2CAP_SUPER_SREJ;
2253 control.reqseq = chan->srej_list.tail;
2254 l2cap_send_sframe(chan, &control);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002255}
2256
2257static void l2cap_send_srej_list(struct l2cap_chan *chan, u16 txseq)
2258{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002259 struct l2cap_ctrl control;
2260 u16 initial_head;
2261 u16 seq;
2262
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002263 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002264
2265 memset(&control, 0, sizeof(control));
2266 control.sframe = 1;
2267 control.super = L2CAP_SUPER_SREJ;
2268
2269 /* Capture initial list head to allow only one pass through the list. */
2270 initial_head = chan->srej_list.head;
2271
2272 do {
2273 seq = l2cap_seq_list_pop(&chan->srej_list);
2274 if (seq == txseq || seq == L2CAP_SEQ_LIST_CLEAR)
2275 break;
2276
2277 control.reqseq = seq;
2278 l2cap_send_sframe(chan, &control);
2279 l2cap_seq_list_append(&chan->srej_list, seq);
2280 } while (chan->srej_list.head != initial_head);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002281}
2282
Mat Martineau608bcc62012-05-17 20:53:32 -07002283static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq)
2284{
2285 struct sk_buff *acked_skb;
2286 u16 ackseq;
2287
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002288 BT_DBG("chan %p, reqseq %u", chan, reqseq);
Mat Martineau608bcc62012-05-17 20:53:32 -07002289
2290 if (chan->unacked_frames == 0 || reqseq == chan->expected_ack_seq)
2291 return;
2292
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002293 BT_DBG("expected_ack_seq %u, unacked_frames %u",
Mat Martineau608bcc62012-05-17 20:53:32 -07002294 chan->expected_ack_seq, chan->unacked_frames);
2295
2296 for (ackseq = chan->expected_ack_seq; ackseq != reqseq;
2297 ackseq = __next_seq(chan, ackseq)) {
2298
2299 acked_skb = l2cap_ertm_seq_in_queue(&chan->tx_q, ackseq);
2300 if (acked_skb) {
2301 skb_unlink(acked_skb, &chan->tx_q);
2302 kfree_skb(acked_skb);
2303 chan->unacked_frames--;
2304 }
2305 }
2306
2307 chan->expected_ack_seq = reqseq;
2308
2309 if (chan->unacked_frames == 0)
2310 __clear_retrans_timer(chan);
2311
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002312 BT_DBG("unacked_frames %u", chan->unacked_frames);
Mat Martineau608bcc62012-05-17 20:53:32 -07002313}
2314
2315static void l2cap_abort_rx_srej_sent(struct l2cap_chan *chan)
2316{
2317 BT_DBG("chan %p", chan);
2318
2319 chan->expected_tx_seq = chan->buffer_seq;
2320 l2cap_seq_list_clear(&chan->srej_list);
2321 skb_queue_purge(&chan->srej_q);
2322 chan->rx_state = L2CAP_RX_STATE_RECV;
2323}
2324
Gustavo Padovand6603662012-05-21 13:58:22 -03002325static void l2cap_tx_state_xmit(struct l2cap_chan *chan,
2326 struct l2cap_ctrl *control,
2327 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002328{
Mat Martineau608bcc62012-05-17 20:53:32 -07002329 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2330 event);
2331
2332 switch (event) {
2333 case L2CAP_EV_DATA_REQUEST:
2334 if (chan->tx_send_head == NULL)
2335 chan->tx_send_head = skb_peek(skbs);
2336
2337 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2338 l2cap_ertm_send(chan);
2339 break;
2340 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2341 BT_DBG("Enter LOCAL_BUSY");
2342 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2343
2344 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2345 /* The SREJ_SENT state must be aborted if we are to
2346 * enter the LOCAL_BUSY state.
2347 */
2348 l2cap_abort_rx_srej_sent(chan);
2349 }
2350
2351 l2cap_send_ack(chan);
2352
2353 break;
2354 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2355 BT_DBG("Exit LOCAL_BUSY");
2356 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2357
2358 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2359 struct l2cap_ctrl local_control;
2360
2361 memset(&local_control, 0, sizeof(local_control));
2362 local_control.sframe = 1;
2363 local_control.super = L2CAP_SUPER_RR;
2364 local_control.poll = 1;
2365 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002366 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002367
2368 chan->retry_count = 1;
2369 __set_monitor_timer(chan);
2370 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2371 }
2372 break;
2373 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2374 l2cap_process_reqseq(chan, control->reqseq);
2375 break;
2376 case L2CAP_EV_EXPLICIT_POLL:
2377 l2cap_send_rr_or_rnr(chan, 1);
2378 chan->retry_count = 1;
2379 __set_monitor_timer(chan);
2380 __clear_ack_timer(chan);
2381 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2382 break;
2383 case L2CAP_EV_RETRANS_TO:
2384 l2cap_send_rr_or_rnr(chan, 1);
2385 chan->retry_count = 1;
2386 __set_monitor_timer(chan);
2387 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2388 break;
2389 case L2CAP_EV_RECV_FBIT:
2390 /* Nothing to process */
2391 break;
2392 default:
2393 break;
2394 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002395}
2396
Gustavo Padovand6603662012-05-21 13:58:22 -03002397static void l2cap_tx_state_wait_f(struct l2cap_chan *chan,
2398 struct l2cap_ctrl *control,
2399 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002400{
Mat Martineau608bcc62012-05-17 20:53:32 -07002401 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2402 event);
2403
2404 switch (event) {
2405 case L2CAP_EV_DATA_REQUEST:
2406 if (chan->tx_send_head == NULL)
2407 chan->tx_send_head = skb_peek(skbs);
2408 /* Queue data, but don't send. */
2409 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2410 break;
2411 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2412 BT_DBG("Enter LOCAL_BUSY");
2413 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2414
2415 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2416 /* The SREJ_SENT state must be aborted if we are to
2417 * enter the LOCAL_BUSY state.
2418 */
2419 l2cap_abort_rx_srej_sent(chan);
2420 }
2421
2422 l2cap_send_ack(chan);
2423
2424 break;
2425 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2426 BT_DBG("Exit LOCAL_BUSY");
2427 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2428
2429 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2430 struct l2cap_ctrl local_control;
2431 memset(&local_control, 0, sizeof(local_control));
2432 local_control.sframe = 1;
2433 local_control.super = L2CAP_SUPER_RR;
2434 local_control.poll = 1;
2435 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002436 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002437
2438 chan->retry_count = 1;
2439 __set_monitor_timer(chan);
2440 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2441 }
2442 break;
2443 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2444 l2cap_process_reqseq(chan, control->reqseq);
2445
2446 /* Fall through */
2447
2448 case L2CAP_EV_RECV_FBIT:
2449 if (control && control->final) {
2450 __clear_monitor_timer(chan);
2451 if (chan->unacked_frames > 0)
2452 __set_retrans_timer(chan);
2453 chan->retry_count = 0;
2454 chan->tx_state = L2CAP_TX_STATE_XMIT;
2455 BT_DBG("recv fbit tx_state 0x2.2%x", chan->tx_state);
2456 }
2457 break;
2458 case L2CAP_EV_EXPLICIT_POLL:
2459 /* Ignore */
2460 break;
2461 case L2CAP_EV_MONITOR_TO:
2462 if (chan->max_tx == 0 || chan->retry_count < chan->max_tx) {
2463 l2cap_send_rr_or_rnr(chan, 1);
2464 __set_monitor_timer(chan);
2465 chan->retry_count++;
2466 } else {
2467 l2cap_send_disconn_req(chan->conn, chan, ECONNABORTED);
2468 }
2469 break;
2470 default:
2471 break;
2472 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002473}
2474
Gustavo Padovand6603662012-05-21 13:58:22 -03002475static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
2476 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002477{
Mat Martineau608bcc62012-05-17 20:53:32 -07002478 BT_DBG("chan %p, control %p, skbs %p, event %d, state %d",
2479 chan, control, skbs, event, chan->tx_state);
2480
2481 switch (chan->tx_state) {
2482 case L2CAP_TX_STATE_XMIT:
Gustavo Padovand6603662012-05-21 13:58:22 -03002483 l2cap_tx_state_xmit(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002484 break;
2485 case L2CAP_TX_STATE_WAIT_F:
Gustavo Padovand6603662012-05-21 13:58:22 -03002486 l2cap_tx_state_wait_f(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002487 break;
2488 default:
2489 /* Ignore event */
2490 break;
2491 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002492}
2493
Mat Martineau4b51dae92012-05-17 20:53:37 -07002494static void l2cap_pass_to_tx(struct l2cap_chan *chan,
2495 struct l2cap_ctrl *control)
2496{
2497 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002498 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_REQSEQ_AND_FBIT);
Mat Martineau4b51dae92012-05-17 20:53:37 -07002499}
2500
Mat Martineauf80842a2012-05-17 20:53:46 -07002501static void l2cap_pass_to_tx_fbit(struct l2cap_chan *chan,
2502 struct l2cap_ctrl *control)
2503{
2504 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002505 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_FBIT);
Mat Martineauf80842a2012-05-17 20:53:46 -07002506}
2507
Linus Torvalds1da177e2005-04-16 15:20:36 -07002508/* Copy frame to all raw sockets on that connection */
2509static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2510{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002511 struct sk_buff *nskb;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002512 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002513
2514 BT_DBG("conn %p", conn);
2515
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002516 mutex_lock(&conn->chan_lock);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002517
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002518 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002519 struct sock *sk = chan->sk;
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002520 if (chan->chan_type != L2CAP_CHAN_RAW)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002521 continue;
2522
2523 /* Don't send frame to the socket it came from */
2524 if (skb->sk == sk)
2525 continue;
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002526 nskb = skb_clone(skb, GFP_ATOMIC);
2527 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002528 continue;
2529
Gustavo Padovan80b98022012-05-27 22:27:51 -03002530 if (chan->ops->recv(chan, nskb))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002531 kfree_skb(nskb);
2532 }
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002533
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002534 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002535}
2536
2537/* ---- L2CAP signalling commands ---- */
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002538static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code,
2539 u8 ident, u16 dlen, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002540{
2541 struct sk_buff *skb, **frag;
2542 struct l2cap_cmd_hdr *cmd;
2543 struct l2cap_hdr *lh;
2544 int len, count;
2545
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002546 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %u",
2547 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002548
2549 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2550 count = min_t(unsigned int, conn->mtu, len);
2551
2552 skb = bt_skb_alloc(count, GFP_ATOMIC);
2553 if (!skb)
2554 return NULL;
2555
2556 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002557 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002558
2559 if (conn->hcon->type == LE_LINK)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002560 lh->cid = __constant_cpu_to_le16(L2CAP_CID_LE_SIGNALING);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002561 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002562 lh->cid = __constant_cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002563
2564 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2565 cmd->code = code;
2566 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002567 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002568
2569 if (dlen) {
2570 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2571 memcpy(skb_put(skb, count), data, count);
2572 data += count;
2573 }
2574
2575 len -= skb->len;
2576
2577 /* Continuation fragments (no L2CAP header) */
2578 frag = &skb_shinfo(skb)->frag_list;
2579 while (len) {
2580 count = min_t(unsigned int, conn->mtu, len);
2581
2582 *frag = bt_skb_alloc(count, GFP_ATOMIC);
2583 if (!*frag)
2584 goto fail;
2585
2586 memcpy(skb_put(*frag, count), data, count);
2587
2588 len -= count;
2589 data += count;
2590
2591 frag = &(*frag)->next;
2592 }
2593
2594 return skb;
2595
2596fail:
2597 kfree_skb(skb);
2598 return NULL;
2599}
2600
2601static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned long *val)
2602{
2603 struct l2cap_conf_opt *opt = *ptr;
2604 int len;
2605
2606 len = L2CAP_CONF_OPT_SIZE + opt->len;
2607 *ptr += len;
2608
2609 *type = opt->type;
2610 *olen = opt->len;
2611
2612 switch (opt->len) {
2613 case 1:
2614 *val = *((u8 *) opt->val);
2615 break;
2616
2617 case 2:
steven miaobfaaeb32010-10-16 18:29:47 -04002618 *val = get_unaligned_le16(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002619 break;
2620
2621 case 4:
steven miaobfaaeb32010-10-16 18:29:47 -04002622 *val = get_unaligned_le32(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002623 break;
2624
2625 default:
2626 *val = (unsigned long) opt->val;
2627 break;
2628 }
2629
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002630 BT_DBG("type 0x%2.2x len %u val 0x%lx", *type, opt->len, *val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002631 return len;
2632}
2633
Linus Torvalds1da177e2005-04-16 15:20:36 -07002634static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2635{
2636 struct l2cap_conf_opt *opt = *ptr;
2637
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002638 BT_DBG("type 0x%2.2x len %u val 0x%lx", type, len, val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002639
2640 opt->type = type;
2641 opt->len = len;
2642
2643 switch (len) {
2644 case 1:
2645 *((u8 *) opt->val) = val;
2646 break;
2647
2648 case 2:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002649 put_unaligned_le16(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002650 break;
2651
2652 case 4:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002653 put_unaligned_le32(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002654 break;
2655
2656 default:
2657 memcpy(opt->val, (void *) val, len);
2658 break;
2659 }
2660
2661 *ptr += L2CAP_CONF_OPT_SIZE + len;
2662}
2663
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002664static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan)
2665{
2666 struct l2cap_conf_efs efs;
2667
Szymon Janc1ec918c2011-11-16 09:32:21 +01002668 switch (chan->mode) {
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002669 case L2CAP_MODE_ERTM:
2670 efs.id = chan->local_id;
2671 efs.stype = chan->local_stype;
2672 efs.msdu = cpu_to_le16(chan->local_msdu);
2673 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002674 efs.acc_lat = __constant_cpu_to_le32(L2CAP_DEFAULT_ACC_LAT);
2675 efs.flush_to = __constant_cpu_to_le32(L2CAP_DEFAULT_FLUSH_TO);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002676 break;
2677
2678 case L2CAP_MODE_STREAMING:
2679 efs.id = 1;
2680 efs.stype = L2CAP_SERV_BESTEFFORT;
2681 efs.msdu = cpu_to_le16(chan->local_msdu);
2682 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
2683 efs.acc_lat = 0;
2684 efs.flush_to = 0;
2685 break;
2686
2687 default:
2688 return;
2689 }
2690
2691 l2cap_add_conf_opt(ptr, L2CAP_CONF_EFS, sizeof(efs),
2692 (unsigned long) &efs);
2693}
2694
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002695static void l2cap_ack_timeout(struct work_struct *work)
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002696{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002697 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau03625202012-05-17 20:53:51 -07002698 ack_timer.work);
2699 u16 frames_to_ack;
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002700
Gustavo F. Padovan2fb9b3d2011-12-22 16:56:05 -02002701 BT_DBG("chan %p", chan);
2702
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02002703 l2cap_chan_lock(chan);
2704
Mat Martineau03625202012-05-17 20:53:51 -07002705 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
2706 chan->last_acked_seq);
2707
2708 if (frames_to_ack)
2709 l2cap_send_rr_or_rnr(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02002710
2711 l2cap_chan_unlock(chan);
Szymon Janc09bfb2e2012-01-11 10:59:49 +01002712 l2cap_chan_put(chan);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002713}
2714
Andrei Emeltchenko466f8002012-05-29 13:59:01 +03002715int l2cap_ertm_init(struct l2cap_chan *chan)
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002716{
Mat Martineau3c588192012-04-11 10:48:42 -07002717 int err;
2718
Mat Martineau105bdf92012-04-27 16:50:48 -07002719 chan->next_tx_seq = 0;
2720 chan->expected_tx_seq = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03002721 chan->expected_ack_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03002722 chan->unacked_frames = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03002723 chan->buffer_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03002724 chan->frames_sent = 0;
Mat Martineau105bdf92012-04-27 16:50:48 -07002725 chan->last_acked_seq = 0;
2726 chan->sdu = NULL;
2727 chan->sdu_last_frag = NULL;
2728 chan->sdu_len = 0;
2729
Mat Martineaud34c34f2012-05-14 14:49:27 -07002730 skb_queue_head_init(&chan->tx_q);
2731
Mat Martineau105bdf92012-04-27 16:50:48 -07002732 if (chan->mode != L2CAP_MODE_ERTM)
2733 return 0;
2734
2735 chan->rx_state = L2CAP_RX_STATE_RECV;
2736 chan->tx_state = L2CAP_TX_STATE_XMIT;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002737
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002738 INIT_DELAYED_WORK(&chan->retrans_timer, l2cap_retrans_timeout);
2739 INIT_DELAYED_WORK(&chan->monitor_timer, l2cap_monitor_timeout);
2740 INIT_DELAYED_WORK(&chan->ack_timer, l2cap_ack_timeout);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002741
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -03002742 skb_queue_head_init(&chan->srej_q);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002743
Mat Martineau3c588192012-04-11 10:48:42 -07002744 err = l2cap_seq_list_init(&chan->srej_list, chan->tx_win);
2745 if (err < 0)
2746 return err;
2747
Mat Martineau9dc9aff2012-05-17 16:20:14 -07002748 err = l2cap_seq_list_init(&chan->retrans_list, chan->remote_tx_win);
2749 if (err < 0)
2750 l2cap_seq_list_free(&chan->srej_list);
2751
2752 return err;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002753}
2754
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002755static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
2756{
2757 switch (mode) {
2758 case L2CAP_MODE_STREAMING:
2759 case L2CAP_MODE_ERTM:
2760 if (l2cap_mode_supported(mode, remote_feat_mask))
2761 return mode;
2762 /* fall through */
2763 default:
2764 return L2CAP_MODE_BASIC;
2765 }
2766}
2767
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002768static inline bool __l2cap_ews_supported(struct l2cap_chan *chan)
2769{
2770 return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_WINDOW;
2771}
2772
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002773static inline bool __l2cap_efs_supported(struct l2cap_chan *chan)
2774{
2775 return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_FLOW;
2776}
2777
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002778static inline void l2cap_txwin_setup(struct l2cap_chan *chan)
2779{
2780 if (chan->tx_win > L2CAP_DEFAULT_TX_WINDOW &&
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002781 __l2cap_ews_supported(chan)) {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002782 /* use extended control field */
2783 set_bit(FLAG_EXT_CTRL, &chan->flags);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002784 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
2785 } else {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002786 chan->tx_win = min_t(u16, chan->tx_win,
2787 L2CAP_DEFAULT_TX_WINDOW);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002788 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
2789 }
Mat Martineauc20f8e32012-07-10 05:47:07 -07002790 chan->ack_win = chan->tx_win;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002791}
2792
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03002793static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002794{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002795 struct l2cap_conf_req *req = data;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002796 struct l2cap_conf_rfc rfc = { .mode = chan->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07002797 void *ptr = req->data;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03002798 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002799
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03002800 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002801
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03002802 if (chan->num_conf_req || chan->num_conf_rsp)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002803 goto done;
2804
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002805 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002806 case L2CAP_MODE_STREAMING:
2807 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03002808 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state))
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03002809 break;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03002810
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002811 if (__l2cap_efs_supported(chan))
2812 set_bit(FLAG_EFS_ENABLE, &chan->flags);
2813
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03002814 /* fall through */
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002815 default:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002816 chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002817 break;
2818 }
2819
2820done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002821 if (chan->imtu != L2CAP_DEFAULT_MTU)
2822 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovan7990681c2011-01-24 16:01:43 -02002823
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002824 switch (chan->mode) {
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002825 case L2CAP_MODE_BASIC:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002826 if (!(chan->conn->feat_mask & L2CAP_FEAT_ERTM) &&
2827 !(chan->conn->feat_mask & L2CAP_FEAT_STREAMING))
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002828 break;
2829
Gustavo F. Padovan62547752010-06-08 20:05:31 -03002830 rfc.mode = L2CAP_MODE_BASIC;
2831 rfc.txwin_size = 0;
2832 rfc.max_transmit = 0;
2833 rfc.retrans_timeout = 0;
2834 rfc.monitor_timeout = 0;
2835 rfc.max_pdu_size = 0;
2836
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002837 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
2838 (unsigned long) &rfc);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002839 break;
2840
2841 case L2CAP_MODE_ERTM:
2842 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002843 rfc.max_transmit = chan->max_tx;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002844 rfc.retrans_timeout = 0;
2845 rfc.monitor_timeout = 0;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03002846
2847 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
2848 L2CAP_EXT_HDR_SIZE -
2849 L2CAP_SDULEN_SIZE -
2850 L2CAP_FCS_SIZE);
2851 rfc.max_pdu_size = cpu_to_le16(size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002852
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002853 l2cap_txwin_setup(chan);
2854
2855 rfc.txwin_size = min_t(u16, chan->tx_win,
2856 L2CAP_DEFAULT_TX_WINDOW);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002857
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002858 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
2859 (unsigned long) &rfc);
2860
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002861 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
2862 l2cap_add_opt_efs(&ptr, chan);
2863
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002864 if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS))
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002865 break;
2866
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002867 if (chan->fcs == L2CAP_FCS_NONE ||
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03002868 test_bit(CONF_NO_FCS_RECV, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002869 chan->fcs = L2CAP_FCS_NONE;
2870 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002871 }
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002872
2873 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
2874 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
2875 chan->tx_win);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002876 break;
2877
2878 case L2CAP_MODE_STREAMING:
Mat Martineau273759e2012-05-17 20:53:53 -07002879 l2cap_txwin_setup(chan);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002880 rfc.mode = L2CAP_MODE_STREAMING;
2881 rfc.txwin_size = 0;
2882 rfc.max_transmit = 0;
2883 rfc.retrans_timeout = 0;
2884 rfc.monitor_timeout = 0;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03002885
2886 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
2887 L2CAP_EXT_HDR_SIZE -
2888 L2CAP_SDULEN_SIZE -
2889 L2CAP_FCS_SIZE);
2890 rfc.max_pdu_size = cpu_to_le16(size);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002891
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002892 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
2893 (unsigned long) &rfc);
2894
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002895 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
2896 l2cap_add_opt_efs(&ptr, chan);
2897
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002898 if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS))
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002899 break;
2900
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002901 if (chan->fcs == L2CAP_FCS_NONE ||
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03002902 test_bit(CONF_NO_FCS_RECV, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002903 chan->fcs = L2CAP_FCS_NONE;
2904 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002905 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002906 break;
2907 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002908
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002909 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03002910 req->flags = __constant_cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002911
2912 return ptr - data;
2913}
2914
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03002915static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002916{
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002917 struct l2cap_conf_rsp *rsp = data;
2918 void *ptr = rsp->data;
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03002919 void *req = chan->conf_req;
2920 int len = chan->conf_len;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002921 int type, hint, olen;
2922 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002923 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03002924 struct l2cap_conf_efs efs;
2925 u8 remote_efs = 0;
Marcel Holtmann861d6882007-10-20 13:37:06 +02002926 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002927 u16 result = L2CAP_CONF_SUCCESS;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03002928 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002929
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03002930 BT_DBG("chan %p", chan);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01002931
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002932 while (len >= L2CAP_CONF_OPT_SIZE) {
2933 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002934
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03002935 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07002936 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002937
2938 switch (type) {
2939 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002940 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002941 break;
2942
2943 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002944 chan->flush_to = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002945 break;
2946
2947 case L2CAP_CONF_QOS:
2948 break;
2949
Marcel Holtmann6464f352007-10-20 13:39:51 +02002950 case L2CAP_CONF_RFC:
2951 if (olen == sizeof(rfc))
2952 memcpy(&rfc, (void *) val, olen);
2953 break;
2954
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002955 case L2CAP_CONF_FCS:
2956 if (val == L2CAP_FCS_NONE)
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03002957 set_bit(CONF_NO_FCS_RECV, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03002958 break;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002959
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03002960 case L2CAP_CONF_EFS:
2961 remote_efs = 1;
2962 if (olen == sizeof(efs))
2963 memcpy(&efs, (void *) val, olen);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002964 break;
2965
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002966 case L2CAP_CONF_EWS:
2967 if (!enable_hs)
2968 return -ECONNREFUSED;
2969
2970 set_bit(FLAG_EXT_CTRL, &chan->flags);
2971 set_bit(CONF_EWS_RECV, &chan->conf_state);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002972 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002973 chan->remote_tx_win = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002974 break;
2975
2976 default:
2977 if (hint)
2978 break;
2979
2980 result = L2CAP_CONF_UNKNOWN;
2981 *((u8 *) ptr++) = type;
2982 break;
2983 }
2984 }
2985
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03002986 if (chan->num_conf_rsp || chan->num_conf_req > 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002987 goto done;
2988
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002989 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002990 case L2CAP_MODE_STREAMING:
2991 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03002992 if (!test_bit(CONF_STATE2_DEVICE, &chan->conf_state)) {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002993 chan->mode = l2cap_select_mode(rfc.mode,
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002994 chan->conn->feat_mask);
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03002995 break;
2996 }
2997
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03002998 if (remote_efs) {
2999 if (__l2cap_efs_supported(chan))
3000 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3001 else
3002 return -ECONNREFUSED;
3003 }
3004
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003005 if (chan->mode != rfc.mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003006 return -ECONNREFUSED;
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03003007
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003008 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003009 }
3010
3011done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003012 if (chan->mode != rfc.mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003013 result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003014 rfc.mode = chan->mode;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003015
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003016 if (chan->num_conf_rsp == 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003017 return -ECONNREFUSED;
3018
3019 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
3020 sizeof(rfc), (unsigned long) &rfc);
3021 }
3022
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003023 if (result == L2CAP_CONF_SUCCESS) {
3024 /* Configure output options and let the other side know
3025 * which ones we don't like. */
3026
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003027 if (mtu < L2CAP_DEFAULT_MIN_MTU)
3028 result = L2CAP_CONF_UNACCEPT;
3029 else {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003030 chan->omtu = mtu;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003031 set_bit(CONF_MTU_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003032 }
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003033 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003034
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003035 if (remote_efs) {
3036 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
3037 efs.stype != L2CAP_SERV_NOTRAFIC &&
3038 efs.stype != chan->local_stype) {
3039
3040 result = L2CAP_CONF_UNACCEPT;
3041
3042 if (chan->num_conf_req >= 1)
3043 return -ECONNREFUSED;
3044
3045 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003046 sizeof(efs),
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003047 (unsigned long) &efs);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003048 } else {
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003049 /* Send PENDING Conf Rsp */
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003050 result = L2CAP_CONF_PENDING;
3051 set_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003052 }
3053 }
3054
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003055 switch (rfc.mode) {
3056 case L2CAP_MODE_BASIC:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003057 chan->fcs = L2CAP_FCS_NONE;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003058 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003059 break;
3060
3061 case L2CAP_MODE_ERTM:
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003062 if (!test_bit(CONF_EWS_RECV, &chan->conf_state))
3063 chan->remote_tx_win = rfc.txwin_size;
3064 else
3065 rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW;
3066
Gustavo F. Padovan2c03a7a2011-03-25 20:15:28 -03003067 chan->remote_max_tx = rfc.max_transmit;
Mat Martineau86b1b262010-08-05 15:54:22 -07003068
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003069 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
3070 chan->conn->mtu -
3071 L2CAP_EXT_HDR_SIZE -
3072 L2CAP_SDULEN_SIZE -
3073 L2CAP_FCS_SIZE);
3074 rfc.max_pdu_size = cpu_to_le16(size);
3075 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003076
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03003077 rfc.retrans_timeout =
Andrei Emeltchenko4fd21a82012-03-12 12:13:10 +02003078 __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03003079 rfc.monitor_timeout =
Andrei Emeltchenko4fd21a82012-03-12 12:13:10 +02003080 __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003081
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003082 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003083
3084 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
3085 sizeof(rfc), (unsigned long) &rfc);
3086
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003087 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3088 chan->remote_id = efs.id;
3089 chan->remote_stype = efs.stype;
3090 chan->remote_msdu = le16_to_cpu(efs.msdu);
3091 chan->remote_flush_to =
3092 le32_to_cpu(efs.flush_to);
3093 chan->remote_acc_lat =
3094 le32_to_cpu(efs.acc_lat);
3095 chan->remote_sdu_itime =
3096 le32_to_cpu(efs.sdu_itime);
3097 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
3098 sizeof(efs), (unsigned long) &efs);
3099 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003100 break;
3101
3102 case L2CAP_MODE_STREAMING:
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003103 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
3104 chan->conn->mtu -
3105 L2CAP_EXT_HDR_SIZE -
3106 L2CAP_SDULEN_SIZE -
3107 L2CAP_FCS_SIZE);
3108 rfc.max_pdu_size = cpu_to_le16(size);
3109 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003110
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003111 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003112
3113 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
3114 sizeof(rfc), (unsigned long) &rfc);
3115
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003116 break;
3117
3118 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02003119 result = L2CAP_CONF_UNACCEPT;
3120
3121 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003122 rfc.mode = chan->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003123 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003124
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003125 if (result == L2CAP_CONF_SUCCESS)
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003126 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003127 }
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003128 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003129 rsp->result = cpu_to_le16(result);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003130 rsp->flags = __constant_cpu_to_le16(0);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003131
3132 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003133}
3134
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03003135static 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 -03003136{
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003137 struct l2cap_conf_req *req = data;
3138 void *ptr = req->data;
3139 int type, olen;
3140 unsigned long val;
Mat Martineau36e999a2011-12-08 17:23:21 -08003141 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003142 struct l2cap_conf_efs efs;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003143
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003144 BT_DBG("chan %p, rsp %p, len %d, req %p", chan, rsp, len, data);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003145
3146 while (len >= L2CAP_CONF_OPT_SIZE) {
3147 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3148
3149 switch (type) {
3150 case L2CAP_CONF_MTU:
3151 if (val < L2CAP_DEFAULT_MIN_MTU) {
3152 *result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003153 chan->imtu = L2CAP_DEFAULT_MIN_MTU;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003154 } else
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003155 chan->imtu = val;
3156 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003157 break;
3158
3159 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003160 chan->flush_to = val;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003161 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003162 2, chan->flush_to);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003163 break;
3164
3165 case L2CAP_CONF_RFC:
3166 if (olen == sizeof(rfc))
3167 memcpy(&rfc, (void *)val, olen);
3168
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003169 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state) &&
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003170 rfc.mode != chan->mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003171 return -ECONNREFUSED;
3172
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003173 chan->fcs = 0;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003174
3175 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
3176 sizeof(rfc), (unsigned long) &rfc);
3177 break;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003178
3179 case L2CAP_CONF_EWS:
Mat Martineauc20f8e32012-07-10 05:47:07 -07003180 chan->ack_win = min_t(u16, val, chan->ack_win);
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003181 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Mat Martineauc20f8e32012-07-10 05:47:07 -07003182 chan->tx_win);
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003183 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003184
3185 case L2CAP_CONF_EFS:
3186 if (olen == sizeof(efs))
3187 memcpy(&efs, (void *)val, olen);
3188
3189 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
3190 efs.stype != L2CAP_SERV_NOTRAFIC &&
3191 efs.stype != chan->local_stype)
3192 return -ECONNREFUSED;
3193
3194 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
3195 sizeof(efs), (unsigned long) &efs);
3196 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003197 }
3198 }
3199
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003200 if (chan->mode == L2CAP_MODE_BASIC && chan->mode != rfc.mode)
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003201 return -ECONNREFUSED;
3202
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003203 chan->mode = rfc.mode;
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003204
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003205 if (*result == L2CAP_CONF_SUCCESS || *result == L2CAP_CONF_PENDING) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003206 switch (rfc.mode) {
3207 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003208 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3209 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
3210 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003211 if (!test_bit(FLAG_EXT_CTRL, &chan->flags))
3212 chan->ack_win = min_t(u16, chan->ack_win,
3213 rfc.txwin_size);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003214
3215 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3216 chan->local_msdu = le16_to_cpu(efs.msdu);
3217 chan->local_sdu_itime =
3218 le32_to_cpu(efs.sdu_itime);
3219 chan->local_acc_lat = le32_to_cpu(efs.acc_lat);
3220 chan->local_flush_to =
3221 le32_to_cpu(efs.flush_to);
3222 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003223 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003224
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003225 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003226 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003227 }
3228 }
3229
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003230 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003231 req->flags = __constant_cpu_to_le16(0);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003232
3233 return ptr - data;
3234}
3235
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003236static int l2cap_build_conf_rsp(struct l2cap_chan *chan, void *data, u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003237{
3238 struct l2cap_conf_rsp *rsp = data;
3239 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003240
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003241 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003242
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003243 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003244 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003245 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003246
3247 return ptr - data;
3248}
3249
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003250void __l2cap_connect_rsp_defer(struct l2cap_chan *chan)
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003251{
3252 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003253 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003254 u8 buf[128];
3255
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003256 rsp.scid = cpu_to_le16(chan->dcid);
3257 rsp.dcid = cpu_to_le16(chan->scid);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003258 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
3259 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003260 l2cap_send_cmd(conn, chan->ident,
3261 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
3262
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003263 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003264 return;
3265
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003266 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
3267 l2cap_build_conf_req(chan, buf), buf);
3268 chan->num_conf_req++;
3269}
3270
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003271static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003272{
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003273 int type, olen;
3274 unsigned long val;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003275 /* Use sane default values in case a misbehaving remote device
3276 * did not send an RFC or extended window size option.
3277 */
3278 u16 txwin_ext = chan->ack_win;
3279 struct l2cap_conf_rfc rfc = {
3280 .mode = chan->mode,
3281 .retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO),
3282 .monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO),
3283 .max_pdu_size = cpu_to_le16(chan->imtu),
3284 .txwin_size = min_t(u16, chan->ack_win, L2CAP_DEFAULT_TX_WINDOW),
3285 };
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003286
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003287 BT_DBG("chan %p, rsp %p, len %d", chan, rsp, len);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003288
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003289 if ((chan->mode != L2CAP_MODE_ERTM) && (chan->mode != L2CAP_MODE_STREAMING))
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003290 return;
3291
3292 while (len >= L2CAP_CONF_OPT_SIZE) {
3293 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3294
Mat Martineauc20f8e32012-07-10 05:47:07 -07003295 switch (type) {
3296 case L2CAP_CONF_RFC:
3297 if (olen == sizeof(rfc))
3298 memcpy(&rfc, (void *)val, olen);
Szymon Janc8f321f82012-06-08 11:33:33 +02003299 break;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003300 case L2CAP_CONF_EWS:
3301 txwin_ext = val;
3302 break;
3303 }
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003304 }
3305
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003306 switch (rfc.mode) {
3307 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003308 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3309 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003310 chan->mps = le16_to_cpu(rfc.max_pdu_size);
3311 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3312 chan->ack_win = min_t(u16, chan->ack_win, txwin_ext);
3313 else
3314 chan->ack_win = min_t(u16, chan->ack_win,
3315 rfc.txwin_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003316 break;
3317 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003318 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003319 }
3320}
3321
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003322static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3323{
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003324 struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003325
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003326 if (rej->reason != L2CAP_REJ_NOT_UNDERSTOOD)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003327 return 0;
3328
3329 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
3330 cmd->ident == conn->info_ident) {
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02003331 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01003332
3333 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003334 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003335
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003336 l2cap_conn_start(conn);
3337 }
3338
3339 return 0;
3340}
3341
Linus Torvalds1da177e2005-04-16 15:20:36 -07003342static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3343{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003344 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
3345 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003346 struct l2cap_chan *chan = NULL, *pchan;
Nathan Holsteind793fe82010-10-15 11:54:02 -04003347 struct sock *parent, *sk = NULL;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003348 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003349
3350 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003351 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003352
Andrei Emeltchenko097db762012-03-09 14:16:17 +02003353 BT_DBG("psm 0x%2.2x scid 0x%4.4x", __le16_to_cpu(psm), scid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003354
3355 /* Check if we have socket listening on psm */
Ido Yarivc2287682012-04-20 15:46:07 -03003356 pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003357 if (!pchan) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003358 result = L2CAP_CR_BAD_PSM;
3359 goto sendresp;
3360 }
3361
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003362 parent = pchan->sk;
3363
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003364 mutex_lock(&conn->chan_lock);
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003365 lock_sock(parent);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00003366
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003367 /* Check if the ACL is secure enough (if not SDP) */
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +03003368 if (psm != __constant_cpu_to_le16(L2CAP_PSM_SDP) &&
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003369 !hci_conn_check_link_mode(conn->hcon)) {
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003370 conn->disc_reason = HCI_ERROR_AUTH_FAILURE;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003371 result = L2CAP_CR_SEC_BLOCK;
3372 goto response;
3373 }
3374
Linus Torvalds1da177e2005-04-16 15:20:36 -07003375 result = L2CAP_CR_NO_MEM;
3376
Gustavo Padovan2dfa1002012-05-27 22:27:58 -03003377 /* Check if we already have channel with that dcid */
3378 if (__l2cap_get_chan_by_dcid(conn, scid))
3379 goto response;
3380
Gustavo Padovan80b98022012-05-27 22:27:51 -03003381 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003382 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003383 goto response;
3384
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003385 sk = chan->sk;
3386
Linus Torvalds1da177e2005-04-16 15:20:36 -07003387 hci_conn_hold(conn->hcon);
3388
Linus Torvalds1da177e2005-04-16 15:20:36 -07003389 bacpy(&bt_sk(sk)->src, conn->src);
3390 bacpy(&bt_sk(sk)->dst, conn->dst);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003391 chan->psm = psm;
3392 chan->dcid = scid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003393
Gustavo F. Padovand1010242011-03-25 00:39:48 -03003394 bt_accept_enqueue(parent, sk);
3395
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003396 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003397
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003398 dcid = chan->scid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003399
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03003400 __set_chan_timer(chan, sk->sk_sndtimeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003401
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003402 chan->ident = cmd->ident;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003403
Marcel Holtmann984947d2009-02-06 23:35:19 +01003404 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02003405 if (l2cap_chan_check_security(chan)) {
Gustavo Padovanc5daa682012-05-16 12:17:10 -03003406 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003407 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003408 result = L2CAP_CR_PEND;
3409 status = L2CAP_CS_AUTHOR_PEND;
3410 parent->sk_data_ready(parent, 0);
3411 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003412 __l2cap_state_change(chan, BT_CONFIG);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003413 result = L2CAP_CR_SUCCESS;
3414 status = L2CAP_CS_NO_INFO;
3415 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003416 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003417 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003418 result = L2CAP_CR_PEND;
3419 status = L2CAP_CS_AUTHEN_PEND;
3420 }
3421 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003422 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003423 result = L2CAP_CR_PEND;
3424 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003425 }
3426
Linus Torvalds1da177e2005-04-16 15:20:36 -07003427response:
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003428 release_sock(parent);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003429 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003430
3431sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003432 rsp.scid = cpu_to_le16(scid);
3433 rsp.dcid = cpu_to_le16(dcid);
3434 rsp.result = cpu_to_le16(result);
3435 rsp.status = cpu_to_le16(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003436 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003437
3438 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
3439 struct l2cap_info_req info;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003440 info.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003441
3442 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
3443 conn->info_ident = l2cap_get_ident(conn);
3444
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08003445 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003446
3447 l2cap_send_cmd(conn, conn->info_ident,
3448 L2CAP_INFO_REQ, sizeof(info), &info);
3449 }
3450
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003451 if (chan && !test_bit(CONF_REQ_SENT, &chan->conf_state) &&
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003452 result == L2CAP_CR_SUCCESS) {
3453 u8 buf[128];
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003454 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003455 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003456 l2cap_build_conf_req(chan, buf), buf);
3457 chan->num_conf_req++;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003458 }
3459
Linus Torvalds1da177e2005-04-16 15:20:36 -07003460 return 0;
3461}
3462
3463static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3464{
3465 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
3466 u16 scid, dcid, result, status;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003467 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003468 u8 req[128];
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003469 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003470
3471 scid = __le16_to_cpu(rsp->scid);
3472 dcid = __le16_to_cpu(rsp->dcid);
3473 result = __le16_to_cpu(rsp->result);
3474 status = __le16_to_cpu(rsp->status);
3475
Andrei Emeltchenko1b009c92012-02-21 12:54:54 +02003476 BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x",
3477 dcid, scid, result, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003478
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003479 mutex_lock(&conn->chan_lock);
3480
Linus Torvalds1da177e2005-04-16 15:20:36 -07003481 if (scid) {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003482 chan = __l2cap_get_chan_by_scid(conn, scid);
3483 if (!chan) {
3484 err = -EFAULT;
3485 goto unlock;
3486 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003487 } else {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003488 chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
3489 if (!chan) {
3490 err = -EFAULT;
3491 goto unlock;
3492 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003493 }
3494
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003495 err = 0;
3496
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003497 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003498
Linus Torvalds1da177e2005-04-16 15:20:36 -07003499 switch (result) {
3500 case L2CAP_CR_SUCCESS:
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03003501 l2cap_state_change(chan, BT_CONFIG);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003502 chan->ident = 0;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003503 chan->dcid = dcid;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003504 clear_bit(CONF_CONNECT_PEND, &chan->conf_state);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003505
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003506 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003507 break;
3508
Linus Torvalds1da177e2005-04-16 15:20:36 -07003509 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003510 l2cap_build_conf_req(chan, req), req);
3511 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003512 break;
3513
3514 case L2CAP_CR_PEND:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003515 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003516 break;
3517
3518 default:
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003519 l2cap_chan_del(chan, ECONNREFUSED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003520 break;
3521 }
3522
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003523 l2cap_chan_unlock(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003524
3525unlock:
3526 mutex_unlock(&conn->chan_lock);
3527
3528 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003529}
3530
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003531static inline void set_default_fcs(struct l2cap_chan *chan)
Mat Martineau8c462b62010-08-24 15:35:42 -07003532{
3533 /* FCS is enabled only in ERTM or streaming mode, if one or both
3534 * sides request it.
3535 */
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003536 if (chan->mode != L2CAP_MODE_ERTM && chan->mode != L2CAP_MODE_STREAMING)
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003537 chan->fcs = L2CAP_FCS_NONE;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003538 else if (!test_bit(CONF_NO_FCS_RECV, &chan->conf_state))
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003539 chan->fcs = L2CAP_FCS_CRC16;
Mat Martineau8c462b62010-08-24 15:35:42 -07003540}
3541
Al Viro88219a02007-07-29 00:17:25 -07003542static 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 -07003543{
3544 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
3545 u16 dcid, flags;
3546 u8 rsp[64];
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003547 struct l2cap_chan *chan;
Mat Martineau3c588192012-04-11 10:48:42 -07003548 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003549
3550 dcid = __le16_to_cpu(req->dcid);
3551 flags = __le16_to_cpu(req->flags);
3552
3553 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
3554
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03003555 chan = l2cap_get_chan_by_scid(conn, dcid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003556 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003557 return -ENOENT;
3558
David S. Miller033b1142011-07-21 13:38:42 -07003559 if (chan->state != BT_CONFIG && chan->state != BT_CONNECT2) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003560 struct l2cap_cmd_rej_cid rej;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003561
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003562 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_INVALID_CID);
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003563 rej.scid = cpu_to_le16(chan->scid);
3564 rej.dcid = cpu_to_le16(chan->dcid);
3565
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003566 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
3567 sizeof(rej), &rej);
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003568 goto unlock;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003569 }
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003570
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003571 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07003572 len = cmd_len - sizeof(*req);
Dan Rosenberg7ac28812011-06-24 08:38:05 -04003573 if (len < 0 || chan->conf_len + len > sizeof(chan->conf_req)) {
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003574 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003575 l2cap_build_conf_rsp(chan, rsp,
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003576 L2CAP_CONF_REJECT, flags), rsp);
3577 goto unlock;
3578 }
3579
3580 /* Store config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003581 memcpy(chan->conf_req + chan->conf_len, req->data, len);
3582 chan->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003583
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003584 if (flags & L2CAP_CONF_FLAG_CONTINUATION) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003585 /* Incomplete config. Send empty response. */
3586 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003587 l2cap_build_conf_rsp(chan, rsp,
Andrei Emeltchenko5325e5b2012-05-23 11:31:22 +03003588 L2CAP_CONF_SUCCESS, flags), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003589 goto unlock;
3590 }
3591
3592 /* Complete config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003593 len = l2cap_parse_conf_req(chan, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003594 if (len < 0) {
Gustavo F. Padovane92c8e72011-04-01 00:53:45 -03003595 l2cap_send_disconn_req(conn, chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003596 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003597 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003598
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003599 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003600 chan->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003601
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003602 /* Reset config buffer. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003603 chan->conf_len = 0;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003604
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003605 if (!test_bit(CONF_OUTPUT_DONE, &chan->conf_state))
Marcel Holtmann876d9482007-10-20 13:35:42 +02003606 goto unlock;
3607
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003608 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003609 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003610
Mat Martineau105bdf92012-04-27 16:50:48 -07003611 if (chan->mode == L2CAP_MODE_ERTM ||
3612 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07003613 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003614
Mat Martineau3c588192012-04-11 10:48:42 -07003615 if (err < 0)
3616 l2cap_send_disconn_req(chan->conn, chan, -err);
3617 else
3618 l2cap_chan_ready(chan);
3619
Marcel Holtmann876d9482007-10-20 13:35:42 +02003620 goto unlock;
3621 }
3622
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003623 if (!test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003624 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003625 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003626 l2cap_build_conf_req(chan, buf), buf);
3627 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003628 }
3629
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003630 /* Got Conf Rsp PENDING from remote side and asume we sent
3631 Conf Rsp PENDING in the code above */
3632 if (test_bit(CONF_REM_CONF_PEND, &chan->conf_state) &&
3633 test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
3634
3635 /* check compatibility */
3636
3637 clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
3638 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
3639
3640 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003641 l2cap_build_conf_rsp(chan, rsp,
Andrei Emeltchenko5325e5b2012-05-23 11:31:22 +03003642 L2CAP_CONF_SUCCESS, flags), rsp);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003643 }
3644
Linus Torvalds1da177e2005-04-16 15:20:36 -07003645unlock:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003646 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07003647 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003648}
3649
3650static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3651{
3652 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
3653 u16 scid, flags, result;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003654 struct l2cap_chan *chan;
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02003655 int len = le16_to_cpu(cmd->len) - sizeof(*rsp);
Mat Martineau3c588192012-04-11 10:48:42 -07003656 int err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003657
3658 scid = __le16_to_cpu(rsp->scid);
3659 flags = __le16_to_cpu(rsp->flags);
3660 result = __le16_to_cpu(rsp->result);
3661
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02003662 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x len %d", scid, flags,
3663 result, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003664
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03003665 chan = l2cap_get_chan_by_scid(conn, scid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003666 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003667 return 0;
3668
3669 switch (result) {
3670 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003671 l2cap_conf_rfc_get(chan, rsp->data, len);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003672 clear_bit(CONF_REM_CONF_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003673 break;
3674
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003675 case L2CAP_CONF_PENDING:
3676 set_bit(CONF_REM_CONF_PEND, &chan->conf_state);
3677
3678 if (test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
3679 char buf[64];
3680
3681 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
3682 buf, &result);
3683 if (len < 0) {
3684 l2cap_send_disconn_req(conn, chan, ECONNRESET);
3685 goto done;
3686 }
3687
3688 /* check compatibility */
3689
3690 clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
3691 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
3692
3693 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003694 l2cap_build_conf_rsp(chan, buf,
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003695 L2CAP_CONF_SUCCESS, 0x0000), buf);
3696 }
3697 goto done;
3698
Linus Torvalds1da177e2005-04-16 15:20:36 -07003699 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003700 if (chan->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003701 char req[64];
3702
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02003703 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
Gustavo F. Padovane92c8e72011-04-01 00:53:45 -03003704 l2cap_send_disconn_req(conn, chan, ECONNRESET);
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02003705 goto done;
3706 }
3707
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003708 /* throw out any old stored conf requests */
3709 result = L2CAP_CONF_SUCCESS;
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03003710 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
3711 req, &result);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003712 if (len < 0) {
Gustavo F. Padovane92c8e72011-04-01 00:53:45 -03003713 l2cap_send_disconn_req(conn, chan, ECONNRESET);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003714 goto done;
3715 }
3716
3717 l2cap_send_cmd(conn, l2cap_get_ident(conn),
3718 L2CAP_CONF_REQ, len, req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003719 chan->num_conf_req++;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003720 if (result != L2CAP_CONF_SUCCESS)
3721 goto done;
3722 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003723 }
3724
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09003725 default:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003726 l2cap_chan_set_err(chan, ECONNRESET);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02003727
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08003728 __set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT);
Gustavo F. Padovane92c8e72011-04-01 00:53:45 -03003729 l2cap_send_disconn_req(conn, chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003730 goto done;
3731 }
3732
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003733 if (flags & L2CAP_CONF_FLAG_CONTINUATION)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003734 goto done;
3735
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003736 set_bit(CONF_INPUT_DONE, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003737
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003738 if (test_bit(CONF_OUTPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003739 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003740
Mat Martineau105bdf92012-04-27 16:50:48 -07003741 if (chan->mode == L2CAP_MODE_ERTM ||
3742 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07003743 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003744
Mat Martineau3c588192012-04-11 10:48:42 -07003745 if (err < 0)
3746 l2cap_send_disconn_req(chan->conn, chan, -err);
3747 else
3748 l2cap_chan_ready(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003749 }
3750
3751done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003752 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07003753 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003754}
3755
3756static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3757{
3758 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
3759 struct l2cap_disconn_rsp rsp;
3760 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003761 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003762 struct sock *sk;
3763
3764 scid = __le16_to_cpu(req->scid);
3765 dcid = __le16_to_cpu(req->dcid);
3766
3767 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
3768
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003769 mutex_lock(&conn->chan_lock);
3770
3771 chan = __l2cap_get_chan_by_scid(conn, dcid);
3772 if (!chan) {
3773 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003774 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003775 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003776
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003777 l2cap_chan_lock(chan);
3778
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003779 sk = chan->sk;
3780
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003781 rsp.dcid = cpu_to_le16(chan->scid);
3782 rsp.scid = cpu_to_le16(chan->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003783 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
3784
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003785 lock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003786 sk->sk_shutdown = SHUTDOWN_MASK;
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003787 release_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003788
Mat Martineau61d6ef32012-04-27 16:50:50 -07003789 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003790 l2cap_chan_del(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003791
3792 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003793
Gustavo Padovan80b98022012-05-27 22:27:51 -03003794 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07003795 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003796
3797 mutex_unlock(&conn->chan_lock);
3798
Linus Torvalds1da177e2005-04-16 15:20:36 -07003799 return 0;
3800}
3801
3802static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3803{
3804 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
3805 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003806 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003807
3808 scid = __le16_to_cpu(rsp->scid);
3809 dcid = __le16_to_cpu(rsp->dcid);
3810
3811 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
3812
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003813 mutex_lock(&conn->chan_lock);
3814
3815 chan = __l2cap_get_chan_by_scid(conn, scid);
3816 if (!chan) {
3817 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003818 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003819 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003820
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003821 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003822
Mat Martineau61d6ef32012-04-27 16:50:50 -07003823 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003824 l2cap_chan_del(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003825
3826 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003827
Gustavo Padovan80b98022012-05-27 22:27:51 -03003828 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07003829 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003830
3831 mutex_unlock(&conn->chan_lock);
3832
Linus Torvalds1da177e2005-04-16 15:20:36 -07003833 return 0;
3834}
3835
3836static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3837{
3838 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003839 u16 type;
3840
3841 type = __le16_to_cpu(req->type);
3842
3843 BT_DBG("type 0x%4.4x", type);
3844
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003845 if (type == L2CAP_IT_FEAT_MASK) {
3846 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003847 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003848 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003849 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
3850 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03003851 if (!disable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003852 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
3853 | L2CAP_FEAT_FCS;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03003854 if (enable_hs)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003855 feat_mask |= L2CAP_FEAT_EXT_FLOW
3856 | L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03003857
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03003858 put_unaligned_le32(feat_mask, rsp->data);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003859 l2cap_send_cmd(conn, cmd->ident,
3860 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003861 } else if (type == L2CAP_IT_FIXED_CHAN) {
3862 u8 buf[12];
3863 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Mat Martineau50a147c2011-11-02 16:18:34 -07003864
3865 if (enable_hs)
3866 l2cap_fixed_chan[0] |= L2CAP_FC_A2MP;
3867 else
3868 l2cap_fixed_chan[0] &= ~L2CAP_FC_A2MP;
3869
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003870 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3871 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Andrei Emeltchenkoc6337ea2011-10-20 17:02:44 +03003872 memcpy(rsp->data, l2cap_fixed_chan, sizeof(l2cap_fixed_chan));
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003873 l2cap_send_cmd(conn, cmd->ident,
3874 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003875 } else {
3876 struct l2cap_info_rsp rsp;
3877 rsp.type = cpu_to_le16(type);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003878 rsp.result = __constant_cpu_to_le16(L2CAP_IR_NOTSUPP);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003879 l2cap_send_cmd(conn, cmd->ident,
3880 L2CAP_INFO_RSP, sizeof(rsp), &rsp);
3881 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003882
3883 return 0;
3884}
3885
3886static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3887{
3888 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
3889 u16 type, result;
3890
3891 type = __le16_to_cpu(rsp->type);
3892 result = __le16_to_cpu(rsp->result);
3893
3894 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
3895
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02003896 /* L2CAP Info req/rsp are unbound to channels, add extra checks */
3897 if (cmd->ident != conn->info_ident ||
3898 conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)
3899 return 0;
3900
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02003901 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003902
Ville Tervoadb08ed2010-08-04 09:43:33 +03003903 if (result != L2CAP_IR_SUCCESS) {
3904 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
3905 conn->info_ident = 0;
3906
3907 l2cap_conn_start(conn);
3908
3909 return 0;
3910 }
3911
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02003912 switch (type) {
3913 case L2CAP_IT_FEAT_MASK:
Harvey Harrison83985312008-05-02 16:25:46 -07003914 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003915
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003916 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003917 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003918 req.type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003919
3920 conn->info_ident = l2cap_get_ident(conn);
3921
3922 l2cap_send_cmd(conn, conn->info_ident,
3923 L2CAP_INFO_REQ, sizeof(req), &req);
3924 } else {
3925 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
3926 conn->info_ident = 0;
3927
3928 l2cap_conn_start(conn);
3929 }
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02003930 break;
3931
3932 case L2CAP_IT_FIXED_CHAN:
3933 conn->fixed_chan_mask = rsp->data[0];
Marcel Holtmann984947d2009-02-06 23:35:19 +01003934 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003935 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003936
3937 l2cap_conn_start(conn);
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02003938 break;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003939 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003940
Linus Torvalds1da177e2005-04-16 15:20:36 -07003941 return 0;
3942}
3943
Mat Martineauf94ff6f2011-11-02 16:18:32 -07003944static inline int l2cap_create_channel_req(struct l2cap_conn *conn,
3945 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3946 void *data)
3947{
3948 struct l2cap_create_chan_req *req = data;
3949 struct l2cap_create_chan_rsp rsp;
3950 u16 psm, scid;
3951
3952 if (cmd_len != sizeof(*req))
3953 return -EPROTO;
3954
3955 if (!enable_hs)
3956 return -EINVAL;
3957
3958 psm = le16_to_cpu(req->psm);
3959 scid = le16_to_cpu(req->scid);
3960
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03003961 BT_DBG("psm 0x%2.2x, scid 0x%4.4x, amp_id %d", psm, scid, req->amp_id);
Mat Martineauf94ff6f2011-11-02 16:18:32 -07003962
3963 /* Placeholder: Always reject */
3964 rsp.dcid = 0;
3965 rsp.scid = cpu_to_le16(scid);
Andrei Emeltchenko8ce0c492012-03-12 12:13:09 +02003966 rsp.result = __constant_cpu_to_le16(L2CAP_CR_NO_MEM);
3967 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineauf94ff6f2011-11-02 16:18:32 -07003968
3969 l2cap_send_cmd(conn, cmd->ident, L2CAP_CREATE_CHAN_RSP,
3970 sizeof(rsp), &rsp);
3971
3972 return 0;
3973}
3974
3975static inline int l2cap_create_channel_rsp(struct l2cap_conn *conn,
3976 struct l2cap_cmd_hdr *cmd, void *data)
3977{
3978 BT_DBG("conn %p", conn);
3979
3980 return l2cap_connect_rsp(conn, cmd, data);
3981}
3982
Mat Martineau8d5a04a2011-11-02 16:18:35 -07003983static void l2cap_send_move_chan_rsp(struct l2cap_conn *conn, u8 ident,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03003984 u16 icid, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07003985{
3986 struct l2cap_move_chan_rsp rsp;
3987
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03003988 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07003989
3990 rsp.icid = cpu_to_le16(icid);
3991 rsp.result = cpu_to_le16(result);
3992
3993 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_RSP, sizeof(rsp), &rsp);
3994}
3995
3996static void l2cap_send_move_chan_cfm(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03003997 struct l2cap_chan *chan,
3998 u16 icid, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07003999{
4000 struct l2cap_move_chan_cfm cfm;
4001 u8 ident;
4002
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004003 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004004
4005 ident = l2cap_get_ident(conn);
4006 if (chan)
4007 chan->ident = ident;
4008
4009 cfm.icid = cpu_to_le16(icid);
4010 cfm.result = cpu_to_le16(result);
4011
4012 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM, sizeof(cfm), &cfm);
4013}
4014
4015static void l2cap_send_move_chan_cfm_rsp(struct l2cap_conn *conn, u8 ident,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004016 u16 icid)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004017{
4018 struct l2cap_move_chan_cfm_rsp rsp;
4019
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004020 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004021
4022 rsp.icid = cpu_to_le16(icid);
4023 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM_RSP, sizeof(rsp), &rsp);
4024}
4025
4026static inline int l2cap_move_channel_req(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004027 struct l2cap_cmd_hdr *cmd,
4028 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004029{
4030 struct l2cap_move_chan_req *req = data;
4031 u16 icid = 0;
4032 u16 result = L2CAP_MR_NOT_ALLOWED;
4033
4034 if (cmd_len != sizeof(*req))
4035 return -EPROTO;
4036
4037 icid = le16_to_cpu(req->icid);
4038
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004039 BT_DBG("icid 0x%4.4x, dest_amp_id %d", icid, req->dest_amp_id);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004040
4041 if (!enable_hs)
4042 return -EINVAL;
4043
4044 /* Placeholder: Always refuse */
4045 l2cap_send_move_chan_rsp(conn, cmd->ident, icid, result);
4046
4047 return 0;
4048}
4049
4050static inline int l2cap_move_channel_rsp(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004051 struct l2cap_cmd_hdr *cmd,
4052 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004053{
4054 struct l2cap_move_chan_rsp *rsp = data;
4055 u16 icid, result;
4056
4057 if (cmd_len != sizeof(*rsp))
4058 return -EPROTO;
4059
4060 icid = le16_to_cpu(rsp->icid);
4061 result = le16_to_cpu(rsp->result);
4062
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004063 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004064
4065 /* Placeholder: Always unconfirmed */
4066 l2cap_send_move_chan_cfm(conn, NULL, icid, L2CAP_MC_UNCONFIRMED);
4067
4068 return 0;
4069}
4070
4071static inline int l2cap_move_channel_confirm(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004072 struct l2cap_cmd_hdr *cmd,
4073 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004074{
4075 struct l2cap_move_chan_cfm *cfm = data;
4076 u16 icid, result;
4077
4078 if (cmd_len != sizeof(*cfm))
4079 return -EPROTO;
4080
4081 icid = le16_to_cpu(cfm->icid);
4082 result = le16_to_cpu(cfm->result);
4083
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004084 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004085
4086 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
4087
4088 return 0;
4089}
4090
4091static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004092 struct l2cap_cmd_hdr *cmd,
4093 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004094{
4095 struct l2cap_move_chan_cfm_rsp *rsp = data;
4096 u16 icid;
4097
4098 if (cmd_len != sizeof(*rsp))
4099 return -EPROTO;
4100
4101 icid = le16_to_cpu(rsp->icid);
4102
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004103 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004104
4105 return 0;
4106}
4107
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03004108static inline int l2cap_check_conn_param(u16 min, u16 max, u16 latency,
Claudio Takahaside731152011-02-11 19:28:55 -02004109 u16 to_multiplier)
4110{
4111 u16 max_latency;
4112
4113 if (min > max || min < 6 || max > 3200)
4114 return -EINVAL;
4115
4116 if (to_multiplier < 10 || to_multiplier > 3200)
4117 return -EINVAL;
4118
4119 if (max >= to_multiplier * 8)
4120 return -EINVAL;
4121
4122 max_latency = (to_multiplier * 8 / max) - 1;
4123 if (latency > 499 || latency > max_latency)
4124 return -EINVAL;
4125
4126 return 0;
4127}
4128
4129static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
4130 struct l2cap_cmd_hdr *cmd, u8 *data)
4131{
4132 struct hci_conn *hcon = conn->hcon;
4133 struct l2cap_conn_param_update_req *req;
4134 struct l2cap_conn_param_update_rsp rsp;
4135 u16 min, max, latency, to_multiplier, cmd_len;
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02004136 int err;
Claudio Takahaside731152011-02-11 19:28:55 -02004137
4138 if (!(hcon->link_mode & HCI_LM_MASTER))
4139 return -EINVAL;
4140
4141 cmd_len = __le16_to_cpu(cmd->len);
4142 if (cmd_len != sizeof(struct l2cap_conn_param_update_req))
4143 return -EPROTO;
4144
4145 req = (struct l2cap_conn_param_update_req *) data;
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03004146 min = __le16_to_cpu(req->min);
4147 max = __le16_to_cpu(req->max);
Claudio Takahaside731152011-02-11 19:28:55 -02004148 latency = __le16_to_cpu(req->latency);
4149 to_multiplier = __le16_to_cpu(req->to_multiplier);
4150
4151 BT_DBG("min 0x%4.4x max 0x%4.4x latency: 0x%4.4x Timeout: 0x%4.4x",
4152 min, max, latency, to_multiplier);
4153
4154 memset(&rsp, 0, sizeof(rsp));
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02004155
4156 err = l2cap_check_conn_param(min, max, latency, to_multiplier);
4157 if (err)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004158 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
Claudio Takahaside731152011-02-11 19:28:55 -02004159 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004160 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED);
Claudio Takahaside731152011-02-11 19:28:55 -02004161
4162 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP,
4163 sizeof(rsp), &rsp);
4164
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02004165 if (!err)
4166 hci_le_conn_update(hcon, min, max, latency, to_multiplier);
4167
Claudio Takahaside731152011-02-11 19:28:55 -02004168 return 0;
4169}
4170
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004171static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
4172 struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
4173{
4174 int err = 0;
4175
4176 switch (cmd->code) {
4177 case L2CAP_COMMAND_REJ:
4178 l2cap_command_rej(conn, cmd, data);
4179 break;
4180
4181 case L2CAP_CONN_REQ:
4182 err = l2cap_connect_req(conn, cmd, data);
4183 break;
4184
4185 case L2CAP_CONN_RSP:
4186 err = l2cap_connect_rsp(conn, cmd, data);
4187 break;
4188
4189 case L2CAP_CONF_REQ:
4190 err = l2cap_config_req(conn, cmd, cmd_len, data);
4191 break;
4192
4193 case L2CAP_CONF_RSP:
4194 err = l2cap_config_rsp(conn, cmd, data);
4195 break;
4196
4197 case L2CAP_DISCONN_REQ:
4198 err = l2cap_disconnect_req(conn, cmd, data);
4199 break;
4200
4201 case L2CAP_DISCONN_RSP:
4202 err = l2cap_disconnect_rsp(conn, cmd, data);
4203 break;
4204
4205 case L2CAP_ECHO_REQ:
4206 l2cap_send_cmd(conn, cmd->ident, L2CAP_ECHO_RSP, cmd_len, data);
4207 break;
4208
4209 case L2CAP_ECHO_RSP:
4210 break;
4211
4212 case L2CAP_INFO_REQ:
4213 err = l2cap_information_req(conn, cmd, data);
4214 break;
4215
4216 case L2CAP_INFO_RSP:
4217 err = l2cap_information_rsp(conn, cmd, data);
4218 break;
4219
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004220 case L2CAP_CREATE_CHAN_REQ:
4221 err = l2cap_create_channel_req(conn, cmd, cmd_len, data);
4222 break;
4223
4224 case L2CAP_CREATE_CHAN_RSP:
4225 err = l2cap_create_channel_rsp(conn, cmd, data);
4226 break;
4227
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004228 case L2CAP_MOVE_CHAN_REQ:
4229 err = l2cap_move_channel_req(conn, cmd, cmd_len, data);
4230 break;
4231
4232 case L2CAP_MOVE_CHAN_RSP:
4233 err = l2cap_move_channel_rsp(conn, cmd, cmd_len, data);
4234 break;
4235
4236 case L2CAP_MOVE_CHAN_CFM:
4237 err = l2cap_move_channel_confirm(conn, cmd, cmd_len, data);
4238 break;
4239
4240 case L2CAP_MOVE_CHAN_CFM_RSP:
4241 err = l2cap_move_channel_confirm_rsp(conn, cmd, cmd_len, data);
4242 break;
4243
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004244 default:
4245 BT_ERR("Unknown BR/EDR signaling command 0x%2.2x", cmd->code);
4246 err = -EINVAL;
4247 break;
4248 }
4249
4250 return err;
4251}
4252
4253static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn,
4254 struct l2cap_cmd_hdr *cmd, u8 *data)
4255{
4256 switch (cmd->code) {
4257 case L2CAP_COMMAND_REJ:
4258 return 0;
4259
4260 case L2CAP_CONN_PARAM_UPDATE_REQ:
Claudio Takahaside731152011-02-11 19:28:55 -02004261 return l2cap_conn_param_update_req(conn, cmd, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004262
4263 case L2CAP_CONN_PARAM_UPDATE_RSP:
4264 return 0;
4265
4266 default:
4267 BT_ERR("Unknown LE signaling command 0x%2.2x", cmd->code);
4268 return -EINVAL;
4269 }
4270}
4271
4272static inline void l2cap_sig_channel(struct l2cap_conn *conn,
4273 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004274{
4275 u8 *data = skb->data;
4276 int len = skb->len;
4277 struct l2cap_cmd_hdr cmd;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004278 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004279
4280 l2cap_raw_recv(conn, skb);
4281
4282 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07004283 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004284 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
4285 data += L2CAP_CMD_HDR_SIZE;
4286 len -= L2CAP_CMD_HDR_SIZE;
4287
Al Viro88219a02007-07-29 00:17:25 -07004288 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004289
Al Viro88219a02007-07-29 00:17:25 -07004290 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 -07004291
Al Viro88219a02007-07-29 00:17:25 -07004292 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004293 BT_DBG("corrupted command");
4294 break;
4295 }
4296
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004297 if (conn->hcon->type == LE_LINK)
4298 err = l2cap_le_sig_cmd(conn, &cmd, data);
4299 else
4300 err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004301
4302 if (err) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03004303 struct l2cap_cmd_rej_unk rej;
Gustavo F. Padovan2c6d1a22011-03-23 14:38:32 -03004304
4305 BT_ERR("Wrong link type (%d)", err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004306
4307 /* FIXME: Map err to a valid reason */
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004308 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004309 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
4310 }
4311
Al Viro88219a02007-07-29 00:17:25 -07004312 data += cmd_len;
4313 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004314 }
4315
4316 kfree_skb(skb);
4317}
4318
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004319static int l2cap_check_fcs(struct l2cap_chan *chan, struct sk_buff *skb)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004320{
4321 u16 our_fcs, rcv_fcs;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03004322 int hdr_size;
4323
4324 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
4325 hdr_size = L2CAP_EXT_HDR_SIZE;
4326 else
4327 hdr_size = L2CAP_ENH_HDR_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004328
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004329 if (chan->fcs == L2CAP_FCS_CRC16) {
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03004330 skb_trim(skb, skb->len - L2CAP_FCS_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004331 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
4332 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
4333
4334 if (our_fcs != rcv_fcs)
João Paulo Rechi Vita7a560e52010-06-22 13:56:27 -03004335 return -EBADMSG;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004336 }
4337 return 0;
4338}
4339
Mat Martineau6ea00482012-05-17 20:53:52 -07004340static void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan)
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004341{
Mat Martineaue31f7632012-05-17 20:53:41 -07004342 struct l2cap_ctrl control;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004343
Mat Martineaue31f7632012-05-17 20:53:41 -07004344 BT_DBG("chan %p", chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004345
Mat Martineaue31f7632012-05-17 20:53:41 -07004346 memset(&control, 0, sizeof(control));
4347 control.sframe = 1;
4348 control.final = 1;
4349 control.reqseq = chan->buffer_seq;
4350 set_bit(CONN_SEND_FBIT, &chan->conn_state);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004351
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03004352 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
Mat Martineaue31f7632012-05-17 20:53:41 -07004353 control.super = L2CAP_SUPER_RNR;
4354 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004355 }
4356
Mat Martineaue31f7632012-05-17 20:53:41 -07004357 if (test_and_clear_bit(CONN_REMOTE_BUSY, &chan->conn_state) &&
4358 chan->unacked_frames > 0)
4359 __set_retrans_timer(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004360
Mat Martineaue31f7632012-05-17 20:53:41 -07004361 /* Send pending iframes */
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03004362 l2cap_ertm_send(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004363
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03004364 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
Mat Martineaue31f7632012-05-17 20:53:41 -07004365 test_bit(CONN_SEND_FBIT, &chan->conn_state)) {
4366 /* F-bit wasn't sent in an s-frame or i-frame yet, so
4367 * send it now.
4368 */
4369 control.super = L2CAP_SUPER_RR;
4370 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004371 }
4372}
4373
Mat Martineau84084a32011-07-22 14:54:00 -07004374static void append_skb_frag(struct sk_buff *skb,
4375 struct sk_buff *new_frag, struct sk_buff **last_frag)
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004376{
Mat Martineau84084a32011-07-22 14:54:00 -07004377 /* skb->len reflects data in skb as well as all fragments
4378 * skb->data_len reflects only data in fragments
4379 */
4380 if (!skb_has_frag_list(skb))
4381 skb_shinfo(skb)->frag_list = new_frag;
4382
4383 new_frag->next = NULL;
4384
4385 (*last_frag)->next = new_frag;
4386 *last_frag = new_frag;
4387
4388 skb->len += new_frag->len;
4389 skb->data_len += new_frag->len;
4390 skb->truesize += new_frag->truesize;
4391}
4392
Mat Martineau4b51dae92012-05-17 20:53:37 -07004393static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb,
4394 struct l2cap_ctrl *control)
Mat Martineau84084a32011-07-22 14:54:00 -07004395{
4396 int err = -EINVAL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004397
Mat Martineau4b51dae92012-05-17 20:53:37 -07004398 switch (control->sar) {
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03004399 case L2CAP_SAR_UNSEGMENTED:
Mat Martineau84084a32011-07-22 14:54:00 -07004400 if (chan->sdu)
4401 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004402
Gustavo Padovan80b98022012-05-27 22:27:51 -03004403 err = chan->ops->recv(chan, skb);
Mat Martineau84084a32011-07-22 14:54:00 -07004404 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004405
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03004406 case L2CAP_SAR_START:
Mat Martineau84084a32011-07-22 14:54:00 -07004407 if (chan->sdu)
4408 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004409
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03004410 chan->sdu_len = get_unaligned_le16(skb->data);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03004411 skb_pull(skb, L2CAP_SDULEN_SIZE);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004412
Mat Martineau84084a32011-07-22 14:54:00 -07004413 if (chan->sdu_len > chan->imtu) {
4414 err = -EMSGSIZE;
4415 break;
4416 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004417
Mat Martineau84084a32011-07-22 14:54:00 -07004418 if (skb->len >= chan->sdu_len)
4419 break;
4420
4421 chan->sdu = skb;
4422 chan->sdu_last_frag = skb;
4423
4424 skb = NULL;
4425 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004426 break;
4427
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03004428 case L2CAP_SAR_CONTINUE:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03004429 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07004430 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004431
Mat Martineau84084a32011-07-22 14:54:00 -07004432 append_skb_frag(chan->sdu, skb,
4433 &chan->sdu_last_frag);
4434 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004435
Mat Martineau84084a32011-07-22 14:54:00 -07004436 if (chan->sdu->len >= chan->sdu_len)
4437 break;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03004438
Mat Martineau84084a32011-07-22 14:54:00 -07004439 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004440 break;
4441
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03004442 case L2CAP_SAR_END:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03004443 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07004444 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004445
Mat Martineau84084a32011-07-22 14:54:00 -07004446 append_skb_frag(chan->sdu, skb,
4447 &chan->sdu_last_frag);
4448 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004449
Mat Martineau84084a32011-07-22 14:54:00 -07004450 if (chan->sdu->len != chan->sdu_len)
4451 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004452
Gustavo Padovan80b98022012-05-27 22:27:51 -03004453 err = chan->ops->recv(chan, chan->sdu);
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03004454
Mat Martineau84084a32011-07-22 14:54:00 -07004455 if (!err) {
4456 /* Reassembly complete */
4457 chan->sdu = NULL;
4458 chan->sdu_last_frag = NULL;
4459 chan->sdu_len = 0;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004460 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004461 break;
4462 }
4463
Mat Martineau84084a32011-07-22 14:54:00 -07004464 if (err) {
4465 kfree_skb(skb);
4466 kfree_skb(chan->sdu);
4467 chan->sdu = NULL;
4468 chan->sdu_last_frag = NULL;
4469 chan->sdu_len = 0;
4470 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004471
Mat Martineau84084a32011-07-22 14:54:00 -07004472 return err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004473}
4474
Mat Martineaue3281402011-07-07 09:39:02 -07004475void l2cap_chan_busy(struct l2cap_chan *chan, int busy)
Gustavo F. Padovan712132eb2010-06-21 19:39:50 -03004476{
Mat Martineau61aa4f52012-05-17 20:53:40 -07004477 u8 event;
4478
4479 if (chan->mode != L2CAP_MODE_ERTM)
4480 return;
4481
4482 event = busy ? L2CAP_EV_LOCAL_BUSY_DETECTED : L2CAP_EV_LOCAL_BUSY_CLEAR;
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03004483 l2cap_tx(chan, NULL, NULL, event);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004484}
4485
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004486static int l2cap_rx_queued_iframes(struct l2cap_chan *chan)
4487{
Mat Martineau63838722012-05-17 20:53:45 -07004488 int err = 0;
4489 /* Pass sequential frames to l2cap_reassemble_sdu()
4490 * until a gap is encountered.
4491 */
4492
4493 BT_DBG("chan %p", chan);
4494
4495 while (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4496 struct sk_buff *skb;
4497 BT_DBG("Searching for skb with txseq %d (queue len %d)",
4498 chan->buffer_seq, skb_queue_len(&chan->srej_q));
4499
4500 skb = l2cap_ertm_seq_in_queue(&chan->srej_q, chan->buffer_seq);
4501
4502 if (!skb)
4503 break;
4504
4505 skb_unlink(skb, &chan->srej_q);
4506 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
4507 err = l2cap_reassemble_sdu(chan, skb, &bt_cb(skb)->control);
4508 if (err)
4509 break;
4510 }
4511
4512 if (skb_queue_empty(&chan->srej_q)) {
4513 chan->rx_state = L2CAP_RX_STATE_RECV;
4514 l2cap_send_ack(chan);
4515 }
4516
4517 return err;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004518}
4519
4520static void l2cap_handle_srej(struct l2cap_chan *chan,
4521 struct l2cap_ctrl *control)
4522{
Mat Martineauf80842a2012-05-17 20:53:46 -07004523 struct sk_buff *skb;
4524
4525 BT_DBG("chan %p, control %p", chan, control);
4526
4527 if (control->reqseq == chan->next_tx_seq) {
4528 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
4529 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
4530 return;
4531 }
4532
4533 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
4534
4535 if (skb == NULL) {
4536 BT_DBG("Seq %d not available for retransmission",
4537 control->reqseq);
4538 return;
4539 }
4540
4541 if (chan->max_tx != 0 && bt_cb(skb)->control.retries >= chan->max_tx) {
4542 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
4543 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
4544 return;
4545 }
4546
4547 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4548
4549 if (control->poll) {
4550 l2cap_pass_to_tx(chan, control);
4551
4552 set_bit(CONN_SEND_FBIT, &chan->conn_state);
4553 l2cap_retransmit(chan, control);
4554 l2cap_ertm_send(chan);
4555
4556 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
4557 set_bit(CONN_SREJ_ACT, &chan->conn_state);
4558 chan->srej_save_reqseq = control->reqseq;
4559 }
4560 } else {
4561 l2cap_pass_to_tx_fbit(chan, control);
4562
4563 if (control->final) {
4564 if (chan->srej_save_reqseq != control->reqseq ||
4565 !test_and_clear_bit(CONN_SREJ_ACT,
4566 &chan->conn_state))
4567 l2cap_retransmit(chan, control);
4568 } else {
4569 l2cap_retransmit(chan, control);
4570 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
4571 set_bit(CONN_SREJ_ACT, &chan->conn_state);
4572 chan->srej_save_reqseq = control->reqseq;
4573 }
4574 }
4575 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004576}
4577
4578static void l2cap_handle_rej(struct l2cap_chan *chan,
4579 struct l2cap_ctrl *control)
4580{
Mat Martineaufcd289d2012-05-17 20:53:47 -07004581 struct sk_buff *skb;
4582
4583 BT_DBG("chan %p, control %p", chan, control);
4584
4585 if (control->reqseq == chan->next_tx_seq) {
4586 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
4587 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
4588 return;
4589 }
4590
4591 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
4592
4593 if (chan->max_tx && skb &&
4594 bt_cb(skb)->control.retries >= chan->max_tx) {
4595 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
4596 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
4597 return;
4598 }
4599
4600 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4601
4602 l2cap_pass_to_tx(chan, control);
4603
4604 if (control->final) {
4605 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state))
4606 l2cap_retransmit_all(chan, control);
4607 } else {
4608 l2cap_retransmit_all(chan, control);
4609 l2cap_ertm_send(chan);
4610 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F)
4611 set_bit(CONN_REJ_ACT, &chan->conn_state);
4612 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004613}
4614
Mat Martineau4b51dae92012-05-17 20:53:37 -07004615static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq)
4616{
4617 BT_DBG("chan %p, txseq %d", chan, txseq);
4618
4619 BT_DBG("last_acked_seq %d, expected_tx_seq %d", chan->last_acked_seq,
4620 chan->expected_tx_seq);
4621
4622 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
4623 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
4624 chan->tx_win) {
4625 /* See notes below regarding "double poll" and
4626 * invalid packets.
4627 */
4628 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
4629 BT_DBG("Invalid/Ignore - after SREJ");
4630 return L2CAP_TXSEQ_INVALID_IGNORE;
4631 } else {
4632 BT_DBG("Invalid - in window after SREJ sent");
4633 return L2CAP_TXSEQ_INVALID;
4634 }
4635 }
4636
4637 if (chan->srej_list.head == txseq) {
4638 BT_DBG("Expected SREJ");
4639 return L2CAP_TXSEQ_EXPECTED_SREJ;
4640 }
4641
4642 if (l2cap_ertm_seq_in_queue(&chan->srej_q, txseq)) {
4643 BT_DBG("Duplicate SREJ - txseq already stored");
4644 return L2CAP_TXSEQ_DUPLICATE_SREJ;
4645 }
4646
4647 if (l2cap_seq_list_contains(&chan->srej_list, txseq)) {
4648 BT_DBG("Unexpected SREJ - not requested");
4649 return L2CAP_TXSEQ_UNEXPECTED_SREJ;
4650 }
4651 }
4652
4653 if (chan->expected_tx_seq == txseq) {
4654 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
4655 chan->tx_win) {
4656 BT_DBG("Invalid - txseq outside tx window");
4657 return L2CAP_TXSEQ_INVALID;
4658 } else {
4659 BT_DBG("Expected");
4660 return L2CAP_TXSEQ_EXPECTED;
4661 }
4662 }
4663
4664 if (__seq_offset(chan, txseq, chan->last_acked_seq) <
4665 __seq_offset(chan, chan->expected_tx_seq,
4666 chan->last_acked_seq)){
4667 BT_DBG("Duplicate - expected_tx_seq later than txseq");
4668 return L2CAP_TXSEQ_DUPLICATE;
4669 }
4670
4671 if (__seq_offset(chan, txseq, chan->last_acked_seq) >= chan->tx_win) {
4672 /* A source of invalid packets is a "double poll" condition,
4673 * where delays cause us to send multiple poll packets. If
4674 * the remote stack receives and processes both polls,
4675 * sequence numbers can wrap around in such a way that a
4676 * resent frame has a sequence number that looks like new data
4677 * with a sequence gap. This would trigger an erroneous SREJ
4678 * request.
4679 *
4680 * Fortunately, this is impossible with a tx window that's
4681 * less than half of the maximum sequence number, which allows
4682 * invalid frames to be safely ignored.
4683 *
4684 * With tx window sizes greater than half of the tx window
4685 * maximum, the frame is invalid and cannot be ignored. This
4686 * causes a disconnect.
4687 */
4688
4689 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
4690 BT_DBG("Invalid/Ignore - txseq outside tx window");
4691 return L2CAP_TXSEQ_INVALID_IGNORE;
4692 } else {
4693 BT_DBG("Invalid - txseq outside tx window");
4694 return L2CAP_TXSEQ_INVALID;
4695 }
4696 } else {
4697 BT_DBG("Unexpected - txseq indicates missing frames");
4698 return L2CAP_TXSEQ_UNEXPECTED;
4699 }
4700}
4701
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004702static int l2cap_rx_state_recv(struct l2cap_chan *chan,
4703 struct l2cap_ctrl *control,
4704 struct sk_buff *skb, u8 event)
4705{
4706 int err = 0;
4707 bool skb_in_use = 0;
4708
4709 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
4710 event);
4711
4712 switch (event) {
4713 case L2CAP_EV_RECV_IFRAME:
4714 switch (l2cap_classify_txseq(chan, control->txseq)) {
4715 case L2CAP_TXSEQ_EXPECTED:
4716 l2cap_pass_to_tx(chan, control);
4717
4718 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4719 BT_DBG("Busy, discarding expected seq %d",
4720 control->txseq);
4721 break;
4722 }
4723
4724 chan->expected_tx_seq = __next_seq(chan,
4725 control->txseq);
4726
4727 chan->buffer_seq = chan->expected_tx_seq;
4728 skb_in_use = 1;
4729
4730 err = l2cap_reassemble_sdu(chan, skb, control);
4731 if (err)
4732 break;
4733
4734 if (control->final) {
4735 if (!test_and_clear_bit(CONN_REJ_ACT,
4736 &chan->conn_state)) {
4737 control->final = 0;
4738 l2cap_retransmit_all(chan, control);
4739 l2cap_ertm_send(chan);
4740 }
4741 }
4742
4743 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
4744 l2cap_send_ack(chan);
4745 break;
4746 case L2CAP_TXSEQ_UNEXPECTED:
4747 l2cap_pass_to_tx(chan, control);
4748
4749 /* Can't issue SREJ frames in the local busy state.
4750 * Drop this frame, it will be seen as missing
4751 * when local busy is exited.
4752 */
4753 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4754 BT_DBG("Busy, discarding unexpected seq %d",
4755 control->txseq);
4756 break;
4757 }
4758
4759 /* There was a gap in the sequence, so an SREJ
4760 * must be sent for each missing frame. The
4761 * current frame is stored for later use.
4762 */
4763 skb_queue_tail(&chan->srej_q, skb);
4764 skb_in_use = 1;
4765 BT_DBG("Queued %p (queue len %d)", skb,
4766 skb_queue_len(&chan->srej_q));
4767
4768 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
4769 l2cap_seq_list_clear(&chan->srej_list);
4770 l2cap_send_srej(chan, control->txseq);
4771
4772 chan->rx_state = L2CAP_RX_STATE_SREJ_SENT;
4773 break;
4774 case L2CAP_TXSEQ_DUPLICATE:
4775 l2cap_pass_to_tx(chan, control);
4776 break;
4777 case L2CAP_TXSEQ_INVALID_IGNORE:
4778 break;
4779 case L2CAP_TXSEQ_INVALID:
4780 default:
4781 l2cap_send_disconn_req(chan->conn, chan,
4782 ECONNRESET);
4783 break;
4784 }
4785 break;
4786 case L2CAP_EV_RECV_RR:
4787 l2cap_pass_to_tx(chan, control);
4788 if (control->final) {
4789 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4790
4791 if (!test_and_clear_bit(CONN_REJ_ACT,
4792 &chan->conn_state)) {
4793 control->final = 0;
4794 l2cap_retransmit_all(chan, control);
4795 }
4796
4797 l2cap_ertm_send(chan);
4798 } else if (control->poll) {
4799 l2cap_send_i_or_rr_or_rnr(chan);
4800 } else {
4801 if (test_and_clear_bit(CONN_REMOTE_BUSY,
4802 &chan->conn_state) &&
4803 chan->unacked_frames)
4804 __set_retrans_timer(chan);
4805
4806 l2cap_ertm_send(chan);
4807 }
4808 break;
4809 case L2CAP_EV_RECV_RNR:
4810 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4811 l2cap_pass_to_tx(chan, control);
4812 if (control && control->poll) {
4813 set_bit(CONN_SEND_FBIT, &chan->conn_state);
4814 l2cap_send_rr_or_rnr(chan, 0);
4815 }
4816 __clear_retrans_timer(chan);
4817 l2cap_seq_list_clear(&chan->retrans_list);
4818 break;
4819 case L2CAP_EV_RECV_REJ:
4820 l2cap_handle_rej(chan, control);
4821 break;
4822 case L2CAP_EV_RECV_SREJ:
4823 l2cap_handle_srej(chan, control);
4824 break;
4825 default:
4826 break;
4827 }
4828
4829 if (skb && !skb_in_use) {
4830 BT_DBG("Freeing %p", skb);
4831 kfree_skb(skb);
4832 }
4833
4834 return err;
4835}
4836
4837static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan,
4838 struct l2cap_ctrl *control,
4839 struct sk_buff *skb, u8 event)
4840{
4841 int err = 0;
4842 u16 txseq = control->txseq;
4843 bool skb_in_use = 0;
4844
4845 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
4846 event);
4847
4848 switch (event) {
4849 case L2CAP_EV_RECV_IFRAME:
4850 switch (l2cap_classify_txseq(chan, txseq)) {
4851 case L2CAP_TXSEQ_EXPECTED:
4852 /* Keep frame for reassembly later */
4853 l2cap_pass_to_tx(chan, control);
4854 skb_queue_tail(&chan->srej_q, skb);
4855 skb_in_use = 1;
4856 BT_DBG("Queued %p (queue len %d)", skb,
4857 skb_queue_len(&chan->srej_q));
4858
4859 chan->expected_tx_seq = __next_seq(chan, txseq);
4860 break;
4861 case L2CAP_TXSEQ_EXPECTED_SREJ:
4862 l2cap_seq_list_pop(&chan->srej_list);
4863
4864 l2cap_pass_to_tx(chan, control);
4865 skb_queue_tail(&chan->srej_q, skb);
4866 skb_in_use = 1;
4867 BT_DBG("Queued %p (queue len %d)", skb,
4868 skb_queue_len(&chan->srej_q));
4869
4870 err = l2cap_rx_queued_iframes(chan);
4871 if (err)
4872 break;
4873
4874 break;
4875 case L2CAP_TXSEQ_UNEXPECTED:
4876 /* Got a frame that can't be reassembled yet.
4877 * Save it for later, and send SREJs to cover
4878 * the missing frames.
4879 */
4880 skb_queue_tail(&chan->srej_q, skb);
4881 skb_in_use = 1;
4882 BT_DBG("Queued %p (queue len %d)", skb,
4883 skb_queue_len(&chan->srej_q));
4884
4885 l2cap_pass_to_tx(chan, control);
4886 l2cap_send_srej(chan, control->txseq);
4887 break;
4888 case L2CAP_TXSEQ_UNEXPECTED_SREJ:
4889 /* This frame was requested with an SREJ, but
4890 * some expected retransmitted frames are
4891 * missing. Request retransmission of missing
4892 * SREJ'd frames.
4893 */
4894 skb_queue_tail(&chan->srej_q, skb);
4895 skb_in_use = 1;
4896 BT_DBG("Queued %p (queue len %d)", skb,
4897 skb_queue_len(&chan->srej_q));
4898
4899 l2cap_pass_to_tx(chan, control);
4900 l2cap_send_srej_list(chan, control->txseq);
4901 break;
4902 case L2CAP_TXSEQ_DUPLICATE_SREJ:
4903 /* We've already queued this frame. Drop this copy. */
4904 l2cap_pass_to_tx(chan, control);
4905 break;
4906 case L2CAP_TXSEQ_DUPLICATE:
4907 /* Expecting a later sequence number, so this frame
4908 * was already received. Ignore it completely.
4909 */
4910 break;
4911 case L2CAP_TXSEQ_INVALID_IGNORE:
4912 break;
4913 case L2CAP_TXSEQ_INVALID:
4914 default:
4915 l2cap_send_disconn_req(chan->conn, chan,
4916 ECONNRESET);
4917 break;
4918 }
4919 break;
4920 case L2CAP_EV_RECV_RR:
4921 l2cap_pass_to_tx(chan, control);
4922 if (control->final) {
4923 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4924
4925 if (!test_and_clear_bit(CONN_REJ_ACT,
4926 &chan->conn_state)) {
4927 control->final = 0;
4928 l2cap_retransmit_all(chan, control);
4929 }
4930
4931 l2cap_ertm_send(chan);
4932 } else if (control->poll) {
4933 if (test_and_clear_bit(CONN_REMOTE_BUSY,
4934 &chan->conn_state) &&
4935 chan->unacked_frames) {
4936 __set_retrans_timer(chan);
4937 }
4938
4939 set_bit(CONN_SEND_FBIT, &chan->conn_state);
4940 l2cap_send_srej_tail(chan);
4941 } else {
4942 if (test_and_clear_bit(CONN_REMOTE_BUSY,
4943 &chan->conn_state) &&
4944 chan->unacked_frames)
4945 __set_retrans_timer(chan);
4946
4947 l2cap_send_ack(chan);
4948 }
4949 break;
4950 case L2CAP_EV_RECV_RNR:
4951 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4952 l2cap_pass_to_tx(chan, control);
4953 if (control->poll) {
4954 l2cap_send_srej_tail(chan);
4955 } else {
4956 struct l2cap_ctrl rr_control;
4957 memset(&rr_control, 0, sizeof(rr_control));
4958 rr_control.sframe = 1;
4959 rr_control.super = L2CAP_SUPER_RR;
4960 rr_control.reqseq = chan->buffer_seq;
4961 l2cap_send_sframe(chan, &rr_control);
4962 }
4963
4964 break;
4965 case L2CAP_EV_RECV_REJ:
4966 l2cap_handle_rej(chan, control);
4967 break;
4968 case L2CAP_EV_RECV_SREJ:
4969 l2cap_handle_srej(chan, control);
4970 break;
4971 }
4972
4973 if (skb && !skb_in_use) {
4974 BT_DBG("Freeing %p", skb);
4975 kfree_skb(skb);
4976 }
4977
4978 return err;
4979}
4980
4981static bool __valid_reqseq(struct l2cap_chan *chan, u16 reqseq)
4982{
4983 /* Make sure reqseq is for a packet that has been sent but not acked */
4984 u16 unacked;
4985
4986 unacked = __seq_offset(chan, chan->next_tx_seq, chan->expected_ack_seq);
4987 return __seq_offset(chan, chan->next_tx_seq, reqseq) <= unacked;
4988}
4989
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07004990static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
4991 struct sk_buff *skb, u8 event)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03004992{
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004993 int err = 0;
4994
4995 BT_DBG("chan %p, control %p, skb %p, event %d, state %d", chan,
4996 control, skb, event, chan->rx_state);
4997
4998 if (__valid_reqseq(chan, control->reqseq)) {
4999 switch (chan->rx_state) {
5000 case L2CAP_RX_STATE_RECV:
5001 err = l2cap_rx_state_recv(chan, control, skb, event);
5002 break;
5003 case L2CAP_RX_STATE_SREJ_SENT:
5004 err = l2cap_rx_state_srej_sent(chan, control, skb,
5005 event);
5006 break;
5007 default:
5008 /* shut it down */
5009 break;
5010 }
5011 } else {
5012 BT_DBG("Invalid reqseq %d (next_tx_seq %d, expected_ack_seq %d",
5013 control->reqseq, chan->next_tx_seq,
5014 chan->expected_ack_seq);
5015 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
5016 }
5017
5018 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005019}
5020
5021static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
5022 struct sk_buff *skb)
5023{
Mat Martineau4b51dae92012-05-17 20:53:37 -07005024 int err = 0;
5025
5026 BT_DBG("chan %p, control %p, skb %p, state %d", chan, control, skb,
5027 chan->rx_state);
5028
5029 if (l2cap_classify_txseq(chan, control->txseq) ==
5030 L2CAP_TXSEQ_EXPECTED) {
5031 l2cap_pass_to_tx(chan, control);
5032
5033 BT_DBG("buffer_seq %d->%d", chan->buffer_seq,
5034 __next_seq(chan, chan->buffer_seq));
5035
5036 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
5037
5038 l2cap_reassemble_sdu(chan, skb, control);
5039 } else {
5040 if (chan->sdu) {
5041 kfree_skb(chan->sdu);
5042 chan->sdu = NULL;
5043 }
5044 chan->sdu_last_frag = NULL;
5045 chan->sdu_len = 0;
5046
5047 if (skb) {
5048 BT_DBG("Freeing %p", skb);
5049 kfree_skb(skb);
5050 }
5051 }
5052
5053 chan->last_acked_seq = control->txseq;
5054 chan->expected_tx_seq = __next_seq(chan, control->txseq);
5055
5056 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005057}
5058
5059static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
5060{
5061 struct l2cap_ctrl *control = &bt_cb(skb)->control;
5062 u16 len;
5063 u8 event;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005064
Mat Martineaub76bbd62012-04-11 10:48:43 -07005065 __unpack_control(chan, skb);
5066
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005067 len = skb->len;
5068
5069 /*
5070 * We can just drop the corrupted I-frame here.
5071 * Receiver will miss it and start proper recovery
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005072 * procedures and ask for retransmission.
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005073 */
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005074 if (l2cap_check_fcs(chan, skb))
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005075 goto drop;
5076
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005077 if (!control->sframe && control->sar == L2CAP_SAR_START)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005078 len -= L2CAP_SDULEN_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005079
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005080 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005081 len -= L2CAP_FCS_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005082
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005083 if (len > chan->mps) {
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03005084 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005085 goto drop;
5086 }
5087
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005088 if (!control->sframe) {
5089 int err;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005090
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005091 BT_DBG("iframe sar %d, reqseq %d, final %d, txseq %d",
5092 control->sar, control->reqseq, control->final,
5093 control->txseq);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03005094
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005095 /* Validate F-bit - F=0 always valid, F=1 only
5096 * valid in TX WAIT_F
5097 */
5098 if (control->final && chan->tx_state != L2CAP_TX_STATE_WAIT_F)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005099 goto drop;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005100
5101 if (chan->mode != L2CAP_MODE_STREAMING) {
5102 event = L2CAP_EV_RECV_IFRAME;
5103 err = l2cap_rx(chan, control, skb, event);
5104 } else {
5105 err = l2cap_stream_rx(chan, control, skb);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005106 }
5107
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005108 if (err)
5109 l2cap_send_disconn_req(chan->conn, chan,
5110 ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005111 } else {
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005112 const u8 rx_func_to_event[4] = {
5113 L2CAP_EV_RECV_RR, L2CAP_EV_RECV_REJ,
5114 L2CAP_EV_RECV_RNR, L2CAP_EV_RECV_SREJ
5115 };
5116
5117 /* Only I-frames are expected in streaming mode */
5118 if (chan->mode == L2CAP_MODE_STREAMING)
5119 goto drop;
5120
5121 BT_DBG("sframe reqseq %d, final %d, poll %d, super %d",
5122 control->reqseq, control->final, control->poll,
5123 control->super);
5124
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005125 if (len != 0) {
5126 BT_ERR("%d", len);
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03005127 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005128 goto drop;
5129 }
5130
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005131 /* Validate F and P bits */
5132 if (control->final && (control->poll ||
5133 chan->tx_state != L2CAP_TX_STATE_WAIT_F))
5134 goto drop;
5135
5136 event = rx_func_to_event[control->super];
5137 if (l2cap_rx(chan, control, skb, event))
5138 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005139 }
5140
5141 return 0;
5142
5143drop:
5144 kfree_skb(skb);
5145 return 0;
5146}
5147
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03005148static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid,
5149 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005150{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03005151 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005152
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03005153 chan = l2cap_get_chan_by_scid(conn, cid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03005154 if (!chan) {
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03005155 if (cid == L2CAP_CID_A2MP) {
5156 chan = a2mp_channel_create(conn, skb);
5157 if (!chan) {
5158 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03005159 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03005160 }
5161
5162 l2cap_chan_lock(chan);
5163 } else {
5164 BT_DBG("unknown cid 0x%4.4x", cid);
5165 /* Drop packet and return */
5166 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03005167 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03005168 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005169 }
5170
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03005171 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005172
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03005173 if (chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005174 goto drop;
5175
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03005176 switch (chan->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005177 case L2CAP_MODE_BASIC:
5178 /* If socket recv buffers overflows we drop data here
5179 * which is *bad* because L2CAP has to be reliable.
5180 * But we don't have any other choice. L2CAP doesn't
5181 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07005182
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03005183 if (chan->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005184 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005185
Gustavo Padovan80b98022012-05-27 22:27:51 -03005186 if (!chan->ops->recv(chan, skb))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005187 goto done;
5188 break;
5189
5190 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03005191 case L2CAP_MODE_STREAMING:
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005192 l2cap_data_rcv(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03005193 goto done;
5194
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005195 default:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03005196 BT_DBG("chan %p: bad mode 0x%2.2x", chan, chan->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005197 break;
5198 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005199
5200drop:
5201 kfree_skb(skb);
5202
5203done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005204 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005205}
5206
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03005207static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm,
5208 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005209{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005210 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005211
Ido Yarivc2287682012-04-20 15:46:07 -03005212 chan = l2cap_global_chan_by_psm(0, psm, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005213 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005214 goto drop;
5215
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02005216 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005217
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03005218 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005219 goto drop;
5220
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03005221 if (chan->imtu < skb->len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005222 goto drop;
5223
Gustavo Padovan80b98022012-05-27 22:27:51 -03005224 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03005225 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005226
5227drop:
5228 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005229}
5230
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03005231static void l2cap_att_channel(struct l2cap_conn *conn, u16 cid,
5232 struct sk_buff *skb)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005233{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005234 struct l2cap_chan *chan;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005235
Ido Yarivc2287682012-04-20 15:46:07 -03005236 chan = l2cap_global_chan_by_scid(0, cid, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005237 if (!chan)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005238 goto drop;
5239
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02005240 BT_DBG("chan %p, len %d", chan, skb->len);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005241
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03005242 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005243 goto drop;
5244
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03005245 if (chan->imtu < skb->len)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005246 goto drop;
5247
Gustavo Padovan80b98022012-05-27 22:27:51 -03005248 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03005249 return;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005250
5251drop:
5252 kfree_skb(skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005253}
5254
Linus Torvalds1da177e2005-04-16 15:20:36 -07005255static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
5256{
5257 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07005258 u16 cid, len;
5259 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005260
5261 skb_pull(skb, L2CAP_HDR_SIZE);
5262 cid = __le16_to_cpu(lh->cid);
5263 len = __le16_to_cpu(lh->len);
5264
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005265 if (len != skb->len) {
5266 kfree_skb(skb);
5267 return;
5268 }
5269
Linus Torvalds1da177e2005-04-16 15:20:36 -07005270 BT_DBG("len %d, cid 0x%4.4x", len, cid);
5271
5272 switch (cid) {
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005273 case L2CAP_CID_LE_SIGNALING:
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03005274 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07005275 l2cap_sig_channel(conn, skb);
5276 break;
5277
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03005278 case L2CAP_CID_CONN_LESS:
Andrei Emeltchenko097db762012-03-09 14:16:17 +02005279 psm = get_unaligned((__le16 *) skb->data);
Andrei Emeltchenko0181a702012-05-29 10:04:05 +03005280 skb_pull(skb, L2CAP_PSMLEN_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005281 l2cap_conless_channel(conn, psm, skb);
5282 break;
5283
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005284 case L2CAP_CID_LE_DATA:
5285 l2cap_att_channel(conn, cid, skb);
5286 break;
5287
Anderson Brigliab501d6a2011-06-07 18:46:31 -03005288 case L2CAP_CID_SMP:
5289 if (smp_sig_channel(conn, skb))
5290 l2cap_conn_del(conn->hcon, EACCES);
5291 break;
5292
Linus Torvalds1da177e2005-04-16 15:20:36 -07005293 default:
5294 l2cap_data_channel(conn, cid, skb);
5295 break;
5296 }
5297}
5298
5299/* ---- L2CAP interface with lower layer (HCI) ---- */
5300
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005301int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005302{
5303 int exact = 0, lm1 = 0, lm2 = 0;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005304 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005305
Linus Torvalds1da177e2005-04-16 15:20:36 -07005306 BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
5307
5308 /* Find listening sockets and check their link_mode */
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005309 read_lock(&chan_list_lock);
5310 list_for_each_entry(c, &chan_list, global_l) {
5311 struct sock *sk = c->sk;
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005312
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03005313 if (c->state != BT_LISTEN)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005314 continue;
5315
5316 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01005317 lm1 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03005318 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01005319 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005320 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01005321 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
5322 lm2 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03005323 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01005324 lm2 |= HCI_LM_MASTER;
5325 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005326 }
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005327 read_unlock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005328
5329 return exact ? lm1 : lm2;
5330}
5331
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005332int l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005333{
Marcel Holtmann01394182006-07-03 10:02:46 +02005334 struct l2cap_conn *conn;
5335
Linus Torvalds1da177e2005-04-16 15:20:36 -07005336 BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
5337
Linus Torvalds1da177e2005-04-16 15:20:36 -07005338 if (!status) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005339 conn = l2cap_conn_add(hcon, status);
5340 if (conn)
5341 l2cap_conn_ready(conn);
Marcel Holtmann01394182006-07-03 10:02:46 +02005342 } else
Joe Perchese1750722011-06-29 18:18:29 -07005343 l2cap_conn_del(hcon, bt_to_errno(status));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005344
5345 return 0;
5346}
5347
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005348int l2cap_disconn_ind(struct hci_conn *hcon)
Marcel Holtmann2950f212009-02-12 14:02:50 +01005349{
5350 struct l2cap_conn *conn = hcon->l2cap_data;
5351
5352 BT_DBG("hcon %p", hcon);
5353
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005354 if (!conn)
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02005355 return HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01005356 return conn->disc_reason;
5357}
5358
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005359int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005360{
5361 BT_DBG("hcon %p reason %d", hcon, reason);
5362
Joe Perchese1750722011-06-29 18:18:29 -07005363 l2cap_conn_del(hcon, bt_to_errno(reason));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005364 return 0;
5365}
5366
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005367static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
Marcel Holtmannf62e4322009-01-15 21:58:44 +01005368{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03005369 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED)
Marcel Holtmann255c7602009-02-04 21:07:19 +01005370 return;
5371
Marcel Holtmannf62e4322009-01-15 21:58:44 +01005372 if (encrypt == 0x00) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005373 if (chan->sec_level == BT_SECURITY_MEDIUM) {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08005374 __set_chan_timer(chan, L2CAP_ENC_TIMEOUT);
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005375 } else if (chan->sec_level == BT_SECURITY_HIGH)
Gustavo F. Padovan0f852722011-05-04 19:42:50 -03005376 l2cap_chan_close(chan, ECONNREFUSED);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01005377 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005378 if (chan->sec_level == BT_SECURITY_MEDIUM)
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03005379 __clear_chan_timer(chan);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01005380 }
5381}
5382
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005383int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005384{
Marcel Holtmann40be4922008-07-14 20:13:50 +02005385 struct l2cap_conn *conn = hcon->l2cap_data;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03005386 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005387
Marcel Holtmann01394182006-07-03 10:02:46 +02005388 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005389 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02005390
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03005391 BT_DBG("conn %p status 0x%2.2x encrypt %u", conn, status, encrypt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005392
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03005393 if (hcon->type == LE_LINK) {
Hemant Gupta35d4adcc2012-04-18 14:46:26 +05305394 if (!status && encrypt)
5395 smp_distribute_keys(conn, 0);
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02005396 cancel_delayed_work(&conn->security_timer);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03005397 }
5398
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02005399 mutex_lock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005400
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02005401 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005402 l2cap_chan_lock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005403
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03005404 BT_DBG("chan %p scid 0x%4.4x state %s", chan, chan->scid,
5405 state_to_string(chan->state));
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03005406
5407 if (chan->scid == L2CAP_CID_LE_DATA) {
5408 if (!status && encrypt) {
5409 chan->sec_level = hcon->sec_level;
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02005410 l2cap_chan_ready(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03005411 }
5412
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005413 l2cap_chan_unlock(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03005414 continue;
5415 }
5416
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03005417 if (test_bit(CONF_CONNECT_PEND, &chan->conf_state)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005418 l2cap_chan_unlock(chan);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01005419 continue;
5420 }
5421
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03005422 if (!status && (chan->state == BT_CONNECTED ||
5423 chan->state == BT_CONFIG)) {
Gustavo Padovana7d77232012-05-13 03:20:07 -03005424 struct sock *sk = chan->sk;
5425
Gustavo Padovanc5daa682012-05-16 12:17:10 -03005426 clear_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags);
Gustavo Padovana7d77232012-05-13 03:20:07 -03005427 sk->sk_state_change(sk);
5428
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005429 l2cap_check_encryption(chan, encrypt);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005430 l2cap_chan_unlock(chan);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02005431 continue;
5432 }
5433
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03005434 if (chan->state == BT_CONNECT) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005435 if (!status) {
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +02005436 l2cap_send_conn_req(chan);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005437 } else {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08005438 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005439 }
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03005440 } else if (chan->state == BT_CONNECT2) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005441 struct sock *sk = chan->sk;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005442 struct l2cap_conn_rsp rsp;
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005443 __u16 res, stat;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005444
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005445 lock_sock(sk);
5446
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005447 if (!status) {
Gustavo Padovanc5daa682012-05-16 12:17:10 -03005448 if (test_bit(BT_SK_DEFER_SETUP,
5449 &bt_sk(sk)->flags)) {
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005450 struct sock *parent = bt_sk(sk)->parent;
5451 res = L2CAP_CR_PEND;
5452 stat = L2CAP_CS_AUTHOR_PEND;
Ilia Kolomisnky05e9a2f2011-07-15 18:30:21 +00005453 if (parent)
5454 parent->sk_data_ready(parent, 0);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005455 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02005456 __l2cap_state_change(chan, BT_CONFIG);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005457 res = L2CAP_CR_SUCCESS;
5458 stat = L2CAP_CS_NO_INFO;
5459 }
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005460 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02005461 __l2cap_state_change(chan, BT_DISCONN);
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08005462 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005463 res = L2CAP_CR_SEC_BLOCK;
5464 stat = L2CAP_CS_NO_INFO;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005465 }
5466
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005467 release_sock(sk);
5468
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03005469 rsp.scid = cpu_to_le16(chan->dcid);
5470 rsp.dcid = cpu_to_le16(chan->scid);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005471 rsp.result = cpu_to_le16(res);
5472 rsp.status = cpu_to_le16(stat);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03005473 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
5474 sizeof(rsp), &rsp);
Mat Martineau2d369352012-05-23 14:59:30 -07005475
5476 if (!test_bit(CONF_REQ_SENT, &chan->conf_state) &&
5477 res == L2CAP_CR_SUCCESS) {
5478 char buf[128];
5479 set_bit(CONF_REQ_SENT, &chan->conf_state);
5480 l2cap_send_cmd(conn, l2cap_get_ident(conn),
5481 L2CAP_CONF_REQ,
5482 l2cap_build_conf_req(chan, buf),
5483 buf);
5484 chan->num_conf_req++;
5485 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005486 }
5487
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005488 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005489 }
5490
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02005491 mutex_unlock(&conn->chan_lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005492
Linus Torvalds1da177e2005-04-16 15:20:36 -07005493 return 0;
5494}
5495
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005496int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005497{
5498 struct l2cap_conn *conn = hcon->l2cap_data;
5499
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02005500 if (!conn)
5501 conn = l2cap_conn_add(hcon, 0);
5502
5503 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005504 goto drop;
5505
5506 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
5507
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +02005508 if (!(flags & ACL_CONT)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005509 struct l2cap_hdr *hdr;
5510 int len;
5511
5512 if (conn->rx_len) {
5513 BT_ERR("Unexpected start frame (len %d)", skb->len);
5514 kfree_skb(conn->rx_skb);
5515 conn->rx_skb = NULL;
5516 conn->rx_len = 0;
5517 l2cap_conn_unreliable(conn, ECOMM);
5518 }
5519
Andrei Emeltchenkoaae7fe22010-09-15 14:28:43 +03005520 /* Start fragment always begin with Basic L2CAP header */
5521 if (skb->len < L2CAP_HDR_SIZE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005522 BT_ERR("Frame is too short (len %d)", skb->len);
5523 l2cap_conn_unreliable(conn, ECOMM);
5524 goto drop;
5525 }
5526
5527 hdr = (struct l2cap_hdr *) skb->data;
5528 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
5529
5530 if (len == skb->len) {
5531 /* Complete frame received */
5532 l2cap_recv_frame(conn, skb);
5533 return 0;
5534 }
5535
5536 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
5537
5538 if (skb->len > len) {
5539 BT_ERR("Frame is too long (len %d, expected len %d)",
5540 skb->len, len);
5541 l2cap_conn_unreliable(conn, ECOMM);
5542 goto drop;
5543 }
5544
5545 /* Allocate skb for the complete frame (with header) */
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03005546 conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC);
5547 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005548 goto drop;
5549
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03005550 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01005551 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005552 conn->rx_len = len - skb->len;
5553 } else {
5554 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
5555
5556 if (!conn->rx_len) {
5557 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
5558 l2cap_conn_unreliable(conn, ECOMM);
5559 goto drop;
5560 }
5561
5562 if (skb->len > conn->rx_len) {
5563 BT_ERR("Fragment is too long (len %d, expected %d)",
5564 skb->len, conn->rx_len);
5565 kfree_skb(conn->rx_skb);
5566 conn->rx_skb = NULL;
5567 conn->rx_len = 0;
5568 l2cap_conn_unreliable(conn, ECOMM);
5569 goto drop;
5570 }
5571
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03005572 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01005573 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005574 conn->rx_len -= skb->len;
5575
5576 if (!conn->rx_len) {
5577 /* Complete frame received */
5578 l2cap_recv_frame(conn, conn->rx_skb);
5579 conn->rx_skb = NULL;
5580 }
5581 }
5582
5583drop:
5584 kfree_skb(skb);
5585 return 0;
5586}
5587
Marcel Holtmannaef7d972010-03-21 05:27:45 +01005588static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005589{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005590 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005591
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02005592 read_lock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005593
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005594 list_for_each_entry(c, &chan_list, global_l) {
5595 struct sock *sk = c->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005596
Gustavo F. Padovan903d3432011-02-10 14:16:06 -02005597 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 +01005598 batostr(&bt_sk(sk)->src),
5599 batostr(&bt_sk(sk)->dst),
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03005600 c->state, __le16_to_cpu(c->psm),
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005601 c->scid, c->dcid, c->imtu, c->omtu,
5602 c->sec_level, c->mode);
Andrei Emeltchenko61e1b4b2012-01-19 11:19:50 +02005603 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005604
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02005605 read_unlock(&chan_list_lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08005606
Marcel Holtmannaef7d972010-03-21 05:27:45 +01005607 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005608}
5609
Marcel Holtmannaef7d972010-03-21 05:27:45 +01005610static int l2cap_debugfs_open(struct inode *inode, struct file *file)
5611{
5612 return single_open(file, l2cap_debugfs_show, inode->i_private);
5613}
5614
5615static const struct file_operations l2cap_debugfs_fops = {
5616 .open = l2cap_debugfs_open,
5617 .read = seq_read,
5618 .llseek = seq_lseek,
5619 .release = single_release,
5620};
5621
5622static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005623
Gustavo F. Padovan64274512011-02-07 20:08:52 -02005624int __init l2cap_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005625{
5626 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08005627
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02005628 err = l2cap_init_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005629 if (err < 0)
5630 return err;
5631
Marcel Holtmannaef7d972010-03-21 05:27:45 +01005632 if (bt_debugfs) {
5633 l2cap_debugfs = debugfs_create_file("l2cap", 0444,
5634 bt_debugfs, NULL, &l2cap_debugfs_fops);
5635 if (!l2cap_debugfs)
5636 BT_ERR("Failed to create L2CAP debug file");
5637 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005638
Linus Torvalds1da177e2005-04-16 15:20:36 -07005639 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005640}
5641
Gustavo F. Padovan64274512011-02-07 20:08:52 -02005642void l2cap_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005643{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01005644 debugfs_remove(l2cap_debugfs);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02005645 l2cap_cleanup_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005646}
5647
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03005648module_param(disable_ertm, bool, 0644);
5649MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode");