blob: 79923d8bbe9722f9eadf46fc4a3b3d444c836b0a [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
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530428void l2cap_chan_hold(struct l2cap_chan *c)
429{
430 BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->refcnt));
431
432 atomic_inc(&c->refcnt);
433}
434
435void l2cap_chan_put(struct l2cap_chan *c)
436{
437 BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->refcnt));
438
439 if (atomic_dec_and_test(&c->refcnt))
440 kfree(c);
441}
442
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +0300443void l2cap_chan_set_defaults(struct l2cap_chan *chan)
444{
445 chan->fcs = L2CAP_FCS_CRC16;
446 chan->max_tx = L2CAP_DEFAULT_MAX_TX;
447 chan->tx_win = L2CAP_DEFAULT_TX_WINDOW;
448 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
Mat Martineauc20f8e32012-07-10 05:47:07 -0700449 chan->ack_win = L2CAP_DEFAULT_TX_WINDOW;
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +0300450 chan->sec_level = BT_SECURITY_LOW;
451
452 set_bit(FLAG_FORCE_ACTIVE, &chan->flags);
453}
454
Andrei Emeltchenko14a28492012-03-23 16:31:49 +0200455static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Marcel Holtmann01394182006-07-03 10:02:46 +0200456{
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300457 BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
Andrei Emeltchenko097db762012-03-09 14:16:17 +0200458 __le16_to_cpu(chan->psm), chan->dcid);
Marcel Holtmann01394182006-07-03 10:02:46 +0200459
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +0200460 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +0100461
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300462 chan->conn = conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200463
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200464 switch (chan->chan_type) {
465 case L2CAP_CHAN_CONN_ORIENTED:
Ville Tervob62f3282011-02-10 22:38:50 -0300466 if (conn->hcon->type == LE_LINK) {
467 /* LE connection */
Andre Guedes6fcb06a2012-05-31 17:01:33 -0300468 chan->omtu = L2CAP_DEFAULT_MTU;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300469 chan->scid = L2CAP_CID_LE_DATA;
470 chan->dcid = L2CAP_CID_LE_DATA;
Ville Tervob62f3282011-02-10 22:38:50 -0300471 } else {
472 /* Alloc CID for connection-oriented socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300473 chan->scid = l2cap_alloc_cid(conn);
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300474 chan->omtu = L2CAP_DEFAULT_MTU;
Ville Tervob62f3282011-02-10 22:38:50 -0300475 }
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200476 break;
477
478 case L2CAP_CHAN_CONN_LESS:
Marcel Holtmann01394182006-07-03 10:02:46 +0200479 /* Connectionless socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300480 chan->scid = L2CAP_CID_CONN_LESS;
481 chan->dcid = L2CAP_CID_CONN_LESS;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300482 chan->omtu = L2CAP_DEFAULT_MTU;
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200483 break;
484
Andrei Emeltchenko416fa752012-05-29 13:59:16 +0300485 case L2CAP_CHAN_CONN_FIX_A2MP:
486 chan->scid = L2CAP_CID_A2MP;
487 chan->dcid = L2CAP_CID_A2MP;
488 chan->omtu = L2CAP_A2MP_DEFAULT_MTU;
489 chan->imtu = L2CAP_A2MP_DEFAULT_MTU;
490 break;
491
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200492 default:
Marcel Holtmann01394182006-07-03 10:02:46 +0200493 /* Raw socket can send/recv signalling messages only */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300494 chan->scid = L2CAP_CID_SIGNALING;
495 chan->dcid = L2CAP_CID_SIGNALING;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300496 chan->omtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann01394182006-07-03 10:02:46 +0200497 }
498
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300499 chan->local_id = L2CAP_BESTEFFORT_ID;
500 chan->local_stype = L2CAP_SERV_BESTEFFORT;
501 chan->local_msdu = L2CAP_DEFAULT_MAX_SDU_SIZE;
502 chan->local_sdu_itime = L2CAP_DEFAULT_SDU_ITIME;
503 chan->local_acc_lat = L2CAP_DEFAULT_ACC_LAT;
504 chan->local_flush_to = L2CAP_DEFAULT_FLUSH_TO;
505
Ulisses Furquim371fd832011-12-21 20:02:36 -0200506 l2cap_chan_hold(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300507
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200508 list_add(&chan->list, &conn->chan_l);
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200509}
510
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300511void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200512{
513 mutex_lock(&conn->chan_lock);
514 __l2cap_chan_add(conn, chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200515 mutex_unlock(&conn->chan_lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200516}
517
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300518void l2cap_chan_del(struct l2cap_chan *chan, int err)
Marcel Holtmann01394182006-07-03 10:02:46 +0200519{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300520 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200521
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300522 __clear_chan_timer(chan);
Marcel Holtmann01394182006-07-03 10:02:46 +0200523
Gustavo F. Padovan49208c92011-04-04 15:59:54 -0300524 BT_DBG("chan %p, conn %p, err %d", chan, conn, err);
Marcel Holtmann01394182006-07-03 10:02:46 +0200525
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900526 if (conn) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300527 /* Delete from channel list */
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200528 list_del(&chan->list);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -0200529
Ulisses Furquim371fd832011-12-21 20:02:36 -0200530 l2cap_chan_put(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300531
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300532 chan->conn = NULL;
Andrei Emeltchenko3cabbfd2012-05-31 11:01:37 +0300533
534 if (chan->chan_type != L2CAP_CHAN_CONN_FIX_A2MP)
535 hci_conn_put(conn->hcon);
Marcel Holtmann01394182006-07-03 10:02:46 +0200536 }
537
Andrei Emeltchenkoc0df7f62012-05-27 22:27:52 -0300538 if (chan->ops->teardown)
539 chan->ops->teardown(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200540
Mat Martineau28270112012-05-17 21:14:09 -0700541 if (test_bit(CONF_NOT_COMPLETE, &chan->conf_state))
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300542 return;
Gustavo F. Padovan2ead70b2011-04-01 15:13:36 -0300543
Gustavo Padovanee556f62012-05-18 20:22:38 -0300544 switch(chan->mode) {
545 case L2CAP_MODE_BASIC:
546 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300547
Gustavo Padovanee556f62012-05-18 20:22:38 -0300548 case L2CAP_MODE_ERTM:
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -0300549 __clear_retrans_timer(chan);
550 __clear_monitor_timer(chan);
551 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300552
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -0300553 skb_queue_purge(&chan->srej_q);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300554
Mat Martineau3c588192012-04-11 10:48:42 -0700555 l2cap_seq_list_free(&chan->srej_list);
556 l2cap_seq_list_free(&chan->retrans_list);
Gustavo Padovanee556f62012-05-18 20:22:38 -0300557
558 /* fall through */
559
560 case L2CAP_MODE_STREAMING:
561 skb_queue_purge(&chan->tx_q);
562 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300563 }
Gustavo Padovanee556f62012-05-18 20:22:38 -0300564
565 return;
Marcel Holtmann01394182006-07-03 10:02:46 +0200566}
567
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300568void l2cap_chan_close(struct l2cap_chan *chan, int reason)
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300569{
570 struct l2cap_conn *conn = chan->conn;
571 struct sock *sk = chan->sk;
572
Andrei Emeltchenkoe05dcc32012-02-17 11:40:56 +0200573 BT_DBG("chan %p state %s sk %p", chan,
574 state_to_string(chan->state), sk);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300575
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300576 switch (chan->state) {
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300577 case BT_LISTEN:
Andrei Emeltchenkoc0df7f62012-05-27 22:27:52 -0300578 if (chan->ops->teardown)
579 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300580 break;
581
582 case BT_CONNECTED:
583 case BT_CONFIG:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300584 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300585 conn->hcon->type == ACL_LINK) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300586 __set_chan_timer(chan, sk->sk_sndtimeo);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300587 l2cap_send_disconn_req(conn, chan, reason);
588 } else
589 l2cap_chan_del(chan, reason);
590 break;
591
592 case BT_CONNECT2:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300593 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300594 conn->hcon->type == ACL_LINK) {
595 struct l2cap_conn_rsp rsp;
596 __u16 result;
597
Gustavo Padovanc5daa682012-05-16 12:17:10 -0300598 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags))
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300599 result = L2CAP_CR_SEC_BLOCK;
600 else
601 result = L2CAP_CR_BAD_PSM;
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300602 l2cap_state_change(chan, BT_DISCONN);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300603
604 rsp.scid = cpu_to_le16(chan->dcid);
605 rsp.dcid = cpu_to_le16(chan->scid);
606 rsp.result = cpu_to_le16(result);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +0300607 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300608 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
609 sizeof(rsp), &rsp);
610 }
611
612 l2cap_chan_del(chan, reason);
613 break;
614
615 case BT_CONNECT:
616 case BT_DISCONN:
617 l2cap_chan_del(chan, reason);
618 break;
619
620 default:
Andrei Emeltchenkoc0df7f62012-05-27 22:27:52 -0300621 if (chan->ops->teardown)
622 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300623 break;
624 }
625}
626
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300627static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530628{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300629 if (chan->chan_type == L2CAP_CHAN_RAW) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300630 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530631 case BT_SECURITY_HIGH:
632 return HCI_AT_DEDICATED_BONDING_MITM;
633 case BT_SECURITY_MEDIUM:
634 return HCI_AT_DEDICATED_BONDING;
635 default:
636 return HCI_AT_NO_BONDING;
637 }
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +0300638 } else if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_SDP)) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300639 if (chan->sec_level == BT_SECURITY_LOW)
640 chan->sec_level = BT_SECURITY_SDP;
Johan Hedberg8556edd32011-01-19 12:06:50 +0530641
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300642 if (chan->sec_level == BT_SECURITY_HIGH)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530643 return HCI_AT_NO_BONDING_MITM;
644 else
645 return HCI_AT_NO_BONDING;
646 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300647 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530648 case BT_SECURITY_HIGH:
649 return HCI_AT_GENERAL_BONDING_MITM;
650 case BT_SECURITY_MEDIUM:
651 return HCI_AT_GENERAL_BONDING;
652 default:
653 return HCI_AT_NO_BONDING;
654 }
655 }
656}
657
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200658/* Service level security */
Gustavo F. Padovand45fc422011-11-05 19:54:24 -0200659int l2cap_chan_check_security(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200660{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300661 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100662 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200663
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300664 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100665
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300666 return hci_conn_security(conn->hcon, chan->sec_level, auth_type);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200667}
668
Johannes Bergb5ad8b72011-06-01 08:54:45 +0200669static u8 l2cap_get_ident(struct l2cap_conn *conn)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200670{
671 u8 id;
672
673 /* Get next available identificator.
674 * 1 - 128 are used by kernel.
675 * 129 - 199 are reserved.
676 * 200 - 254 are used by utilities like l2ping, etc.
677 */
678
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200679 spin_lock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200680
681 if (++conn->tx_ident > 128)
682 conn->tx_ident = 1;
683
684 id = conn->tx_ident;
685
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200686 spin_unlock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200687
688 return id;
689}
690
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300691static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200692{
693 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200694 u8 flags;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200695
696 BT_DBG("code 0x%2.2x", code);
697
698 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300699 return;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200700
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200701 if (lmp_no_flush_capable(conn->hcon->hdev))
702 flags = ACL_START_NO_FLUSH;
703 else
704 flags = ACL_START;
705
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700706 bt_cb(skb)->force_active = BT_POWER_FORCE_ACTIVE_ON;
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +0200707 skb->priority = HCI_PRIO_MAX;
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700708
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200709 hci_send_acl(conn->hchan, skb, flags);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200710}
711
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200712static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb)
713{
714 struct hci_conn *hcon = chan->conn->hcon;
715 u16 flags;
716
717 BT_DBG("chan %p, skb %p len %d priority %u", chan, skb, skb->len,
718 skb->priority);
719
720 if (!test_bit(FLAG_FLUSHABLE, &chan->flags) &&
721 lmp_no_flush_capable(hcon->hdev))
722 flags = ACL_START_NO_FLUSH;
723 else
724 flags = ACL_START;
725
726 bt_cb(skb)->force_active = test_bit(FLAG_FORCE_ACTIVE, &chan->flags);
727 hci_send_acl(chan->conn->hchan, skb, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700728}
729
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700730static void __unpack_enhanced_control(u16 enh, struct l2cap_ctrl *control)
731{
732 control->reqseq = (enh & L2CAP_CTRL_REQSEQ) >> L2CAP_CTRL_REQSEQ_SHIFT;
733 control->final = (enh & L2CAP_CTRL_FINAL) >> L2CAP_CTRL_FINAL_SHIFT;
734
735 if (enh & L2CAP_CTRL_FRAME_TYPE) {
736 /* S-Frame */
737 control->sframe = 1;
738 control->poll = (enh & L2CAP_CTRL_POLL) >> L2CAP_CTRL_POLL_SHIFT;
739 control->super = (enh & L2CAP_CTRL_SUPERVISE) >> L2CAP_CTRL_SUPER_SHIFT;
740
741 control->sar = 0;
742 control->txseq = 0;
743 } else {
744 /* I-Frame */
745 control->sframe = 0;
746 control->sar = (enh & L2CAP_CTRL_SAR) >> L2CAP_CTRL_SAR_SHIFT;
747 control->txseq = (enh & L2CAP_CTRL_TXSEQ) >> L2CAP_CTRL_TXSEQ_SHIFT;
748
749 control->poll = 0;
750 control->super = 0;
751 }
752}
753
754static void __unpack_extended_control(u32 ext, struct l2cap_ctrl *control)
755{
756 control->reqseq = (ext & L2CAP_EXT_CTRL_REQSEQ) >> L2CAP_EXT_CTRL_REQSEQ_SHIFT;
757 control->final = (ext & L2CAP_EXT_CTRL_FINAL) >> L2CAP_EXT_CTRL_FINAL_SHIFT;
758
759 if (ext & L2CAP_EXT_CTRL_FRAME_TYPE) {
760 /* S-Frame */
761 control->sframe = 1;
762 control->poll = (ext & L2CAP_EXT_CTRL_POLL) >> L2CAP_EXT_CTRL_POLL_SHIFT;
763 control->super = (ext & L2CAP_EXT_CTRL_SUPERVISE) >> L2CAP_EXT_CTRL_SUPER_SHIFT;
764
765 control->sar = 0;
766 control->txseq = 0;
767 } else {
768 /* I-Frame */
769 control->sframe = 0;
770 control->sar = (ext & L2CAP_EXT_CTRL_SAR) >> L2CAP_EXT_CTRL_SAR_SHIFT;
771 control->txseq = (ext & L2CAP_EXT_CTRL_TXSEQ) >> L2CAP_EXT_CTRL_TXSEQ_SHIFT;
772
773 control->poll = 0;
774 control->super = 0;
775 }
776}
777
778static inline void __unpack_control(struct l2cap_chan *chan,
779 struct sk_buff *skb)
780{
781 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
782 __unpack_extended_control(get_unaligned_le32(skb->data),
783 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700784 skb_pull(skb, L2CAP_EXT_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700785 } else {
786 __unpack_enhanced_control(get_unaligned_le16(skb->data),
787 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700788 skb_pull(skb, L2CAP_ENH_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700789 }
790}
791
792static u32 __pack_extended_control(struct l2cap_ctrl *control)
793{
794 u32 packed;
795
796 packed = control->reqseq << L2CAP_EXT_CTRL_REQSEQ_SHIFT;
797 packed |= control->final << L2CAP_EXT_CTRL_FINAL_SHIFT;
798
799 if (control->sframe) {
800 packed |= control->poll << L2CAP_EXT_CTRL_POLL_SHIFT;
801 packed |= control->super << L2CAP_EXT_CTRL_SUPER_SHIFT;
802 packed |= L2CAP_EXT_CTRL_FRAME_TYPE;
803 } else {
804 packed |= control->sar << L2CAP_EXT_CTRL_SAR_SHIFT;
805 packed |= control->txseq << L2CAP_EXT_CTRL_TXSEQ_SHIFT;
806 }
807
808 return packed;
809}
810
811static u16 __pack_enhanced_control(struct l2cap_ctrl *control)
812{
813 u16 packed;
814
815 packed = control->reqseq << L2CAP_CTRL_REQSEQ_SHIFT;
816 packed |= control->final << L2CAP_CTRL_FINAL_SHIFT;
817
818 if (control->sframe) {
819 packed |= control->poll << L2CAP_CTRL_POLL_SHIFT;
820 packed |= control->super << L2CAP_CTRL_SUPER_SHIFT;
821 packed |= L2CAP_CTRL_FRAME_TYPE;
822 } else {
823 packed |= control->sar << L2CAP_CTRL_SAR_SHIFT;
824 packed |= control->txseq << L2CAP_CTRL_TXSEQ_SHIFT;
825 }
826
827 return packed;
828}
829
830static inline void __pack_control(struct l2cap_chan *chan,
831 struct l2cap_ctrl *control,
832 struct sk_buff *skb)
833{
834 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
835 put_unaligned_le32(__pack_extended_control(control),
836 skb->data + L2CAP_HDR_SIZE);
837 } else {
838 put_unaligned_le16(__pack_enhanced_control(control),
839 skb->data + L2CAP_HDR_SIZE);
840 }
841}
842
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300843static inline unsigned int __ertm_hdr_size(struct l2cap_chan *chan)
844{
845 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
846 return L2CAP_EXT_HDR_SIZE;
847 else
848 return L2CAP_ENH_HDR_SIZE;
849}
850
Mat Martineaua67d7f62012-05-17 20:53:35 -0700851static struct sk_buff *l2cap_create_sframe_pdu(struct l2cap_chan *chan,
852 u32 control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300853{
854 struct sk_buff *skb;
855 struct l2cap_hdr *lh;
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300856 int hlen = __ertm_hdr_size(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300857
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300858 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300859 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300860
Mat Martineaua67d7f62012-05-17 20:53:35 -0700861 skb = bt_skb_alloc(hlen, GFP_KERNEL);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300862
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300863 if (!skb)
Mat Martineaua67d7f62012-05-17 20:53:35 -0700864 return ERR_PTR(-ENOMEM);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300865
866 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300867 lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300868 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +0300869
Mat Martineaua67d7f62012-05-17 20:53:35 -0700870 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
871 put_unaligned_le32(control, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
872 else
873 put_unaligned_le16(control, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300874
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -0300875 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineaua67d7f62012-05-17 20:53:35 -0700876 u16 fcs = crc16(0, (u8 *)skb->data, skb->len);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300877 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300878 }
879
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200880 skb->priority = HCI_PRIO_MAX;
Mat Martineaua67d7f62012-05-17 20:53:35 -0700881 return skb;
882}
883
884static void l2cap_send_sframe(struct l2cap_chan *chan,
885 struct l2cap_ctrl *control)
886{
887 struct sk_buff *skb;
888 u32 control_field;
889
890 BT_DBG("chan %p, control %p", chan, control);
891
892 if (!control->sframe)
893 return;
894
895 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state) &&
896 !control->poll)
897 control->final = 1;
898
899 if (control->super == L2CAP_SUPER_RR)
900 clear_bit(CONN_RNR_SENT, &chan->conn_state);
901 else if (control->super == L2CAP_SUPER_RNR)
902 set_bit(CONN_RNR_SENT, &chan->conn_state);
903
904 if (control->super != L2CAP_SUPER_SREJ) {
905 chan->last_acked_seq = control->reqseq;
906 __clear_ack_timer(chan);
907 }
908
909 BT_DBG("reqseq %d, final %d, poll %d, super %d", control->reqseq,
910 control->final, control->poll, control->super);
911
912 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
913 control_field = __pack_extended_control(control);
914 else
915 control_field = __pack_enhanced_control(control);
916
917 skb = l2cap_create_sframe_pdu(chan, control_field);
918 if (!IS_ERR(skb))
919 l2cap_do_send(chan, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300920}
921
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700922static void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, bool poll)
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300923{
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700924 struct l2cap_ctrl control;
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300925
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700926 BT_DBG("chan %p, poll %d", chan, poll);
927
928 memset(&control, 0, sizeof(control));
929 control.sframe = 1;
930 control.poll = poll;
931
932 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
933 control.super = L2CAP_SUPER_RNR;
934 else
935 control.super = L2CAP_SUPER_RR;
936
937 control.reqseq = chan->buffer_seq;
938 l2cap_send_sframe(chan, &control);
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300939}
940
Gustavo F. Padovanb4450032011-04-12 18:15:09 -0300941static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan)
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300942{
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -0300943 return !test_bit(CONF_CONNECT_PEND, &chan->conf_state);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300944}
945
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +0200946static void l2cap_send_conn_req(struct l2cap_chan *chan)
947{
948 struct l2cap_conn *conn = chan->conn;
949 struct l2cap_conn_req req;
950
951 req.scid = cpu_to_le16(chan->scid);
952 req.psm = chan->psm;
953
954 chan->ident = l2cap_get_ident(conn);
955
956 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
957
958 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, sizeof(req), &req);
959}
960
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -0300961static void l2cap_chan_ready(struct l2cap_chan *chan)
962{
Mat Martineau28270112012-05-17 21:14:09 -0700963 /* This clears all conf flags, including CONF_NOT_COMPLETE */
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -0300964 chan->conf_state = 0;
965 __clear_chan_timer(chan);
966
Andrei Emeltchenko54a59aa2012-05-27 22:27:53 -0300967 chan->state = BT_CONNECTED;
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -0300968
Andrei Emeltchenkofd83e2c2012-05-30 09:55:32 +0300969 chan->ops->ready(chan);
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -0300970}
971
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -0300972static void l2cap_do_start(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200973{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300974 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200975
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -0300976 if (conn->hcon->type == LE_LINK) {
977 l2cap_chan_ready(chan);
978 return;
979 }
980
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200981 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +0100982 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
983 return;
984
Gustavo F. Padovand45fc422011-11-05 19:54:24 -0200985 if (l2cap_chan_check_security(chan) &&
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +0200986 __l2cap_no_conn_pending(chan))
987 l2cap_send_conn_req(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200988 } else {
989 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +0300990 req.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200991
992 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
993 conn->info_ident = l2cap_get_ident(conn);
994
Marcel Holtmannba13ccd2012-03-01 14:25:33 -0800995 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200996
997 l2cap_send_cmd(conn, conn->info_ident,
998 L2CAP_INFO_REQ, sizeof(req), &req);
999 }
1000}
1001
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001002static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
1003{
1004 u32 local_feat_mask = l2cap_feat_mask;
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03001005 if (!disable_ertm)
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001006 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
1007
1008 switch (mode) {
1009 case L2CAP_MODE_ERTM:
1010 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
1011 case L2CAP_MODE_STREAMING:
1012 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
1013 default:
1014 return 0x00;
1015 }
1016}
1017
Gustavo F. Padovan4519de92011-04-28 17:55:53 -03001018static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *chan, int err)
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001019{
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001020 struct sock *sk = chan->sk;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001021 struct l2cap_disconn_req req;
1022
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001023 if (!conn)
1024 return;
1025
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03001026 if (chan->mode == L2CAP_MODE_ERTM) {
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03001027 __clear_retrans_timer(chan);
1028 __clear_monitor_timer(chan);
1029 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001030 }
1031
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001032 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
1033 __l2cap_state_change(chan, BT_DISCONN);
1034 return;
1035 }
1036
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001037 req.dcid = cpu_to_le16(chan->dcid);
1038 req.scid = cpu_to_le16(chan->scid);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001039 l2cap_send_cmd(conn, l2cap_get_ident(conn),
1040 L2CAP_DISCONN_REQ, sizeof(req), &req);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001041
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001042 lock_sock(sk);
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001043 __l2cap_state_change(chan, BT_DISCONN);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02001044 __l2cap_chan_set_err(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001045 release_sock(sk);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001046}
1047
Linus Torvalds1da177e2005-04-16 15:20:36 -07001048/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001049static void l2cap_conn_start(struct l2cap_conn *conn)
1050{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001051 struct l2cap_chan *chan, *tmp;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001052
1053 BT_DBG("conn %p", conn);
1054
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001055 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001056
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001057 list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001058 struct sock *sk = chan->sk;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001059
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001060 l2cap_chan_lock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001061
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001062 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001063 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001064 continue;
1065 }
1066
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001067 if (chan->state == BT_CONNECT) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001068 if (!l2cap_chan_check_security(chan) ||
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03001069 !__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001070 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001071 continue;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02001072 }
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001073
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001074 if (!l2cap_mode_supported(chan->mode, conn->feat_mask)
1075 && test_bit(CONF_STATE2_DEVICE,
1076 &chan->conf_state)) {
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001077 l2cap_chan_close(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001078 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001079 continue;
1080 }
1081
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +02001082 l2cap_send_conn_req(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001083
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001084 } else if (chan->state == BT_CONNECT2) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001085 struct l2cap_conn_rsp rsp;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001086 char buf[128];
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001087 rsp.scid = cpu_to_le16(chan->dcid);
1088 rsp.dcid = cpu_to_le16(chan->scid);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001089
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001090 if (l2cap_chan_check_security(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001091 lock_sock(sk);
Gustavo Padovanc5daa682012-05-16 12:17:10 -03001092 if (test_bit(BT_SK_DEFER_SETUP,
1093 &bt_sk(sk)->flags)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001094 struct sock *parent = bt_sk(sk)->parent;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001095 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1096 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
Ilia Kolomisnky05e9a2f2011-07-15 18:30:21 +00001097 if (parent)
1098 parent->sk_data_ready(parent, 0);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001099
1100 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001101 __l2cap_state_change(chan, BT_CONFIG);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001102 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
1103 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001104 }
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001105 release_sock(sk);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001106 } else {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001107 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1108 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001109 }
1110
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001111 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
1112 sizeof(rsp), &rsp);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001113
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001114 if (test_bit(CONF_REQ_SENT, &chan->conf_state) ||
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001115 rsp.result != L2CAP_CR_SUCCESS) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001116 l2cap_chan_unlock(chan);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001117 continue;
1118 }
1119
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001120 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001121 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03001122 l2cap_build_conf_req(chan, buf), buf);
1123 chan->num_conf_req++;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001124 }
1125
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001126 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001127 }
1128
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001129 mutex_unlock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001130}
1131
Ido Yarivc2287682012-04-20 15:46:07 -03001132/* Find socket with cid and source/destination bdaddr.
Ville Tervob62f3282011-02-10 22:38:50 -03001133 * Returns closest match, locked.
1134 */
Andrei Emeltchenkod9b88702012-03-12 12:13:08 +02001135static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid,
Ido Yarivc2287682012-04-20 15:46:07 -03001136 bdaddr_t *src,
1137 bdaddr_t *dst)
Ville Tervob62f3282011-02-10 22:38:50 -03001138{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001139 struct l2cap_chan *c, *c1 = NULL;
Ville Tervob62f3282011-02-10 22:38:50 -03001140
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001141 read_lock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001142
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001143 list_for_each_entry(c, &chan_list, global_l) {
1144 struct sock *sk = c->sk;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001145
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001146 if (state && c->state != state)
Ville Tervob62f3282011-02-10 22:38:50 -03001147 continue;
1148
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001149 if (c->scid == cid) {
Ido Yarivc2287682012-04-20 15:46:07 -03001150 int src_match, dst_match;
1151 int src_any, dst_any;
1152
Ville Tervob62f3282011-02-10 22:38:50 -03001153 /* Exact match. */
Ido Yarivc2287682012-04-20 15:46:07 -03001154 src_match = !bacmp(&bt_sk(sk)->src, src);
1155 dst_match = !bacmp(&bt_sk(sk)->dst, dst);
1156 if (src_match && dst_match) {
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001157 read_unlock(&chan_list_lock);
1158 return c;
1159 }
Ville Tervob62f3282011-02-10 22:38:50 -03001160
1161 /* Closest match */
Ido Yarivc2287682012-04-20 15:46:07 -03001162 src_any = !bacmp(&bt_sk(sk)->src, BDADDR_ANY);
1163 dst_any = !bacmp(&bt_sk(sk)->dst, BDADDR_ANY);
1164 if ((src_match && dst_any) || (src_any && dst_match) ||
1165 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001166 c1 = c;
Ville Tervob62f3282011-02-10 22:38:50 -03001167 }
1168 }
Gustavo F. Padovan280f2942011-04-13 19:01:22 -03001169
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001170 read_unlock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001171
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001172 return c1;
Ville Tervob62f3282011-02-10 22:38:50 -03001173}
1174
1175static void l2cap_le_conn_ready(struct l2cap_conn *conn)
1176{
Gustavo F. Padovanc916fbe2011-04-04 16:00:55 -03001177 struct sock *parent, *sk;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001178 struct l2cap_chan *chan, *pchan;
Ville Tervob62f3282011-02-10 22:38:50 -03001179
1180 BT_DBG("");
1181
1182 /* Check if we have socket listening on cid */
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001183 pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_LE_DATA,
Ido Yarivc2287682012-04-20 15:46:07 -03001184 conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001185 if (!pchan)
Ville Tervob62f3282011-02-10 22:38:50 -03001186 return;
1187
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001188 parent = pchan->sk;
1189
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03001190 lock_sock(parent);
Gustavo F. Padovan62f3a2c2011-04-14 18:34:34 -03001191
Gustavo Padovan80b98022012-05-27 22:27:51 -03001192 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001193 if (!chan)
Ville Tervob62f3282011-02-10 22:38:50 -03001194 goto clean;
1195
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001196 sk = chan->sk;
Gustavo F. Padovan5d41ce12011-04-08 15:40:02 -03001197
Ville Tervob62f3282011-02-10 22:38:50 -03001198 hci_conn_hold(conn->hcon);
1199
Ville Tervob62f3282011-02-10 22:38:50 -03001200 bacpy(&bt_sk(sk)->src, conn->src);
1201 bacpy(&bt_sk(sk)->dst, conn->dst);
1202
Gustavo F. Padovand1010242011-03-25 00:39:48 -03001203 bt_accept_enqueue(parent, sk);
1204
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02001205 l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001206
Gustavo Padovan6754e0d2012-05-25 09:30:56 -03001207 l2cap_chan_ready(chan);
Ville Tervob62f3282011-02-10 22:38:50 -03001208
Ville Tervob62f3282011-02-10 22:38:50 -03001209clean:
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03001210 release_sock(parent);
Ville Tervob62f3282011-02-10 22:38:50 -03001211}
1212
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001213static void l2cap_conn_ready(struct l2cap_conn *conn)
1214{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001215 struct l2cap_chan *chan;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001216
1217 BT_DBG("conn %p", conn);
1218
Ville Tervob62f3282011-02-10 22:38:50 -03001219 if (!conn->hcon->out && conn->hcon->type == LE_LINK)
1220 l2cap_le_conn_ready(conn);
1221
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03001222 if (conn->hcon->out && conn->hcon->type == LE_LINK)
1223 smp_conn_security(conn, conn->hcon->pending_sec_level);
1224
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001225 mutex_lock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001226
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001227 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001228
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001229 l2cap_chan_lock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001230
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001231 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
1232 l2cap_chan_unlock(chan);
1233 continue;
1234 }
1235
Vinicius Costa Gomes63128452011-06-17 22:46:26 -03001236 if (conn->hcon->type == LE_LINK) {
Anderson Brigliab501d6a2011-06-07 18:46:31 -03001237 if (smp_conn_security(conn, chan->sec_level))
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02001238 l2cap_chan_ready(chan);
Ville Tervoacd7d372011-02-10 22:38:49 -03001239
Vinicius Costa Gomes63128452011-06-17 22:46:26 -03001240 } else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001241 struct sock *sk = chan->sk;
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001242 __clear_chan_timer(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001243 lock_sock(sk);
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001244 __l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001245 sk->sk_state_change(sk);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001246 release_sock(sk);
Anderson Brigliab501d6a2011-06-07 18:46:31 -03001247
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001248 } else if (chan->state == BT_CONNECT)
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001249 l2cap_do_start(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001250
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001251 l2cap_chan_unlock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001252 }
1253
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001254 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001255}
1256
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001257/* Notify sockets that we cannot guaranty reliability anymore */
1258static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
1259{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001260 struct l2cap_chan *chan;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001261
1262 BT_DBG("conn %p", conn);
1263
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001264 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001265
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001266 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenkoecf61bd2011-10-11 14:04:32 +03001267 if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags))
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02001268 __l2cap_chan_set_err(chan, err);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001269 }
1270
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001271 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001272}
1273
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001274static void l2cap_info_timeout(struct work_struct *work)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001275{
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001276 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo F. Padovan030013d2011-12-20 10:57:28 -02001277 info_timer.work);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001278
Marcel Holtmann984947d2009-02-06 23:35:19 +01001279 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01001280 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01001281
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001282 l2cap_conn_start(conn);
1283}
1284
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001285static void l2cap_conn_del(struct hci_conn *hcon, int err)
1286{
1287 struct l2cap_conn *conn = hcon->l2cap_data;
1288 struct l2cap_chan *chan, *l;
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001289
1290 if (!conn)
1291 return;
1292
1293 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
1294
1295 kfree_skb(conn->rx_skb);
1296
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001297 mutex_lock(&conn->chan_lock);
1298
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001299 /* Kill channels */
1300 list_for_each_entry_safe(chan, l, &conn->chan_l, list) {
Mat Martineau61d6ef32012-04-27 16:50:50 -07001301 l2cap_chan_hold(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001302 l2cap_chan_lock(chan);
1303
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001304 l2cap_chan_del(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001305
1306 l2cap_chan_unlock(chan);
1307
Gustavo Padovan80b98022012-05-27 22:27:51 -03001308 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07001309 l2cap_chan_put(chan);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001310 }
1311
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001312 mutex_unlock(&conn->chan_lock);
1313
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001314 hci_chan_del(conn->hchan);
1315
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001316 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
Ulisses Furquim127074b2012-01-30 18:26:29 -02001317 cancel_delayed_work_sync(&conn->info_timer);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001318
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001319 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) {
Ulisses Furquim127074b2012-01-30 18:26:29 -02001320 cancel_delayed_work_sync(&conn->security_timer);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -03001321 smp_chan_destroy(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001322 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001323
1324 hcon->l2cap_data = NULL;
1325 kfree(conn);
1326}
1327
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001328static void security_timeout(struct work_struct *work)
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001329{
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001330 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
1331 security_timer.work);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001332
Johan Hedbergd06cc412012-06-06 18:44:11 +08001333 BT_DBG("conn %p", conn);
1334
1335 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) {
1336 smp_chan_destroy(conn);
1337 l2cap_conn_del(conn->hcon, ETIMEDOUT);
1338 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001339}
1340
Linus Torvalds1da177e2005-04-16 15:20:36 -07001341static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
1342{
Marcel Holtmann01394182006-07-03 10:02:46 +02001343 struct l2cap_conn *conn = hcon->l2cap_data;
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001344 struct hci_chan *hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001345
Marcel Holtmann01394182006-07-03 10:02:46 +02001346 if (conn || status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001347 return conn;
1348
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001349 hchan = hci_chan_create(hcon);
1350 if (!hchan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001351 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001352
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001353 conn = kzalloc(sizeof(struct l2cap_conn), GFP_ATOMIC);
1354 if (!conn) {
1355 hci_chan_del(hchan);
1356 return NULL;
1357 }
1358
Linus Torvalds1da177e2005-04-16 15:20:36 -07001359 hcon->l2cap_data = conn;
1360 conn->hcon = hcon;
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001361 conn->hchan = hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001362
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001363 BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan);
Marcel Holtmann01394182006-07-03 10:02:46 +02001364
Ville Tervoacd7d372011-02-10 22:38:49 -03001365 if (hcon->hdev->le_mtu && hcon->type == LE_LINK)
1366 conn->mtu = hcon->hdev->le_mtu;
1367 else
1368 conn->mtu = hcon->hdev->acl_mtu;
1369
Linus Torvalds1da177e2005-04-16 15:20:36 -07001370 conn->src = &hcon->hdev->bdaddr;
1371 conn->dst = &hcon->dst;
1372
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001373 conn->feat_mask = 0;
1374
Linus Torvalds1da177e2005-04-16 15:20:36 -07001375 spin_lock_init(&conn->lock);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001376 mutex_init(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001377
1378 INIT_LIST_HEAD(&conn->chan_l);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001379
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001380 if (hcon->type == LE_LINK)
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001381 INIT_DELAYED_WORK(&conn->security_timer, security_timeout);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001382 else
Gustavo F. Padovan030013d2011-12-20 10:57:28 -02001383 INIT_DELAYED_WORK(&conn->info_timer, l2cap_info_timeout);
Dave Young45054dc2009-10-18 20:28:30 +00001384
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001385 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01001386
Linus Torvalds1da177e2005-04-16 15:20:36 -07001387 return conn;
1388}
1389
Linus Torvalds1da177e2005-04-16 15:20:36 -07001390/* ---- Socket interface ---- */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001391
Ido Yarivc2287682012-04-20 15:46:07 -03001392/* Find socket with psm and source / destination bdaddr.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001393 * Returns closest match.
1394 */
Ido Yarivc2287682012-04-20 15:46:07 -03001395static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
1396 bdaddr_t *src,
1397 bdaddr_t *dst)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001398{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001399 struct l2cap_chan *c, *c1 = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001400
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001401 read_lock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001402
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001403 list_for_each_entry(c, &chan_list, global_l) {
1404 struct sock *sk = c->sk;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001405
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001406 if (state && c->state != state)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001407 continue;
1408
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001409 if (c->psm == psm) {
Ido Yarivc2287682012-04-20 15:46:07 -03001410 int src_match, dst_match;
1411 int src_any, dst_any;
1412
Linus Torvalds1da177e2005-04-16 15:20:36 -07001413 /* Exact match. */
Ido Yarivc2287682012-04-20 15:46:07 -03001414 src_match = !bacmp(&bt_sk(sk)->src, src);
1415 dst_match = !bacmp(&bt_sk(sk)->dst, dst);
1416 if (src_match && dst_match) {
Johannes Berga7567b22011-06-01 08:29:54 +02001417 read_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001418 return c;
1419 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001420
1421 /* Closest match */
Ido Yarivc2287682012-04-20 15:46:07 -03001422 src_any = !bacmp(&bt_sk(sk)->src, BDADDR_ANY);
1423 dst_any = !bacmp(&bt_sk(sk)->dst, BDADDR_ANY);
1424 if ((src_match && dst_any) || (src_any && dst_match) ||
1425 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001426 c1 = c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001427 }
1428 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001429
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001430 read_unlock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001431
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001432 return c1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001433}
1434
Andre Guedes8e9f9892012-04-24 21:02:55 -03001435int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
1436 bdaddr_t *dst, u8 dst_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001437{
Gustavo F. Padovan5d41ce12011-04-08 15:40:02 -03001438 struct sock *sk = chan->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001439 bdaddr_t *src = &bt_sk(sk)->src;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001440 struct l2cap_conn *conn;
1441 struct hci_conn *hcon;
1442 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001443 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +02001444 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001445
Andre Guedes8e9f9892012-04-24 21:02:55 -03001446 BT_DBG("%s -> %s (type %u) psm 0x%2.2x", batostr(src), batostr(dst),
1447 dst_type, __le16_to_cpu(chan->psm));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001448
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001449 hdev = hci_get_route(dst, src);
1450 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001451 return -EHOSTUNREACH;
1452
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001453 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001454
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001455 l2cap_chan_lock(chan);
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001456
1457 /* PSM must be odd and lsb of upper byte must be 0 */
1458 if ((__le16_to_cpu(psm) & 0x0101) != 0x0001 && !cid &&
1459 chan->chan_type != L2CAP_CHAN_RAW) {
1460 err = -EINVAL;
1461 goto done;
1462 }
1463
1464 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && !(psm || cid)) {
1465 err = -EINVAL;
1466 goto done;
1467 }
1468
1469 switch (chan->mode) {
1470 case L2CAP_MODE_BASIC:
1471 break;
1472 case L2CAP_MODE_ERTM:
1473 case L2CAP_MODE_STREAMING:
1474 if (!disable_ertm)
1475 break;
1476 /* fall through */
1477 default:
1478 err = -ENOTSUPP;
1479 goto done;
1480 }
1481
Gustavo Padovan0797e012012-05-27 22:27:54 -03001482 switch (chan->state) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001483 case BT_CONNECT:
1484 case BT_CONNECT2:
1485 case BT_CONFIG:
1486 /* Already connecting */
1487 err = 0;
1488 goto done;
1489
1490 case BT_CONNECTED:
1491 /* Already connected */
1492 err = -EISCONN;
1493 goto done;
1494
1495 case BT_OPEN:
1496 case BT_BOUND:
1497 /* Can connect */
1498 break;
1499
1500 default:
1501 err = -EBADFD;
1502 goto done;
1503 }
1504
1505 /* Set destination address and psm */
Gustavo Padovan0797e012012-05-27 22:27:54 -03001506 lock_sock(sk);
Gustavo F. Padovan9219b2a2012-01-02 20:08:04 -02001507 bacpy(&bt_sk(sk)->dst, dst);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001508 release_sock(sk);
1509
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001510 chan->psm = psm;
1511 chan->dcid = cid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001512
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001513 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001514
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001515 if (chan->dcid == L2CAP_CID_LE_DATA)
Andre Guedes8e9f9892012-04-24 21:02:55 -03001516 hcon = hci_connect(hdev, LE_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001517 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001518 else
Andre Guedes8e9f9892012-04-24 21:02:55 -03001519 hcon = hci_connect(hdev, ACL_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001520 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001521
Ville Tervo30e76272011-02-22 16:10:53 -03001522 if (IS_ERR(hcon)) {
1523 err = PTR_ERR(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001524 goto done;
Ville Tervo30e76272011-02-22 16:10:53 -03001525 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001526
1527 conn = l2cap_conn_add(hcon, 0);
1528 if (!conn) {
1529 hci_conn_put(hcon);
Ville Tervo30e76272011-02-22 16:10:53 -03001530 err = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001531 goto done;
1532 }
1533
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001534 if (hcon->type == LE_LINK) {
1535 err = 0;
1536
1537 if (!list_empty(&conn->chan_l)) {
1538 err = -EBUSY;
1539 hci_conn_put(hcon);
1540 }
1541
1542 if (err)
1543 goto done;
1544 }
1545
Linus Torvalds1da177e2005-04-16 15:20:36 -07001546 /* Update source addr of the socket */
1547 bacpy(src, conn->src);
1548
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001549 l2cap_chan_unlock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001550 l2cap_chan_add(conn, chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001551 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001552
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001553 l2cap_state_change(chan, BT_CONNECT);
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001554 __set_chan_timer(chan, sk->sk_sndtimeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001555
1556 if (hcon->state == BT_CONNECTED) {
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001557 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001558 __clear_chan_timer(chan);
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001559 if (l2cap_chan_check_security(chan))
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001560 l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001561 } else
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001562 l2cap_do_start(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001563 }
1564
Ville Tervo30e76272011-02-22 16:10:53 -03001565 err = 0;
1566
Linus Torvalds1da177e2005-04-16 15:20:36 -07001567done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001568 l2cap_chan_unlock(chan);
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001569 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001570 hci_dev_put(hdev);
1571 return err;
1572}
1573
Gustavo F. Padovandcba0db2011-02-04 03:08:36 -02001574int __l2cap_wait_ack(struct sock *sk)
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001575{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001576 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001577 DECLARE_WAITQUEUE(wait, current);
1578 int err = 0;
1579 int timeo = HZ/5;
1580
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001581 add_wait_queue(sk_sleep(sk), &wait);
Peter Hurleya71a0cf2011-07-25 18:36:26 -04001582 set_current_state(TASK_INTERRUPTIBLE);
1583 while (chan->unacked_frames > 0 && chan->conn) {
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001584 if (!timeo)
1585 timeo = HZ/5;
1586
1587 if (signal_pending(current)) {
1588 err = sock_intr_errno(timeo);
1589 break;
1590 }
1591
1592 release_sock(sk);
1593 timeo = schedule_timeout(timeo);
1594 lock_sock(sk);
Peter Hurleya71a0cf2011-07-25 18:36:26 -04001595 set_current_state(TASK_INTERRUPTIBLE);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001596
1597 err = sock_error(sk);
1598 if (err)
1599 break;
1600 }
1601 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001602 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001603 return err;
1604}
1605
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001606static void l2cap_monitor_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001607{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001608 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001609 monitor_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001610
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03001611 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001612
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001613 l2cap_chan_lock(chan);
1614
Mat Martineau80909e02012-05-17 20:53:50 -07001615 if (!chan->conn) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001616 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001617 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001618 return;
1619 }
1620
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001621 l2cap_tx(chan, NULL, NULL, L2CAP_EV_MONITOR_TO);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001622
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001623 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001624 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001625}
1626
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001627static void l2cap_retrans_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001628{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001629 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001630 retrans_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001631
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03001632 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001633
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001634 l2cap_chan_lock(chan);
1635
Mat Martineau80909e02012-05-17 20:53:50 -07001636 if (!chan->conn) {
1637 l2cap_chan_unlock(chan);
1638 l2cap_chan_put(chan);
1639 return;
1640 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001641
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001642 l2cap_tx(chan, NULL, NULL, L2CAP_EV_RETRANS_TO);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001643 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001644 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001645}
1646
Gustavo Padovand6603662012-05-21 13:58:22 -03001647static void l2cap_streaming_send(struct l2cap_chan *chan,
1648 struct sk_buff_head *skbs)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001649{
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001650 struct sk_buff *skb;
Mat Martineau37339372012-05-17 20:53:33 -07001651 struct l2cap_ctrl *control;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001652
Mat Martineau37339372012-05-17 20:53:33 -07001653 BT_DBG("chan %p, skbs %p", chan, skbs);
1654
Mat Martineau37339372012-05-17 20:53:33 -07001655 skb_queue_splice_tail_init(skbs, &chan->tx_q);
1656
1657 while (!skb_queue_empty(&chan->tx_q)) {
1658
1659 skb = skb_dequeue(&chan->tx_q);
1660
1661 bt_cb(skb)->control.retries = 1;
1662 control = &bt_cb(skb)->control;
1663
1664 control->reqseq = 0;
1665 control->txseq = chan->next_tx_seq;
1666
1667 __pack_control(chan, control, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001668
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001669 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau37339372012-05-17 20:53:33 -07001670 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
1671 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001672 }
1673
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001674 l2cap_do_send(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001675
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001676 BT_DBG("Sent txseq %u", control->txseq);
Mat Martineau37339372012-05-17 20:53:33 -07001677
Andrei Emeltchenko836be932011-10-17 12:19:57 +03001678 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau37339372012-05-17 20:53:33 -07001679 chan->frames_sent++;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001680 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001681}
1682
Szymon Janc67c9e842011-07-28 16:24:33 +02001683static int l2cap_ertm_send(struct l2cap_chan *chan)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001684{
1685 struct sk_buff *skb, *tx_skb;
Mat Martineau18a48e72012-05-17 20:53:34 -07001686 struct l2cap_ctrl *control;
1687 int sent = 0;
1688
1689 BT_DBG("chan %p", chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001690
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001691 if (chan->state != BT_CONNECTED)
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001692 return -ENOTCONN;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001693
Mat Martineau94122bb2012-05-02 09:42:02 -07001694 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1695 return 0;
1696
Mat Martineau18a48e72012-05-17 20:53:34 -07001697 while (chan->tx_send_head &&
1698 chan->unacked_frames < chan->remote_tx_win &&
1699 chan->tx_state == L2CAP_TX_STATE_XMIT) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001700
Mat Martineau18a48e72012-05-17 20:53:34 -07001701 skb = chan->tx_send_head;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001702
Mat Martineau18a48e72012-05-17 20:53:34 -07001703 bt_cb(skb)->control.retries = 1;
1704 control = &bt_cb(skb)->control;
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03001705
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03001706 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
Mat Martineau18a48e72012-05-17 20:53:34 -07001707 control->final = 1;
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03001708
Mat Martineau18a48e72012-05-17 20:53:34 -07001709 control->reqseq = chan->buffer_seq;
1710 chan->last_acked_seq = chan->buffer_seq;
1711 control->txseq = chan->next_tx_seq;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001712
Mat Martineau18a48e72012-05-17 20:53:34 -07001713 __pack_control(chan, control, skb);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001714
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001715 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau18a48e72012-05-17 20:53:34 -07001716 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
1717 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001718 }
1719
Mat Martineau18a48e72012-05-17 20:53:34 -07001720 /* Clone after data has been modified. Data is assumed to be
1721 read-only (for locking purposes) on cloned sk_buffs.
1722 */
1723 tx_skb = skb_clone(skb, GFP_KERNEL);
1724
1725 if (!tx_skb)
1726 break;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001727
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03001728 __set_retrans_timer(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001729
Andrei Emeltchenko836be932011-10-17 12:19:57 +03001730 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau18a48e72012-05-17 20:53:34 -07001731 chan->unacked_frames++;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03001732 chan->frames_sent++;
Mat Martineau18a48e72012-05-17 20:53:34 -07001733 sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001734
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03001735 if (skb_queue_is_last(&chan->tx_q, skb))
1736 chan->tx_send_head = NULL;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001737 else
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03001738 chan->tx_send_head = skb_queue_next(&chan->tx_q, skb);
Mat Martineau18a48e72012-05-17 20:53:34 -07001739
1740 l2cap_do_send(chan, tx_skb);
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001741 BT_DBG("Sent txseq %u", control->txseq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001742 }
1743
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001744 BT_DBG("Sent %d, %u unacked, %u in ERTM queue", sent,
1745 chan->unacked_frames, skb_queue_len(&chan->tx_q));
Mat Martineau18a48e72012-05-17 20:53:34 -07001746
1747 return sent;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001748}
1749
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001750static void l2cap_ertm_resend(struct l2cap_chan *chan)
1751{
1752 struct l2cap_ctrl control;
1753 struct sk_buff *skb;
1754 struct sk_buff *tx_skb;
1755 u16 seq;
1756
1757 BT_DBG("chan %p", chan);
1758
1759 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1760 return;
1761
1762 while (chan->retrans_list.head != L2CAP_SEQ_LIST_CLEAR) {
1763 seq = l2cap_seq_list_pop(&chan->retrans_list);
1764
1765 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, seq);
1766 if (!skb) {
1767 BT_DBG("Error: Can't retransmit seq %d, frame missing",
1768 seq);
1769 continue;
1770 }
1771
1772 bt_cb(skb)->control.retries++;
1773 control = bt_cb(skb)->control;
1774
1775 if (chan->max_tx != 0 &&
1776 bt_cb(skb)->control.retries > chan->max_tx) {
1777 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
1778 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
1779 l2cap_seq_list_clear(&chan->retrans_list);
1780 break;
1781 }
1782
1783 control.reqseq = chan->buffer_seq;
1784 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
1785 control.final = 1;
1786 else
1787 control.final = 0;
1788
1789 if (skb_cloned(skb)) {
1790 /* Cloned sk_buffs are read-only, so we need a
1791 * writeable copy
1792 */
1793 tx_skb = skb_copy(skb, GFP_ATOMIC);
1794 } else {
1795 tx_skb = skb_clone(skb, GFP_ATOMIC);
1796 }
1797
1798 if (!tx_skb) {
1799 l2cap_seq_list_clear(&chan->retrans_list);
1800 break;
1801 }
1802
1803 /* Update skb contents */
1804 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
1805 put_unaligned_le32(__pack_extended_control(&control),
1806 tx_skb->data + L2CAP_HDR_SIZE);
1807 } else {
1808 put_unaligned_le16(__pack_enhanced_control(&control),
1809 tx_skb->data + L2CAP_HDR_SIZE);
1810 }
1811
1812 if (chan->fcs == L2CAP_FCS_CRC16) {
1813 u16 fcs = crc16(0, (u8 *) tx_skb->data, tx_skb->len);
1814 put_unaligned_le16(fcs, skb_put(tx_skb,
1815 L2CAP_FCS_SIZE));
1816 }
1817
1818 l2cap_do_send(chan, tx_skb);
1819
1820 BT_DBG("Resent txseq %d", control.txseq);
1821
1822 chan->last_acked_seq = chan->buffer_seq;
1823 }
1824}
1825
Mat Martineauf80842a2012-05-17 20:53:46 -07001826static void l2cap_retransmit(struct l2cap_chan *chan,
1827 struct l2cap_ctrl *control)
1828{
1829 BT_DBG("chan %p, control %p", chan, control);
1830
1831 l2cap_seq_list_append(&chan->retrans_list, control->reqseq);
1832 l2cap_ertm_resend(chan);
1833}
1834
Mat Martineaud2a7ac52012-05-17 20:53:42 -07001835static void l2cap_retransmit_all(struct l2cap_chan *chan,
1836 struct l2cap_ctrl *control)
1837{
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001838 struct sk_buff *skb;
1839
1840 BT_DBG("chan %p, control %p", chan, control);
1841
1842 if (control->poll)
1843 set_bit(CONN_SEND_FBIT, &chan->conn_state);
1844
1845 l2cap_seq_list_clear(&chan->retrans_list);
1846
1847 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1848 return;
1849
1850 if (chan->unacked_frames) {
1851 skb_queue_walk(&chan->tx_q, skb) {
1852 if (bt_cb(skb)->control.txseq == control->reqseq ||
1853 skb == chan->tx_send_head)
1854 break;
1855 }
1856
1857 skb_queue_walk_from(&chan->tx_q, skb) {
1858 if (skb == chan->tx_send_head)
1859 break;
1860
1861 l2cap_seq_list_append(&chan->retrans_list,
1862 bt_cb(skb)->control.txseq);
1863 }
1864
1865 l2cap_ertm_resend(chan);
1866 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07001867}
1868
Szymon Jancb17e73b2012-01-11 10:59:47 +01001869static void l2cap_send_ack(struct l2cap_chan *chan)
1870{
Mat Martineau0a0aba42012-05-17 20:53:39 -07001871 struct l2cap_ctrl control;
1872 u16 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
1873 chan->last_acked_seq);
1874 int threshold;
1875
1876 BT_DBG("chan %p last_acked_seq %d buffer_seq %d",
1877 chan, chan->last_acked_seq, chan->buffer_seq);
1878
1879 memset(&control, 0, sizeof(control));
1880 control.sframe = 1;
1881
1882 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
1883 chan->rx_state == L2CAP_RX_STATE_RECV) {
1884 __clear_ack_timer(chan);
1885 control.super = L2CAP_SUPER_RNR;
1886 control.reqseq = chan->buffer_seq;
1887 l2cap_send_sframe(chan, &control);
1888 } else {
1889 if (!test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) {
1890 l2cap_ertm_send(chan);
1891 /* If any i-frames were sent, they included an ack */
1892 if (chan->buffer_seq == chan->last_acked_seq)
1893 frames_to_ack = 0;
1894 }
1895
Mat Martineauc20f8e32012-07-10 05:47:07 -07001896 /* Ack now if the window is 3/4ths full.
Mat Martineau0a0aba42012-05-17 20:53:39 -07001897 * Calculate without mul or div
1898 */
Mat Martineauc20f8e32012-07-10 05:47:07 -07001899 threshold = chan->ack_win;
Mat Martineau0a0aba42012-05-17 20:53:39 -07001900 threshold += threshold << 1;
1901 threshold >>= 2;
1902
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001903 BT_DBG("frames_to_ack %u, threshold %d", frames_to_ack,
Mat Martineau0a0aba42012-05-17 20:53:39 -07001904 threshold);
1905
1906 if (frames_to_ack >= threshold) {
1907 __clear_ack_timer(chan);
1908 control.super = L2CAP_SUPER_RR;
1909 control.reqseq = chan->buffer_seq;
1910 l2cap_send_sframe(chan, &control);
1911 frames_to_ack = 0;
1912 }
1913
1914 if (frames_to_ack)
1915 __set_ack_timer(chan);
1916 }
Szymon Jancb17e73b2012-01-11 10:59:47 +01001917}
1918
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001919static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
1920 struct msghdr *msg, int len,
1921 int count, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001922{
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02001923 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001924 struct sk_buff **frag;
Gustavo Padovan90338942012-04-06 20:15:47 -03001925 int sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001926
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03001927 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001928 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001929
1930 sent += count;
1931 len -= count;
1932
1933 /* Continuation fragments (no L2CAP header) */
1934 frag = &skb_shinfo(skb)->frag_list;
1935 while (len) {
Gustavo Padovanfbe00702012-05-15 13:22:55 -03001936 struct sk_buff *tmp;
1937
Linus Torvalds1da177e2005-04-16 15:20:36 -07001938 count = min_t(unsigned int, conn->mtu, len);
1939
Gustavo Padovanfbe00702012-05-15 13:22:55 -03001940 tmp = chan->ops->alloc_skb(chan, count,
1941 msg->msg_flags & MSG_DONTWAIT);
1942 if (IS_ERR(tmp))
1943 return PTR_ERR(tmp);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02001944
Gustavo Padovanfbe00702012-05-15 13:22:55 -03001945 *frag = tmp;
1946
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001947 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
1948 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001949
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02001950 (*frag)->priority = skb->priority;
1951
Linus Torvalds1da177e2005-04-16 15:20:36 -07001952 sent += count;
1953 len -= count;
1954
Gustavo Padovan2d0ed3d2012-05-11 13:16:12 -03001955 skb->len += (*frag)->len;
1956 skb->data_len += (*frag)->len;
1957
Linus Torvalds1da177e2005-04-16 15:20:36 -07001958 frag = &(*frag)->next;
1959 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001960
1961 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001962}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001963
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02001964static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001965 struct msghdr *msg, size_t len,
1966 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001967{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001968 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001969 struct sk_buff *skb;
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03001970 int err, count, hlen = L2CAP_HDR_SIZE + L2CAP_PSMLEN_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001971 struct l2cap_hdr *lh;
1972
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001973 BT_DBG("chan %p len %zu priority %u", chan, len, priority);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001974
1975 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02001976
1977 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03001978 msg->msg_flags & MSG_DONTWAIT);
1979 if (IS_ERR(skb))
1980 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001981
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02001982 skb->priority = priority;
1983
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001984 /* Create L2CAP header */
1985 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001986 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenkodaf6a78c2012-05-03 10:55:52 +03001987 lh->len = cpu_to_le16(len + L2CAP_PSMLEN_SIZE);
1988 put_unaligned(chan->psm, skb_put(skb, L2CAP_PSMLEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001989
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02001990 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001991 if (unlikely(err < 0)) {
1992 kfree_skb(skb);
1993 return ERR_PTR(err);
1994 }
1995 return skb;
1996}
1997
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02001998static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001999 struct msghdr *msg, size_t len,
2000 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002001{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002002 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002003 struct sk_buff *skb;
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002004 int err, count;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002005 struct l2cap_hdr *lh;
2006
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002007 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002008
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002009 count = min_t(unsigned int, (conn->mtu - L2CAP_HDR_SIZE), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002010
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002011 skb = chan->ops->alloc_skb(chan, count + L2CAP_HDR_SIZE,
Gustavo Padovan90338942012-04-06 20:15:47 -03002012 msg->msg_flags & MSG_DONTWAIT);
2013 if (IS_ERR(skb))
2014 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002015
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002016 skb->priority = priority;
2017
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002018 /* Create L2CAP header */
2019 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002020 lh->cid = cpu_to_le16(chan->dcid);
Gustavo Padovan6ff9b5e2012-05-02 11:56:17 -03002021 lh->len = cpu_to_le16(len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002022
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002023 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002024 if (unlikely(err < 0)) {
2025 kfree_skb(skb);
2026 return ERR_PTR(err);
2027 }
2028 return skb;
2029}
2030
Luiz Augusto von Dentzab0ff762011-09-12 20:00:50 +03002031static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002032 struct msghdr *msg, size_t len,
2033 u16 sdulen)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002034{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002035 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002036 struct sk_buff *skb;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002037 int err, count, hlen;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002038 struct l2cap_hdr *lh;
2039
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002040 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002041
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03002042 if (!conn)
2043 return ERR_PTR(-ENOTCONN);
2044
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002045 hlen = __ertm_hdr_size(chan);
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002046
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002047 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002048 hlen += L2CAP_SDULEN_SIZE;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002049
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002050 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002051 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002052
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002053 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002054
2055 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002056 msg->msg_flags & MSG_DONTWAIT);
2057 if (IS_ERR(skb))
2058 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002059
2060 /* Create L2CAP header */
2061 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002062 lh->cid = cpu_to_le16(chan->dcid);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002063 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002064
Mat Martineau18a48e72012-05-17 20:53:34 -07002065 /* Control header is populated later */
2066 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
2067 put_unaligned_le32(0, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
2068 else
2069 put_unaligned_le16(0, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002070
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002071 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002072 put_unaligned_le16(sdulen, skb_put(skb, L2CAP_SDULEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002073
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002074 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002075 if (unlikely(err < 0)) {
2076 kfree_skb(skb);
2077 return ERR_PTR(err);
2078 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002079
Mat Martineau18a48e72012-05-17 20:53:34 -07002080 bt_cb(skb)->control.fcs = chan->fcs;
Mat Martineau3ce35142012-04-25 16:36:14 -07002081 bt_cb(skb)->control.retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002082 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002083}
2084
Mat Martineau94122bb2012-05-02 09:42:02 -07002085static int l2cap_segment_sdu(struct l2cap_chan *chan,
2086 struct sk_buff_head *seg_queue,
2087 struct msghdr *msg, size_t len)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002088{
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002089 struct sk_buff *skb;
Mat Martineau94122bb2012-05-02 09:42:02 -07002090 u16 sdu_len;
2091 size_t pdu_len;
Mat Martineau94122bb2012-05-02 09:42:02 -07002092 u8 sar;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002093
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002094 BT_DBG("chan %p, msg %p, len %zu", chan, msg, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002095
Mat Martineau94122bb2012-05-02 09:42:02 -07002096 /* It is critical that ERTM PDUs fit in a single HCI fragment,
2097 * so fragmented skbs are not used. The HCI layer's handling
2098 * of fragmented skbs is not compatible with ERTM's queueing.
2099 */
2100
2101 /* PDU size is derived from the HCI MTU */
2102 pdu_len = chan->conn->mtu;
2103
2104 pdu_len = min_t(size_t, pdu_len, L2CAP_BREDR_MAX_PAYLOAD);
2105
2106 /* Adjust for largest possible L2CAP overhead. */
Gustavo Padovan35d401d2012-05-25 18:57:05 -03002107 if (chan->fcs)
2108 pdu_len -= L2CAP_FCS_SIZE;
2109
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002110 pdu_len -= __ertm_hdr_size(chan);
Mat Martineau94122bb2012-05-02 09:42:02 -07002111
2112 /* Remote device may have requested smaller PDUs */
2113 pdu_len = min_t(size_t, pdu_len, chan->remote_mps);
2114
2115 if (len <= pdu_len) {
2116 sar = L2CAP_SAR_UNSEGMENTED;
2117 sdu_len = 0;
2118 pdu_len = len;
2119 } else {
2120 sar = L2CAP_SAR_START;
2121 sdu_len = len;
2122 pdu_len -= L2CAP_SDULEN_SIZE;
2123 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002124
2125 while (len > 0) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002126 skb = l2cap_create_iframe_pdu(chan, msg, pdu_len, sdu_len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002127
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002128 if (IS_ERR(skb)) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002129 __skb_queue_purge(seg_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002130 return PTR_ERR(skb);
2131 }
2132
Mat Martineau94122bb2012-05-02 09:42:02 -07002133 bt_cb(skb)->control.sar = sar;
2134 __skb_queue_tail(seg_queue, skb);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002135
Mat Martineau94122bb2012-05-02 09:42:02 -07002136 len -= pdu_len;
2137 if (sdu_len) {
2138 sdu_len = 0;
2139 pdu_len += L2CAP_SDULEN_SIZE;
2140 }
2141
2142 if (len <= pdu_len) {
2143 sar = L2CAP_SAR_END;
2144 pdu_len = len;
2145 } else {
2146 sar = L2CAP_SAR_CONTINUE;
2147 }
2148 }
2149
Gustavo Padovanf0f62792012-05-29 13:29:17 -03002150 return 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002151}
2152
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002153int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
2154 u32 priority)
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002155{
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002156 struct sk_buff *skb;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002157 int err;
Mat Martineau94122bb2012-05-02 09:42:02 -07002158 struct sk_buff_head seg_queue;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002159
2160 /* Connectionless channel */
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002161 if (chan->chan_type == L2CAP_CHAN_CONN_LESS) {
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002162 skb = l2cap_create_connless_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 return len;
2168 }
2169
2170 switch (chan->mode) {
2171 case L2CAP_MODE_BASIC:
2172 /* Check outgoing MTU */
2173 if (len > chan->omtu)
2174 return -EMSGSIZE;
2175
2176 /* Create a basic PDU */
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002177 skb = l2cap_create_basic_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002178 if (IS_ERR(skb))
2179 return PTR_ERR(skb);
2180
2181 l2cap_do_send(chan, skb);
2182 err = len;
2183 break;
2184
2185 case L2CAP_MODE_ERTM:
2186 case L2CAP_MODE_STREAMING:
Mat Martineau94122bb2012-05-02 09:42:02 -07002187 /* Check outgoing MTU */
2188 if (len > chan->omtu) {
2189 err = -EMSGSIZE;
2190 break;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002191 }
2192
Mat Martineau94122bb2012-05-02 09:42:02 -07002193 __skb_queue_head_init(&seg_queue);
2194
2195 /* Do segmentation before calling in to the state machine,
2196 * since it's possible to block while waiting for memory
2197 * allocation.
2198 */
2199 err = l2cap_segment_sdu(chan, &seg_queue, msg, len);
2200
2201 /* The channel could have been closed while segmenting,
2202 * check that it is still connected.
2203 */
2204 if (chan->state != BT_CONNECTED) {
2205 __skb_queue_purge(&seg_queue);
2206 err = -ENOTCONN;
2207 }
2208
2209 if (err)
2210 break;
2211
Mat Martineau37339372012-05-17 20:53:33 -07002212 if (chan->mode == L2CAP_MODE_ERTM)
Gustavo Padovand6603662012-05-21 13:58:22 -03002213 l2cap_tx(chan, NULL, &seg_queue, L2CAP_EV_DATA_REQUEST);
Mat Martineau37339372012-05-17 20:53:33 -07002214 else
Gustavo Padovand6603662012-05-21 13:58:22 -03002215 l2cap_streaming_send(chan, &seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002216
Gustavo Padovand6603662012-05-21 13:58:22 -03002217 err = len;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002218
Mat Martineau94122bb2012-05-02 09:42:02 -07002219 /* If the skbs were not queued for sending, they'll still be in
2220 * seg_queue and need to be purged.
2221 */
2222 __skb_queue_purge(&seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002223 break;
2224
2225 default:
2226 BT_DBG("bad state %1.1x", chan->mode);
2227 err = -EBADFD;
2228 }
2229
2230 return err;
2231}
2232
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002233static void l2cap_send_srej(struct l2cap_chan *chan, u16 txseq)
2234{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002235 struct l2cap_ctrl control;
2236 u16 seq;
2237
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002238 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002239
2240 memset(&control, 0, sizeof(control));
2241 control.sframe = 1;
2242 control.super = L2CAP_SUPER_SREJ;
2243
2244 for (seq = chan->expected_tx_seq; seq != txseq;
2245 seq = __next_seq(chan, seq)) {
2246 if (!l2cap_ertm_seq_in_queue(&chan->srej_q, seq)) {
2247 control.reqseq = seq;
2248 l2cap_send_sframe(chan, &control);
2249 l2cap_seq_list_append(&chan->srej_list, seq);
2250 }
2251 }
2252
2253 chan->expected_tx_seq = __next_seq(chan, txseq);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002254}
2255
2256static void l2cap_send_srej_tail(struct l2cap_chan *chan)
2257{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002258 struct l2cap_ctrl control;
2259
2260 BT_DBG("chan %p", chan);
2261
2262 if (chan->srej_list.tail == L2CAP_SEQ_LIST_CLEAR)
2263 return;
2264
2265 memset(&control, 0, sizeof(control));
2266 control.sframe = 1;
2267 control.super = L2CAP_SUPER_SREJ;
2268 control.reqseq = chan->srej_list.tail;
2269 l2cap_send_sframe(chan, &control);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002270}
2271
2272static void l2cap_send_srej_list(struct l2cap_chan *chan, u16 txseq)
2273{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002274 struct l2cap_ctrl control;
2275 u16 initial_head;
2276 u16 seq;
2277
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002278 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002279
2280 memset(&control, 0, sizeof(control));
2281 control.sframe = 1;
2282 control.super = L2CAP_SUPER_SREJ;
2283
2284 /* Capture initial list head to allow only one pass through the list. */
2285 initial_head = chan->srej_list.head;
2286
2287 do {
2288 seq = l2cap_seq_list_pop(&chan->srej_list);
2289 if (seq == txseq || seq == L2CAP_SEQ_LIST_CLEAR)
2290 break;
2291
2292 control.reqseq = seq;
2293 l2cap_send_sframe(chan, &control);
2294 l2cap_seq_list_append(&chan->srej_list, seq);
2295 } while (chan->srej_list.head != initial_head);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002296}
2297
Mat Martineau608bcc62012-05-17 20:53:32 -07002298static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq)
2299{
2300 struct sk_buff *acked_skb;
2301 u16 ackseq;
2302
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002303 BT_DBG("chan %p, reqseq %u", chan, reqseq);
Mat Martineau608bcc62012-05-17 20:53:32 -07002304
2305 if (chan->unacked_frames == 0 || reqseq == chan->expected_ack_seq)
2306 return;
2307
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002308 BT_DBG("expected_ack_seq %u, unacked_frames %u",
Mat Martineau608bcc62012-05-17 20:53:32 -07002309 chan->expected_ack_seq, chan->unacked_frames);
2310
2311 for (ackseq = chan->expected_ack_seq; ackseq != reqseq;
2312 ackseq = __next_seq(chan, ackseq)) {
2313
2314 acked_skb = l2cap_ertm_seq_in_queue(&chan->tx_q, ackseq);
2315 if (acked_skb) {
2316 skb_unlink(acked_skb, &chan->tx_q);
2317 kfree_skb(acked_skb);
2318 chan->unacked_frames--;
2319 }
2320 }
2321
2322 chan->expected_ack_seq = reqseq;
2323
2324 if (chan->unacked_frames == 0)
2325 __clear_retrans_timer(chan);
2326
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002327 BT_DBG("unacked_frames %u", chan->unacked_frames);
Mat Martineau608bcc62012-05-17 20:53:32 -07002328}
2329
2330static void l2cap_abort_rx_srej_sent(struct l2cap_chan *chan)
2331{
2332 BT_DBG("chan %p", chan);
2333
2334 chan->expected_tx_seq = chan->buffer_seq;
2335 l2cap_seq_list_clear(&chan->srej_list);
2336 skb_queue_purge(&chan->srej_q);
2337 chan->rx_state = L2CAP_RX_STATE_RECV;
2338}
2339
Gustavo Padovand6603662012-05-21 13:58:22 -03002340static void l2cap_tx_state_xmit(struct l2cap_chan *chan,
2341 struct l2cap_ctrl *control,
2342 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002343{
Mat Martineau608bcc62012-05-17 20:53:32 -07002344 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2345 event);
2346
2347 switch (event) {
2348 case L2CAP_EV_DATA_REQUEST:
2349 if (chan->tx_send_head == NULL)
2350 chan->tx_send_head = skb_peek(skbs);
2351
2352 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2353 l2cap_ertm_send(chan);
2354 break;
2355 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2356 BT_DBG("Enter LOCAL_BUSY");
2357 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2358
2359 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2360 /* The SREJ_SENT state must be aborted if we are to
2361 * enter the LOCAL_BUSY state.
2362 */
2363 l2cap_abort_rx_srej_sent(chan);
2364 }
2365
2366 l2cap_send_ack(chan);
2367
2368 break;
2369 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2370 BT_DBG("Exit LOCAL_BUSY");
2371 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2372
2373 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2374 struct l2cap_ctrl local_control;
2375
2376 memset(&local_control, 0, sizeof(local_control));
2377 local_control.sframe = 1;
2378 local_control.super = L2CAP_SUPER_RR;
2379 local_control.poll = 1;
2380 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002381 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002382
2383 chan->retry_count = 1;
2384 __set_monitor_timer(chan);
2385 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2386 }
2387 break;
2388 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2389 l2cap_process_reqseq(chan, control->reqseq);
2390 break;
2391 case L2CAP_EV_EXPLICIT_POLL:
2392 l2cap_send_rr_or_rnr(chan, 1);
2393 chan->retry_count = 1;
2394 __set_monitor_timer(chan);
2395 __clear_ack_timer(chan);
2396 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2397 break;
2398 case L2CAP_EV_RETRANS_TO:
2399 l2cap_send_rr_or_rnr(chan, 1);
2400 chan->retry_count = 1;
2401 __set_monitor_timer(chan);
2402 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2403 break;
2404 case L2CAP_EV_RECV_FBIT:
2405 /* Nothing to process */
2406 break;
2407 default:
2408 break;
2409 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002410}
2411
Gustavo Padovand6603662012-05-21 13:58:22 -03002412static void l2cap_tx_state_wait_f(struct l2cap_chan *chan,
2413 struct l2cap_ctrl *control,
2414 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002415{
Mat Martineau608bcc62012-05-17 20:53:32 -07002416 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2417 event);
2418
2419 switch (event) {
2420 case L2CAP_EV_DATA_REQUEST:
2421 if (chan->tx_send_head == NULL)
2422 chan->tx_send_head = skb_peek(skbs);
2423 /* Queue data, but don't send. */
2424 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2425 break;
2426 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2427 BT_DBG("Enter LOCAL_BUSY");
2428 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2429
2430 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2431 /* The SREJ_SENT state must be aborted if we are to
2432 * enter the LOCAL_BUSY state.
2433 */
2434 l2cap_abort_rx_srej_sent(chan);
2435 }
2436
2437 l2cap_send_ack(chan);
2438
2439 break;
2440 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2441 BT_DBG("Exit LOCAL_BUSY");
2442 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2443
2444 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2445 struct l2cap_ctrl local_control;
2446 memset(&local_control, 0, sizeof(local_control));
2447 local_control.sframe = 1;
2448 local_control.super = L2CAP_SUPER_RR;
2449 local_control.poll = 1;
2450 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002451 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002452
2453 chan->retry_count = 1;
2454 __set_monitor_timer(chan);
2455 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2456 }
2457 break;
2458 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2459 l2cap_process_reqseq(chan, control->reqseq);
2460
2461 /* Fall through */
2462
2463 case L2CAP_EV_RECV_FBIT:
2464 if (control && control->final) {
2465 __clear_monitor_timer(chan);
2466 if (chan->unacked_frames > 0)
2467 __set_retrans_timer(chan);
2468 chan->retry_count = 0;
2469 chan->tx_state = L2CAP_TX_STATE_XMIT;
2470 BT_DBG("recv fbit tx_state 0x2.2%x", chan->tx_state);
2471 }
2472 break;
2473 case L2CAP_EV_EXPLICIT_POLL:
2474 /* Ignore */
2475 break;
2476 case L2CAP_EV_MONITOR_TO:
2477 if (chan->max_tx == 0 || chan->retry_count < chan->max_tx) {
2478 l2cap_send_rr_or_rnr(chan, 1);
2479 __set_monitor_timer(chan);
2480 chan->retry_count++;
2481 } else {
2482 l2cap_send_disconn_req(chan->conn, chan, ECONNABORTED);
2483 }
2484 break;
2485 default:
2486 break;
2487 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002488}
2489
Gustavo Padovand6603662012-05-21 13:58:22 -03002490static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
2491 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002492{
Mat Martineau608bcc62012-05-17 20:53:32 -07002493 BT_DBG("chan %p, control %p, skbs %p, event %d, state %d",
2494 chan, control, skbs, event, chan->tx_state);
2495
2496 switch (chan->tx_state) {
2497 case L2CAP_TX_STATE_XMIT:
Gustavo Padovand6603662012-05-21 13:58:22 -03002498 l2cap_tx_state_xmit(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002499 break;
2500 case L2CAP_TX_STATE_WAIT_F:
Gustavo Padovand6603662012-05-21 13:58:22 -03002501 l2cap_tx_state_wait_f(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002502 break;
2503 default:
2504 /* Ignore event */
2505 break;
2506 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002507}
2508
Mat Martineau4b51dae92012-05-17 20:53:37 -07002509static void l2cap_pass_to_tx(struct l2cap_chan *chan,
2510 struct l2cap_ctrl *control)
2511{
2512 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002513 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_REQSEQ_AND_FBIT);
Mat Martineau4b51dae92012-05-17 20:53:37 -07002514}
2515
Mat Martineauf80842a2012-05-17 20:53:46 -07002516static void l2cap_pass_to_tx_fbit(struct l2cap_chan *chan,
2517 struct l2cap_ctrl *control)
2518{
2519 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002520 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_FBIT);
Mat Martineauf80842a2012-05-17 20:53:46 -07002521}
2522
Linus Torvalds1da177e2005-04-16 15:20:36 -07002523/* Copy frame to all raw sockets on that connection */
2524static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2525{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002526 struct sk_buff *nskb;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002527 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002528
2529 BT_DBG("conn %p", conn);
2530
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002531 mutex_lock(&conn->chan_lock);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002532
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002533 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002534 struct sock *sk = chan->sk;
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002535 if (chan->chan_type != L2CAP_CHAN_RAW)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002536 continue;
2537
2538 /* Don't send frame to the socket it came from */
2539 if (skb->sk == sk)
2540 continue;
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002541 nskb = skb_clone(skb, GFP_ATOMIC);
2542 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002543 continue;
2544
Gustavo Padovan80b98022012-05-27 22:27:51 -03002545 if (chan->ops->recv(chan, nskb))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002546 kfree_skb(nskb);
2547 }
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002548
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002549 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002550}
2551
2552/* ---- L2CAP signalling commands ---- */
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002553static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code,
2554 u8 ident, u16 dlen, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002555{
2556 struct sk_buff *skb, **frag;
2557 struct l2cap_cmd_hdr *cmd;
2558 struct l2cap_hdr *lh;
2559 int len, count;
2560
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002561 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %u",
2562 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002563
2564 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2565 count = min_t(unsigned int, conn->mtu, len);
2566
2567 skb = bt_skb_alloc(count, GFP_ATOMIC);
2568 if (!skb)
2569 return NULL;
2570
2571 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002572 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002573
2574 if (conn->hcon->type == LE_LINK)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002575 lh->cid = __constant_cpu_to_le16(L2CAP_CID_LE_SIGNALING);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002576 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002577 lh->cid = __constant_cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002578
2579 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2580 cmd->code = code;
2581 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002582 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002583
2584 if (dlen) {
2585 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2586 memcpy(skb_put(skb, count), data, count);
2587 data += count;
2588 }
2589
2590 len -= skb->len;
2591
2592 /* Continuation fragments (no L2CAP header) */
2593 frag = &skb_shinfo(skb)->frag_list;
2594 while (len) {
2595 count = min_t(unsigned int, conn->mtu, len);
2596
2597 *frag = bt_skb_alloc(count, GFP_ATOMIC);
2598 if (!*frag)
2599 goto fail;
2600
2601 memcpy(skb_put(*frag, count), data, count);
2602
2603 len -= count;
2604 data += count;
2605
2606 frag = &(*frag)->next;
2607 }
2608
2609 return skb;
2610
2611fail:
2612 kfree_skb(skb);
2613 return NULL;
2614}
2615
2616static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned long *val)
2617{
2618 struct l2cap_conf_opt *opt = *ptr;
2619 int len;
2620
2621 len = L2CAP_CONF_OPT_SIZE + opt->len;
2622 *ptr += len;
2623
2624 *type = opt->type;
2625 *olen = opt->len;
2626
2627 switch (opt->len) {
2628 case 1:
2629 *val = *((u8 *) opt->val);
2630 break;
2631
2632 case 2:
steven miaobfaaeb32010-10-16 18:29:47 -04002633 *val = get_unaligned_le16(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002634 break;
2635
2636 case 4:
steven miaobfaaeb32010-10-16 18:29:47 -04002637 *val = get_unaligned_le32(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002638 break;
2639
2640 default:
2641 *val = (unsigned long) opt->val;
2642 break;
2643 }
2644
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002645 BT_DBG("type 0x%2.2x len %u val 0x%lx", *type, opt->len, *val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002646 return len;
2647}
2648
Linus Torvalds1da177e2005-04-16 15:20:36 -07002649static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2650{
2651 struct l2cap_conf_opt *opt = *ptr;
2652
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002653 BT_DBG("type 0x%2.2x len %u val 0x%lx", type, len, val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002654
2655 opt->type = type;
2656 opt->len = len;
2657
2658 switch (len) {
2659 case 1:
2660 *((u8 *) opt->val) = val;
2661 break;
2662
2663 case 2:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002664 put_unaligned_le16(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002665 break;
2666
2667 case 4:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002668 put_unaligned_le32(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002669 break;
2670
2671 default:
2672 memcpy(opt->val, (void *) val, len);
2673 break;
2674 }
2675
2676 *ptr += L2CAP_CONF_OPT_SIZE + len;
2677}
2678
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002679static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan)
2680{
2681 struct l2cap_conf_efs efs;
2682
Szymon Janc1ec918c2011-11-16 09:32:21 +01002683 switch (chan->mode) {
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002684 case L2CAP_MODE_ERTM:
2685 efs.id = chan->local_id;
2686 efs.stype = chan->local_stype;
2687 efs.msdu = cpu_to_le16(chan->local_msdu);
2688 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002689 efs.acc_lat = __constant_cpu_to_le32(L2CAP_DEFAULT_ACC_LAT);
2690 efs.flush_to = __constant_cpu_to_le32(L2CAP_DEFAULT_FLUSH_TO);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002691 break;
2692
2693 case L2CAP_MODE_STREAMING:
2694 efs.id = 1;
2695 efs.stype = L2CAP_SERV_BESTEFFORT;
2696 efs.msdu = cpu_to_le16(chan->local_msdu);
2697 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
2698 efs.acc_lat = 0;
2699 efs.flush_to = 0;
2700 break;
2701
2702 default:
2703 return;
2704 }
2705
2706 l2cap_add_conf_opt(ptr, L2CAP_CONF_EFS, sizeof(efs),
2707 (unsigned long) &efs);
2708}
2709
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002710static void l2cap_ack_timeout(struct work_struct *work)
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002711{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002712 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau03625202012-05-17 20:53:51 -07002713 ack_timer.work);
2714 u16 frames_to_ack;
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002715
Gustavo F. Padovan2fb9b3d2011-12-22 16:56:05 -02002716 BT_DBG("chan %p", chan);
2717
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02002718 l2cap_chan_lock(chan);
2719
Mat Martineau03625202012-05-17 20:53:51 -07002720 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
2721 chan->last_acked_seq);
2722
2723 if (frames_to_ack)
2724 l2cap_send_rr_or_rnr(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02002725
2726 l2cap_chan_unlock(chan);
Szymon Janc09bfb2e2012-01-11 10:59:49 +01002727 l2cap_chan_put(chan);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002728}
2729
Andrei Emeltchenko466f8002012-05-29 13:59:01 +03002730int l2cap_ertm_init(struct l2cap_chan *chan)
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002731{
Mat Martineau3c588192012-04-11 10:48:42 -07002732 int err;
2733
Mat Martineau105bdf92012-04-27 16:50:48 -07002734 chan->next_tx_seq = 0;
2735 chan->expected_tx_seq = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03002736 chan->expected_ack_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03002737 chan->unacked_frames = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03002738 chan->buffer_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03002739 chan->frames_sent = 0;
Mat Martineau105bdf92012-04-27 16:50:48 -07002740 chan->last_acked_seq = 0;
2741 chan->sdu = NULL;
2742 chan->sdu_last_frag = NULL;
2743 chan->sdu_len = 0;
2744
Mat Martineaud34c34f2012-05-14 14:49:27 -07002745 skb_queue_head_init(&chan->tx_q);
2746
Mat Martineau105bdf92012-04-27 16:50:48 -07002747 if (chan->mode != L2CAP_MODE_ERTM)
2748 return 0;
2749
2750 chan->rx_state = L2CAP_RX_STATE_RECV;
2751 chan->tx_state = L2CAP_TX_STATE_XMIT;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002752
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002753 INIT_DELAYED_WORK(&chan->retrans_timer, l2cap_retrans_timeout);
2754 INIT_DELAYED_WORK(&chan->monitor_timer, l2cap_monitor_timeout);
2755 INIT_DELAYED_WORK(&chan->ack_timer, l2cap_ack_timeout);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002756
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -03002757 skb_queue_head_init(&chan->srej_q);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002758
Mat Martineau3c588192012-04-11 10:48:42 -07002759 err = l2cap_seq_list_init(&chan->srej_list, chan->tx_win);
2760 if (err < 0)
2761 return err;
2762
Mat Martineau9dc9aff2012-05-17 16:20:14 -07002763 err = l2cap_seq_list_init(&chan->retrans_list, chan->remote_tx_win);
2764 if (err < 0)
2765 l2cap_seq_list_free(&chan->srej_list);
2766
2767 return err;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002768}
2769
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002770static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
2771{
2772 switch (mode) {
2773 case L2CAP_MODE_STREAMING:
2774 case L2CAP_MODE_ERTM:
2775 if (l2cap_mode_supported(mode, remote_feat_mask))
2776 return mode;
2777 /* fall through */
2778 default:
2779 return L2CAP_MODE_BASIC;
2780 }
2781}
2782
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002783static inline bool __l2cap_ews_supported(struct l2cap_chan *chan)
2784{
2785 return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_WINDOW;
2786}
2787
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002788static inline bool __l2cap_efs_supported(struct l2cap_chan *chan)
2789{
2790 return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_FLOW;
2791}
2792
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002793static inline void l2cap_txwin_setup(struct l2cap_chan *chan)
2794{
2795 if (chan->tx_win > L2CAP_DEFAULT_TX_WINDOW &&
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002796 __l2cap_ews_supported(chan)) {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002797 /* use extended control field */
2798 set_bit(FLAG_EXT_CTRL, &chan->flags);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002799 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
2800 } else {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002801 chan->tx_win = min_t(u16, chan->tx_win,
2802 L2CAP_DEFAULT_TX_WINDOW);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002803 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
2804 }
Mat Martineauc20f8e32012-07-10 05:47:07 -07002805 chan->ack_win = chan->tx_win;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002806}
2807
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03002808static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002809{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002810 struct l2cap_conf_req *req = data;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002811 struct l2cap_conf_rfc rfc = { .mode = chan->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07002812 void *ptr = req->data;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03002813 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002814
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03002815 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002816
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03002817 if (chan->num_conf_req || chan->num_conf_rsp)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002818 goto done;
2819
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002820 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002821 case L2CAP_MODE_STREAMING:
2822 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03002823 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state))
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03002824 break;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03002825
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002826 if (__l2cap_efs_supported(chan))
2827 set_bit(FLAG_EFS_ENABLE, &chan->flags);
2828
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03002829 /* fall through */
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002830 default:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002831 chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002832 break;
2833 }
2834
2835done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002836 if (chan->imtu != L2CAP_DEFAULT_MTU)
2837 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovan7990681c2011-01-24 16:01:43 -02002838
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002839 switch (chan->mode) {
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002840 case L2CAP_MODE_BASIC:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002841 if (!(chan->conn->feat_mask & L2CAP_FEAT_ERTM) &&
2842 !(chan->conn->feat_mask & L2CAP_FEAT_STREAMING))
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002843 break;
2844
Gustavo F. Padovan62547752010-06-08 20:05:31 -03002845 rfc.mode = L2CAP_MODE_BASIC;
2846 rfc.txwin_size = 0;
2847 rfc.max_transmit = 0;
2848 rfc.retrans_timeout = 0;
2849 rfc.monitor_timeout = 0;
2850 rfc.max_pdu_size = 0;
2851
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002852 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
2853 (unsigned long) &rfc);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002854 break;
2855
2856 case L2CAP_MODE_ERTM:
2857 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002858 rfc.max_transmit = chan->max_tx;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002859 rfc.retrans_timeout = 0;
2860 rfc.monitor_timeout = 0;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03002861
2862 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
2863 L2CAP_EXT_HDR_SIZE -
2864 L2CAP_SDULEN_SIZE -
2865 L2CAP_FCS_SIZE);
2866 rfc.max_pdu_size = cpu_to_le16(size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002867
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002868 l2cap_txwin_setup(chan);
2869
2870 rfc.txwin_size = min_t(u16, chan->tx_win,
2871 L2CAP_DEFAULT_TX_WINDOW);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002872
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002873 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
2874 (unsigned long) &rfc);
2875
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002876 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
2877 l2cap_add_opt_efs(&ptr, chan);
2878
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002879 if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS))
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002880 break;
2881
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002882 if (chan->fcs == L2CAP_FCS_NONE ||
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03002883 test_bit(CONF_NO_FCS_RECV, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002884 chan->fcs = L2CAP_FCS_NONE;
2885 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002886 }
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002887
2888 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
2889 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
2890 chan->tx_win);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002891 break;
2892
2893 case L2CAP_MODE_STREAMING:
Mat Martineau273759e2012-05-17 20:53:53 -07002894 l2cap_txwin_setup(chan);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002895 rfc.mode = L2CAP_MODE_STREAMING;
2896 rfc.txwin_size = 0;
2897 rfc.max_transmit = 0;
2898 rfc.retrans_timeout = 0;
2899 rfc.monitor_timeout = 0;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03002900
2901 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
2902 L2CAP_EXT_HDR_SIZE -
2903 L2CAP_SDULEN_SIZE -
2904 L2CAP_FCS_SIZE);
2905 rfc.max_pdu_size = cpu_to_le16(size);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002906
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002907 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
2908 (unsigned long) &rfc);
2909
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002910 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
2911 l2cap_add_opt_efs(&ptr, chan);
2912
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002913 if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS))
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002914 break;
2915
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002916 if (chan->fcs == L2CAP_FCS_NONE ||
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03002917 test_bit(CONF_NO_FCS_RECV, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002918 chan->fcs = L2CAP_FCS_NONE;
2919 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002920 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002921 break;
2922 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002923
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002924 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03002925 req->flags = __constant_cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002926
2927 return ptr - data;
2928}
2929
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03002930static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002931{
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002932 struct l2cap_conf_rsp *rsp = data;
2933 void *ptr = rsp->data;
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03002934 void *req = chan->conf_req;
2935 int len = chan->conf_len;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002936 int type, hint, olen;
2937 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002938 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03002939 struct l2cap_conf_efs efs;
2940 u8 remote_efs = 0;
Marcel Holtmann861d6882007-10-20 13:37:06 +02002941 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002942 u16 result = L2CAP_CONF_SUCCESS;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03002943 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002944
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03002945 BT_DBG("chan %p", chan);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01002946
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002947 while (len >= L2CAP_CONF_OPT_SIZE) {
2948 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002949
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03002950 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07002951 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002952
2953 switch (type) {
2954 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002955 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002956 break;
2957
2958 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002959 chan->flush_to = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002960 break;
2961
2962 case L2CAP_CONF_QOS:
2963 break;
2964
Marcel Holtmann6464f352007-10-20 13:39:51 +02002965 case L2CAP_CONF_RFC:
2966 if (olen == sizeof(rfc))
2967 memcpy(&rfc, (void *) val, olen);
2968 break;
2969
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002970 case L2CAP_CONF_FCS:
2971 if (val == L2CAP_FCS_NONE)
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03002972 set_bit(CONF_NO_FCS_RECV, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03002973 break;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002974
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03002975 case L2CAP_CONF_EFS:
2976 remote_efs = 1;
2977 if (olen == sizeof(efs))
2978 memcpy(&efs, (void *) val, olen);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002979 break;
2980
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002981 case L2CAP_CONF_EWS:
2982 if (!enable_hs)
2983 return -ECONNREFUSED;
2984
2985 set_bit(FLAG_EXT_CTRL, &chan->flags);
2986 set_bit(CONF_EWS_RECV, &chan->conf_state);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002987 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002988 chan->remote_tx_win = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002989 break;
2990
2991 default:
2992 if (hint)
2993 break;
2994
2995 result = L2CAP_CONF_UNKNOWN;
2996 *((u8 *) ptr++) = type;
2997 break;
2998 }
2999 }
3000
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003001 if (chan->num_conf_rsp || chan->num_conf_req > 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003002 goto done;
3003
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003004 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003005 case L2CAP_MODE_STREAMING:
3006 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003007 if (!test_bit(CONF_STATE2_DEVICE, &chan->conf_state)) {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003008 chan->mode = l2cap_select_mode(rfc.mode,
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003009 chan->conn->feat_mask);
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003010 break;
3011 }
3012
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003013 if (remote_efs) {
3014 if (__l2cap_efs_supported(chan))
3015 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3016 else
3017 return -ECONNREFUSED;
3018 }
3019
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003020 if (chan->mode != rfc.mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003021 return -ECONNREFUSED;
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03003022
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003023 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003024 }
3025
3026done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003027 if (chan->mode != rfc.mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003028 result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003029 rfc.mode = chan->mode;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003030
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003031 if (chan->num_conf_rsp == 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003032 return -ECONNREFUSED;
3033
3034 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
3035 sizeof(rfc), (unsigned long) &rfc);
3036 }
3037
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003038 if (result == L2CAP_CONF_SUCCESS) {
3039 /* Configure output options and let the other side know
3040 * which ones we don't like. */
3041
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003042 if (mtu < L2CAP_DEFAULT_MIN_MTU)
3043 result = L2CAP_CONF_UNACCEPT;
3044 else {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003045 chan->omtu = mtu;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003046 set_bit(CONF_MTU_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003047 }
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003048 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003049
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003050 if (remote_efs) {
3051 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
3052 efs.stype != L2CAP_SERV_NOTRAFIC &&
3053 efs.stype != chan->local_stype) {
3054
3055 result = L2CAP_CONF_UNACCEPT;
3056
3057 if (chan->num_conf_req >= 1)
3058 return -ECONNREFUSED;
3059
3060 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003061 sizeof(efs),
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003062 (unsigned long) &efs);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003063 } else {
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003064 /* Send PENDING Conf Rsp */
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003065 result = L2CAP_CONF_PENDING;
3066 set_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003067 }
3068 }
3069
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003070 switch (rfc.mode) {
3071 case L2CAP_MODE_BASIC:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003072 chan->fcs = L2CAP_FCS_NONE;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003073 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003074 break;
3075
3076 case L2CAP_MODE_ERTM:
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003077 if (!test_bit(CONF_EWS_RECV, &chan->conf_state))
3078 chan->remote_tx_win = rfc.txwin_size;
3079 else
3080 rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW;
3081
Gustavo F. Padovan2c03a7a2011-03-25 20:15:28 -03003082 chan->remote_max_tx = rfc.max_transmit;
Mat Martineau86b1b262010-08-05 15:54:22 -07003083
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003084 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
3085 chan->conn->mtu -
3086 L2CAP_EXT_HDR_SIZE -
3087 L2CAP_SDULEN_SIZE -
3088 L2CAP_FCS_SIZE);
3089 rfc.max_pdu_size = cpu_to_le16(size);
3090 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003091
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03003092 rfc.retrans_timeout =
Andrei Emeltchenko4fd21a82012-03-12 12:13:10 +02003093 __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03003094 rfc.monitor_timeout =
Andrei Emeltchenko4fd21a82012-03-12 12:13:10 +02003095 __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003096
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003097 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003098
3099 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
3100 sizeof(rfc), (unsigned long) &rfc);
3101
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003102 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3103 chan->remote_id = efs.id;
3104 chan->remote_stype = efs.stype;
3105 chan->remote_msdu = le16_to_cpu(efs.msdu);
3106 chan->remote_flush_to =
3107 le32_to_cpu(efs.flush_to);
3108 chan->remote_acc_lat =
3109 le32_to_cpu(efs.acc_lat);
3110 chan->remote_sdu_itime =
3111 le32_to_cpu(efs.sdu_itime);
3112 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
3113 sizeof(efs), (unsigned long) &efs);
3114 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003115 break;
3116
3117 case L2CAP_MODE_STREAMING:
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003118 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
3119 chan->conn->mtu -
3120 L2CAP_EXT_HDR_SIZE -
3121 L2CAP_SDULEN_SIZE -
3122 L2CAP_FCS_SIZE);
3123 rfc.max_pdu_size = cpu_to_le16(size);
3124 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003125
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003126 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003127
3128 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
3129 sizeof(rfc), (unsigned long) &rfc);
3130
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003131 break;
3132
3133 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02003134 result = L2CAP_CONF_UNACCEPT;
3135
3136 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003137 rfc.mode = chan->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003138 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003139
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003140 if (result == L2CAP_CONF_SUCCESS)
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003141 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003142 }
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003143 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003144 rsp->result = cpu_to_le16(result);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003145 rsp->flags = __constant_cpu_to_le16(0);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003146
3147 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003148}
3149
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03003150static 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 -03003151{
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003152 struct l2cap_conf_req *req = data;
3153 void *ptr = req->data;
3154 int type, olen;
3155 unsigned long val;
Mat Martineau36e999a2011-12-08 17:23:21 -08003156 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003157 struct l2cap_conf_efs efs;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003158
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003159 BT_DBG("chan %p, rsp %p, len %d, req %p", chan, rsp, len, data);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003160
3161 while (len >= L2CAP_CONF_OPT_SIZE) {
3162 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3163
3164 switch (type) {
3165 case L2CAP_CONF_MTU:
3166 if (val < L2CAP_DEFAULT_MIN_MTU) {
3167 *result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003168 chan->imtu = L2CAP_DEFAULT_MIN_MTU;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003169 } else
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003170 chan->imtu = val;
3171 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003172 break;
3173
3174 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003175 chan->flush_to = val;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003176 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003177 2, chan->flush_to);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003178 break;
3179
3180 case L2CAP_CONF_RFC:
3181 if (olen == sizeof(rfc))
3182 memcpy(&rfc, (void *)val, olen);
3183
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003184 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state) &&
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003185 rfc.mode != chan->mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003186 return -ECONNREFUSED;
3187
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003188 chan->fcs = 0;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003189
3190 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
3191 sizeof(rfc), (unsigned long) &rfc);
3192 break;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003193
3194 case L2CAP_CONF_EWS:
Mat Martineauc20f8e32012-07-10 05:47:07 -07003195 chan->ack_win = min_t(u16, val, chan->ack_win);
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003196 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Mat Martineauc20f8e32012-07-10 05:47:07 -07003197 chan->tx_win);
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003198 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003199
3200 case L2CAP_CONF_EFS:
3201 if (olen == sizeof(efs))
3202 memcpy(&efs, (void *)val, olen);
3203
3204 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
3205 efs.stype != L2CAP_SERV_NOTRAFIC &&
3206 efs.stype != chan->local_stype)
3207 return -ECONNREFUSED;
3208
3209 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
3210 sizeof(efs), (unsigned long) &efs);
3211 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003212 }
3213 }
3214
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003215 if (chan->mode == L2CAP_MODE_BASIC && chan->mode != rfc.mode)
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003216 return -ECONNREFUSED;
3217
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003218 chan->mode = rfc.mode;
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003219
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003220 if (*result == L2CAP_CONF_SUCCESS || *result == L2CAP_CONF_PENDING) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003221 switch (rfc.mode) {
3222 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003223 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3224 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
3225 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003226 if (!test_bit(FLAG_EXT_CTRL, &chan->flags))
3227 chan->ack_win = min_t(u16, chan->ack_win,
3228 rfc.txwin_size);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003229
3230 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3231 chan->local_msdu = le16_to_cpu(efs.msdu);
3232 chan->local_sdu_itime =
3233 le32_to_cpu(efs.sdu_itime);
3234 chan->local_acc_lat = le32_to_cpu(efs.acc_lat);
3235 chan->local_flush_to =
3236 le32_to_cpu(efs.flush_to);
3237 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003238 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003239
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003240 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003241 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003242 }
3243 }
3244
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003245 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003246 req->flags = __constant_cpu_to_le16(0);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003247
3248 return ptr - data;
3249}
3250
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003251static int l2cap_build_conf_rsp(struct l2cap_chan *chan, void *data, u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003252{
3253 struct l2cap_conf_rsp *rsp = data;
3254 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003255
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003256 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003257
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003258 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003259 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003260 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003261
3262 return ptr - data;
3263}
3264
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003265void __l2cap_connect_rsp_defer(struct l2cap_chan *chan)
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003266{
3267 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003268 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003269 u8 buf[128];
3270
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003271 rsp.scid = cpu_to_le16(chan->dcid);
3272 rsp.dcid = cpu_to_le16(chan->scid);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003273 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
3274 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003275 l2cap_send_cmd(conn, chan->ident,
3276 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
3277
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003278 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003279 return;
3280
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003281 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
3282 l2cap_build_conf_req(chan, buf), buf);
3283 chan->num_conf_req++;
3284}
3285
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003286static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003287{
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003288 int type, olen;
3289 unsigned long val;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003290 /* Use sane default values in case a misbehaving remote device
3291 * did not send an RFC or extended window size option.
3292 */
3293 u16 txwin_ext = chan->ack_win;
3294 struct l2cap_conf_rfc rfc = {
3295 .mode = chan->mode,
3296 .retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO),
3297 .monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO),
3298 .max_pdu_size = cpu_to_le16(chan->imtu),
3299 .txwin_size = min_t(u16, chan->ack_win, L2CAP_DEFAULT_TX_WINDOW),
3300 };
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003301
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003302 BT_DBG("chan %p, rsp %p, len %d", chan, rsp, len);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003303
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003304 if ((chan->mode != L2CAP_MODE_ERTM) && (chan->mode != L2CAP_MODE_STREAMING))
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003305 return;
3306
3307 while (len >= L2CAP_CONF_OPT_SIZE) {
3308 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3309
Mat Martineauc20f8e32012-07-10 05:47:07 -07003310 switch (type) {
3311 case L2CAP_CONF_RFC:
3312 if (olen == sizeof(rfc))
3313 memcpy(&rfc, (void *)val, olen);
Szymon Janc8f321f82012-06-08 11:33:33 +02003314 break;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003315 case L2CAP_CONF_EWS:
3316 txwin_ext = val;
3317 break;
3318 }
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003319 }
3320
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003321 switch (rfc.mode) {
3322 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003323 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3324 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003325 chan->mps = le16_to_cpu(rfc.max_pdu_size);
3326 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3327 chan->ack_win = min_t(u16, chan->ack_win, txwin_ext);
3328 else
3329 chan->ack_win = min_t(u16, chan->ack_win,
3330 rfc.txwin_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003331 break;
3332 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003333 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003334 }
3335}
3336
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003337static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3338{
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003339 struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003340
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003341 if (rej->reason != L2CAP_REJ_NOT_UNDERSTOOD)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003342 return 0;
3343
3344 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
3345 cmd->ident == conn->info_ident) {
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02003346 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01003347
3348 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003349 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003350
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003351 l2cap_conn_start(conn);
3352 }
3353
3354 return 0;
3355}
3356
Linus Torvalds1da177e2005-04-16 15:20:36 -07003357static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3358{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003359 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
3360 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003361 struct l2cap_chan *chan = NULL, *pchan;
Nathan Holsteind793fe82010-10-15 11:54:02 -04003362 struct sock *parent, *sk = NULL;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003363 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003364
3365 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003366 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003367
Andrei Emeltchenko097db762012-03-09 14:16:17 +02003368 BT_DBG("psm 0x%2.2x scid 0x%4.4x", __le16_to_cpu(psm), scid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003369
3370 /* Check if we have socket listening on psm */
Ido Yarivc2287682012-04-20 15:46:07 -03003371 pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003372 if (!pchan) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003373 result = L2CAP_CR_BAD_PSM;
3374 goto sendresp;
3375 }
3376
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003377 parent = pchan->sk;
3378
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003379 mutex_lock(&conn->chan_lock);
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003380 lock_sock(parent);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00003381
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003382 /* Check if the ACL is secure enough (if not SDP) */
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +03003383 if (psm != __constant_cpu_to_le16(L2CAP_PSM_SDP) &&
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003384 !hci_conn_check_link_mode(conn->hcon)) {
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003385 conn->disc_reason = HCI_ERROR_AUTH_FAILURE;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003386 result = L2CAP_CR_SEC_BLOCK;
3387 goto response;
3388 }
3389
Linus Torvalds1da177e2005-04-16 15:20:36 -07003390 result = L2CAP_CR_NO_MEM;
3391
Gustavo Padovan2dfa1002012-05-27 22:27:58 -03003392 /* Check if we already have channel with that dcid */
3393 if (__l2cap_get_chan_by_dcid(conn, scid))
3394 goto response;
3395
Gustavo Padovan80b98022012-05-27 22:27:51 -03003396 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003397 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003398 goto response;
3399
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003400 sk = chan->sk;
3401
Linus Torvalds1da177e2005-04-16 15:20:36 -07003402 hci_conn_hold(conn->hcon);
3403
Linus Torvalds1da177e2005-04-16 15:20:36 -07003404 bacpy(&bt_sk(sk)->src, conn->src);
3405 bacpy(&bt_sk(sk)->dst, conn->dst);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003406 chan->psm = psm;
3407 chan->dcid = scid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003408
Gustavo F. Padovand1010242011-03-25 00:39:48 -03003409 bt_accept_enqueue(parent, sk);
3410
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003411 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003412
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003413 dcid = chan->scid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003414
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03003415 __set_chan_timer(chan, sk->sk_sndtimeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003416
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003417 chan->ident = cmd->ident;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003418
Marcel Holtmann984947d2009-02-06 23:35:19 +01003419 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02003420 if (l2cap_chan_check_security(chan)) {
Gustavo Padovanc5daa682012-05-16 12:17:10 -03003421 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003422 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003423 result = L2CAP_CR_PEND;
3424 status = L2CAP_CS_AUTHOR_PEND;
3425 parent->sk_data_ready(parent, 0);
3426 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003427 __l2cap_state_change(chan, BT_CONFIG);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003428 result = L2CAP_CR_SUCCESS;
3429 status = L2CAP_CS_NO_INFO;
3430 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003431 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003432 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003433 result = L2CAP_CR_PEND;
3434 status = L2CAP_CS_AUTHEN_PEND;
3435 }
3436 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003437 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003438 result = L2CAP_CR_PEND;
3439 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003440 }
3441
Linus Torvalds1da177e2005-04-16 15:20:36 -07003442response:
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003443 release_sock(parent);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003444 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003445
3446sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003447 rsp.scid = cpu_to_le16(scid);
3448 rsp.dcid = cpu_to_le16(dcid);
3449 rsp.result = cpu_to_le16(result);
3450 rsp.status = cpu_to_le16(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003451 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003452
3453 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
3454 struct l2cap_info_req info;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003455 info.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003456
3457 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
3458 conn->info_ident = l2cap_get_ident(conn);
3459
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08003460 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003461
3462 l2cap_send_cmd(conn, conn->info_ident,
3463 L2CAP_INFO_REQ, sizeof(info), &info);
3464 }
3465
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003466 if (chan && !test_bit(CONF_REQ_SENT, &chan->conf_state) &&
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003467 result == L2CAP_CR_SUCCESS) {
3468 u8 buf[128];
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003469 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003470 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003471 l2cap_build_conf_req(chan, buf), buf);
3472 chan->num_conf_req++;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003473 }
3474
Linus Torvalds1da177e2005-04-16 15:20:36 -07003475 return 0;
3476}
3477
3478static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3479{
3480 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
3481 u16 scid, dcid, result, status;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003482 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003483 u8 req[128];
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003484 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003485
3486 scid = __le16_to_cpu(rsp->scid);
3487 dcid = __le16_to_cpu(rsp->dcid);
3488 result = __le16_to_cpu(rsp->result);
3489 status = __le16_to_cpu(rsp->status);
3490
Andrei Emeltchenko1b009c92012-02-21 12:54:54 +02003491 BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x",
3492 dcid, scid, result, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003493
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003494 mutex_lock(&conn->chan_lock);
3495
Linus Torvalds1da177e2005-04-16 15:20:36 -07003496 if (scid) {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003497 chan = __l2cap_get_chan_by_scid(conn, scid);
3498 if (!chan) {
3499 err = -EFAULT;
3500 goto unlock;
3501 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003502 } else {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003503 chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
3504 if (!chan) {
3505 err = -EFAULT;
3506 goto unlock;
3507 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003508 }
3509
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003510 err = 0;
3511
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003512 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003513
Linus Torvalds1da177e2005-04-16 15:20:36 -07003514 switch (result) {
3515 case L2CAP_CR_SUCCESS:
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03003516 l2cap_state_change(chan, BT_CONFIG);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003517 chan->ident = 0;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003518 chan->dcid = dcid;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003519 clear_bit(CONF_CONNECT_PEND, &chan->conf_state);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003520
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003521 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003522 break;
3523
Linus Torvalds1da177e2005-04-16 15:20:36 -07003524 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003525 l2cap_build_conf_req(chan, req), req);
3526 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003527 break;
3528
3529 case L2CAP_CR_PEND:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003530 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003531 break;
3532
3533 default:
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003534 l2cap_chan_del(chan, ECONNREFUSED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003535 break;
3536 }
3537
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003538 l2cap_chan_unlock(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003539
3540unlock:
3541 mutex_unlock(&conn->chan_lock);
3542
3543 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003544}
3545
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003546static inline void set_default_fcs(struct l2cap_chan *chan)
Mat Martineau8c462b62010-08-24 15:35:42 -07003547{
3548 /* FCS is enabled only in ERTM or streaming mode, if one or both
3549 * sides request it.
3550 */
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003551 if (chan->mode != L2CAP_MODE_ERTM && chan->mode != L2CAP_MODE_STREAMING)
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003552 chan->fcs = L2CAP_FCS_NONE;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003553 else if (!test_bit(CONF_NO_FCS_RECV, &chan->conf_state))
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003554 chan->fcs = L2CAP_FCS_CRC16;
Mat Martineau8c462b62010-08-24 15:35:42 -07003555}
3556
Al Viro88219a02007-07-29 00:17:25 -07003557static 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 -07003558{
3559 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
3560 u16 dcid, flags;
3561 u8 rsp[64];
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003562 struct l2cap_chan *chan;
Mat Martineau3c588192012-04-11 10:48:42 -07003563 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003564
3565 dcid = __le16_to_cpu(req->dcid);
3566 flags = __le16_to_cpu(req->flags);
3567
3568 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
3569
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03003570 chan = l2cap_get_chan_by_scid(conn, dcid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003571 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003572 return -ENOENT;
3573
David S. Miller033b1142011-07-21 13:38:42 -07003574 if (chan->state != BT_CONFIG && chan->state != BT_CONNECT2) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003575 struct l2cap_cmd_rej_cid rej;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003576
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003577 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_INVALID_CID);
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003578 rej.scid = cpu_to_le16(chan->scid);
3579 rej.dcid = cpu_to_le16(chan->dcid);
3580
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003581 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
3582 sizeof(rej), &rej);
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003583 goto unlock;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003584 }
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003585
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003586 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07003587 len = cmd_len - sizeof(*req);
Dan Rosenberg7ac28812011-06-24 08:38:05 -04003588 if (len < 0 || chan->conf_len + len > sizeof(chan->conf_req)) {
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003589 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003590 l2cap_build_conf_rsp(chan, rsp,
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003591 L2CAP_CONF_REJECT, flags), rsp);
3592 goto unlock;
3593 }
3594
3595 /* Store config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003596 memcpy(chan->conf_req + chan->conf_len, req->data, len);
3597 chan->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003598
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003599 if (flags & L2CAP_CONF_FLAG_CONTINUATION) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003600 /* Incomplete config. Send empty response. */
3601 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003602 l2cap_build_conf_rsp(chan, rsp,
Andrei Emeltchenko5325e5b2012-05-23 11:31:22 +03003603 L2CAP_CONF_SUCCESS, flags), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003604 goto unlock;
3605 }
3606
3607 /* Complete config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003608 len = l2cap_parse_conf_req(chan, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003609 if (len < 0) {
Gustavo F. Padovane92c8e72011-04-01 00:53:45 -03003610 l2cap_send_disconn_req(conn, chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003611 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003612 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003613
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003614 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003615 chan->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003616
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003617 /* Reset config buffer. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003618 chan->conf_len = 0;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003619
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003620 if (!test_bit(CONF_OUTPUT_DONE, &chan->conf_state))
Marcel Holtmann876d9482007-10-20 13:35:42 +02003621 goto unlock;
3622
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003623 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003624 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003625
Mat Martineau105bdf92012-04-27 16:50:48 -07003626 if (chan->mode == L2CAP_MODE_ERTM ||
3627 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07003628 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003629
Mat Martineau3c588192012-04-11 10:48:42 -07003630 if (err < 0)
3631 l2cap_send_disconn_req(chan->conn, chan, -err);
3632 else
3633 l2cap_chan_ready(chan);
3634
Marcel Holtmann876d9482007-10-20 13:35:42 +02003635 goto unlock;
3636 }
3637
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003638 if (!test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003639 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003640 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003641 l2cap_build_conf_req(chan, buf), buf);
3642 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003643 }
3644
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003645 /* Got Conf Rsp PENDING from remote side and asume we sent
3646 Conf Rsp PENDING in the code above */
3647 if (test_bit(CONF_REM_CONF_PEND, &chan->conf_state) &&
3648 test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
3649
3650 /* check compatibility */
3651
3652 clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
3653 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
3654
3655 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003656 l2cap_build_conf_rsp(chan, rsp,
Andrei Emeltchenko5325e5b2012-05-23 11:31:22 +03003657 L2CAP_CONF_SUCCESS, flags), rsp);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003658 }
3659
Linus Torvalds1da177e2005-04-16 15:20:36 -07003660unlock:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003661 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07003662 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003663}
3664
3665static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3666{
3667 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
3668 u16 scid, flags, result;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003669 struct l2cap_chan *chan;
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02003670 int len = le16_to_cpu(cmd->len) - sizeof(*rsp);
Mat Martineau3c588192012-04-11 10:48:42 -07003671 int err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003672
3673 scid = __le16_to_cpu(rsp->scid);
3674 flags = __le16_to_cpu(rsp->flags);
3675 result = __le16_to_cpu(rsp->result);
3676
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02003677 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x len %d", scid, flags,
3678 result, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003679
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03003680 chan = l2cap_get_chan_by_scid(conn, scid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003681 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003682 return 0;
3683
3684 switch (result) {
3685 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003686 l2cap_conf_rfc_get(chan, rsp->data, len);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003687 clear_bit(CONF_REM_CONF_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003688 break;
3689
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003690 case L2CAP_CONF_PENDING:
3691 set_bit(CONF_REM_CONF_PEND, &chan->conf_state);
3692
3693 if (test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
3694 char buf[64];
3695
3696 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
3697 buf, &result);
3698 if (len < 0) {
3699 l2cap_send_disconn_req(conn, chan, ECONNRESET);
3700 goto done;
3701 }
3702
3703 /* check compatibility */
3704
3705 clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
3706 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
3707
3708 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003709 l2cap_build_conf_rsp(chan, buf,
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003710 L2CAP_CONF_SUCCESS, 0x0000), buf);
3711 }
3712 goto done;
3713
Linus Torvalds1da177e2005-04-16 15:20:36 -07003714 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003715 if (chan->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003716 char req[64];
3717
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02003718 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
Gustavo F. Padovane92c8e72011-04-01 00:53:45 -03003719 l2cap_send_disconn_req(conn, chan, ECONNRESET);
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02003720 goto done;
3721 }
3722
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003723 /* throw out any old stored conf requests */
3724 result = L2CAP_CONF_SUCCESS;
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03003725 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
3726 req, &result);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003727 if (len < 0) {
Gustavo F. Padovane92c8e72011-04-01 00:53:45 -03003728 l2cap_send_disconn_req(conn, chan, ECONNRESET);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003729 goto done;
3730 }
3731
3732 l2cap_send_cmd(conn, l2cap_get_ident(conn),
3733 L2CAP_CONF_REQ, len, req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003734 chan->num_conf_req++;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003735 if (result != L2CAP_CONF_SUCCESS)
3736 goto done;
3737 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003738 }
3739
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09003740 default:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003741 l2cap_chan_set_err(chan, ECONNRESET);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02003742
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08003743 __set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT);
Gustavo F. Padovane92c8e72011-04-01 00:53:45 -03003744 l2cap_send_disconn_req(conn, chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003745 goto done;
3746 }
3747
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003748 if (flags & L2CAP_CONF_FLAG_CONTINUATION)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003749 goto done;
3750
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003751 set_bit(CONF_INPUT_DONE, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003752
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003753 if (test_bit(CONF_OUTPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003754 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003755
Mat Martineau105bdf92012-04-27 16:50:48 -07003756 if (chan->mode == L2CAP_MODE_ERTM ||
3757 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07003758 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003759
Mat Martineau3c588192012-04-11 10:48:42 -07003760 if (err < 0)
3761 l2cap_send_disconn_req(chan->conn, chan, -err);
3762 else
3763 l2cap_chan_ready(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003764 }
3765
3766done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003767 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07003768 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003769}
3770
3771static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3772{
3773 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
3774 struct l2cap_disconn_rsp rsp;
3775 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003776 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003777 struct sock *sk;
3778
3779 scid = __le16_to_cpu(req->scid);
3780 dcid = __le16_to_cpu(req->dcid);
3781
3782 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
3783
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003784 mutex_lock(&conn->chan_lock);
3785
3786 chan = __l2cap_get_chan_by_scid(conn, dcid);
3787 if (!chan) {
3788 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003789 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003790 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003791
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003792 l2cap_chan_lock(chan);
3793
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003794 sk = chan->sk;
3795
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003796 rsp.dcid = cpu_to_le16(chan->scid);
3797 rsp.scid = cpu_to_le16(chan->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003798 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
3799
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003800 lock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003801 sk->sk_shutdown = SHUTDOWN_MASK;
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003802 release_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003803
Mat Martineau61d6ef32012-04-27 16:50:50 -07003804 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003805 l2cap_chan_del(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003806
3807 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003808
Gustavo Padovan80b98022012-05-27 22:27:51 -03003809 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07003810 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003811
3812 mutex_unlock(&conn->chan_lock);
3813
Linus Torvalds1da177e2005-04-16 15:20:36 -07003814 return 0;
3815}
3816
3817static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3818{
3819 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
3820 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003821 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003822
3823 scid = __le16_to_cpu(rsp->scid);
3824 dcid = __le16_to_cpu(rsp->dcid);
3825
3826 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
3827
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003828 mutex_lock(&conn->chan_lock);
3829
3830 chan = __l2cap_get_chan_by_scid(conn, scid);
3831 if (!chan) {
3832 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003833 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003834 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003835
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003836 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003837
Mat Martineau61d6ef32012-04-27 16:50:50 -07003838 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003839 l2cap_chan_del(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003840
3841 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003842
Gustavo Padovan80b98022012-05-27 22:27:51 -03003843 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07003844 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003845
3846 mutex_unlock(&conn->chan_lock);
3847
Linus Torvalds1da177e2005-04-16 15:20:36 -07003848 return 0;
3849}
3850
3851static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3852{
3853 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003854 u16 type;
3855
3856 type = __le16_to_cpu(req->type);
3857
3858 BT_DBG("type 0x%4.4x", type);
3859
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003860 if (type == L2CAP_IT_FEAT_MASK) {
3861 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003862 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003863 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003864 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
3865 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03003866 if (!disable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003867 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
3868 | L2CAP_FEAT_FCS;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03003869 if (enable_hs)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003870 feat_mask |= L2CAP_FEAT_EXT_FLOW
3871 | L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03003872
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03003873 put_unaligned_le32(feat_mask, rsp->data);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003874 l2cap_send_cmd(conn, cmd->ident,
3875 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003876 } else if (type == L2CAP_IT_FIXED_CHAN) {
3877 u8 buf[12];
3878 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Mat Martineau50a147c2011-11-02 16:18:34 -07003879
3880 if (enable_hs)
3881 l2cap_fixed_chan[0] |= L2CAP_FC_A2MP;
3882 else
3883 l2cap_fixed_chan[0] &= ~L2CAP_FC_A2MP;
3884
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003885 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3886 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Andrei Emeltchenkoc6337ea2011-10-20 17:02:44 +03003887 memcpy(rsp->data, l2cap_fixed_chan, sizeof(l2cap_fixed_chan));
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003888 l2cap_send_cmd(conn, cmd->ident,
3889 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003890 } else {
3891 struct l2cap_info_rsp rsp;
3892 rsp.type = cpu_to_le16(type);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003893 rsp.result = __constant_cpu_to_le16(L2CAP_IR_NOTSUPP);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003894 l2cap_send_cmd(conn, cmd->ident,
3895 L2CAP_INFO_RSP, sizeof(rsp), &rsp);
3896 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003897
3898 return 0;
3899}
3900
3901static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3902{
3903 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
3904 u16 type, result;
3905
3906 type = __le16_to_cpu(rsp->type);
3907 result = __le16_to_cpu(rsp->result);
3908
3909 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
3910
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02003911 /* L2CAP Info req/rsp are unbound to channels, add extra checks */
3912 if (cmd->ident != conn->info_ident ||
3913 conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)
3914 return 0;
3915
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02003916 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003917
Ville Tervoadb08ed2010-08-04 09:43:33 +03003918 if (result != L2CAP_IR_SUCCESS) {
3919 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
3920 conn->info_ident = 0;
3921
3922 l2cap_conn_start(conn);
3923
3924 return 0;
3925 }
3926
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02003927 switch (type) {
3928 case L2CAP_IT_FEAT_MASK:
Harvey Harrison83985312008-05-02 16:25:46 -07003929 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003930
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003931 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003932 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003933 req.type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003934
3935 conn->info_ident = l2cap_get_ident(conn);
3936
3937 l2cap_send_cmd(conn, conn->info_ident,
3938 L2CAP_INFO_REQ, sizeof(req), &req);
3939 } else {
3940 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
3941 conn->info_ident = 0;
3942
3943 l2cap_conn_start(conn);
3944 }
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02003945 break;
3946
3947 case L2CAP_IT_FIXED_CHAN:
3948 conn->fixed_chan_mask = rsp->data[0];
Marcel Holtmann984947d2009-02-06 23:35:19 +01003949 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003950 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003951
3952 l2cap_conn_start(conn);
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02003953 break;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003954 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003955
Linus Torvalds1da177e2005-04-16 15:20:36 -07003956 return 0;
3957}
3958
Mat Martineauf94ff6f2011-11-02 16:18:32 -07003959static inline int l2cap_create_channel_req(struct l2cap_conn *conn,
3960 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3961 void *data)
3962{
3963 struct l2cap_create_chan_req *req = data;
3964 struct l2cap_create_chan_rsp rsp;
3965 u16 psm, scid;
3966
3967 if (cmd_len != sizeof(*req))
3968 return -EPROTO;
3969
3970 if (!enable_hs)
3971 return -EINVAL;
3972
3973 psm = le16_to_cpu(req->psm);
3974 scid = le16_to_cpu(req->scid);
3975
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03003976 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 -07003977
3978 /* Placeholder: Always reject */
3979 rsp.dcid = 0;
3980 rsp.scid = cpu_to_le16(scid);
Andrei Emeltchenko8ce0c492012-03-12 12:13:09 +02003981 rsp.result = __constant_cpu_to_le16(L2CAP_CR_NO_MEM);
3982 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineauf94ff6f2011-11-02 16:18:32 -07003983
3984 l2cap_send_cmd(conn, cmd->ident, L2CAP_CREATE_CHAN_RSP,
3985 sizeof(rsp), &rsp);
3986
3987 return 0;
3988}
3989
3990static inline int l2cap_create_channel_rsp(struct l2cap_conn *conn,
3991 struct l2cap_cmd_hdr *cmd, void *data)
3992{
3993 BT_DBG("conn %p", conn);
3994
3995 return l2cap_connect_rsp(conn, cmd, data);
3996}
3997
Mat Martineau8d5a04a2011-11-02 16:18:35 -07003998static void l2cap_send_move_chan_rsp(struct l2cap_conn *conn, u8 ident,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03003999 u16 icid, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004000{
4001 struct l2cap_move_chan_rsp rsp;
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 rsp.icid = cpu_to_le16(icid);
4006 rsp.result = cpu_to_le16(result);
4007
4008 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_RSP, sizeof(rsp), &rsp);
4009}
4010
4011static void l2cap_send_move_chan_cfm(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004012 struct l2cap_chan *chan,
4013 u16 icid, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004014{
4015 struct l2cap_move_chan_cfm cfm;
4016 u8 ident;
4017
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004018 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004019
4020 ident = l2cap_get_ident(conn);
4021 if (chan)
4022 chan->ident = ident;
4023
4024 cfm.icid = cpu_to_le16(icid);
4025 cfm.result = cpu_to_le16(result);
4026
4027 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM, sizeof(cfm), &cfm);
4028}
4029
4030static void l2cap_send_move_chan_cfm_rsp(struct l2cap_conn *conn, u8 ident,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004031 u16 icid)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004032{
4033 struct l2cap_move_chan_cfm_rsp rsp;
4034
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004035 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004036
4037 rsp.icid = cpu_to_le16(icid);
4038 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM_RSP, sizeof(rsp), &rsp);
4039}
4040
4041static inline int l2cap_move_channel_req(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004042 struct l2cap_cmd_hdr *cmd,
4043 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004044{
4045 struct l2cap_move_chan_req *req = data;
4046 u16 icid = 0;
4047 u16 result = L2CAP_MR_NOT_ALLOWED;
4048
4049 if (cmd_len != sizeof(*req))
4050 return -EPROTO;
4051
4052 icid = le16_to_cpu(req->icid);
4053
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004054 BT_DBG("icid 0x%4.4x, dest_amp_id %d", icid, req->dest_amp_id);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004055
4056 if (!enable_hs)
4057 return -EINVAL;
4058
4059 /* Placeholder: Always refuse */
4060 l2cap_send_move_chan_rsp(conn, cmd->ident, icid, result);
4061
4062 return 0;
4063}
4064
4065static inline int l2cap_move_channel_rsp(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004066 struct l2cap_cmd_hdr *cmd,
4067 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004068{
4069 struct l2cap_move_chan_rsp *rsp = data;
4070 u16 icid, result;
4071
4072 if (cmd_len != sizeof(*rsp))
4073 return -EPROTO;
4074
4075 icid = le16_to_cpu(rsp->icid);
4076 result = le16_to_cpu(rsp->result);
4077
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004078 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004079
4080 /* Placeholder: Always unconfirmed */
4081 l2cap_send_move_chan_cfm(conn, NULL, icid, L2CAP_MC_UNCONFIRMED);
4082
4083 return 0;
4084}
4085
4086static inline int l2cap_move_channel_confirm(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004087 struct l2cap_cmd_hdr *cmd,
4088 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004089{
4090 struct l2cap_move_chan_cfm *cfm = data;
4091 u16 icid, result;
4092
4093 if (cmd_len != sizeof(*cfm))
4094 return -EPROTO;
4095
4096 icid = le16_to_cpu(cfm->icid);
4097 result = le16_to_cpu(cfm->result);
4098
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004099 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004100
4101 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
4102
4103 return 0;
4104}
4105
4106static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004107 struct l2cap_cmd_hdr *cmd,
4108 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004109{
4110 struct l2cap_move_chan_cfm_rsp *rsp = data;
4111 u16 icid;
4112
4113 if (cmd_len != sizeof(*rsp))
4114 return -EPROTO;
4115
4116 icid = le16_to_cpu(rsp->icid);
4117
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004118 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004119
4120 return 0;
4121}
4122
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03004123static inline int l2cap_check_conn_param(u16 min, u16 max, u16 latency,
Claudio Takahaside731152011-02-11 19:28:55 -02004124 u16 to_multiplier)
4125{
4126 u16 max_latency;
4127
4128 if (min > max || min < 6 || max > 3200)
4129 return -EINVAL;
4130
4131 if (to_multiplier < 10 || to_multiplier > 3200)
4132 return -EINVAL;
4133
4134 if (max >= to_multiplier * 8)
4135 return -EINVAL;
4136
4137 max_latency = (to_multiplier * 8 / max) - 1;
4138 if (latency > 499 || latency > max_latency)
4139 return -EINVAL;
4140
4141 return 0;
4142}
4143
4144static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
4145 struct l2cap_cmd_hdr *cmd, u8 *data)
4146{
4147 struct hci_conn *hcon = conn->hcon;
4148 struct l2cap_conn_param_update_req *req;
4149 struct l2cap_conn_param_update_rsp rsp;
4150 u16 min, max, latency, to_multiplier, cmd_len;
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02004151 int err;
Claudio Takahaside731152011-02-11 19:28:55 -02004152
4153 if (!(hcon->link_mode & HCI_LM_MASTER))
4154 return -EINVAL;
4155
4156 cmd_len = __le16_to_cpu(cmd->len);
4157 if (cmd_len != sizeof(struct l2cap_conn_param_update_req))
4158 return -EPROTO;
4159
4160 req = (struct l2cap_conn_param_update_req *) data;
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03004161 min = __le16_to_cpu(req->min);
4162 max = __le16_to_cpu(req->max);
Claudio Takahaside731152011-02-11 19:28:55 -02004163 latency = __le16_to_cpu(req->latency);
4164 to_multiplier = __le16_to_cpu(req->to_multiplier);
4165
4166 BT_DBG("min 0x%4.4x max 0x%4.4x latency: 0x%4.4x Timeout: 0x%4.4x",
4167 min, max, latency, to_multiplier);
4168
4169 memset(&rsp, 0, sizeof(rsp));
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02004170
4171 err = l2cap_check_conn_param(min, max, latency, to_multiplier);
4172 if (err)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004173 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
Claudio Takahaside731152011-02-11 19:28:55 -02004174 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004175 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED);
Claudio Takahaside731152011-02-11 19:28:55 -02004176
4177 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP,
4178 sizeof(rsp), &rsp);
4179
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02004180 if (!err)
4181 hci_le_conn_update(hcon, min, max, latency, to_multiplier);
4182
Claudio Takahaside731152011-02-11 19:28:55 -02004183 return 0;
4184}
4185
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004186static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
4187 struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
4188{
4189 int err = 0;
4190
4191 switch (cmd->code) {
4192 case L2CAP_COMMAND_REJ:
4193 l2cap_command_rej(conn, cmd, data);
4194 break;
4195
4196 case L2CAP_CONN_REQ:
4197 err = l2cap_connect_req(conn, cmd, data);
4198 break;
4199
4200 case L2CAP_CONN_RSP:
4201 err = l2cap_connect_rsp(conn, cmd, data);
4202 break;
4203
4204 case L2CAP_CONF_REQ:
4205 err = l2cap_config_req(conn, cmd, cmd_len, data);
4206 break;
4207
4208 case L2CAP_CONF_RSP:
4209 err = l2cap_config_rsp(conn, cmd, data);
4210 break;
4211
4212 case L2CAP_DISCONN_REQ:
4213 err = l2cap_disconnect_req(conn, cmd, data);
4214 break;
4215
4216 case L2CAP_DISCONN_RSP:
4217 err = l2cap_disconnect_rsp(conn, cmd, data);
4218 break;
4219
4220 case L2CAP_ECHO_REQ:
4221 l2cap_send_cmd(conn, cmd->ident, L2CAP_ECHO_RSP, cmd_len, data);
4222 break;
4223
4224 case L2CAP_ECHO_RSP:
4225 break;
4226
4227 case L2CAP_INFO_REQ:
4228 err = l2cap_information_req(conn, cmd, data);
4229 break;
4230
4231 case L2CAP_INFO_RSP:
4232 err = l2cap_information_rsp(conn, cmd, data);
4233 break;
4234
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004235 case L2CAP_CREATE_CHAN_REQ:
4236 err = l2cap_create_channel_req(conn, cmd, cmd_len, data);
4237 break;
4238
4239 case L2CAP_CREATE_CHAN_RSP:
4240 err = l2cap_create_channel_rsp(conn, cmd, data);
4241 break;
4242
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004243 case L2CAP_MOVE_CHAN_REQ:
4244 err = l2cap_move_channel_req(conn, cmd, cmd_len, data);
4245 break;
4246
4247 case L2CAP_MOVE_CHAN_RSP:
4248 err = l2cap_move_channel_rsp(conn, cmd, cmd_len, data);
4249 break;
4250
4251 case L2CAP_MOVE_CHAN_CFM:
4252 err = l2cap_move_channel_confirm(conn, cmd, cmd_len, data);
4253 break;
4254
4255 case L2CAP_MOVE_CHAN_CFM_RSP:
4256 err = l2cap_move_channel_confirm_rsp(conn, cmd, cmd_len, data);
4257 break;
4258
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004259 default:
4260 BT_ERR("Unknown BR/EDR signaling command 0x%2.2x", cmd->code);
4261 err = -EINVAL;
4262 break;
4263 }
4264
4265 return err;
4266}
4267
4268static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn,
4269 struct l2cap_cmd_hdr *cmd, u8 *data)
4270{
4271 switch (cmd->code) {
4272 case L2CAP_COMMAND_REJ:
4273 return 0;
4274
4275 case L2CAP_CONN_PARAM_UPDATE_REQ:
Claudio Takahaside731152011-02-11 19:28:55 -02004276 return l2cap_conn_param_update_req(conn, cmd, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004277
4278 case L2CAP_CONN_PARAM_UPDATE_RSP:
4279 return 0;
4280
4281 default:
4282 BT_ERR("Unknown LE signaling command 0x%2.2x", cmd->code);
4283 return -EINVAL;
4284 }
4285}
4286
4287static inline void l2cap_sig_channel(struct l2cap_conn *conn,
4288 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004289{
4290 u8 *data = skb->data;
4291 int len = skb->len;
4292 struct l2cap_cmd_hdr cmd;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004293 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004294
4295 l2cap_raw_recv(conn, skb);
4296
4297 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07004298 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004299 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
4300 data += L2CAP_CMD_HDR_SIZE;
4301 len -= L2CAP_CMD_HDR_SIZE;
4302
Al Viro88219a02007-07-29 00:17:25 -07004303 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004304
Al Viro88219a02007-07-29 00:17:25 -07004305 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 -07004306
Al Viro88219a02007-07-29 00:17:25 -07004307 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004308 BT_DBG("corrupted command");
4309 break;
4310 }
4311
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004312 if (conn->hcon->type == LE_LINK)
4313 err = l2cap_le_sig_cmd(conn, &cmd, data);
4314 else
4315 err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004316
4317 if (err) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03004318 struct l2cap_cmd_rej_unk rej;
Gustavo F. Padovan2c6d1a22011-03-23 14:38:32 -03004319
4320 BT_ERR("Wrong link type (%d)", err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004321
4322 /* FIXME: Map err to a valid reason */
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004323 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004324 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
4325 }
4326
Al Viro88219a02007-07-29 00:17:25 -07004327 data += cmd_len;
4328 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004329 }
4330
4331 kfree_skb(skb);
4332}
4333
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004334static int l2cap_check_fcs(struct l2cap_chan *chan, struct sk_buff *skb)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004335{
4336 u16 our_fcs, rcv_fcs;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03004337 int hdr_size;
4338
4339 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
4340 hdr_size = L2CAP_EXT_HDR_SIZE;
4341 else
4342 hdr_size = L2CAP_ENH_HDR_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004343
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004344 if (chan->fcs == L2CAP_FCS_CRC16) {
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03004345 skb_trim(skb, skb->len - L2CAP_FCS_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004346 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
4347 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
4348
4349 if (our_fcs != rcv_fcs)
João Paulo Rechi Vita7a560e52010-06-22 13:56:27 -03004350 return -EBADMSG;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004351 }
4352 return 0;
4353}
4354
Mat Martineau6ea00482012-05-17 20:53:52 -07004355static void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan)
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004356{
Mat Martineaue31f7632012-05-17 20:53:41 -07004357 struct l2cap_ctrl control;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004358
Mat Martineaue31f7632012-05-17 20:53:41 -07004359 BT_DBG("chan %p", chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004360
Mat Martineaue31f7632012-05-17 20:53:41 -07004361 memset(&control, 0, sizeof(control));
4362 control.sframe = 1;
4363 control.final = 1;
4364 control.reqseq = chan->buffer_seq;
4365 set_bit(CONN_SEND_FBIT, &chan->conn_state);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004366
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03004367 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
Mat Martineaue31f7632012-05-17 20:53:41 -07004368 control.super = L2CAP_SUPER_RNR;
4369 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004370 }
4371
Mat Martineaue31f7632012-05-17 20:53:41 -07004372 if (test_and_clear_bit(CONN_REMOTE_BUSY, &chan->conn_state) &&
4373 chan->unacked_frames > 0)
4374 __set_retrans_timer(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004375
Mat Martineaue31f7632012-05-17 20:53:41 -07004376 /* Send pending iframes */
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03004377 l2cap_ertm_send(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004378
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03004379 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
Mat Martineaue31f7632012-05-17 20:53:41 -07004380 test_bit(CONN_SEND_FBIT, &chan->conn_state)) {
4381 /* F-bit wasn't sent in an s-frame or i-frame yet, so
4382 * send it now.
4383 */
4384 control.super = L2CAP_SUPER_RR;
4385 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004386 }
4387}
4388
Mat Martineau84084a32011-07-22 14:54:00 -07004389static void append_skb_frag(struct sk_buff *skb,
4390 struct sk_buff *new_frag, struct sk_buff **last_frag)
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004391{
Mat Martineau84084a32011-07-22 14:54:00 -07004392 /* skb->len reflects data in skb as well as all fragments
4393 * skb->data_len reflects only data in fragments
4394 */
4395 if (!skb_has_frag_list(skb))
4396 skb_shinfo(skb)->frag_list = new_frag;
4397
4398 new_frag->next = NULL;
4399
4400 (*last_frag)->next = new_frag;
4401 *last_frag = new_frag;
4402
4403 skb->len += new_frag->len;
4404 skb->data_len += new_frag->len;
4405 skb->truesize += new_frag->truesize;
4406}
4407
Mat Martineau4b51dae92012-05-17 20:53:37 -07004408static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb,
4409 struct l2cap_ctrl *control)
Mat Martineau84084a32011-07-22 14:54:00 -07004410{
4411 int err = -EINVAL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004412
Mat Martineau4b51dae92012-05-17 20:53:37 -07004413 switch (control->sar) {
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03004414 case L2CAP_SAR_UNSEGMENTED:
Mat Martineau84084a32011-07-22 14:54:00 -07004415 if (chan->sdu)
4416 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004417
Gustavo Padovan80b98022012-05-27 22:27:51 -03004418 err = chan->ops->recv(chan, skb);
Mat Martineau84084a32011-07-22 14:54:00 -07004419 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004420
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03004421 case L2CAP_SAR_START:
Mat Martineau84084a32011-07-22 14:54:00 -07004422 if (chan->sdu)
4423 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004424
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03004425 chan->sdu_len = get_unaligned_le16(skb->data);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03004426 skb_pull(skb, L2CAP_SDULEN_SIZE);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004427
Mat Martineau84084a32011-07-22 14:54:00 -07004428 if (chan->sdu_len > chan->imtu) {
4429 err = -EMSGSIZE;
4430 break;
4431 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004432
Mat Martineau84084a32011-07-22 14:54:00 -07004433 if (skb->len >= chan->sdu_len)
4434 break;
4435
4436 chan->sdu = skb;
4437 chan->sdu_last_frag = skb;
4438
4439 skb = NULL;
4440 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004441 break;
4442
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03004443 case L2CAP_SAR_CONTINUE:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03004444 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07004445 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004446
Mat Martineau84084a32011-07-22 14:54:00 -07004447 append_skb_frag(chan->sdu, skb,
4448 &chan->sdu_last_frag);
4449 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004450
Mat Martineau84084a32011-07-22 14:54:00 -07004451 if (chan->sdu->len >= chan->sdu_len)
4452 break;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03004453
Mat Martineau84084a32011-07-22 14:54:00 -07004454 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004455 break;
4456
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03004457 case L2CAP_SAR_END:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03004458 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07004459 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004460
Mat Martineau84084a32011-07-22 14:54:00 -07004461 append_skb_frag(chan->sdu, skb,
4462 &chan->sdu_last_frag);
4463 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004464
Mat Martineau84084a32011-07-22 14:54:00 -07004465 if (chan->sdu->len != chan->sdu_len)
4466 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004467
Gustavo Padovan80b98022012-05-27 22:27:51 -03004468 err = chan->ops->recv(chan, chan->sdu);
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03004469
Mat Martineau84084a32011-07-22 14:54:00 -07004470 if (!err) {
4471 /* Reassembly complete */
4472 chan->sdu = NULL;
4473 chan->sdu_last_frag = NULL;
4474 chan->sdu_len = 0;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004475 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004476 break;
4477 }
4478
Mat Martineau84084a32011-07-22 14:54:00 -07004479 if (err) {
4480 kfree_skb(skb);
4481 kfree_skb(chan->sdu);
4482 chan->sdu = NULL;
4483 chan->sdu_last_frag = NULL;
4484 chan->sdu_len = 0;
4485 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004486
Mat Martineau84084a32011-07-22 14:54:00 -07004487 return err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004488}
4489
Mat Martineaue3281402011-07-07 09:39:02 -07004490void l2cap_chan_busy(struct l2cap_chan *chan, int busy)
Gustavo F. Padovan712132eb2010-06-21 19:39:50 -03004491{
Mat Martineau61aa4f52012-05-17 20:53:40 -07004492 u8 event;
4493
4494 if (chan->mode != L2CAP_MODE_ERTM)
4495 return;
4496
4497 event = busy ? L2CAP_EV_LOCAL_BUSY_DETECTED : L2CAP_EV_LOCAL_BUSY_CLEAR;
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03004498 l2cap_tx(chan, NULL, NULL, event);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004499}
4500
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004501static int l2cap_rx_queued_iframes(struct l2cap_chan *chan)
4502{
Mat Martineau63838722012-05-17 20:53:45 -07004503 int err = 0;
4504 /* Pass sequential frames to l2cap_reassemble_sdu()
4505 * until a gap is encountered.
4506 */
4507
4508 BT_DBG("chan %p", chan);
4509
4510 while (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4511 struct sk_buff *skb;
4512 BT_DBG("Searching for skb with txseq %d (queue len %d)",
4513 chan->buffer_seq, skb_queue_len(&chan->srej_q));
4514
4515 skb = l2cap_ertm_seq_in_queue(&chan->srej_q, chan->buffer_seq);
4516
4517 if (!skb)
4518 break;
4519
4520 skb_unlink(skb, &chan->srej_q);
4521 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
4522 err = l2cap_reassemble_sdu(chan, skb, &bt_cb(skb)->control);
4523 if (err)
4524 break;
4525 }
4526
4527 if (skb_queue_empty(&chan->srej_q)) {
4528 chan->rx_state = L2CAP_RX_STATE_RECV;
4529 l2cap_send_ack(chan);
4530 }
4531
4532 return err;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004533}
4534
4535static void l2cap_handle_srej(struct l2cap_chan *chan,
4536 struct l2cap_ctrl *control)
4537{
Mat Martineauf80842a2012-05-17 20:53:46 -07004538 struct sk_buff *skb;
4539
4540 BT_DBG("chan %p, control %p", chan, control);
4541
4542 if (control->reqseq == chan->next_tx_seq) {
4543 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
4544 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
4545 return;
4546 }
4547
4548 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
4549
4550 if (skb == NULL) {
4551 BT_DBG("Seq %d not available for retransmission",
4552 control->reqseq);
4553 return;
4554 }
4555
4556 if (chan->max_tx != 0 && bt_cb(skb)->control.retries >= chan->max_tx) {
4557 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
4558 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
4559 return;
4560 }
4561
4562 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4563
4564 if (control->poll) {
4565 l2cap_pass_to_tx(chan, control);
4566
4567 set_bit(CONN_SEND_FBIT, &chan->conn_state);
4568 l2cap_retransmit(chan, control);
4569 l2cap_ertm_send(chan);
4570
4571 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
4572 set_bit(CONN_SREJ_ACT, &chan->conn_state);
4573 chan->srej_save_reqseq = control->reqseq;
4574 }
4575 } else {
4576 l2cap_pass_to_tx_fbit(chan, control);
4577
4578 if (control->final) {
4579 if (chan->srej_save_reqseq != control->reqseq ||
4580 !test_and_clear_bit(CONN_SREJ_ACT,
4581 &chan->conn_state))
4582 l2cap_retransmit(chan, control);
4583 } else {
4584 l2cap_retransmit(chan, control);
4585 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
4586 set_bit(CONN_SREJ_ACT, &chan->conn_state);
4587 chan->srej_save_reqseq = control->reqseq;
4588 }
4589 }
4590 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004591}
4592
4593static void l2cap_handle_rej(struct l2cap_chan *chan,
4594 struct l2cap_ctrl *control)
4595{
Mat Martineaufcd289d2012-05-17 20:53:47 -07004596 struct sk_buff *skb;
4597
4598 BT_DBG("chan %p, control %p", chan, control);
4599
4600 if (control->reqseq == chan->next_tx_seq) {
4601 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
4602 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
4603 return;
4604 }
4605
4606 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
4607
4608 if (chan->max_tx && skb &&
4609 bt_cb(skb)->control.retries >= chan->max_tx) {
4610 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
4611 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
4612 return;
4613 }
4614
4615 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4616
4617 l2cap_pass_to_tx(chan, control);
4618
4619 if (control->final) {
4620 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state))
4621 l2cap_retransmit_all(chan, control);
4622 } else {
4623 l2cap_retransmit_all(chan, control);
4624 l2cap_ertm_send(chan);
4625 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F)
4626 set_bit(CONN_REJ_ACT, &chan->conn_state);
4627 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004628}
4629
Mat Martineau4b51dae92012-05-17 20:53:37 -07004630static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq)
4631{
4632 BT_DBG("chan %p, txseq %d", chan, txseq);
4633
4634 BT_DBG("last_acked_seq %d, expected_tx_seq %d", chan->last_acked_seq,
4635 chan->expected_tx_seq);
4636
4637 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
4638 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
4639 chan->tx_win) {
4640 /* See notes below regarding "double poll" and
4641 * invalid packets.
4642 */
4643 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
4644 BT_DBG("Invalid/Ignore - after SREJ");
4645 return L2CAP_TXSEQ_INVALID_IGNORE;
4646 } else {
4647 BT_DBG("Invalid - in window after SREJ sent");
4648 return L2CAP_TXSEQ_INVALID;
4649 }
4650 }
4651
4652 if (chan->srej_list.head == txseq) {
4653 BT_DBG("Expected SREJ");
4654 return L2CAP_TXSEQ_EXPECTED_SREJ;
4655 }
4656
4657 if (l2cap_ertm_seq_in_queue(&chan->srej_q, txseq)) {
4658 BT_DBG("Duplicate SREJ - txseq already stored");
4659 return L2CAP_TXSEQ_DUPLICATE_SREJ;
4660 }
4661
4662 if (l2cap_seq_list_contains(&chan->srej_list, txseq)) {
4663 BT_DBG("Unexpected SREJ - not requested");
4664 return L2CAP_TXSEQ_UNEXPECTED_SREJ;
4665 }
4666 }
4667
4668 if (chan->expected_tx_seq == txseq) {
4669 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
4670 chan->tx_win) {
4671 BT_DBG("Invalid - txseq outside tx window");
4672 return L2CAP_TXSEQ_INVALID;
4673 } else {
4674 BT_DBG("Expected");
4675 return L2CAP_TXSEQ_EXPECTED;
4676 }
4677 }
4678
4679 if (__seq_offset(chan, txseq, chan->last_acked_seq) <
4680 __seq_offset(chan, chan->expected_tx_seq,
4681 chan->last_acked_seq)){
4682 BT_DBG("Duplicate - expected_tx_seq later than txseq");
4683 return L2CAP_TXSEQ_DUPLICATE;
4684 }
4685
4686 if (__seq_offset(chan, txseq, chan->last_acked_seq) >= chan->tx_win) {
4687 /* A source of invalid packets is a "double poll" condition,
4688 * where delays cause us to send multiple poll packets. If
4689 * the remote stack receives and processes both polls,
4690 * sequence numbers can wrap around in such a way that a
4691 * resent frame has a sequence number that looks like new data
4692 * with a sequence gap. This would trigger an erroneous SREJ
4693 * request.
4694 *
4695 * Fortunately, this is impossible with a tx window that's
4696 * less than half of the maximum sequence number, which allows
4697 * invalid frames to be safely ignored.
4698 *
4699 * With tx window sizes greater than half of the tx window
4700 * maximum, the frame is invalid and cannot be ignored. This
4701 * causes a disconnect.
4702 */
4703
4704 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
4705 BT_DBG("Invalid/Ignore - txseq outside tx window");
4706 return L2CAP_TXSEQ_INVALID_IGNORE;
4707 } else {
4708 BT_DBG("Invalid - txseq outside tx window");
4709 return L2CAP_TXSEQ_INVALID;
4710 }
4711 } else {
4712 BT_DBG("Unexpected - txseq indicates missing frames");
4713 return L2CAP_TXSEQ_UNEXPECTED;
4714 }
4715}
4716
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004717static int l2cap_rx_state_recv(struct l2cap_chan *chan,
4718 struct l2cap_ctrl *control,
4719 struct sk_buff *skb, u8 event)
4720{
4721 int err = 0;
4722 bool skb_in_use = 0;
4723
4724 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
4725 event);
4726
4727 switch (event) {
4728 case L2CAP_EV_RECV_IFRAME:
4729 switch (l2cap_classify_txseq(chan, control->txseq)) {
4730 case L2CAP_TXSEQ_EXPECTED:
4731 l2cap_pass_to_tx(chan, control);
4732
4733 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4734 BT_DBG("Busy, discarding expected seq %d",
4735 control->txseq);
4736 break;
4737 }
4738
4739 chan->expected_tx_seq = __next_seq(chan,
4740 control->txseq);
4741
4742 chan->buffer_seq = chan->expected_tx_seq;
4743 skb_in_use = 1;
4744
4745 err = l2cap_reassemble_sdu(chan, skb, control);
4746 if (err)
4747 break;
4748
4749 if (control->final) {
4750 if (!test_and_clear_bit(CONN_REJ_ACT,
4751 &chan->conn_state)) {
4752 control->final = 0;
4753 l2cap_retransmit_all(chan, control);
4754 l2cap_ertm_send(chan);
4755 }
4756 }
4757
4758 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
4759 l2cap_send_ack(chan);
4760 break;
4761 case L2CAP_TXSEQ_UNEXPECTED:
4762 l2cap_pass_to_tx(chan, control);
4763
4764 /* Can't issue SREJ frames in the local busy state.
4765 * Drop this frame, it will be seen as missing
4766 * when local busy is exited.
4767 */
4768 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4769 BT_DBG("Busy, discarding unexpected seq %d",
4770 control->txseq);
4771 break;
4772 }
4773
4774 /* There was a gap in the sequence, so an SREJ
4775 * must be sent for each missing frame. The
4776 * current frame is stored for later use.
4777 */
4778 skb_queue_tail(&chan->srej_q, skb);
4779 skb_in_use = 1;
4780 BT_DBG("Queued %p (queue len %d)", skb,
4781 skb_queue_len(&chan->srej_q));
4782
4783 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
4784 l2cap_seq_list_clear(&chan->srej_list);
4785 l2cap_send_srej(chan, control->txseq);
4786
4787 chan->rx_state = L2CAP_RX_STATE_SREJ_SENT;
4788 break;
4789 case L2CAP_TXSEQ_DUPLICATE:
4790 l2cap_pass_to_tx(chan, control);
4791 break;
4792 case L2CAP_TXSEQ_INVALID_IGNORE:
4793 break;
4794 case L2CAP_TXSEQ_INVALID:
4795 default:
4796 l2cap_send_disconn_req(chan->conn, chan,
4797 ECONNRESET);
4798 break;
4799 }
4800 break;
4801 case L2CAP_EV_RECV_RR:
4802 l2cap_pass_to_tx(chan, control);
4803 if (control->final) {
4804 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4805
4806 if (!test_and_clear_bit(CONN_REJ_ACT,
4807 &chan->conn_state)) {
4808 control->final = 0;
4809 l2cap_retransmit_all(chan, control);
4810 }
4811
4812 l2cap_ertm_send(chan);
4813 } else if (control->poll) {
4814 l2cap_send_i_or_rr_or_rnr(chan);
4815 } else {
4816 if (test_and_clear_bit(CONN_REMOTE_BUSY,
4817 &chan->conn_state) &&
4818 chan->unacked_frames)
4819 __set_retrans_timer(chan);
4820
4821 l2cap_ertm_send(chan);
4822 }
4823 break;
4824 case L2CAP_EV_RECV_RNR:
4825 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4826 l2cap_pass_to_tx(chan, control);
4827 if (control && control->poll) {
4828 set_bit(CONN_SEND_FBIT, &chan->conn_state);
4829 l2cap_send_rr_or_rnr(chan, 0);
4830 }
4831 __clear_retrans_timer(chan);
4832 l2cap_seq_list_clear(&chan->retrans_list);
4833 break;
4834 case L2CAP_EV_RECV_REJ:
4835 l2cap_handle_rej(chan, control);
4836 break;
4837 case L2CAP_EV_RECV_SREJ:
4838 l2cap_handle_srej(chan, control);
4839 break;
4840 default:
4841 break;
4842 }
4843
4844 if (skb && !skb_in_use) {
4845 BT_DBG("Freeing %p", skb);
4846 kfree_skb(skb);
4847 }
4848
4849 return err;
4850}
4851
4852static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan,
4853 struct l2cap_ctrl *control,
4854 struct sk_buff *skb, u8 event)
4855{
4856 int err = 0;
4857 u16 txseq = control->txseq;
4858 bool skb_in_use = 0;
4859
4860 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
4861 event);
4862
4863 switch (event) {
4864 case L2CAP_EV_RECV_IFRAME:
4865 switch (l2cap_classify_txseq(chan, txseq)) {
4866 case L2CAP_TXSEQ_EXPECTED:
4867 /* Keep frame for reassembly later */
4868 l2cap_pass_to_tx(chan, control);
4869 skb_queue_tail(&chan->srej_q, skb);
4870 skb_in_use = 1;
4871 BT_DBG("Queued %p (queue len %d)", skb,
4872 skb_queue_len(&chan->srej_q));
4873
4874 chan->expected_tx_seq = __next_seq(chan, txseq);
4875 break;
4876 case L2CAP_TXSEQ_EXPECTED_SREJ:
4877 l2cap_seq_list_pop(&chan->srej_list);
4878
4879 l2cap_pass_to_tx(chan, control);
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 err = l2cap_rx_queued_iframes(chan);
4886 if (err)
4887 break;
4888
4889 break;
4890 case L2CAP_TXSEQ_UNEXPECTED:
4891 /* Got a frame that can't be reassembled yet.
4892 * Save it for later, and send SREJs to cover
4893 * the missing frames.
4894 */
4895 skb_queue_tail(&chan->srej_q, skb);
4896 skb_in_use = 1;
4897 BT_DBG("Queued %p (queue len %d)", skb,
4898 skb_queue_len(&chan->srej_q));
4899
4900 l2cap_pass_to_tx(chan, control);
4901 l2cap_send_srej(chan, control->txseq);
4902 break;
4903 case L2CAP_TXSEQ_UNEXPECTED_SREJ:
4904 /* This frame was requested with an SREJ, but
4905 * some expected retransmitted frames are
4906 * missing. Request retransmission of missing
4907 * SREJ'd frames.
4908 */
4909 skb_queue_tail(&chan->srej_q, skb);
4910 skb_in_use = 1;
4911 BT_DBG("Queued %p (queue len %d)", skb,
4912 skb_queue_len(&chan->srej_q));
4913
4914 l2cap_pass_to_tx(chan, control);
4915 l2cap_send_srej_list(chan, control->txseq);
4916 break;
4917 case L2CAP_TXSEQ_DUPLICATE_SREJ:
4918 /* We've already queued this frame. Drop this copy. */
4919 l2cap_pass_to_tx(chan, control);
4920 break;
4921 case L2CAP_TXSEQ_DUPLICATE:
4922 /* Expecting a later sequence number, so this frame
4923 * was already received. Ignore it completely.
4924 */
4925 break;
4926 case L2CAP_TXSEQ_INVALID_IGNORE:
4927 break;
4928 case L2CAP_TXSEQ_INVALID:
4929 default:
4930 l2cap_send_disconn_req(chan->conn, chan,
4931 ECONNRESET);
4932 break;
4933 }
4934 break;
4935 case L2CAP_EV_RECV_RR:
4936 l2cap_pass_to_tx(chan, control);
4937 if (control->final) {
4938 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4939
4940 if (!test_and_clear_bit(CONN_REJ_ACT,
4941 &chan->conn_state)) {
4942 control->final = 0;
4943 l2cap_retransmit_all(chan, control);
4944 }
4945
4946 l2cap_ertm_send(chan);
4947 } else if (control->poll) {
4948 if (test_and_clear_bit(CONN_REMOTE_BUSY,
4949 &chan->conn_state) &&
4950 chan->unacked_frames) {
4951 __set_retrans_timer(chan);
4952 }
4953
4954 set_bit(CONN_SEND_FBIT, &chan->conn_state);
4955 l2cap_send_srej_tail(chan);
4956 } else {
4957 if (test_and_clear_bit(CONN_REMOTE_BUSY,
4958 &chan->conn_state) &&
4959 chan->unacked_frames)
4960 __set_retrans_timer(chan);
4961
4962 l2cap_send_ack(chan);
4963 }
4964 break;
4965 case L2CAP_EV_RECV_RNR:
4966 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4967 l2cap_pass_to_tx(chan, control);
4968 if (control->poll) {
4969 l2cap_send_srej_tail(chan);
4970 } else {
4971 struct l2cap_ctrl rr_control;
4972 memset(&rr_control, 0, sizeof(rr_control));
4973 rr_control.sframe = 1;
4974 rr_control.super = L2CAP_SUPER_RR;
4975 rr_control.reqseq = chan->buffer_seq;
4976 l2cap_send_sframe(chan, &rr_control);
4977 }
4978
4979 break;
4980 case L2CAP_EV_RECV_REJ:
4981 l2cap_handle_rej(chan, control);
4982 break;
4983 case L2CAP_EV_RECV_SREJ:
4984 l2cap_handle_srej(chan, control);
4985 break;
4986 }
4987
4988 if (skb && !skb_in_use) {
4989 BT_DBG("Freeing %p", skb);
4990 kfree_skb(skb);
4991 }
4992
4993 return err;
4994}
4995
4996static bool __valid_reqseq(struct l2cap_chan *chan, u16 reqseq)
4997{
4998 /* Make sure reqseq is for a packet that has been sent but not acked */
4999 u16 unacked;
5000
5001 unacked = __seq_offset(chan, chan->next_tx_seq, chan->expected_ack_seq);
5002 return __seq_offset(chan, chan->next_tx_seq, reqseq) <= unacked;
5003}
5004
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005005static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
5006 struct sk_buff *skb, u8 event)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005007{
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005008 int err = 0;
5009
5010 BT_DBG("chan %p, control %p, skb %p, event %d, state %d", chan,
5011 control, skb, event, chan->rx_state);
5012
5013 if (__valid_reqseq(chan, control->reqseq)) {
5014 switch (chan->rx_state) {
5015 case L2CAP_RX_STATE_RECV:
5016 err = l2cap_rx_state_recv(chan, control, skb, event);
5017 break;
5018 case L2CAP_RX_STATE_SREJ_SENT:
5019 err = l2cap_rx_state_srej_sent(chan, control, skb,
5020 event);
5021 break;
5022 default:
5023 /* shut it down */
5024 break;
5025 }
5026 } else {
5027 BT_DBG("Invalid reqseq %d (next_tx_seq %d, expected_ack_seq %d",
5028 control->reqseq, chan->next_tx_seq,
5029 chan->expected_ack_seq);
5030 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
5031 }
5032
5033 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005034}
5035
5036static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
5037 struct sk_buff *skb)
5038{
Mat Martineau4b51dae92012-05-17 20:53:37 -07005039 int err = 0;
5040
5041 BT_DBG("chan %p, control %p, skb %p, state %d", chan, control, skb,
5042 chan->rx_state);
5043
5044 if (l2cap_classify_txseq(chan, control->txseq) ==
5045 L2CAP_TXSEQ_EXPECTED) {
5046 l2cap_pass_to_tx(chan, control);
5047
5048 BT_DBG("buffer_seq %d->%d", chan->buffer_seq,
5049 __next_seq(chan, chan->buffer_seq));
5050
5051 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
5052
5053 l2cap_reassemble_sdu(chan, skb, control);
5054 } else {
5055 if (chan->sdu) {
5056 kfree_skb(chan->sdu);
5057 chan->sdu = NULL;
5058 }
5059 chan->sdu_last_frag = NULL;
5060 chan->sdu_len = 0;
5061
5062 if (skb) {
5063 BT_DBG("Freeing %p", skb);
5064 kfree_skb(skb);
5065 }
5066 }
5067
5068 chan->last_acked_seq = control->txseq;
5069 chan->expected_tx_seq = __next_seq(chan, control->txseq);
5070
5071 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005072}
5073
5074static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
5075{
5076 struct l2cap_ctrl *control = &bt_cb(skb)->control;
5077 u16 len;
5078 u8 event;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005079
Mat Martineaub76bbd62012-04-11 10:48:43 -07005080 __unpack_control(chan, skb);
5081
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005082 len = skb->len;
5083
5084 /*
5085 * We can just drop the corrupted I-frame here.
5086 * Receiver will miss it and start proper recovery
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005087 * procedures and ask for retransmission.
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005088 */
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005089 if (l2cap_check_fcs(chan, skb))
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005090 goto drop;
5091
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005092 if (!control->sframe && control->sar == L2CAP_SAR_START)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005093 len -= L2CAP_SDULEN_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005094
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005095 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005096 len -= L2CAP_FCS_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005097
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005098 if (len > chan->mps) {
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03005099 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005100 goto drop;
5101 }
5102
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005103 if (!control->sframe) {
5104 int err;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005105
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005106 BT_DBG("iframe sar %d, reqseq %d, final %d, txseq %d",
5107 control->sar, control->reqseq, control->final,
5108 control->txseq);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03005109
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005110 /* Validate F-bit - F=0 always valid, F=1 only
5111 * valid in TX WAIT_F
5112 */
5113 if (control->final && chan->tx_state != L2CAP_TX_STATE_WAIT_F)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005114 goto drop;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005115
5116 if (chan->mode != L2CAP_MODE_STREAMING) {
5117 event = L2CAP_EV_RECV_IFRAME;
5118 err = l2cap_rx(chan, control, skb, event);
5119 } else {
5120 err = l2cap_stream_rx(chan, control, skb);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005121 }
5122
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005123 if (err)
5124 l2cap_send_disconn_req(chan->conn, chan,
5125 ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005126 } else {
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005127 const u8 rx_func_to_event[4] = {
5128 L2CAP_EV_RECV_RR, L2CAP_EV_RECV_REJ,
5129 L2CAP_EV_RECV_RNR, L2CAP_EV_RECV_SREJ
5130 };
5131
5132 /* Only I-frames are expected in streaming mode */
5133 if (chan->mode == L2CAP_MODE_STREAMING)
5134 goto drop;
5135
5136 BT_DBG("sframe reqseq %d, final %d, poll %d, super %d",
5137 control->reqseq, control->final, control->poll,
5138 control->super);
5139
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005140 if (len != 0) {
5141 BT_ERR("%d", len);
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03005142 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005143 goto drop;
5144 }
5145
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005146 /* Validate F and P bits */
5147 if (control->final && (control->poll ||
5148 chan->tx_state != L2CAP_TX_STATE_WAIT_F))
5149 goto drop;
5150
5151 event = rx_func_to_event[control->super];
5152 if (l2cap_rx(chan, control, skb, event))
5153 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005154 }
5155
5156 return 0;
5157
5158drop:
5159 kfree_skb(skb);
5160 return 0;
5161}
5162
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03005163static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid,
5164 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005165{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03005166 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005167
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03005168 chan = l2cap_get_chan_by_scid(conn, cid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03005169 if (!chan) {
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03005170 if (cid == L2CAP_CID_A2MP) {
5171 chan = a2mp_channel_create(conn, skb);
5172 if (!chan) {
5173 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03005174 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03005175 }
5176
5177 l2cap_chan_lock(chan);
5178 } else {
5179 BT_DBG("unknown cid 0x%4.4x", cid);
5180 /* Drop packet and return */
5181 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03005182 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03005183 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005184 }
5185
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03005186 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005187
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03005188 if (chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005189 goto drop;
5190
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03005191 switch (chan->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005192 case L2CAP_MODE_BASIC:
5193 /* If socket recv buffers overflows we drop data here
5194 * which is *bad* because L2CAP has to be reliable.
5195 * But we don't have any other choice. L2CAP doesn't
5196 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07005197
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03005198 if (chan->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005199 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005200
Gustavo Padovan80b98022012-05-27 22:27:51 -03005201 if (!chan->ops->recv(chan, skb))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005202 goto done;
5203 break;
5204
5205 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03005206 case L2CAP_MODE_STREAMING:
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005207 l2cap_data_rcv(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03005208 goto done;
5209
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005210 default:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03005211 BT_DBG("chan %p: bad mode 0x%2.2x", chan, chan->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005212 break;
5213 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005214
5215drop:
5216 kfree_skb(skb);
5217
5218done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005219 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005220}
5221
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03005222static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm,
5223 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005224{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005225 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005226
Ido Yarivc2287682012-04-20 15:46:07 -03005227 chan = l2cap_global_chan_by_psm(0, psm, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005228 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005229 goto drop;
5230
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02005231 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005232
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03005233 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005234 goto drop;
5235
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03005236 if (chan->imtu < skb->len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005237 goto drop;
5238
Gustavo Padovan80b98022012-05-27 22:27:51 -03005239 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03005240 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005241
5242drop:
5243 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005244}
5245
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03005246static void l2cap_att_channel(struct l2cap_conn *conn, u16 cid,
5247 struct sk_buff *skb)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005248{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005249 struct l2cap_chan *chan;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005250
Ido Yarivc2287682012-04-20 15:46:07 -03005251 chan = l2cap_global_chan_by_scid(0, cid, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005252 if (!chan)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005253 goto drop;
5254
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02005255 BT_DBG("chan %p, len %d", chan, skb->len);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005256
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03005257 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005258 goto drop;
5259
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03005260 if (chan->imtu < skb->len)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005261 goto drop;
5262
Gustavo Padovan80b98022012-05-27 22:27:51 -03005263 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03005264 return;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005265
5266drop:
5267 kfree_skb(skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005268}
5269
Linus Torvalds1da177e2005-04-16 15:20:36 -07005270static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
5271{
5272 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07005273 u16 cid, len;
5274 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005275
5276 skb_pull(skb, L2CAP_HDR_SIZE);
5277 cid = __le16_to_cpu(lh->cid);
5278 len = __le16_to_cpu(lh->len);
5279
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005280 if (len != skb->len) {
5281 kfree_skb(skb);
5282 return;
5283 }
5284
Linus Torvalds1da177e2005-04-16 15:20:36 -07005285 BT_DBG("len %d, cid 0x%4.4x", len, cid);
5286
5287 switch (cid) {
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005288 case L2CAP_CID_LE_SIGNALING:
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03005289 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07005290 l2cap_sig_channel(conn, skb);
5291 break;
5292
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03005293 case L2CAP_CID_CONN_LESS:
Andrei Emeltchenko097db762012-03-09 14:16:17 +02005294 psm = get_unaligned((__le16 *) skb->data);
Andrei Emeltchenko0181a702012-05-29 10:04:05 +03005295 skb_pull(skb, L2CAP_PSMLEN_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005296 l2cap_conless_channel(conn, psm, skb);
5297 break;
5298
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005299 case L2CAP_CID_LE_DATA:
5300 l2cap_att_channel(conn, cid, skb);
5301 break;
5302
Anderson Brigliab501d6a2011-06-07 18:46:31 -03005303 case L2CAP_CID_SMP:
5304 if (smp_sig_channel(conn, skb))
5305 l2cap_conn_del(conn->hcon, EACCES);
5306 break;
5307
Linus Torvalds1da177e2005-04-16 15:20:36 -07005308 default:
5309 l2cap_data_channel(conn, cid, skb);
5310 break;
5311 }
5312}
5313
5314/* ---- L2CAP interface with lower layer (HCI) ---- */
5315
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005316int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005317{
5318 int exact = 0, lm1 = 0, lm2 = 0;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005319 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005320
Linus Torvalds1da177e2005-04-16 15:20:36 -07005321 BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
5322
5323 /* Find listening sockets and check their link_mode */
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005324 read_lock(&chan_list_lock);
5325 list_for_each_entry(c, &chan_list, global_l) {
5326 struct sock *sk = c->sk;
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005327
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03005328 if (c->state != BT_LISTEN)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005329 continue;
5330
5331 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01005332 lm1 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03005333 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01005334 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005335 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01005336 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
5337 lm2 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03005338 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01005339 lm2 |= HCI_LM_MASTER;
5340 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005341 }
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005342 read_unlock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005343
5344 return exact ? lm1 : lm2;
5345}
5346
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03005347void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005348{
Marcel Holtmann01394182006-07-03 10:02:46 +02005349 struct l2cap_conn *conn;
5350
Linus Torvalds1da177e2005-04-16 15:20:36 -07005351 BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
5352
Linus Torvalds1da177e2005-04-16 15:20:36 -07005353 if (!status) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005354 conn = l2cap_conn_add(hcon, status);
5355 if (conn)
5356 l2cap_conn_ready(conn);
Marcel Holtmann01394182006-07-03 10:02:46 +02005357 } else
Joe Perchese1750722011-06-29 18:18:29 -07005358 l2cap_conn_del(hcon, bt_to_errno(status));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005359
Linus Torvalds1da177e2005-04-16 15:20:36 -07005360}
5361
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005362int l2cap_disconn_ind(struct hci_conn *hcon)
Marcel Holtmann2950f212009-02-12 14:02:50 +01005363{
5364 struct l2cap_conn *conn = hcon->l2cap_data;
5365
5366 BT_DBG("hcon %p", hcon);
5367
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005368 if (!conn)
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02005369 return HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01005370 return conn->disc_reason;
5371}
5372
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03005373void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005374{
5375 BT_DBG("hcon %p reason %d", hcon, reason);
5376
Joe Perchese1750722011-06-29 18:18:29 -07005377 l2cap_conn_del(hcon, bt_to_errno(reason));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005378}
5379
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005380static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
Marcel Holtmannf62e4322009-01-15 21:58:44 +01005381{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03005382 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED)
Marcel Holtmann255c7602009-02-04 21:07:19 +01005383 return;
5384
Marcel Holtmannf62e4322009-01-15 21:58:44 +01005385 if (encrypt == 0x00) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005386 if (chan->sec_level == BT_SECURITY_MEDIUM) {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08005387 __set_chan_timer(chan, L2CAP_ENC_TIMEOUT);
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005388 } else if (chan->sec_level == BT_SECURITY_HIGH)
Gustavo F. Padovan0f852722011-05-04 19:42:50 -03005389 l2cap_chan_close(chan, ECONNREFUSED);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01005390 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005391 if (chan->sec_level == BT_SECURITY_MEDIUM)
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03005392 __clear_chan_timer(chan);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01005393 }
5394}
5395
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005396int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005397{
Marcel Holtmann40be4922008-07-14 20:13:50 +02005398 struct l2cap_conn *conn = hcon->l2cap_data;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03005399 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005400
Marcel Holtmann01394182006-07-03 10:02:46 +02005401 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005402 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02005403
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03005404 BT_DBG("conn %p status 0x%2.2x encrypt %u", conn, status, encrypt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005405
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03005406 if (hcon->type == LE_LINK) {
Hemant Gupta35d4adcc2012-04-18 14:46:26 +05305407 if (!status && encrypt)
5408 smp_distribute_keys(conn, 0);
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02005409 cancel_delayed_work(&conn->security_timer);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03005410 }
5411
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02005412 mutex_lock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005413
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02005414 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005415 l2cap_chan_lock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005416
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03005417 BT_DBG("chan %p scid 0x%4.4x state %s", chan, chan->scid,
5418 state_to_string(chan->state));
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03005419
Andrei Emeltchenko78eb2f92012-07-19 17:03:47 +03005420 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
5421 l2cap_chan_unlock(chan);
5422 continue;
5423 }
5424
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03005425 if (chan->scid == L2CAP_CID_LE_DATA) {
5426 if (!status && encrypt) {
5427 chan->sec_level = hcon->sec_level;
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02005428 l2cap_chan_ready(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03005429 }
5430
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005431 l2cap_chan_unlock(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03005432 continue;
5433 }
5434
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03005435 if (test_bit(CONF_CONNECT_PEND, &chan->conf_state)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005436 l2cap_chan_unlock(chan);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01005437 continue;
5438 }
5439
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03005440 if (!status && (chan->state == BT_CONNECTED ||
5441 chan->state == BT_CONFIG)) {
Gustavo Padovana7d77232012-05-13 03:20:07 -03005442 struct sock *sk = chan->sk;
5443
Gustavo Padovanc5daa682012-05-16 12:17:10 -03005444 clear_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags);
Gustavo Padovana7d77232012-05-13 03:20:07 -03005445 sk->sk_state_change(sk);
5446
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005447 l2cap_check_encryption(chan, encrypt);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005448 l2cap_chan_unlock(chan);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02005449 continue;
5450 }
5451
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03005452 if (chan->state == BT_CONNECT) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005453 if (!status) {
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +02005454 l2cap_send_conn_req(chan);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005455 } else {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08005456 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005457 }
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03005458 } else if (chan->state == BT_CONNECT2) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005459 struct sock *sk = chan->sk;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005460 struct l2cap_conn_rsp rsp;
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005461 __u16 res, stat;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005462
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005463 lock_sock(sk);
5464
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005465 if (!status) {
Gustavo Padovanc5daa682012-05-16 12:17:10 -03005466 if (test_bit(BT_SK_DEFER_SETUP,
5467 &bt_sk(sk)->flags)) {
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005468 struct sock *parent = bt_sk(sk)->parent;
5469 res = L2CAP_CR_PEND;
5470 stat = L2CAP_CS_AUTHOR_PEND;
Ilia Kolomisnky05e9a2f2011-07-15 18:30:21 +00005471 if (parent)
5472 parent->sk_data_ready(parent, 0);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005473 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02005474 __l2cap_state_change(chan, BT_CONFIG);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005475 res = L2CAP_CR_SUCCESS;
5476 stat = L2CAP_CS_NO_INFO;
5477 }
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005478 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02005479 __l2cap_state_change(chan, BT_DISCONN);
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08005480 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005481 res = L2CAP_CR_SEC_BLOCK;
5482 stat = L2CAP_CS_NO_INFO;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005483 }
5484
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005485 release_sock(sk);
5486
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03005487 rsp.scid = cpu_to_le16(chan->dcid);
5488 rsp.dcid = cpu_to_le16(chan->scid);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005489 rsp.result = cpu_to_le16(res);
5490 rsp.status = cpu_to_le16(stat);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03005491 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
5492 sizeof(rsp), &rsp);
Mat Martineau2d369352012-05-23 14:59:30 -07005493
5494 if (!test_bit(CONF_REQ_SENT, &chan->conf_state) &&
5495 res == L2CAP_CR_SUCCESS) {
5496 char buf[128];
5497 set_bit(CONF_REQ_SENT, &chan->conf_state);
5498 l2cap_send_cmd(conn, l2cap_get_ident(conn),
5499 L2CAP_CONF_REQ,
5500 l2cap_build_conf_req(chan, buf),
5501 buf);
5502 chan->num_conf_req++;
5503 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005504 }
5505
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005506 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005507 }
5508
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02005509 mutex_unlock(&conn->chan_lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005510
Linus Torvalds1da177e2005-04-16 15:20:36 -07005511 return 0;
5512}
5513
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005514int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005515{
5516 struct l2cap_conn *conn = hcon->l2cap_data;
5517
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02005518 if (!conn)
5519 conn = l2cap_conn_add(hcon, 0);
5520
5521 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005522 goto drop;
5523
5524 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
5525
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +02005526 if (!(flags & ACL_CONT)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005527 struct l2cap_hdr *hdr;
5528 int len;
5529
5530 if (conn->rx_len) {
5531 BT_ERR("Unexpected start frame (len %d)", skb->len);
5532 kfree_skb(conn->rx_skb);
5533 conn->rx_skb = NULL;
5534 conn->rx_len = 0;
5535 l2cap_conn_unreliable(conn, ECOMM);
5536 }
5537
Andrei Emeltchenkoaae7fe22010-09-15 14:28:43 +03005538 /* Start fragment always begin with Basic L2CAP header */
5539 if (skb->len < L2CAP_HDR_SIZE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005540 BT_ERR("Frame is too short (len %d)", skb->len);
5541 l2cap_conn_unreliable(conn, ECOMM);
5542 goto drop;
5543 }
5544
5545 hdr = (struct l2cap_hdr *) skb->data;
5546 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
5547
5548 if (len == skb->len) {
5549 /* Complete frame received */
5550 l2cap_recv_frame(conn, skb);
5551 return 0;
5552 }
5553
5554 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
5555
5556 if (skb->len > len) {
5557 BT_ERR("Frame is too long (len %d, expected len %d)",
5558 skb->len, len);
5559 l2cap_conn_unreliable(conn, ECOMM);
5560 goto drop;
5561 }
5562
5563 /* Allocate skb for the complete frame (with header) */
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03005564 conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC);
5565 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005566 goto drop;
5567
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03005568 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01005569 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005570 conn->rx_len = len - skb->len;
5571 } else {
5572 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
5573
5574 if (!conn->rx_len) {
5575 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
5576 l2cap_conn_unreliable(conn, ECOMM);
5577 goto drop;
5578 }
5579
5580 if (skb->len > conn->rx_len) {
5581 BT_ERR("Fragment is too long (len %d, expected %d)",
5582 skb->len, conn->rx_len);
5583 kfree_skb(conn->rx_skb);
5584 conn->rx_skb = NULL;
5585 conn->rx_len = 0;
5586 l2cap_conn_unreliable(conn, ECOMM);
5587 goto drop;
5588 }
5589
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03005590 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01005591 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005592 conn->rx_len -= skb->len;
5593
5594 if (!conn->rx_len) {
5595 /* Complete frame received */
5596 l2cap_recv_frame(conn, conn->rx_skb);
5597 conn->rx_skb = NULL;
5598 }
5599 }
5600
5601drop:
5602 kfree_skb(skb);
5603 return 0;
5604}
5605
Marcel Holtmannaef7d972010-03-21 05:27:45 +01005606static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005607{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005608 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005609
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02005610 read_lock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005611
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005612 list_for_each_entry(c, &chan_list, global_l) {
5613 struct sock *sk = c->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005614
Gustavo F. Padovan903d3432011-02-10 14:16:06 -02005615 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 +01005616 batostr(&bt_sk(sk)->src),
5617 batostr(&bt_sk(sk)->dst),
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03005618 c->state, __le16_to_cpu(c->psm),
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005619 c->scid, c->dcid, c->imtu, c->omtu,
5620 c->sec_level, c->mode);
Andrei Emeltchenko61e1b4b2012-01-19 11:19:50 +02005621 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005622
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02005623 read_unlock(&chan_list_lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08005624
Marcel Holtmannaef7d972010-03-21 05:27:45 +01005625 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005626}
5627
Marcel Holtmannaef7d972010-03-21 05:27:45 +01005628static int l2cap_debugfs_open(struct inode *inode, struct file *file)
5629{
5630 return single_open(file, l2cap_debugfs_show, inode->i_private);
5631}
5632
5633static const struct file_operations l2cap_debugfs_fops = {
5634 .open = l2cap_debugfs_open,
5635 .read = seq_read,
5636 .llseek = seq_lseek,
5637 .release = single_release,
5638};
5639
5640static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005641
Gustavo F. Padovan64274512011-02-07 20:08:52 -02005642int __init l2cap_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005643{
5644 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08005645
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02005646 err = l2cap_init_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005647 if (err < 0)
5648 return err;
5649
Marcel Holtmannaef7d972010-03-21 05:27:45 +01005650 if (bt_debugfs) {
5651 l2cap_debugfs = debugfs_create_file("l2cap", 0444,
5652 bt_debugfs, NULL, &l2cap_debugfs_fops);
5653 if (!l2cap_debugfs)
5654 BT_ERR("Failed to create L2CAP debug file");
5655 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005656
Linus Torvalds1da177e2005-04-16 15:20:36 -07005657 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005658}
5659
Gustavo F. Padovan64274512011-02-07 20:08:52 -02005660void l2cap_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005661{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01005662 debugfs_remove(l2cap_debugfs);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02005663 l2cap_cleanup_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005664}
5665
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03005666module_param(disable_ertm, bool, 0644);
5667MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode");