blob: 8ae6a21cf6433f2c9fe8de41850d7f8544029a43 [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>
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +020041#include <net/bluetooth/amp.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070042
Mat Martineaud1de6d42012-05-17 20:53:55 -070043bool disable_ertm;
Marcel Holtmannf0709e02007-10-20 13:38:51 +020044
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -070045static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN;
Mat Martineau50a147c2011-11-02 16:18:34 -070046static u8 l2cap_fixed_chan[8] = { L2CAP_FC_L2CAP, };
Linus Torvalds1da177e2005-04-16 15:20:36 -070047
Johannes Bergb5ad8b72011-06-01 08:54:45 +020048static LIST_HEAD(chan_list);
49static DEFINE_RWLOCK(chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -070050
Linus Torvalds1da177e2005-04-16 15:20:36 -070051static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +010052 u8 code, u8 ident, u16 dlen, void *data);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -030053static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
Gustavo Padovan2d792812012-10-06 10:07:01 +010054 void *data);
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -030055static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +020056static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err);
Linus Torvalds1da177e2005-04-16 15:20:36 -070057
Gustavo Padovand6603662012-05-21 13:58:22 -030058static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
Gustavo Padovan2d792812012-10-06 10:07:01 +010059 struct sk_buff_head *skbs, u8 event);
Mat Martineau608bcc62012-05-17 20:53:32 -070060
Marcel Holtmann01394182006-07-03 10:02:46 +020061/* ---- L2CAP channels ---- */
Gustavo F. Padovan71ba0e52011-05-17 14:34:52 -030062
Gustavo Padovan2d792812012-10-06 10:07:01 +010063static struct l2cap_chan *__l2cap_get_chan_by_dcid(struct l2cap_conn *conn,
64 u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +020065{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020066 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030067
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020068 list_for_each_entry(c, &conn->chan_l, list) {
69 if (c->dcid == cid)
70 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +020071 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020072 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +020073}
74
Gustavo Padovan2d792812012-10-06 10:07:01 +010075static struct l2cap_chan *__l2cap_get_chan_by_scid(struct l2cap_conn *conn,
76 u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +020077{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020078 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030079
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020080 list_for_each_entry(c, &conn->chan_l, list) {
81 if (c->scid == cid)
82 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +020083 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020084 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +020085}
86
87/* Find channel with given SCID.
Mat Martineauef191ad2012-05-02 09:42:00 -070088 * Returns locked channel. */
Gustavo Padovan2d792812012-10-06 10:07:01 +010089static struct l2cap_chan *l2cap_get_chan_by_scid(struct l2cap_conn *conn,
90 u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +020091{
Gustavo F. Padovan48454072011-03-25 00:22:30 -030092 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030093
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020094 mutex_lock(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030095 c = __l2cap_get_chan_by_scid(conn, cid);
Mat Martineauef191ad2012-05-02 09:42:00 -070096 if (c)
97 l2cap_chan_lock(c);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020098 mutex_unlock(&conn->chan_lock);
99
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300100 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +0200101}
102
Mat Martineaub1a130b2012-10-23 15:24:09 -0700103/* Find channel with given DCID.
104 * Returns locked channel.
105 */
106static struct l2cap_chan *l2cap_get_chan_by_dcid(struct l2cap_conn *conn,
107 u16 cid)
108{
109 struct l2cap_chan *c;
110
111 mutex_lock(&conn->chan_lock);
112 c = __l2cap_get_chan_by_dcid(conn, cid);
113 if (c)
114 l2cap_chan_lock(c);
115 mutex_unlock(&conn->chan_lock);
116
117 return c;
118}
119
Gustavo Padovan2d792812012-10-06 10:07:01 +0100120static struct l2cap_chan *__l2cap_get_chan_by_ident(struct l2cap_conn *conn,
121 u8 ident)
Marcel Holtmann01394182006-07-03 10:02:46 +0200122{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200123 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300124
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200125 list_for_each_entry(c, &conn->chan_l, list) {
126 if (c->ident == ident)
127 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +0200128 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200129 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200130}
131
Mat Martineau5b155ef2012-10-23 15:24:14 -0700132static struct l2cap_chan *l2cap_get_chan_by_ident(struct l2cap_conn *conn,
133 u8 ident)
134{
135 struct l2cap_chan *c;
136
137 mutex_lock(&conn->chan_lock);
138 c = __l2cap_get_chan_by_ident(conn, ident);
139 if (c)
140 l2cap_chan_lock(c);
141 mutex_unlock(&conn->chan_lock);
142
143 return c;
144}
145
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300146static struct l2cap_chan *__l2cap_global_chan_by_addr(__le16 psm, bdaddr_t *src)
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300147{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300148 struct l2cap_chan *c;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300149
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300150 list_for_each_entry(c, &chan_list, global_l) {
151 if (c->sport == psm && !bacmp(&bt_sk(c->sk)->src, src))
Szymon Janc250938c2011-11-16 09:32:22 +0100152 return c;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300153 }
Szymon Janc250938c2011-11-16 09:32:22 +0100154 return NULL;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300155}
156
157int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm)
158{
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300159 int err;
160
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200161 write_lock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300162
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300163 if (psm && __l2cap_global_chan_by_addr(psm, src)) {
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300164 err = -EADDRINUSE;
165 goto done;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300166 }
167
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300168 if (psm) {
169 chan->psm = psm;
170 chan->sport = psm;
171 err = 0;
172 } else {
173 u16 p;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300174
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300175 err = -EINVAL;
176 for (p = 0x1001; p < 0x1100; p += 2)
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300177 if (!__l2cap_global_chan_by_addr(cpu_to_le16(p), src)) {
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300178 chan->psm = cpu_to_le16(p);
179 chan->sport = cpu_to_le16(p);
180 err = 0;
181 break;
182 }
183 }
184
185done:
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200186 write_unlock(&chan_list_lock);
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300187 return err;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300188}
189
190int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid)
191{
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200192 write_lock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300193
194 chan->scid = scid;
195
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200196 write_unlock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300197
198 return 0;
199}
200
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300201static u16 l2cap_alloc_cid(struct l2cap_conn *conn)
Marcel Holtmann01394182006-07-03 10:02:46 +0200202{
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300203 u16 cid = L2CAP_CID_DYN_START;
Marcel Holtmann01394182006-07-03 10:02:46 +0200204
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300205 for (; cid < L2CAP_CID_DYN_END; cid++) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300206 if (!__l2cap_get_chan_by_scid(conn, cid))
Marcel Holtmann01394182006-07-03 10:02:46 +0200207 return cid;
208 }
209
210 return 0;
211}
212
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +0200213static void __l2cap_state_change(struct l2cap_chan *chan, int state)
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300214{
Andrei Emeltchenko42d2d872012-02-17 11:40:57 +0200215 BT_DBG("chan %p %s -> %s", chan, state_to_string(chan->state),
Gustavo Padovan2d792812012-10-06 10:07:01 +0100216 state_to_string(state));
Gustavo F. Padovanbadaaa02011-11-23 20:11:46 -0200217
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300218 chan->state = state;
Gustavo Padovan80b98022012-05-27 22:27:51 -0300219 chan->ops->state_change(chan, state);
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300220}
221
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +0200222static void l2cap_state_change(struct l2cap_chan *chan, int state)
223{
224 struct sock *sk = chan->sk;
225
226 lock_sock(sk);
227 __l2cap_state_change(chan, state);
228 release_sock(sk);
229}
230
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +0200231static inline void __l2cap_chan_set_err(struct l2cap_chan *chan, int err)
232{
233 struct sock *sk = chan->sk;
234
235 sk->sk_err = err;
236}
237
238static inline void l2cap_chan_set_err(struct l2cap_chan *chan, int err)
239{
240 struct sock *sk = chan->sk;
241
242 lock_sock(sk);
243 __l2cap_chan_set_err(chan, err);
244 release_sock(sk);
245}
246
Mat Martineau4239d162012-05-17 20:53:49 -0700247static void __set_retrans_timer(struct l2cap_chan *chan)
248{
249 if (!delayed_work_pending(&chan->monitor_timer) &&
250 chan->retrans_timeout) {
251 l2cap_set_timer(chan, &chan->retrans_timer,
252 msecs_to_jiffies(chan->retrans_timeout));
253 }
254}
255
256static void __set_monitor_timer(struct l2cap_chan *chan)
257{
258 __clear_retrans_timer(chan);
259 if (chan->monitor_timeout) {
260 l2cap_set_timer(chan, &chan->monitor_timer,
261 msecs_to_jiffies(chan->monitor_timeout));
262 }
263}
264
Mat Martineau608bcc62012-05-17 20:53:32 -0700265static struct sk_buff *l2cap_ertm_seq_in_queue(struct sk_buff_head *head,
266 u16 seq)
267{
268 struct sk_buff *skb;
269
270 skb_queue_walk(head, skb) {
271 if (bt_cb(skb)->control.txseq == seq)
272 return skb;
273 }
274
275 return NULL;
276}
277
Mat Martineau3c588192012-04-11 10:48:42 -0700278/* ---- L2CAP sequence number lists ---- */
279
280/* For ERTM, ordered lists of sequence numbers must be tracked for
281 * SREJ requests that are received and for frames that are to be
282 * retransmitted. These seq_list functions implement a singly-linked
283 * list in an array, where membership in the list can also be checked
284 * in constant time. Items can also be added to the tail of the list
285 * and removed from the head in constant time, without further memory
286 * allocs or frees.
287 */
288
289static int l2cap_seq_list_init(struct l2cap_seq_list *seq_list, u16 size)
290{
291 size_t alloc_size, i;
292
293 /* Allocated size is a power of 2 to map sequence numbers
294 * (which may be up to 14 bits) in to a smaller array that is
295 * sized for the negotiated ERTM transmit windows.
296 */
297 alloc_size = roundup_pow_of_two(size);
298
299 seq_list->list = kmalloc(sizeof(u16) * alloc_size, GFP_KERNEL);
300 if (!seq_list->list)
301 return -ENOMEM;
302
303 seq_list->mask = alloc_size - 1;
304 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
305 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
306 for (i = 0; i < alloc_size; i++)
307 seq_list->list[i] = L2CAP_SEQ_LIST_CLEAR;
308
309 return 0;
310}
311
312static inline void l2cap_seq_list_free(struct l2cap_seq_list *seq_list)
313{
314 kfree(seq_list->list);
315}
316
317static inline bool l2cap_seq_list_contains(struct l2cap_seq_list *seq_list,
318 u16 seq)
319{
320 /* Constant-time check for list membership */
321 return seq_list->list[seq & seq_list->mask] != L2CAP_SEQ_LIST_CLEAR;
322}
323
324static u16 l2cap_seq_list_remove(struct l2cap_seq_list *seq_list, u16 seq)
325{
326 u16 mask = seq_list->mask;
327
328 if (seq_list->head == L2CAP_SEQ_LIST_CLEAR) {
329 /* In case someone tries to pop the head of an empty list */
330 return L2CAP_SEQ_LIST_CLEAR;
331 } else if (seq_list->head == seq) {
332 /* Head can be removed in constant time */
333 seq_list->head = seq_list->list[seq & mask];
334 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_CLEAR;
335
336 if (seq_list->head == L2CAP_SEQ_LIST_TAIL) {
337 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
338 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
339 }
340 } else {
341 /* Walk the list to find the sequence number */
342 u16 prev = seq_list->head;
343 while (seq_list->list[prev & mask] != seq) {
344 prev = seq_list->list[prev & mask];
345 if (prev == L2CAP_SEQ_LIST_TAIL)
346 return L2CAP_SEQ_LIST_CLEAR;
347 }
348
349 /* Unlink the number from the list and clear it */
350 seq_list->list[prev & mask] = seq_list->list[seq & mask];
351 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_CLEAR;
352 if (seq_list->tail == seq)
353 seq_list->tail = prev;
354 }
355 return seq;
356}
357
358static inline u16 l2cap_seq_list_pop(struct l2cap_seq_list *seq_list)
359{
360 /* Remove the head in constant time */
361 return l2cap_seq_list_remove(seq_list, seq_list->head);
362}
363
364static void l2cap_seq_list_clear(struct l2cap_seq_list *seq_list)
365{
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300366 u16 i;
Mat Martineau3c588192012-04-11 10:48:42 -0700367
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300368 if (seq_list->head == L2CAP_SEQ_LIST_CLEAR)
369 return;
370
371 for (i = 0; i <= seq_list->mask; i++)
372 seq_list->list[i] = L2CAP_SEQ_LIST_CLEAR;
373
374 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
375 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
Mat Martineau3c588192012-04-11 10:48:42 -0700376}
377
378static void l2cap_seq_list_append(struct l2cap_seq_list *seq_list, u16 seq)
379{
380 u16 mask = seq_list->mask;
381
382 /* All appends happen in constant time */
383
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300384 if (seq_list->list[seq & mask] != L2CAP_SEQ_LIST_CLEAR)
385 return;
Mat Martineau3c588192012-04-11 10:48:42 -0700386
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300387 if (seq_list->tail == L2CAP_SEQ_LIST_CLEAR)
388 seq_list->head = seq;
389 else
390 seq_list->list[seq_list->tail & mask] = seq;
391
392 seq_list->tail = seq;
393 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_TAIL;
Mat Martineau3c588192012-04-11 10:48:42 -0700394}
395
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300396static void l2cap_chan_timeout(struct work_struct *work)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300397{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300398 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100399 chan_timer.work);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200400 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300401 int reason;
402
Andrei Emeltchenkoe05dcc32012-02-17 11:40:56 +0200403 BT_DBG("chan %p state %s", chan, state_to_string(chan->state));
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300404
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200405 mutex_lock(&conn->chan_lock);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200406 l2cap_chan_lock(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300407
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300408 if (chan->state == BT_CONNECTED || chan->state == BT_CONFIG)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300409 reason = ECONNREFUSED;
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300410 else if (chan->state == BT_CONNECT &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100411 chan->sec_level != BT_SECURITY_SDP)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300412 reason = ECONNREFUSED;
413 else
414 reason = ETIMEDOUT;
415
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300416 l2cap_chan_close(chan, reason);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300417
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200418 l2cap_chan_unlock(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300419
Gustavo Padovan80b98022012-05-27 22:27:51 -0300420 chan->ops->close(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200421 mutex_unlock(&conn->chan_lock);
422
Ulisses Furquim371fd832011-12-21 20:02:36 -0200423 l2cap_chan_put(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300424}
425
Gustavo Padovaneef1d9b2012-03-25 13:59:16 -0300426struct l2cap_chan *l2cap_chan_create(void)
Marcel Holtmann01394182006-07-03 10:02:46 +0200427{
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300428 struct l2cap_chan *chan;
Marcel Holtmann01394182006-07-03 10:02:46 +0200429
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300430 chan = kzalloc(sizeof(*chan), GFP_ATOMIC);
431 if (!chan)
432 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200433
Andrei Emeltchenkoc03b3552012-02-21 12:54:56 +0200434 mutex_init(&chan->lock);
435
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200436 write_lock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300437 list_add(&chan->global_l, &chan_list);
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200438 write_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300439
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300440 INIT_DELAYED_WORK(&chan->chan_timer, l2cap_chan_timeout);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300441
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300442 chan->state = BT_OPEN;
443
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530444 kref_init(&chan->kref);
Gustavo F. Padovan71ba0e52011-05-17 14:34:52 -0300445
Mat Martineau28270112012-05-17 21:14:09 -0700446 /* This flag is cleared in l2cap_chan_ready() */
447 set_bit(CONF_NOT_COMPLETE, &chan->conf_state);
448
Gustavo Padovaneef1d9b2012-03-25 13:59:16 -0300449 BT_DBG("chan %p", chan);
Szymon Jancabc545b2011-11-03 16:05:44 +0100450
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300451 return chan;
Marcel Holtmann01394182006-07-03 10:02:46 +0200452}
453
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530454static void l2cap_chan_destroy(struct kref *kref)
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300455{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530456 struct l2cap_chan *chan = container_of(kref, struct l2cap_chan, kref);
457
Jaganath Kanakkassery4af66c62012-07-13 18:17:55 +0530458 BT_DBG("chan %p", chan);
459
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200460 write_lock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300461 list_del(&chan->global_l);
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200462 write_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300463
Jaganath Kanakkassery4af66c62012-07-13 18:17:55 +0530464 kfree(chan);
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300465}
466
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530467void l2cap_chan_hold(struct l2cap_chan *c)
468{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530469 BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->kref.refcount));
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530470
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530471 kref_get(&c->kref);
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530472}
473
474void l2cap_chan_put(struct l2cap_chan *c)
475{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530476 BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->kref.refcount));
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530477
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530478 kref_put(&c->kref, l2cap_chan_destroy);
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530479}
480
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +0300481void l2cap_chan_set_defaults(struct l2cap_chan *chan)
482{
483 chan->fcs = L2CAP_FCS_CRC16;
484 chan->max_tx = L2CAP_DEFAULT_MAX_TX;
485 chan->tx_win = L2CAP_DEFAULT_TX_WINDOW;
486 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
Mat Martineauc20f8e32012-07-10 05:47:07 -0700487 chan->ack_win = L2CAP_DEFAULT_TX_WINDOW;
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +0300488 chan->sec_level = BT_SECURITY_LOW;
489
490 set_bit(FLAG_FORCE_ACTIVE, &chan->flags);
491}
492
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +0300493void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Marcel Holtmann01394182006-07-03 10:02:46 +0200494{
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300495 BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
Andrei Emeltchenko097db762012-03-09 14:16:17 +0200496 __le16_to_cpu(chan->psm), chan->dcid);
Marcel Holtmann01394182006-07-03 10:02:46 +0200497
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +0200498 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +0100499
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300500 chan->conn = conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200501
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200502 switch (chan->chan_type) {
503 case L2CAP_CHAN_CONN_ORIENTED:
Ville Tervob62f3282011-02-10 22:38:50 -0300504 if (conn->hcon->type == LE_LINK) {
505 /* LE connection */
Andre Guedes6fcb06a2012-05-31 17:01:33 -0300506 chan->omtu = L2CAP_DEFAULT_MTU;
Johan Hedberg9f22398c2013-04-29 19:35:38 +0300507 if (chan->dcid == L2CAP_CID_ATT)
508 chan->scid = L2CAP_CID_ATT;
509 else
510 chan->scid = l2cap_alloc_cid(conn);
Ville Tervob62f3282011-02-10 22:38:50 -0300511 } else {
512 /* Alloc CID for connection-oriented socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300513 chan->scid = l2cap_alloc_cid(conn);
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300514 chan->omtu = L2CAP_DEFAULT_MTU;
Ville Tervob62f3282011-02-10 22:38:50 -0300515 }
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200516 break;
517
518 case L2CAP_CHAN_CONN_LESS:
Marcel Holtmann01394182006-07-03 10:02:46 +0200519 /* Connectionless socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300520 chan->scid = L2CAP_CID_CONN_LESS;
521 chan->dcid = L2CAP_CID_CONN_LESS;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300522 chan->omtu = L2CAP_DEFAULT_MTU;
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200523 break;
524
Andrei Emeltchenko416fa752012-05-29 13:59:16 +0300525 case L2CAP_CHAN_CONN_FIX_A2MP:
526 chan->scid = L2CAP_CID_A2MP;
527 chan->dcid = L2CAP_CID_A2MP;
528 chan->omtu = L2CAP_A2MP_DEFAULT_MTU;
529 chan->imtu = L2CAP_A2MP_DEFAULT_MTU;
530 break;
531
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200532 default:
Marcel Holtmann01394182006-07-03 10:02:46 +0200533 /* Raw socket can send/recv signalling messages only */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300534 chan->scid = L2CAP_CID_SIGNALING;
535 chan->dcid = L2CAP_CID_SIGNALING;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300536 chan->omtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann01394182006-07-03 10:02:46 +0200537 }
538
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300539 chan->local_id = L2CAP_BESTEFFORT_ID;
540 chan->local_stype = L2CAP_SERV_BESTEFFORT;
541 chan->local_msdu = L2CAP_DEFAULT_MAX_SDU_SIZE;
542 chan->local_sdu_itime = L2CAP_DEFAULT_SDU_ITIME;
543 chan->local_acc_lat = L2CAP_DEFAULT_ACC_LAT;
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +0300544 chan->local_flush_to = L2CAP_EFS_DEFAULT_FLUSH_TO;
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300545
Ulisses Furquim371fd832011-12-21 20:02:36 -0200546 l2cap_chan_hold(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300547
Johan Hedberg5ee98912013-04-29 19:35:43 +0300548 hci_conn_hold(conn->hcon);
549
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200550 list_add(&chan->list, &conn->chan_l);
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200551}
552
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300553void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200554{
555 mutex_lock(&conn->chan_lock);
556 __l2cap_chan_add(conn, chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200557 mutex_unlock(&conn->chan_lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200558}
559
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300560void l2cap_chan_del(struct l2cap_chan *chan, int err)
Marcel Holtmann01394182006-07-03 10:02:46 +0200561{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300562 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200563
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300564 __clear_chan_timer(chan);
Marcel Holtmann01394182006-07-03 10:02:46 +0200565
Gustavo F. Padovan49208c92011-04-04 15:59:54 -0300566 BT_DBG("chan %p, conn %p, err %d", chan, conn, err);
Marcel Holtmann01394182006-07-03 10:02:46 +0200567
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900568 if (conn) {
Andrei Emeltchenko56f60982012-10-15 11:58:44 +0300569 struct amp_mgr *mgr = conn->hcon->amp_mgr;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300570 /* Delete from channel list */
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200571 list_del(&chan->list);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -0200572
Ulisses Furquim371fd832011-12-21 20:02:36 -0200573 l2cap_chan_put(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300574
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300575 chan->conn = NULL;
Andrei Emeltchenko3cabbfd2012-05-31 11:01:37 +0300576
577 if (chan->chan_type != L2CAP_CHAN_CONN_FIX_A2MP)
David Herrmann76a68ba2013-04-06 20:28:37 +0200578 hci_conn_drop(conn->hcon);
Andrei Emeltchenko56f60982012-10-15 11:58:44 +0300579
580 if (mgr && mgr->bredr_chan == chan)
581 mgr->bredr_chan = NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200582 }
583
Andrei Emeltchenko419e08c2012-10-31 15:46:34 +0200584 if (chan->hs_hchan) {
585 struct hci_chan *hs_hchan = chan->hs_hchan;
586
587 BT_DBG("chan %p disconnect hs_hchan %p", chan, hs_hchan);
588 amp_disconnect_logical_link(hs_hchan);
589 }
590
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100591 chan->ops->teardown(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200592
Mat Martineau28270112012-05-17 21:14:09 -0700593 if (test_bit(CONF_NOT_COMPLETE, &chan->conf_state))
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300594 return;
Gustavo F. Padovan2ead70b2011-04-01 15:13:36 -0300595
Gustavo Padovanee556f62012-05-18 20:22:38 -0300596 switch(chan->mode) {
597 case L2CAP_MODE_BASIC:
598 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300599
Gustavo Padovanee556f62012-05-18 20:22:38 -0300600 case L2CAP_MODE_ERTM:
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -0300601 __clear_retrans_timer(chan);
602 __clear_monitor_timer(chan);
603 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300604
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -0300605 skb_queue_purge(&chan->srej_q);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300606
Mat Martineau3c588192012-04-11 10:48:42 -0700607 l2cap_seq_list_free(&chan->srej_list);
608 l2cap_seq_list_free(&chan->retrans_list);
Gustavo Padovanee556f62012-05-18 20:22:38 -0300609
610 /* fall through */
611
612 case L2CAP_MODE_STREAMING:
613 skb_queue_purge(&chan->tx_q);
614 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300615 }
Gustavo Padovanee556f62012-05-18 20:22:38 -0300616
617 return;
Marcel Holtmann01394182006-07-03 10:02:46 +0200618}
619
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300620void l2cap_chan_close(struct l2cap_chan *chan, int reason)
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300621{
622 struct l2cap_conn *conn = chan->conn;
623 struct sock *sk = chan->sk;
624
Gustavo Padovan2d792812012-10-06 10:07:01 +0100625 BT_DBG("chan %p state %s sk %p", chan, state_to_string(chan->state),
626 sk);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300627
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300628 switch (chan->state) {
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300629 case BT_LISTEN:
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100630 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300631 break;
632
633 case BT_CONNECTED:
634 case BT_CONFIG:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300635 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100636 conn->hcon->type == ACL_LINK) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300637 __set_chan_timer(chan, sk->sk_sndtimeo);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +0200638 l2cap_send_disconn_req(chan, reason);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300639 } else
640 l2cap_chan_del(chan, reason);
641 break;
642
643 case BT_CONNECT2:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300644 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100645 conn->hcon->type == ACL_LINK) {
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300646 struct l2cap_conn_rsp rsp;
647 __u16 result;
648
Gustavo Padovanc5daa682012-05-16 12:17:10 -0300649 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags))
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300650 result = L2CAP_CR_SEC_BLOCK;
651 else
652 result = L2CAP_CR_BAD_PSM;
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300653 l2cap_state_change(chan, BT_DISCONN);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300654
655 rsp.scid = cpu_to_le16(chan->dcid);
656 rsp.dcid = cpu_to_le16(chan->scid);
657 rsp.result = cpu_to_le16(result);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +0300658 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300659 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100660 sizeof(rsp), &rsp);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300661 }
662
663 l2cap_chan_del(chan, reason);
664 break;
665
666 case BT_CONNECT:
667 case BT_DISCONN:
668 l2cap_chan_del(chan, reason);
669 break;
670
671 default:
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100672 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300673 break;
674 }
675}
676
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300677static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530678{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300679 if (chan->chan_type == L2CAP_CHAN_RAW) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300680 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530681 case BT_SECURITY_HIGH:
682 return HCI_AT_DEDICATED_BONDING_MITM;
683 case BT_SECURITY_MEDIUM:
684 return HCI_AT_DEDICATED_BONDING;
685 default:
686 return HCI_AT_NO_BONDING;
687 }
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +0300688 } else if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_SDP)) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300689 if (chan->sec_level == BT_SECURITY_LOW)
690 chan->sec_level = BT_SECURITY_SDP;
Johan Hedberg8556edd32011-01-19 12:06:50 +0530691
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300692 if (chan->sec_level == BT_SECURITY_HIGH)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530693 return HCI_AT_NO_BONDING_MITM;
694 else
695 return HCI_AT_NO_BONDING;
696 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300697 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530698 case BT_SECURITY_HIGH:
699 return HCI_AT_GENERAL_BONDING_MITM;
700 case BT_SECURITY_MEDIUM:
701 return HCI_AT_GENERAL_BONDING;
702 default:
703 return HCI_AT_NO_BONDING;
704 }
705 }
706}
707
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200708/* Service level security */
Gustavo F. Padovand45fc422011-11-05 19:54:24 -0200709int l2cap_chan_check_security(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200710{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300711 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100712 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200713
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300714 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100715
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300716 return hci_conn_security(conn->hcon, chan->sec_level, auth_type);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200717}
718
Johannes Bergb5ad8b72011-06-01 08:54:45 +0200719static u8 l2cap_get_ident(struct l2cap_conn *conn)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200720{
721 u8 id;
722
723 /* Get next available identificator.
724 * 1 - 128 are used by kernel.
725 * 129 - 199 are reserved.
726 * 200 - 254 are used by utilities like l2ping, etc.
727 */
728
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200729 spin_lock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200730
731 if (++conn->tx_ident > 128)
732 conn->tx_ident = 1;
733
734 id = conn->tx_ident;
735
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200736 spin_unlock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200737
738 return id;
739}
740
Gustavo Padovan2d792812012-10-06 10:07:01 +0100741static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
742 void *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200743{
744 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200745 u8 flags;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200746
747 BT_DBG("code 0x%2.2x", code);
748
749 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300750 return;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200751
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200752 if (lmp_no_flush_capable(conn->hcon->hdev))
753 flags = ACL_START_NO_FLUSH;
754 else
755 flags = ACL_START;
756
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700757 bt_cb(skb)->force_active = BT_POWER_FORCE_ACTIVE_ON;
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +0200758 skb->priority = HCI_PRIO_MAX;
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700759
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200760 hci_send_acl(conn->hchan, skb, flags);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200761}
762
Mat Martineau02b0fbb2012-10-23 15:24:10 -0700763static bool __chan_is_moving(struct l2cap_chan *chan)
764{
765 return chan->move_state != L2CAP_MOVE_STABLE &&
766 chan->move_state != L2CAP_MOVE_WAIT_PREPARE;
767}
768
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200769static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb)
770{
771 struct hci_conn *hcon = chan->conn->hcon;
772 u16 flags;
773
774 BT_DBG("chan %p, skb %p len %d priority %u", chan, skb, skb->len,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100775 skb->priority);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200776
Mat Martineaud5f8a752012-10-23 15:24:18 -0700777 if (chan->hs_hcon && !__chan_is_moving(chan)) {
778 if (chan->hs_hchan)
779 hci_send_acl(chan->hs_hchan, skb, ACL_COMPLETE);
780 else
781 kfree_skb(skb);
782
783 return;
784 }
785
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200786 if (!test_bit(FLAG_FLUSHABLE, &chan->flags) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100787 lmp_no_flush_capable(hcon->hdev))
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200788 flags = ACL_START_NO_FLUSH;
789 else
790 flags = ACL_START;
791
792 bt_cb(skb)->force_active = test_bit(FLAG_FORCE_ACTIVE, &chan->flags);
793 hci_send_acl(chan->conn->hchan, skb, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700794}
795
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700796static void __unpack_enhanced_control(u16 enh, struct l2cap_ctrl *control)
797{
798 control->reqseq = (enh & L2CAP_CTRL_REQSEQ) >> L2CAP_CTRL_REQSEQ_SHIFT;
799 control->final = (enh & L2CAP_CTRL_FINAL) >> L2CAP_CTRL_FINAL_SHIFT;
800
801 if (enh & L2CAP_CTRL_FRAME_TYPE) {
802 /* S-Frame */
803 control->sframe = 1;
804 control->poll = (enh & L2CAP_CTRL_POLL) >> L2CAP_CTRL_POLL_SHIFT;
805 control->super = (enh & L2CAP_CTRL_SUPERVISE) >> L2CAP_CTRL_SUPER_SHIFT;
806
807 control->sar = 0;
808 control->txseq = 0;
809 } else {
810 /* I-Frame */
811 control->sframe = 0;
812 control->sar = (enh & L2CAP_CTRL_SAR) >> L2CAP_CTRL_SAR_SHIFT;
813 control->txseq = (enh & L2CAP_CTRL_TXSEQ) >> L2CAP_CTRL_TXSEQ_SHIFT;
814
815 control->poll = 0;
816 control->super = 0;
817 }
818}
819
820static void __unpack_extended_control(u32 ext, struct l2cap_ctrl *control)
821{
822 control->reqseq = (ext & L2CAP_EXT_CTRL_REQSEQ) >> L2CAP_EXT_CTRL_REQSEQ_SHIFT;
823 control->final = (ext & L2CAP_EXT_CTRL_FINAL) >> L2CAP_EXT_CTRL_FINAL_SHIFT;
824
825 if (ext & L2CAP_EXT_CTRL_FRAME_TYPE) {
826 /* S-Frame */
827 control->sframe = 1;
828 control->poll = (ext & L2CAP_EXT_CTRL_POLL) >> L2CAP_EXT_CTRL_POLL_SHIFT;
829 control->super = (ext & L2CAP_EXT_CTRL_SUPERVISE) >> L2CAP_EXT_CTRL_SUPER_SHIFT;
830
831 control->sar = 0;
832 control->txseq = 0;
833 } else {
834 /* I-Frame */
835 control->sframe = 0;
836 control->sar = (ext & L2CAP_EXT_CTRL_SAR) >> L2CAP_EXT_CTRL_SAR_SHIFT;
837 control->txseq = (ext & L2CAP_EXT_CTRL_TXSEQ) >> L2CAP_EXT_CTRL_TXSEQ_SHIFT;
838
839 control->poll = 0;
840 control->super = 0;
841 }
842}
843
844static inline void __unpack_control(struct l2cap_chan *chan,
845 struct sk_buff *skb)
846{
847 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
848 __unpack_extended_control(get_unaligned_le32(skb->data),
849 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700850 skb_pull(skb, L2CAP_EXT_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700851 } else {
852 __unpack_enhanced_control(get_unaligned_le16(skb->data),
853 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700854 skb_pull(skb, L2CAP_ENH_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700855 }
856}
857
858static u32 __pack_extended_control(struct l2cap_ctrl *control)
859{
860 u32 packed;
861
862 packed = control->reqseq << L2CAP_EXT_CTRL_REQSEQ_SHIFT;
863 packed |= control->final << L2CAP_EXT_CTRL_FINAL_SHIFT;
864
865 if (control->sframe) {
866 packed |= control->poll << L2CAP_EXT_CTRL_POLL_SHIFT;
867 packed |= control->super << L2CAP_EXT_CTRL_SUPER_SHIFT;
868 packed |= L2CAP_EXT_CTRL_FRAME_TYPE;
869 } else {
870 packed |= control->sar << L2CAP_EXT_CTRL_SAR_SHIFT;
871 packed |= control->txseq << L2CAP_EXT_CTRL_TXSEQ_SHIFT;
872 }
873
874 return packed;
875}
876
877static u16 __pack_enhanced_control(struct l2cap_ctrl *control)
878{
879 u16 packed;
880
881 packed = control->reqseq << L2CAP_CTRL_REQSEQ_SHIFT;
882 packed |= control->final << L2CAP_CTRL_FINAL_SHIFT;
883
884 if (control->sframe) {
885 packed |= control->poll << L2CAP_CTRL_POLL_SHIFT;
886 packed |= control->super << L2CAP_CTRL_SUPER_SHIFT;
887 packed |= L2CAP_CTRL_FRAME_TYPE;
888 } else {
889 packed |= control->sar << L2CAP_CTRL_SAR_SHIFT;
890 packed |= control->txseq << L2CAP_CTRL_TXSEQ_SHIFT;
891 }
892
893 return packed;
894}
895
896static inline void __pack_control(struct l2cap_chan *chan,
897 struct l2cap_ctrl *control,
898 struct sk_buff *skb)
899{
900 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
901 put_unaligned_le32(__pack_extended_control(control),
902 skb->data + L2CAP_HDR_SIZE);
903 } else {
904 put_unaligned_le16(__pack_enhanced_control(control),
905 skb->data + L2CAP_HDR_SIZE);
906 }
907}
908
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300909static inline unsigned int __ertm_hdr_size(struct l2cap_chan *chan)
910{
911 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
912 return L2CAP_EXT_HDR_SIZE;
913 else
914 return L2CAP_ENH_HDR_SIZE;
915}
916
Mat Martineaua67d7f62012-05-17 20:53:35 -0700917static struct sk_buff *l2cap_create_sframe_pdu(struct l2cap_chan *chan,
918 u32 control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300919{
920 struct sk_buff *skb;
921 struct l2cap_hdr *lh;
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300922 int hlen = __ertm_hdr_size(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300923
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300924 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300925 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300926
Mat Martineaua67d7f62012-05-17 20:53:35 -0700927 skb = bt_skb_alloc(hlen, GFP_KERNEL);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300928
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300929 if (!skb)
Mat Martineaua67d7f62012-05-17 20:53:35 -0700930 return ERR_PTR(-ENOMEM);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300931
932 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300933 lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300934 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +0300935
Mat Martineaua67d7f62012-05-17 20:53:35 -0700936 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
937 put_unaligned_le32(control, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
938 else
939 put_unaligned_le16(control, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300940
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -0300941 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineaua67d7f62012-05-17 20:53:35 -0700942 u16 fcs = crc16(0, (u8 *)skb->data, skb->len);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300943 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300944 }
945
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200946 skb->priority = HCI_PRIO_MAX;
Mat Martineaua67d7f62012-05-17 20:53:35 -0700947 return skb;
948}
949
950static void l2cap_send_sframe(struct l2cap_chan *chan,
951 struct l2cap_ctrl *control)
952{
953 struct sk_buff *skb;
954 u32 control_field;
955
956 BT_DBG("chan %p, control %p", chan, control);
957
958 if (!control->sframe)
959 return;
960
Mat Martineaub99e13a2012-10-23 15:24:19 -0700961 if (__chan_is_moving(chan))
962 return;
963
Mat Martineaua67d7f62012-05-17 20:53:35 -0700964 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state) &&
965 !control->poll)
966 control->final = 1;
967
968 if (control->super == L2CAP_SUPER_RR)
969 clear_bit(CONN_RNR_SENT, &chan->conn_state);
970 else if (control->super == L2CAP_SUPER_RNR)
971 set_bit(CONN_RNR_SENT, &chan->conn_state);
972
973 if (control->super != L2CAP_SUPER_SREJ) {
974 chan->last_acked_seq = control->reqseq;
975 __clear_ack_timer(chan);
976 }
977
978 BT_DBG("reqseq %d, final %d, poll %d, super %d", control->reqseq,
979 control->final, control->poll, control->super);
980
981 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
982 control_field = __pack_extended_control(control);
983 else
984 control_field = __pack_enhanced_control(control);
985
986 skb = l2cap_create_sframe_pdu(chan, control_field);
987 if (!IS_ERR(skb))
988 l2cap_do_send(chan, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300989}
990
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700991static void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, bool poll)
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300992{
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700993 struct l2cap_ctrl control;
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300994
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700995 BT_DBG("chan %p, poll %d", chan, poll);
996
997 memset(&control, 0, sizeof(control));
998 control.sframe = 1;
999 control.poll = poll;
1000
1001 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
1002 control.super = L2CAP_SUPER_RNR;
1003 else
1004 control.super = L2CAP_SUPER_RR;
1005
1006 control.reqseq = chan->buffer_seq;
1007 l2cap_send_sframe(chan, &control);
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001008}
1009
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03001010static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan)
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03001011{
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001012 return !test_bit(CONF_CONNECT_PEND, &chan->conf_state);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03001013}
1014
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001015static bool __amp_capable(struct l2cap_chan *chan)
1016{
1017 struct l2cap_conn *conn = chan->conn;
1018
1019 if (enable_hs &&
Andrei Emeltchenko5d054162012-11-29 17:46:05 +02001020 hci_amp_capable() &&
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001021 chan->chan_policy == BT_CHANNEL_POLICY_AMP_PREFERRED &&
1022 conn->fixed_chan_mask & L2CAP_FC_A2MP)
1023 return true;
1024 else
1025 return false;
1026}
1027
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +02001028static bool l2cap_check_efs(struct l2cap_chan *chan)
1029{
1030 /* Check EFS parameters */
1031 return true;
1032}
1033
Andrei Emeltchenko2766be42012-09-27 17:26:21 +03001034void l2cap_send_conn_req(struct l2cap_chan *chan)
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +02001035{
1036 struct l2cap_conn *conn = chan->conn;
1037 struct l2cap_conn_req req;
1038
1039 req.scid = cpu_to_le16(chan->scid);
1040 req.psm = chan->psm;
1041
1042 chan->ident = l2cap_get_ident(conn);
1043
1044 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
1045
1046 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, sizeof(req), &req);
1047}
1048
Mat Martineau8eb200b2012-10-23 15:24:17 -07001049static void l2cap_send_create_chan_req(struct l2cap_chan *chan, u8 amp_id)
1050{
1051 struct l2cap_create_chan_req req;
1052 req.scid = cpu_to_le16(chan->scid);
1053 req.psm = chan->psm;
1054 req.amp_id = amp_id;
1055
1056 chan->ident = l2cap_get_ident(chan->conn);
1057
1058 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_REQ,
1059 sizeof(req), &req);
1060}
1061
Mat Martineau02b0fbb2012-10-23 15:24:10 -07001062static void l2cap_move_setup(struct l2cap_chan *chan)
1063{
1064 struct sk_buff *skb;
1065
1066 BT_DBG("chan %p", chan);
1067
1068 if (chan->mode != L2CAP_MODE_ERTM)
1069 return;
1070
1071 __clear_retrans_timer(chan);
1072 __clear_monitor_timer(chan);
1073 __clear_ack_timer(chan);
1074
1075 chan->retry_count = 0;
1076 skb_queue_walk(&chan->tx_q, skb) {
1077 if (bt_cb(skb)->control.retries)
1078 bt_cb(skb)->control.retries = 1;
1079 else
1080 break;
1081 }
1082
1083 chan->expected_tx_seq = chan->buffer_seq;
1084
1085 clear_bit(CONN_REJ_ACT, &chan->conn_state);
1086 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
1087 l2cap_seq_list_clear(&chan->retrans_list);
1088 l2cap_seq_list_clear(&chan->srej_list);
1089 skb_queue_purge(&chan->srej_q);
1090
1091 chan->tx_state = L2CAP_TX_STATE_XMIT;
1092 chan->rx_state = L2CAP_RX_STATE_MOVE;
1093
1094 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
1095}
1096
Mat Martineau5f3847a2012-10-23 15:24:12 -07001097static void l2cap_move_done(struct l2cap_chan *chan)
1098{
1099 u8 move_role = chan->move_role;
1100 BT_DBG("chan %p", chan);
1101
1102 chan->move_state = L2CAP_MOVE_STABLE;
1103 chan->move_role = L2CAP_MOVE_ROLE_NONE;
1104
1105 if (chan->mode != L2CAP_MODE_ERTM)
1106 return;
1107
1108 switch (move_role) {
1109 case L2CAP_MOVE_ROLE_INITIATOR:
1110 l2cap_tx(chan, NULL, NULL, L2CAP_EV_EXPLICIT_POLL);
1111 chan->rx_state = L2CAP_RX_STATE_WAIT_F;
1112 break;
1113 case L2CAP_MOVE_ROLE_RESPONDER:
1114 chan->rx_state = L2CAP_RX_STATE_WAIT_P;
1115 break;
1116 }
1117}
1118
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001119static void l2cap_chan_ready(struct l2cap_chan *chan)
1120{
Mat Martineau28270112012-05-17 21:14:09 -07001121 /* This clears all conf flags, including CONF_NOT_COMPLETE */
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001122 chan->conf_state = 0;
1123 __clear_chan_timer(chan);
1124
Andrei Emeltchenko54a59aa2012-05-27 22:27:53 -03001125 chan->state = BT_CONNECTED;
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001126
Andrei Emeltchenkofd83e2c2012-05-30 09:55:32 +03001127 chan->ops->ready(chan);
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001128}
1129
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001130static void l2cap_start_connection(struct l2cap_chan *chan)
1131{
1132 if (__amp_capable(chan)) {
1133 BT_DBG("chan %p AMP capable: discover AMPs", chan);
1134 a2mp_discover_amp(chan);
1135 } else {
1136 l2cap_send_conn_req(chan);
1137 }
1138}
1139
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001140static void l2cap_do_start(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001141{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001142 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001143
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001144 if (conn->hcon->type == LE_LINK) {
1145 l2cap_chan_ready(chan);
1146 return;
1147 }
1148
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001149 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01001150 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
1151 return;
1152
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001153 if (l2cap_chan_check_security(chan) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01001154 __l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001155 l2cap_start_connection(chan);
1156 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001157 } else {
1158 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001159 req.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001160
1161 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
1162 conn->info_ident = l2cap_get_ident(conn);
1163
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08001164 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001165
Gustavo Padovan2d792812012-10-06 10:07:01 +01001166 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
1167 sizeof(req), &req);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001168 }
1169}
1170
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001171static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
1172{
1173 u32 local_feat_mask = l2cap_feat_mask;
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03001174 if (!disable_ertm)
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001175 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
1176
1177 switch (mode) {
1178 case L2CAP_MODE_ERTM:
1179 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
1180 case L2CAP_MODE_STREAMING:
1181 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
1182 default:
1183 return 0x00;
1184 }
1185}
1186
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02001187static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err)
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001188{
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001189 struct sock *sk = chan->sk;
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02001190 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001191 struct l2cap_disconn_req req;
1192
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001193 if (!conn)
1194 return;
1195
Andrei Emeltchenkoaad3d0e2012-09-06 15:05:42 +03001196 if (chan->mode == L2CAP_MODE_ERTM && chan->state == BT_CONNECTED) {
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03001197 __clear_retrans_timer(chan);
1198 __clear_monitor_timer(chan);
1199 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001200 }
1201
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001202 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
Gustavo Padovand1177732012-10-06 11:47:38 +01001203 l2cap_state_change(chan, BT_DISCONN);
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001204 return;
1205 }
1206
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001207 req.dcid = cpu_to_le16(chan->dcid);
1208 req.scid = cpu_to_le16(chan->scid);
Gustavo Padovan2d792812012-10-06 10:07:01 +01001209 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_DISCONN_REQ,
1210 sizeof(req), &req);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001211
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001212 lock_sock(sk);
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001213 __l2cap_state_change(chan, BT_DISCONN);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02001214 __l2cap_chan_set_err(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001215 release_sock(sk);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001216}
1217
Linus Torvalds1da177e2005-04-16 15:20:36 -07001218/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001219static void l2cap_conn_start(struct l2cap_conn *conn)
1220{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001221 struct l2cap_chan *chan, *tmp;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001222
1223 BT_DBG("conn %p", conn);
1224
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001225 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001226
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001227 list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001228 struct sock *sk = chan->sk;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001229
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001230 l2cap_chan_lock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001231
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001232 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001233 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001234 continue;
1235 }
1236
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001237 if (chan->state == BT_CONNECT) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001238 if (!l2cap_chan_check_security(chan) ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001239 !__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001240 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001241 continue;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02001242 }
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001243
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001244 if (!l2cap_mode_supported(chan->mode, conn->feat_mask)
Gustavo Padovan2d792812012-10-06 10:07:01 +01001245 && test_bit(CONF_STATE2_DEVICE,
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001246 &chan->conf_state)) {
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001247 l2cap_chan_close(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001248 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001249 continue;
1250 }
1251
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001252 l2cap_start_connection(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001253
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001254 } else if (chan->state == BT_CONNECT2) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001255 struct l2cap_conn_rsp rsp;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001256 char buf[128];
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001257 rsp.scid = cpu_to_le16(chan->dcid);
1258 rsp.dcid = cpu_to_le16(chan->scid);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001259
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001260 if (l2cap_chan_check_security(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001261 lock_sock(sk);
Gustavo Padovanc5daa682012-05-16 12:17:10 -03001262 if (test_bit(BT_SK_DEFER_SETUP,
1263 &bt_sk(sk)->flags)) {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001264 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1265 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08001266 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001267
1268 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001269 __l2cap_state_change(chan, BT_CONFIG);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001270 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
1271 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001272 }
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001273 release_sock(sk);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001274 } else {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001275 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1276 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001277 }
1278
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001279 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001280 sizeof(rsp), &rsp);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001281
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001282 if (test_bit(CONF_REQ_SENT, &chan->conf_state) ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001283 rsp.result != L2CAP_CR_SUCCESS) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001284 l2cap_chan_unlock(chan);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001285 continue;
1286 }
1287
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001288 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001289 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001290 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03001291 chan->num_conf_req++;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001292 }
1293
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001294 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001295 }
1296
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001297 mutex_unlock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001298}
1299
Ido Yarivc2287682012-04-20 15:46:07 -03001300/* Find socket with cid and source/destination bdaddr.
Ville Tervob62f3282011-02-10 22:38:50 -03001301 * Returns closest match, locked.
1302 */
Andrei Emeltchenkod9b88702012-03-12 12:13:08 +02001303static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid,
Ido Yarivc2287682012-04-20 15:46:07 -03001304 bdaddr_t *src,
1305 bdaddr_t *dst)
Ville Tervob62f3282011-02-10 22:38:50 -03001306{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001307 struct l2cap_chan *c, *c1 = NULL;
Ville Tervob62f3282011-02-10 22:38:50 -03001308
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001309 read_lock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001310
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001311 list_for_each_entry(c, &chan_list, global_l) {
1312 struct sock *sk = c->sk;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001313
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001314 if (state && c->state != state)
Ville Tervob62f3282011-02-10 22:38:50 -03001315 continue;
1316
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001317 if (c->scid == cid) {
Ido Yarivc2287682012-04-20 15:46:07 -03001318 int src_match, dst_match;
1319 int src_any, dst_any;
1320
Ville Tervob62f3282011-02-10 22:38:50 -03001321 /* Exact match. */
Ido Yarivc2287682012-04-20 15:46:07 -03001322 src_match = !bacmp(&bt_sk(sk)->src, src);
1323 dst_match = !bacmp(&bt_sk(sk)->dst, dst);
1324 if (src_match && dst_match) {
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001325 read_unlock(&chan_list_lock);
1326 return c;
1327 }
Ville Tervob62f3282011-02-10 22:38:50 -03001328
1329 /* Closest match */
Ido Yarivc2287682012-04-20 15:46:07 -03001330 src_any = !bacmp(&bt_sk(sk)->src, BDADDR_ANY);
1331 dst_any = !bacmp(&bt_sk(sk)->dst, BDADDR_ANY);
1332 if ((src_match && dst_any) || (src_any && dst_match) ||
1333 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001334 c1 = c;
Ville Tervob62f3282011-02-10 22:38:50 -03001335 }
1336 }
Gustavo F. Padovan280f2942011-04-13 19:01:22 -03001337
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001338 read_unlock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001339
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001340 return c1;
Ville Tervob62f3282011-02-10 22:38:50 -03001341}
1342
1343static void l2cap_le_conn_ready(struct l2cap_conn *conn)
1344{
Johan Hedberg60bac1842013-04-29 19:35:41 +03001345 struct sock *parent;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001346 struct l2cap_chan *chan, *pchan;
Ville Tervob62f3282011-02-10 22:38:50 -03001347
1348 BT_DBG("");
1349
1350 /* Check if we have socket listening on cid */
Johan Hedberg073d1cf2013-04-29 19:35:35 +03001351 pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_ATT,
Ido Yarivc2287682012-04-20 15:46:07 -03001352 conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001353 if (!pchan)
Ville Tervob62f3282011-02-10 22:38:50 -03001354 return;
1355
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001356 parent = pchan->sk;
1357
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03001358 lock_sock(parent);
Gustavo F. Padovan62f3a2c2011-04-14 18:34:34 -03001359
Gustavo Padovan80b98022012-05-27 22:27:51 -03001360 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001361 if (!chan)
Ville Tervob62f3282011-02-10 22:38:50 -03001362 goto clean;
1363
Johan Hedberg9f22398c2013-04-29 19:35:38 +03001364 chan->dcid = L2CAP_CID_ATT;
1365
Johan Hedberg60bac1842013-04-29 19:35:41 +03001366 bacpy(&bt_sk(chan->sk)->src, conn->src);
1367 bacpy(&bt_sk(chan->sk)->dst, conn->dst);
Ville Tervob62f3282011-02-10 22:38:50 -03001368
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02001369 l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001370
Ville Tervob62f3282011-02-10 22:38:50 -03001371clean:
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03001372 release_sock(parent);
Ville Tervob62f3282011-02-10 22:38:50 -03001373}
1374
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001375static void l2cap_conn_ready(struct l2cap_conn *conn)
1376{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001377 struct l2cap_chan *chan;
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001378 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001379
1380 BT_DBG("conn %p", conn);
1381
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001382 if (!hcon->out && hcon->type == LE_LINK)
Ville Tervob62f3282011-02-10 22:38:50 -03001383 l2cap_le_conn_ready(conn);
1384
Johan Hedbergd8729922013-04-29 19:35:39 +03001385 /* For outgoing pairing which doesn't necessarily have an
1386 * associated socket (e.g. mgmt_pair_device).
1387 */
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001388 if (hcon->out && hcon->type == LE_LINK)
1389 smp_conn_security(hcon, hcon->pending_sec_level);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03001390
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001391 mutex_lock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001392
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001393 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001394
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001395 l2cap_chan_lock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001396
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001397 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
1398 l2cap_chan_unlock(chan);
1399 continue;
1400 }
1401
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001402 if (hcon->type == LE_LINK) {
1403 if (smp_conn_security(hcon, chan->sec_level))
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02001404 l2cap_chan_ready(chan);
Ville Tervoacd7d372011-02-10 22:38:49 -03001405
Vinicius Costa Gomes63128452011-06-17 22:46:26 -03001406 } else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001407 struct sock *sk = chan->sk;
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001408 __clear_chan_timer(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001409 lock_sock(sk);
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001410 __l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001411 sk->sk_state_change(sk);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001412 release_sock(sk);
Anderson Brigliab501d6a2011-06-07 18:46:31 -03001413
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001414 } else if (chan->state == BT_CONNECT)
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001415 l2cap_do_start(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001416
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001417 l2cap_chan_unlock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001418 }
1419
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001420 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001421}
1422
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001423/* Notify sockets that we cannot guaranty reliability anymore */
1424static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
1425{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001426 struct l2cap_chan *chan;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001427
1428 BT_DBG("conn %p", conn);
1429
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001430 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001431
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001432 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenkoecf61bd2011-10-11 14:04:32 +03001433 if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags))
Gustavo Padovan1d8b1fd2012-10-06 11:34:52 +01001434 l2cap_chan_set_err(chan, err);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001435 }
1436
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001437 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001438}
1439
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001440static void l2cap_info_timeout(struct work_struct *work)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001441{
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001442 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001443 info_timer.work);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001444
Marcel Holtmann984947d2009-02-06 23:35:19 +01001445 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01001446 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01001447
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001448 l2cap_conn_start(conn);
1449}
1450
David Herrmann2c8e1412013-04-06 20:28:45 +02001451/*
1452 * l2cap_user
1453 * External modules can register l2cap_user objects on l2cap_conn. The ->probe
1454 * callback is called during registration. The ->remove callback is called
1455 * during unregistration.
1456 * An l2cap_user object can either be explicitly unregistered or when the
1457 * underlying l2cap_conn object is deleted. This guarantees that l2cap->hcon,
1458 * l2cap->hchan, .. are valid as long as the remove callback hasn't been called.
1459 * External modules must own a reference to the l2cap_conn object if they intend
1460 * to call l2cap_unregister_user(). The l2cap_conn object might get destroyed at
1461 * any time if they don't.
1462 */
1463
1464int l2cap_register_user(struct l2cap_conn *conn, struct l2cap_user *user)
1465{
1466 struct hci_dev *hdev = conn->hcon->hdev;
1467 int ret;
1468
1469 /* We need to check whether l2cap_conn is registered. If it is not, we
1470 * must not register the l2cap_user. l2cap_conn_del() is unregisters
1471 * l2cap_conn objects, but doesn't provide its own locking. Instead, it
1472 * relies on the parent hci_conn object to be locked. This itself relies
1473 * on the hci_dev object to be locked. So we must lock the hci device
1474 * here, too. */
1475
1476 hci_dev_lock(hdev);
1477
1478 if (user->list.next || user->list.prev) {
1479 ret = -EINVAL;
1480 goto out_unlock;
1481 }
1482
1483 /* conn->hchan is NULL after l2cap_conn_del() was called */
1484 if (!conn->hchan) {
1485 ret = -ENODEV;
1486 goto out_unlock;
1487 }
1488
1489 ret = user->probe(conn, user);
1490 if (ret)
1491 goto out_unlock;
1492
1493 list_add(&user->list, &conn->users);
1494 ret = 0;
1495
1496out_unlock:
1497 hci_dev_unlock(hdev);
1498 return ret;
1499}
1500EXPORT_SYMBOL(l2cap_register_user);
1501
1502void l2cap_unregister_user(struct l2cap_conn *conn, struct l2cap_user *user)
1503{
1504 struct hci_dev *hdev = conn->hcon->hdev;
1505
1506 hci_dev_lock(hdev);
1507
1508 if (!user->list.next || !user->list.prev)
1509 goto out_unlock;
1510
1511 list_del(&user->list);
1512 user->list.next = NULL;
1513 user->list.prev = NULL;
1514 user->remove(conn, user);
1515
1516out_unlock:
1517 hci_dev_unlock(hdev);
1518}
1519EXPORT_SYMBOL(l2cap_unregister_user);
1520
1521static void l2cap_unregister_all_users(struct l2cap_conn *conn)
1522{
1523 struct l2cap_user *user;
1524
1525 while (!list_empty(&conn->users)) {
1526 user = list_first_entry(&conn->users, struct l2cap_user, list);
1527 list_del(&user->list);
1528 user->list.next = NULL;
1529 user->list.prev = NULL;
1530 user->remove(conn, user);
1531 }
1532}
1533
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001534static void l2cap_conn_del(struct hci_conn *hcon, int err)
1535{
1536 struct l2cap_conn *conn = hcon->l2cap_data;
1537 struct l2cap_chan *chan, *l;
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001538
1539 if (!conn)
1540 return;
1541
1542 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
1543
1544 kfree_skb(conn->rx_skb);
1545
David Herrmann2c8e1412013-04-06 20:28:45 +02001546 l2cap_unregister_all_users(conn);
1547
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001548 mutex_lock(&conn->chan_lock);
1549
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001550 /* Kill channels */
1551 list_for_each_entry_safe(chan, l, &conn->chan_l, list) {
Mat Martineau61d6ef32012-04-27 16:50:50 -07001552 l2cap_chan_hold(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001553 l2cap_chan_lock(chan);
1554
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001555 l2cap_chan_del(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001556
1557 l2cap_chan_unlock(chan);
1558
Gustavo Padovan80b98022012-05-27 22:27:51 -03001559 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07001560 l2cap_chan_put(chan);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001561 }
1562
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001563 mutex_unlock(&conn->chan_lock);
1564
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001565 hci_chan_del(conn->hchan);
1566
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001567 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
Ulisses Furquim127074b2012-01-30 18:26:29 -02001568 cancel_delayed_work_sync(&conn->info_timer);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001569
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001570 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) {
Ulisses Furquim127074b2012-01-30 18:26:29 -02001571 cancel_delayed_work_sync(&conn->security_timer);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -03001572 smp_chan_destroy(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001573 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001574
1575 hcon->l2cap_data = NULL;
David Herrmann9c903e32013-04-06 20:28:44 +02001576 conn->hchan = NULL;
1577 l2cap_conn_put(conn);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001578}
1579
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001580static void security_timeout(struct work_struct *work)
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001581{
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001582 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001583 security_timer.work);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001584
Johan Hedbergd06cc412012-06-06 18:44:11 +08001585 BT_DBG("conn %p", conn);
1586
1587 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) {
1588 smp_chan_destroy(conn);
1589 l2cap_conn_del(conn->hcon, ETIMEDOUT);
1590 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001591}
1592
Claudio Takahasibaf43252013-04-11 13:55:50 -03001593static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001594{
Marcel Holtmann01394182006-07-03 10:02:46 +02001595 struct l2cap_conn *conn = hcon->l2cap_data;
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001596 struct hci_chan *hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001597
Claudio Takahasibaf43252013-04-11 13:55:50 -03001598 if (conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001599 return conn;
1600
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001601 hchan = hci_chan_create(hcon);
1602 if (!hchan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001603 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001604
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03001605 conn = kzalloc(sizeof(struct l2cap_conn), GFP_KERNEL);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001606 if (!conn) {
1607 hci_chan_del(hchan);
1608 return NULL;
1609 }
1610
David Herrmann9c903e32013-04-06 20:28:44 +02001611 kref_init(&conn->ref);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001612 hcon->l2cap_data = conn;
1613 conn->hcon = hcon;
David Herrmann9c903e32013-04-06 20:28:44 +02001614 hci_conn_get(conn->hcon);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001615 conn->hchan = hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001616
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001617 BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan);
Marcel Holtmann01394182006-07-03 10:02:46 +02001618
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001619 switch (hcon->type) {
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001620 case LE_LINK:
1621 if (hcon->hdev->le_mtu) {
1622 conn->mtu = hcon->hdev->le_mtu;
1623 break;
1624 }
1625 /* fall through */
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001626 default:
Ville Tervoacd7d372011-02-10 22:38:49 -03001627 conn->mtu = hcon->hdev->acl_mtu;
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001628 break;
1629 }
Ville Tervoacd7d372011-02-10 22:38:49 -03001630
Linus Torvalds1da177e2005-04-16 15:20:36 -07001631 conn->src = &hcon->hdev->bdaddr;
1632 conn->dst = &hcon->dst;
1633
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001634 conn->feat_mask = 0;
1635
Linus Torvalds1da177e2005-04-16 15:20:36 -07001636 spin_lock_init(&conn->lock);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001637 mutex_init(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001638
1639 INIT_LIST_HEAD(&conn->chan_l);
David Herrmann2c8e1412013-04-06 20:28:45 +02001640 INIT_LIST_HEAD(&conn->users);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001641
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001642 if (hcon->type == LE_LINK)
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001643 INIT_DELAYED_WORK(&conn->security_timer, security_timeout);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001644 else
Gustavo F. Padovan030013d2011-12-20 10:57:28 -02001645 INIT_DELAYED_WORK(&conn->info_timer, l2cap_info_timeout);
Dave Young45054dc2009-10-18 20:28:30 +00001646
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001647 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01001648
Linus Torvalds1da177e2005-04-16 15:20:36 -07001649 return conn;
1650}
1651
David Herrmann9c903e32013-04-06 20:28:44 +02001652static void l2cap_conn_free(struct kref *ref)
1653{
1654 struct l2cap_conn *conn = container_of(ref, struct l2cap_conn, ref);
1655
1656 hci_conn_put(conn->hcon);
1657 kfree(conn);
1658}
1659
1660void l2cap_conn_get(struct l2cap_conn *conn)
1661{
1662 kref_get(&conn->ref);
1663}
1664EXPORT_SYMBOL(l2cap_conn_get);
1665
1666void l2cap_conn_put(struct l2cap_conn *conn)
1667{
1668 kref_put(&conn->ref, l2cap_conn_free);
1669}
1670EXPORT_SYMBOL(l2cap_conn_put);
1671
Linus Torvalds1da177e2005-04-16 15:20:36 -07001672/* ---- Socket interface ---- */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001673
Ido Yarivc2287682012-04-20 15:46:07 -03001674/* Find socket with psm and source / destination bdaddr.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001675 * Returns closest match.
1676 */
Ido Yarivc2287682012-04-20 15:46:07 -03001677static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
1678 bdaddr_t *src,
1679 bdaddr_t *dst)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001680{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001681 struct l2cap_chan *c, *c1 = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001682
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001683 read_lock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001684
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001685 list_for_each_entry(c, &chan_list, global_l) {
1686 struct sock *sk = c->sk;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001687
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001688 if (state && c->state != state)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001689 continue;
1690
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001691 if (c->psm == psm) {
Ido Yarivc2287682012-04-20 15:46:07 -03001692 int src_match, dst_match;
1693 int src_any, dst_any;
1694
Linus Torvalds1da177e2005-04-16 15:20:36 -07001695 /* Exact match. */
Ido Yarivc2287682012-04-20 15:46:07 -03001696 src_match = !bacmp(&bt_sk(sk)->src, src);
1697 dst_match = !bacmp(&bt_sk(sk)->dst, dst);
1698 if (src_match && dst_match) {
Johannes Berga7567b22011-06-01 08:29:54 +02001699 read_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001700 return c;
1701 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001702
1703 /* Closest match */
Ido Yarivc2287682012-04-20 15:46:07 -03001704 src_any = !bacmp(&bt_sk(sk)->src, BDADDR_ANY);
1705 dst_any = !bacmp(&bt_sk(sk)->dst, BDADDR_ANY);
1706 if ((src_match && dst_any) || (src_any && dst_match) ||
1707 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001708 c1 = c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001709 }
1710 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001711
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001712 read_unlock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001713
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001714 return c1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001715}
1716
Andre Guedes8e9f9892012-04-24 21:02:55 -03001717int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
1718 bdaddr_t *dst, u8 dst_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001719{
Gustavo F. Padovan5d41ce12011-04-08 15:40:02 -03001720 struct sock *sk = chan->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001721 bdaddr_t *src = &bt_sk(sk)->src;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001722 struct l2cap_conn *conn;
1723 struct hci_conn *hcon;
1724 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001725 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +02001726 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001727
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001728 BT_DBG("%pMR -> %pMR (type %u) psm 0x%2.2x", src, dst,
Syam Sidhardhanab195162012-07-27 23:51:22 +05301729 dst_type, __le16_to_cpu(psm));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001730
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001731 hdev = hci_get_route(dst, src);
1732 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001733 return -EHOSTUNREACH;
1734
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001735 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001736
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001737 l2cap_chan_lock(chan);
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001738
1739 /* PSM must be odd and lsb of upper byte must be 0 */
1740 if ((__le16_to_cpu(psm) & 0x0101) != 0x0001 && !cid &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01001741 chan->chan_type != L2CAP_CHAN_RAW) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001742 err = -EINVAL;
1743 goto done;
1744 }
1745
1746 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && !(psm || cid)) {
1747 err = -EINVAL;
1748 goto done;
1749 }
1750
1751 switch (chan->mode) {
1752 case L2CAP_MODE_BASIC:
1753 break;
1754 case L2CAP_MODE_ERTM:
1755 case L2CAP_MODE_STREAMING:
1756 if (!disable_ertm)
1757 break;
1758 /* fall through */
1759 default:
1760 err = -ENOTSUPP;
1761 goto done;
1762 }
1763
Gustavo Padovan0797e012012-05-27 22:27:54 -03001764 switch (chan->state) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001765 case BT_CONNECT:
1766 case BT_CONNECT2:
1767 case BT_CONFIG:
1768 /* Already connecting */
1769 err = 0;
1770 goto done;
1771
1772 case BT_CONNECTED:
1773 /* Already connected */
1774 err = -EISCONN;
1775 goto done;
1776
1777 case BT_OPEN:
1778 case BT_BOUND:
1779 /* Can connect */
1780 break;
1781
1782 default:
1783 err = -EBADFD;
1784 goto done;
1785 }
1786
1787 /* Set destination address and psm */
Gustavo Padovan0797e012012-05-27 22:27:54 -03001788 lock_sock(sk);
Gustavo F. Padovan9219b2a2012-01-02 20:08:04 -02001789 bacpy(&bt_sk(sk)->dst, dst);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001790 release_sock(sk);
1791
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001792 chan->psm = psm;
1793 chan->dcid = cid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001794
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001795 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001796
Johan Hedbergf224ca52013-04-29 19:35:36 +03001797 if (bdaddr_type_is_le(dst_type))
Andre Guedes8e9f9892012-04-24 21:02:55 -03001798 hcon = hci_connect(hdev, LE_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001799 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001800 else
Andre Guedes8e9f9892012-04-24 21:02:55 -03001801 hcon = hci_connect(hdev, ACL_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001802 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001803
Ville Tervo30e76272011-02-22 16:10:53 -03001804 if (IS_ERR(hcon)) {
1805 err = PTR_ERR(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001806 goto done;
Ville Tervo30e76272011-02-22 16:10:53 -03001807 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001808
Claudio Takahasibaf43252013-04-11 13:55:50 -03001809 conn = l2cap_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001810 if (!conn) {
David Herrmann76a68ba2013-04-06 20:28:37 +02001811 hci_conn_drop(hcon);
Ville Tervo30e76272011-02-22 16:10:53 -03001812 err = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001813 goto done;
1814 }
1815
Johan Hedberg141d5702013-04-29 19:35:37 +03001816 if (cid && __l2cap_get_chan_by_dcid(conn, cid)) {
1817 hci_conn_drop(hcon);
1818 err = -EBUSY;
1819 goto done;
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001820 }
1821
Linus Torvalds1da177e2005-04-16 15:20:36 -07001822 /* Update source addr of the socket */
1823 bacpy(src, conn->src);
1824
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001825 l2cap_chan_unlock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001826 l2cap_chan_add(conn, chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001827 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001828
Johan Hedberg5ee98912013-04-29 19:35:43 +03001829 /* l2cap_chan_add takes its own ref so we can drop this one */
1830 hci_conn_drop(hcon);
1831
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001832 l2cap_state_change(chan, BT_CONNECT);
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001833 __set_chan_timer(chan, sk->sk_sndtimeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001834
1835 if (hcon->state == BT_CONNECTED) {
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001836 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001837 __clear_chan_timer(chan);
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001838 if (l2cap_chan_check_security(chan))
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001839 l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001840 } else
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001841 l2cap_do_start(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001842 }
1843
Ville Tervo30e76272011-02-22 16:10:53 -03001844 err = 0;
1845
Linus Torvalds1da177e2005-04-16 15:20:36 -07001846done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001847 l2cap_chan_unlock(chan);
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001848 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001849 hci_dev_put(hdev);
1850 return err;
1851}
1852
Gustavo F. Padovandcba0db2011-02-04 03:08:36 -02001853int __l2cap_wait_ack(struct sock *sk)
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001854{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001855 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001856 DECLARE_WAITQUEUE(wait, current);
1857 int err = 0;
1858 int timeo = HZ/5;
1859
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001860 add_wait_queue(sk_sleep(sk), &wait);
Peter Hurleya71a0cf2011-07-25 18:36:26 -04001861 set_current_state(TASK_INTERRUPTIBLE);
1862 while (chan->unacked_frames > 0 && chan->conn) {
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001863 if (!timeo)
1864 timeo = HZ/5;
1865
1866 if (signal_pending(current)) {
1867 err = sock_intr_errno(timeo);
1868 break;
1869 }
1870
1871 release_sock(sk);
1872 timeo = schedule_timeout(timeo);
1873 lock_sock(sk);
Peter Hurleya71a0cf2011-07-25 18:36:26 -04001874 set_current_state(TASK_INTERRUPTIBLE);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001875
1876 err = sock_error(sk);
1877 if (err)
1878 break;
1879 }
1880 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001881 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001882 return err;
1883}
1884
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001885static void l2cap_monitor_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001886{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001887 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001888 monitor_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001889
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03001890 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001891
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001892 l2cap_chan_lock(chan);
1893
Mat Martineau80909e02012-05-17 20:53:50 -07001894 if (!chan->conn) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001895 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001896 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001897 return;
1898 }
1899
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001900 l2cap_tx(chan, NULL, NULL, L2CAP_EV_MONITOR_TO);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001901
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001902 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001903 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001904}
1905
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001906static void l2cap_retrans_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001907{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001908 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001909 retrans_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001910
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03001911 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001912
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001913 l2cap_chan_lock(chan);
1914
Mat Martineau80909e02012-05-17 20:53:50 -07001915 if (!chan->conn) {
1916 l2cap_chan_unlock(chan);
1917 l2cap_chan_put(chan);
1918 return;
1919 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001920
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001921 l2cap_tx(chan, NULL, NULL, L2CAP_EV_RETRANS_TO);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001922 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001923 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001924}
1925
Gustavo Padovand6603662012-05-21 13:58:22 -03001926static void l2cap_streaming_send(struct l2cap_chan *chan,
1927 struct sk_buff_head *skbs)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001928{
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001929 struct sk_buff *skb;
Mat Martineau37339372012-05-17 20:53:33 -07001930 struct l2cap_ctrl *control;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001931
Mat Martineau37339372012-05-17 20:53:33 -07001932 BT_DBG("chan %p, skbs %p", chan, skbs);
1933
Mat Martineaub99e13a2012-10-23 15:24:19 -07001934 if (__chan_is_moving(chan))
1935 return;
1936
Mat Martineau37339372012-05-17 20:53:33 -07001937 skb_queue_splice_tail_init(skbs, &chan->tx_q);
1938
1939 while (!skb_queue_empty(&chan->tx_q)) {
1940
1941 skb = skb_dequeue(&chan->tx_q);
1942
1943 bt_cb(skb)->control.retries = 1;
1944 control = &bt_cb(skb)->control;
1945
1946 control->reqseq = 0;
1947 control->txseq = chan->next_tx_seq;
1948
1949 __pack_control(chan, control, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001950
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001951 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau37339372012-05-17 20:53:33 -07001952 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
1953 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001954 }
1955
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001956 l2cap_do_send(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001957
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001958 BT_DBG("Sent txseq %u", control->txseq);
Mat Martineau37339372012-05-17 20:53:33 -07001959
Andrei Emeltchenko836be932011-10-17 12:19:57 +03001960 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau37339372012-05-17 20:53:33 -07001961 chan->frames_sent++;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001962 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001963}
1964
Szymon Janc67c9e842011-07-28 16:24:33 +02001965static int l2cap_ertm_send(struct l2cap_chan *chan)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001966{
1967 struct sk_buff *skb, *tx_skb;
Mat Martineau18a48e72012-05-17 20:53:34 -07001968 struct l2cap_ctrl *control;
1969 int sent = 0;
1970
1971 BT_DBG("chan %p", chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001972
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001973 if (chan->state != BT_CONNECTED)
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001974 return -ENOTCONN;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001975
Mat Martineau94122bb2012-05-02 09:42:02 -07001976 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1977 return 0;
1978
Mat Martineaub99e13a2012-10-23 15:24:19 -07001979 if (__chan_is_moving(chan))
1980 return 0;
1981
Mat Martineau18a48e72012-05-17 20:53:34 -07001982 while (chan->tx_send_head &&
1983 chan->unacked_frames < chan->remote_tx_win &&
1984 chan->tx_state == L2CAP_TX_STATE_XMIT) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001985
Mat Martineau18a48e72012-05-17 20:53:34 -07001986 skb = chan->tx_send_head;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001987
Mat Martineau18a48e72012-05-17 20:53:34 -07001988 bt_cb(skb)->control.retries = 1;
1989 control = &bt_cb(skb)->control;
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03001990
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03001991 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
Mat Martineau18a48e72012-05-17 20:53:34 -07001992 control->final = 1;
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03001993
Mat Martineau18a48e72012-05-17 20:53:34 -07001994 control->reqseq = chan->buffer_seq;
1995 chan->last_acked_seq = chan->buffer_seq;
1996 control->txseq = chan->next_tx_seq;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001997
Mat Martineau18a48e72012-05-17 20:53:34 -07001998 __pack_control(chan, control, skb);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001999
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002000 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau18a48e72012-05-17 20:53:34 -07002001 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
2002 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002003 }
2004
Mat Martineau18a48e72012-05-17 20:53:34 -07002005 /* Clone after data has been modified. Data is assumed to be
2006 read-only (for locking purposes) on cloned sk_buffs.
2007 */
2008 tx_skb = skb_clone(skb, GFP_KERNEL);
2009
2010 if (!tx_skb)
2011 break;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03002012
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03002013 __set_retrans_timer(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002014
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002015 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau18a48e72012-05-17 20:53:34 -07002016 chan->unacked_frames++;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03002017 chan->frames_sent++;
Mat Martineau18a48e72012-05-17 20:53:34 -07002018 sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002019
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03002020 if (skb_queue_is_last(&chan->tx_q, skb))
2021 chan->tx_send_head = NULL;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002022 else
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03002023 chan->tx_send_head = skb_queue_next(&chan->tx_q, skb);
Mat Martineau18a48e72012-05-17 20:53:34 -07002024
2025 l2cap_do_send(chan, tx_skb);
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002026 BT_DBG("Sent txseq %u", control->txseq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002027 }
2028
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002029 BT_DBG("Sent %d, %u unacked, %u in ERTM queue", sent,
2030 chan->unacked_frames, skb_queue_len(&chan->tx_q));
Mat Martineau18a48e72012-05-17 20:53:34 -07002031
2032 return sent;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03002033}
2034
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002035static void l2cap_ertm_resend(struct l2cap_chan *chan)
2036{
2037 struct l2cap_ctrl control;
2038 struct sk_buff *skb;
2039 struct sk_buff *tx_skb;
2040 u16 seq;
2041
2042 BT_DBG("chan %p", chan);
2043
2044 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2045 return;
2046
Mat Martineaub99e13a2012-10-23 15:24:19 -07002047 if (__chan_is_moving(chan))
2048 return;
2049
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002050 while (chan->retrans_list.head != L2CAP_SEQ_LIST_CLEAR) {
2051 seq = l2cap_seq_list_pop(&chan->retrans_list);
2052
2053 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, seq);
2054 if (!skb) {
2055 BT_DBG("Error: Can't retransmit seq %d, frame missing",
Gustavo Padovan2d792812012-10-06 10:07:01 +01002056 seq);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002057 continue;
2058 }
2059
2060 bt_cb(skb)->control.retries++;
2061 control = bt_cb(skb)->control;
2062
2063 if (chan->max_tx != 0 &&
2064 bt_cb(skb)->control.retries > chan->max_tx) {
2065 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02002066 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002067 l2cap_seq_list_clear(&chan->retrans_list);
2068 break;
2069 }
2070
2071 control.reqseq = chan->buffer_seq;
2072 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
2073 control.final = 1;
2074 else
2075 control.final = 0;
2076
2077 if (skb_cloned(skb)) {
2078 /* Cloned sk_buffs are read-only, so we need a
2079 * writeable copy
2080 */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002081 tx_skb = skb_copy(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002082 } else {
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002083 tx_skb = skb_clone(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002084 }
2085
2086 if (!tx_skb) {
2087 l2cap_seq_list_clear(&chan->retrans_list);
2088 break;
2089 }
2090
2091 /* Update skb contents */
2092 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
2093 put_unaligned_le32(__pack_extended_control(&control),
2094 tx_skb->data + L2CAP_HDR_SIZE);
2095 } else {
2096 put_unaligned_le16(__pack_enhanced_control(&control),
2097 tx_skb->data + L2CAP_HDR_SIZE);
2098 }
2099
2100 if (chan->fcs == L2CAP_FCS_CRC16) {
2101 u16 fcs = crc16(0, (u8 *) tx_skb->data, tx_skb->len);
2102 put_unaligned_le16(fcs, skb_put(tx_skb,
2103 L2CAP_FCS_SIZE));
2104 }
2105
2106 l2cap_do_send(chan, tx_skb);
2107
2108 BT_DBG("Resent txseq %d", control.txseq);
2109
2110 chan->last_acked_seq = chan->buffer_seq;
2111 }
2112}
2113
Mat Martineauf80842a2012-05-17 20:53:46 -07002114static void l2cap_retransmit(struct l2cap_chan *chan,
2115 struct l2cap_ctrl *control)
2116{
2117 BT_DBG("chan %p, control %p", chan, control);
2118
2119 l2cap_seq_list_append(&chan->retrans_list, control->reqseq);
2120 l2cap_ertm_resend(chan);
2121}
2122
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002123static void l2cap_retransmit_all(struct l2cap_chan *chan,
2124 struct l2cap_ctrl *control)
2125{
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002126 struct sk_buff *skb;
2127
2128 BT_DBG("chan %p, control %p", chan, control);
2129
2130 if (control->poll)
2131 set_bit(CONN_SEND_FBIT, &chan->conn_state);
2132
2133 l2cap_seq_list_clear(&chan->retrans_list);
2134
2135 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2136 return;
2137
2138 if (chan->unacked_frames) {
2139 skb_queue_walk(&chan->tx_q, skb) {
2140 if (bt_cb(skb)->control.txseq == control->reqseq ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01002141 skb == chan->tx_send_head)
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002142 break;
2143 }
2144
2145 skb_queue_walk_from(&chan->tx_q, skb) {
2146 if (skb == chan->tx_send_head)
2147 break;
2148
2149 l2cap_seq_list_append(&chan->retrans_list,
2150 bt_cb(skb)->control.txseq);
2151 }
2152
2153 l2cap_ertm_resend(chan);
2154 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002155}
2156
Szymon Jancb17e73b2012-01-11 10:59:47 +01002157static void l2cap_send_ack(struct l2cap_chan *chan)
2158{
Mat Martineau0a0aba42012-05-17 20:53:39 -07002159 struct l2cap_ctrl control;
2160 u16 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
2161 chan->last_acked_seq);
2162 int threshold;
2163
2164 BT_DBG("chan %p last_acked_seq %d buffer_seq %d",
2165 chan, chan->last_acked_seq, chan->buffer_seq);
2166
2167 memset(&control, 0, sizeof(control));
2168 control.sframe = 1;
2169
2170 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
2171 chan->rx_state == L2CAP_RX_STATE_RECV) {
2172 __clear_ack_timer(chan);
2173 control.super = L2CAP_SUPER_RNR;
2174 control.reqseq = chan->buffer_seq;
2175 l2cap_send_sframe(chan, &control);
2176 } else {
2177 if (!test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) {
2178 l2cap_ertm_send(chan);
2179 /* If any i-frames were sent, they included an ack */
2180 if (chan->buffer_seq == chan->last_acked_seq)
2181 frames_to_ack = 0;
2182 }
2183
Mat Martineauc20f8e32012-07-10 05:47:07 -07002184 /* Ack now if the window is 3/4ths full.
Mat Martineau0a0aba42012-05-17 20:53:39 -07002185 * Calculate without mul or div
2186 */
Mat Martineauc20f8e32012-07-10 05:47:07 -07002187 threshold = chan->ack_win;
Mat Martineau0a0aba42012-05-17 20:53:39 -07002188 threshold += threshold << 1;
2189 threshold >>= 2;
2190
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002191 BT_DBG("frames_to_ack %u, threshold %d", frames_to_ack,
Mat Martineau0a0aba42012-05-17 20:53:39 -07002192 threshold);
2193
2194 if (frames_to_ack >= threshold) {
2195 __clear_ack_timer(chan);
2196 control.super = L2CAP_SUPER_RR;
2197 control.reqseq = chan->buffer_seq;
2198 l2cap_send_sframe(chan, &control);
2199 frames_to_ack = 0;
2200 }
2201
2202 if (frames_to_ack)
2203 __set_ack_timer(chan);
2204 }
Szymon Jancb17e73b2012-01-11 10:59:47 +01002205}
2206
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002207static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
2208 struct msghdr *msg, int len,
2209 int count, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002210{
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002211 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002212 struct sk_buff **frag;
Gustavo Padovan90338942012-04-06 20:15:47 -03002213 int sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002214
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03002215 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002216 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002217
2218 sent += count;
2219 len -= count;
2220
2221 /* Continuation fragments (no L2CAP header) */
2222 frag = &skb_shinfo(skb)->frag_list;
2223 while (len) {
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002224 struct sk_buff *tmp;
2225
Linus Torvalds1da177e2005-04-16 15:20:36 -07002226 count = min_t(unsigned int, conn->mtu, len);
2227
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002228 tmp = chan->ops->alloc_skb(chan, count,
2229 msg->msg_flags & MSG_DONTWAIT);
2230 if (IS_ERR(tmp))
2231 return PTR_ERR(tmp);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002232
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002233 *frag = tmp;
2234
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002235 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
2236 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002237
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002238 (*frag)->priority = skb->priority;
2239
Linus Torvalds1da177e2005-04-16 15:20:36 -07002240 sent += count;
2241 len -= count;
2242
Gustavo Padovan2d0ed3d2012-05-11 13:16:12 -03002243 skb->len += (*frag)->len;
2244 skb->data_len += (*frag)->len;
2245
Linus Torvalds1da177e2005-04-16 15:20:36 -07002246 frag = &(*frag)->next;
2247 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002248
2249 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002250}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002251
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002252static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002253 struct msghdr *msg, size_t len,
2254 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002255{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002256 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002257 struct sk_buff *skb;
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002258 int err, count, hlen = L2CAP_HDR_SIZE + L2CAP_PSMLEN_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002259 struct l2cap_hdr *lh;
2260
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002261 BT_DBG("chan %p len %zu priority %u", chan, len, priority);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002262
2263 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002264
2265 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002266 msg->msg_flags & MSG_DONTWAIT);
2267 if (IS_ERR(skb))
2268 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002269
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002270 skb->priority = priority;
2271
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002272 /* Create L2CAP header */
2273 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002274 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenkodaf6a78c2012-05-03 10:55:52 +03002275 lh->len = cpu_to_le16(len + L2CAP_PSMLEN_SIZE);
2276 put_unaligned(chan->psm, skb_put(skb, L2CAP_PSMLEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002277
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002278 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002279 if (unlikely(err < 0)) {
2280 kfree_skb(skb);
2281 return ERR_PTR(err);
2282 }
2283 return skb;
2284}
2285
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002286static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002287 struct msghdr *msg, size_t len,
2288 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002289{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002290 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002291 struct sk_buff *skb;
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002292 int err, count;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002293 struct l2cap_hdr *lh;
2294
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002295 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002296
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002297 count = min_t(unsigned int, (conn->mtu - L2CAP_HDR_SIZE), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002298
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002299 skb = chan->ops->alloc_skb(chan, count + L2CAP_HDR_SIZE,
Gustavo Padovan90338942012-04-06 20:15:47 -03002300 msg->msg_flags & MSG_DONTWAIT);
2301 if (IS_ERR(skb))
2302 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002303
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002304 skb->priority = priority;
2305
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002306 /* Create L2CAP header */
2307 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002308 lh->cid = cpu_to_le16(chan->dcid);
Gustavo Padovan6ff9b5e2012-05-02 11:56:17 -03002309 lh->len = cpu_to_le16(len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002310
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002311 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002312 if (unlikely(err < 0)) {
2313 kfree_skb(skb);
2314 return ERR_PTR(err);
2315 }
2316 return skb;
2317}
2318
Luiz Augusto von Dentzab0ff762011-09-12 20:00:50 +03002319static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002320 struct msghdr *msg, size_t len,
2321 u16 sdulen)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002322{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002323 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002324 struct sk_buff *skb;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002325 int err, count, hlen;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002326 struct l2cap_hdr *lh;
2327
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002328 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002329
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03002330 if (!conn)
2331 return ERR_PTR(-ENOTCONN);
2332
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002333 hlen = __ertm_hdr_size(chan);
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002334
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002335 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002336 hlen += L2CAP_SDULEN_SIZE;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002337
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002338 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002339 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002340
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002341 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002342
2343 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002344 msg->msg_flags & MSG_DONTWAIT);
2345 if (IS_ERR(skb))
2346 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002347
2348 /* Create L2CAP header */
2349 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002350 lh->cid = cpu_to_le16(chan->dcid);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002351 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002352
Mat Martineau18a48e72012-05-17 20:53:34 -07002353 /* Control header is populated later */
2354 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
2355 put_unaligned_le32(0, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
2356 else
2357 put_unaligned_le16(0, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002358
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002359 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002360 put_unaligned_le16(sdulen, skb_put(skb, L2CAP_SDULEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002361
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002362 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002363 if (unlikely(err < 0)) {
2364 kfree_skb(skb);
2365 return ERR_PTR(err);
2366 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002367
Mat Martineau18a48e72012-05-17 20:53:34 -07002368 bt_cb(skb)->control.fcs = chan->fcs;
Mat Martineau3ce35142012-04-25 16:36:14 -07002369 bt_cb(skb)->control.retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002370 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002371}
2372
Mat Martineau94122bb2012-05-02 09:42:02 -07002373static int l2cap_segment_sdu(struct l2cap_chan *chan,
2374 struct sk_buff_head *seg_queue,
2375 struct msghdr *msg, size_t len)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002376{
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002377 struct sk_buff *skb;
Mat Martineau94122bb2012-05-02 09:42:02 -07002378 u16 sdu_len;
2379 size_t pdu_len;
Mat Martineau94122bb2012-05-02 09:42:02 -07002380 u8 sar;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002381
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002382 BT_DBG("chan %p, msg %p, len %zu", chan, msg, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002383
Mat Martineau94122bb2012-05-02 09:42:02 -07002384 /* It is critical that ERTM PDUs fit in a single HCI fragment,
2385 * so fragmented skbs are not used. The HCI layer's handling
2386 * of fragmented skbs is not compatible with ERTM's queueing.
2387 */
2388
2389 /* PDU size is derived from the HCI MTU */
2390 pdu_len = chan->conn->mtu;
2391
Mat Martineaua5495742012-10-23 15:24:21 -07002392 /* Constrain PDU size for BR/EDR connections */
2393 if (!chan->hs_hcon)
2394 pdu_len = min_t(size_t, pdu_len, L2CAP_BREDR_MAX_PAYLOAD);
Mat Martineau94122bb2012-05-02 09:42:02 -07002395
2396 /* Adjust for largest possible L2CAP overhead. */
Gustavo Padovan35d401d2012-05-25 18:57:05 -03002397 if (chan->fcs)
2398 pdu_len -= L2CAP_FCS_SIZE;
2399
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002400 pdu_len -= __ertm_hdr_size(chan);
Mat Martineau94122bb2012-05-02 09:42:02 -07002401
2402 /* Remote device may have requested smaller PDUs */
2403 pdu_len = min_t(size_t, pdu_len, chan->remote_mps);
2404
2405 if (len <= pdu_len) {
2406 sar = L2CAP_SAR_UNSEGMENTED;
2407 sdu_len = 0;
2408 pdu_len = len;
2409 } else {
2410 sar = L2CAP_SAR_START;
2411 sdu_len = len;
2412 pdu_len -= L2CAP_SDULEN_SIZE;
2413 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002414
2415 while (len > 0) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002416 skb = l2cap_create_iframe_pdu(chan, msg, pdu_len, sdu_len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002417
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002418 if (IS_ERR(skb)) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002419 __skb_queue_purge(seg_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002420 return PTR_ERR(skb);
2421 }
2422
Mat Martineau94122bb2012-05-02 09:42:02 -07002423 bt_cb(skb)->control.sar = sar;
2424 __skb_queue_tail(seg_queue, skb);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002425
Mat Martineau94122bb2012-05-02 09:42:02 -07002426 len -= pdu_len;
2427 if (sdu_len) {
2428 sdu_len = 0;
2429 pdu_len += L2CAP_SDULEN_SIZE;
2430 }
2431
2432 if (len <= pdu_len) {
2433 sar = L2CAP_SAR_END;
2434 pdu_len = len;
2435 } else {
2436 sar = L2CAP_SAR_CONTINUE;
2437 }
2438 }
2439
Gustavo Padovanf0f62792012-05-29 13:29:17 -03002440 return 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002441}
2442
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002443int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01002444 u32 priority)
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002445{
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002446 struct sk_buff *skb;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002447 int err;
Mat Martineau94122bb2012-05-02 09:42:02 -07002448 struct sk_buff_head seg_queue;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002449
2450 /* Connectionless channel */
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002451 if (chan->chan_type == L2CAP_CHAN_CONN_LESS) {
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002452 skb = l2cap_create_connless_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002453 if (IS_ERR(skb))
2454 return PTR_ERR(skb);
2455
2456 l2cap_do_send(chan, skb);
2457 return len;
2458 }
2459
2460 switch (chan->mode) {
2461 case L2CAP_MODE_BASIC:
2462 /* Check outgoing MTU */
2463 if (len > chan->omtu)
2464 return -EMSGSIZE;
2465
2466 /* Create a basic PDU */
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002467 skb = l2cap_create_basic_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002468 if (IS_ERR(skb))
2469 return PTR_ERR(skb);
2470
2471 l2cap_do_send(chan, skb);
2472 err = len;
2473 break;
2474
2475 case L2CAP_MODE_ERTM:
2476 case L2CAP_MODE_STREAMING:
Mat Martineau94122bb2012-05-02 09:42:02 -07002477 /* Check outgoing MTU */
2478 if (len > chan->omtu) {
2479 err = -EMSGSIZE;
2480 break;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002481 }
2482
Mat Martineau94122bb2012-05-02 09:42:02 -07002483 __skb_queue_head_init(&seg_queue);
2484
2485 /* Do segmentation before calling in to the state machine,
2486 * since it's possible to block while waiting for memory
2487 * allocation.
2488 */
2489 err = l2cap_segment_sdu(chan, &seg_queue, msg, len);
2490
2491 /* The channel could have been closed while segmenting,
2492 * check that it is still connected.
2493 */
2494 if (chan->state != BT_CONNECTED) {
2495 __skb_queue_purge(&seg_queue);
2496 err = -ENOTCONN;
2497 }
2498
2499 if (err)
2500 break;
2501
Mat Martineau37339372012-05-17 20:53:33 -07002502 if (chan->mode == L2CAP_MODE_ERTM)
Gustavo Padovand6603662012-05-21 13:58:22 -03002503 l2cap_tx(chan, NULL, &seg_queue, L2CAP_EV_DATA_REQUEST);
Mat Martineau37339372012-05-17 20:53:33 -07002504 else
Gustavo Padovand6603662012-05-21 13:58:22 -03002505 l2cap_streaming_send(chan, &seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002506
Gustavo Padovand6603662012-05-21 13:58:22 -03002507 err = len;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002508
Mat Martineau94122bb2012-05-02 09:42:02 -07002509 /* If the skbs were not queued for sending, they'll still be in
2510 * seg_queue and need to be purged.
2511 */
2512 __skb_queue_purge(&seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002513 break;
2514
2515 default:
2516 BT_DBG("bad state %1.1x", chan->mode);
2517 err = -EBADFD;
2518 }
2519
2520 return err;
2521}
2522
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002523static void l2cap_send_srej(struct l2cap_chan *chan, u16 txseq)
2524{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002525 struct l2cap_ctrl control;
2526 u16 seq;
2527
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002528 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002529
2530 memset(&control, 0, sizeof(control));
2531 control.sframe = 1;
2532 control.super = L2CAP_SUPER_SREJ;
2533
2534 for (seq = chan->expected_tx_seq; seq != txseq;
2535 seq = __next_seq(chan, seq)) {
2536 if (!l2cap_ertm_seq_in_queue(&chan->srej_q, seq)) {
2537 control.reqseq = seq;
2538 l2cap_send_sframe(chan, &control);
2539 l2cap_seq_list_append(&chan->srej_list, seq);
2540 }
2541 }
2542
2543 chan->expected_tx_seq = __next_seq(chan, txseq);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002544}
2545
2546static void l2cap_send_srej_tail(struct l2cap_chan *chan)
2547{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002548 struct l2cap_ctrl control;
2549
2550 BT_DBG("chan %p", chan);
2551
2552 if (chan->srej_list.tail == L2CAP_SEQ_LIST_CLEAR)
2553 return;
2554
2555 memset(&control, 0, sizeof(control));
2556 control.sframe = 1;
2557 control.super = L2CAP_SUPER_SREJ;
2558 control.reqseq = chan->srej_list.tail;
2559 l2cap_send_sframe(chan, &control);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002560}
2561
2562static void l2cap_send_srej_list(struct l2cap_chan *chan, u16 txseq)
2563{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002564 struct l2cap_ctrl control;
2565 u16 initial_head;
2566 u16 seq;
2567
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002568 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002569
2570 memset(&control, 0, sizeof(control));
2571 control.sframe = 1;
2572 control.super = L2CAP_SUPER_SREJ;
2573
2574 /* Capture initial list head to allow only one pass through the list. */
2575 initial_head = chan->srej_list.head;
2576
2577 do {
2578 seq = l2cap_seq_list_pop(&chan->srej_list);
2579 if (seq == txseq || seq == L2CAP_SEQ_LIST_CLEAR)
2580 break;
2581
2582 control.reqseq = seq;
2583 l2cap_send_sframe(chan, &control);
2584 l2cap_seq_list_append(&chan->srej_list, seq);
2585 } while (chan->srej_list.head != initial_head);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002586}
2587
Mat Martineau608bcc62012-05-17 20:53:32 -07002588static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq)
2589{
2590 struct sk_buff *acked_skb;
2591 u16 ackseq;
2592
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002593 BT_DBG("chan %p, reqseq %u", chan, reqseq);
Mat Martineau608bcc62012-05-17 20:53:32 -07002594
2595 if (chan->unacked_frames == 0 || reqseq == chan->expected_ack_seq)
2596 return;
2597
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002598 BT_DBG("expected_ack_seq %u, unacked_frames %u",
Mat Martineau608bcc62012-05-17 20:53:32 -07002599 chan->expected_ack_seq, chan->unacked_frames);
2600
2601 for (ackseq = chan->expected_ack_seq; ackseq != reqseq;
2602 ackseq = __next_seq(chan, ackseq)) {
2603
2604 acked_skb = l2cap_ertm_seq_in_queue(&chan->tx_q, ackseq);
2605 if (acked_skb) {
2606 skb_unlink(acked_skb, &chan->tx_q);
2607 kfree_skb(acked_skb);
2608 chan->unacked_frames--;
2609 }
2610 }
2611
2612 chan->expected_ack_seq = reqseq;
2613
2614 if (chan->unacked_frames == 0)
2615 __clear_retrans_timer(chan);
2616
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002617 BT_DBG("unacked_frames %u", chan->unacked_frames);
Mat Martineau608bcc62012-05-17 20:53:32 -07002618}
2619
2620static void l2cap_abort_rx_srej_sent(struct l2cap_chan *chan)
2621{
2622 BT_DBG("chan %p", chan);
2623
2624 chan->expected_tx_seq = chan->buffer_seq;
2625 l2cap_seq_list_clear(&chan->srej_list);
2626 skb_queue_purge(&chan->srej_q);
2627 chan->rx_state = L2CAP_RX_STATE_RECV;
2628}
2629
Gustavo Padovand6603662012-05-21 13:58:22 -03002630static void l2cap_tx_state_xmit(struct l2cap_chan *chan,
2631 struct l2cap_ctrl *control,
2632 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002633{
Mat Martineau608bcc62012-05-17 20:53:32 -07002634 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2635 event);
2636
2637 switch (event) {
2638 case L2CAP_EV_DATA_REQUEST:
2639 if (chan->tx_send_head == NULL)
2640 chan->tx_send_head = skb_peek(skbs);
2641
2642 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2643 l2cap_ertm_send(chan);
2644 break;
2645 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2646 BT_DBG("Enter LOCAL_BUSY");
2647 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2648
2649 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2650 /* The SREJ_SENT state must be aborted if we are to
2651 * enter the LOCAL_BUSY state.
2652 */
2653 l2cap_abort_rx_srej_sent(chan);
2654 }
2655
2656 l2cap_send_ack(chan);
2657
2658 break;
2659 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2660 BT_DBG("Exit LOCAL_BUSY");
2661 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2662
2663 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2664 struct l2cap_ctrl local_control;
2665
2666 memset(&local_control, 0, sizeof(local_control));
2667 local_control.sframe = 1;
2668 local_control.super = L2CAP_SUPER_RR;
2669 local_control.poll = 1;
2670 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002671 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002672
2673 chan->retry_count = 1;
2674 __set_monitor_timer(chan);
2675 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2676 }
2677 break;
2678 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2679 l2cap_process_reqseq(chan, control->reqseq);
2680 break;
2681 case L2CAP_EV_EXPLICIT_POLL:
2682 l2cap_send_rr_or_rnr(chan, 1);
2683 chan->retry_count = 1;
2684 __set_monitor_timer(chan);
2685 __clear_ack_timer(chan);
2686 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2687 break;
2688 case L2CAP_EV_RETRANS_TO:
2689 l2cap_send_rr_or_rnr(chan, 1);
2690 chan->retry_count = 1;
2691 __set_monitor_timer(chan);
2692 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2693 break;
2694 case L2CAP_EV_RECV_FBIT:
2695 /* Nothing to process */
2696 break;
2697 default:
2698 break;
2699 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002700}
2701
Gustavo Padovand6603662012-05-21 13:58:22 -03002702static void l2cap_tx_state_wait_f(struct l2cap_chan *chan,
2703 struct l2cap_ctrl *control,
2704 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002705{
Mat Martineau608bcc62012-05-17 20:53:32 -07002706 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2707 event);
2708
2709 switch (event) {
2710 case L2CAP_EV_DATA_REQUEST:
2711 if (chan->tx_send_head == NULL)
2712 chan->tx_send_head = skb_peek(skbs);
2713 /* Queue data, but don't send. */
2714 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2715 break;
2716 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2717 BT_DBG("Enter LOCAL_BUSY");
2718 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2719
2720 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2721 /* The SREJ_SENT state must be aborted if we are to
2722 * enter the LOCAL_BUSY state.
2723 */
2724 l2cap_abort_rx_srej_sent(chan);
2725 }
2726
2727 l2cap_send_ack(chan);
2728
2729 break;
2730 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2731 BT_DBG("Exit LOCAL_BUSY");
2732 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2733
2734 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2735 struct l2cap_ctrl local_control;
2736 memset(&local_control, 0, sizeof(local_control));
2737 local_control.sframe = 1;
2738 local_control.super = L2CAP_SUPER_RR;
2739 local_control.poll = 1;
2740 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002741 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002742
2743 chan->retry_count = 1;
2744 __set_monitor_timer(chan);
2745 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2746 }
2747 break;
2748 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2749 l2cap_process_reqseq(chan, control->reqseq);
2750
2751 /* Fall through */
2752
2753 case L2CAP_EV_RECV_FBIT:
2754 if (control && control->final) {
2755 __clear_monitor_timer(chan);
2756 if (chan->unacked_frames > 0)
2757 __set_retrans_timer(chan);
2758 chan->retry_count = 0;
2759 chan->tx_state = L2CAP_TX_STATE_XMIT;
2760 BT_DBG("recv fbit tx_state 0x2.2%x", chan->tx_state);
2761 }
2762 break;
2763 case L2CAP_EV_EXPLICIT_POLL:
2764 /* Ignore */
2765 break;
2766 case L2CAP_EV_MONITOR_TO:
2767 if (chan->max_tx == 0 || chan->retry_count < chan->max_tx) {
2768 l2cap_send_rr_or_rnr(chan, 1);
2769 __set_monitor_timer(chan);
2770 chan->retry_count++;
2771 } else {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02002772 l2cap_send_disconn_req(chan, ECONNABORTED);
Mat Martineau608bcc62012-05-17 20:53:32 -07002773 }
2774 break;
2775 default:
2776 break;
2777 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002778}
2779
Gustavo Padovand6603662012-05-21 13:58:22 -03002780static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
2781 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002782{
Mat Martineau608bcc62012-05-17 20:53:32 -07002783 BT_DBG("chan %p, control %p, skbs %p, event %d, state %d",
2784 chan, control, skbs, event, chan->tx_state);
2785
2786 switch (chan->tx_state) {
2787 case L2CAP_TX_STATE_XMIT:
Gustavo Padovand6603662012-05-21 13:58:22 -03002788 l2cap_tx_state_xmit(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002789 break;
2790 case L2CAP_TX_STATE_WAIT_F:
Gustavo Padovand6603662012-05-21 13:58:22 -03002791 l2cap_tx_state_wait_f(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002792 break;
2793 default:
2794 /* Ignore event */
2795 break;
2796 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002797}
2798
Mat Martineau4b51dae92012-05-17 20:53:37 -07002799static void l2cap_pass_to_tx(struct l2cap_chan *chan,
2800 struct l2cap_ctrl *control)
2801{
2802 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002803 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_REQSEQ_AND_FBIT);
Mat Martineau4b51dae92012-05-17 20:53:37 -07002804}
2805
Mat Martineauf80842a2012-05-17 20:53:46 -07002806static void l2cap_pass_to_tx_fbit(struct l2cap_chan *chan,
2807 struct l2cap_ctrl *control)
2808{
2809 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002810 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_FBIT);
Mat Martineauf80842a2012-05-17 20:53:46 -07002811}
2812
Linus Torvalds1da177e2005-04-16 15:20:36 -07002813/* Copy frame to all raw sockets on that connection */
2814static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2815{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002816 struct sk_buff *nskb;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002817 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002818
2819 BT_DBG("conn %p", conn);
2820
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002821 mutex_lock(&conn->chan_lock);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002822
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002823 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002824 struct sock *sk = chan->sk;
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002825 if (chan->chan_type != L2CAP_CHAN_RAW)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002826 continue;
2827
2828 /* Don't send frame to the socket it came from */
2829 if (skb->sk == sk)
2830 continue;
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002831 nskb = skb_clone(skb, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002832 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002833 continue;
2834
Gustavo Padovan80b98022012-05-27 22:27:51 -03002835 if (chan->ops->recv(chan, nskb))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002836 kfree_skb(nskb);
2837 }
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002838
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002839 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002840}
2841
2842/* ---- L2CAP signalling commands ---- */
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002843static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code,
2844 u8 ident, u16 dlen, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002845{
2846 struct sk_buff *skb, **frag;
2847 struct l2cap_cmd_hdr *cmd;
2848 struct l2cap_hdr *lh;
2849 int len, count;
2850
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002851 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %u",
2852 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002853
Anderson Lizardo300b9622013-06-02 16:30:40 -04002854 if (conn->mtu < L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE)
2855 return NULL;
2856
Linus Torvalds1da177e2005-04-16 15:20:36 -07002857 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2858 count = min_t(unsigned int, conn->mtu, len);
2859
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002860 skb = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002861 if (!skb)
2862 return NULL;
2863
2864 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002865 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002866
2867 if (conn->hcon->type == LE_LINK)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002868 lh->cid = __constant_cpu_to_le16(L2CAP_CID_LE_SIGNALING);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002869 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002870 lh->cid = __constant_cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002871
2872 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2873 cmd->code = code;
2874 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002875 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002876
2877 if (dlen) {
2878 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2879 memcpy(skb_put(skb, count), data, count);
2880 data += count;
2881 }
2882
2883 len -= skb->len;
2884
2885 /* Continuation fragments (no L2CAP header) */
2886 frag = &skb_shinfo(skb)->frag_list;
2887 while (len) {
2888 count = min_t(unsigned int, conn->mtu, len);
2889
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002890 *frag = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002891 if (!*frag)
2892 goto fail;
2893
2894 memcpy(skb_put(*frag, count), data, count);
2895
2896 len -= count;
2897 data += count;
2898
2899 frag = &(*frag)->next;
2900 }
2901
2902 return skb;
2903
2904fail:
2905 kfree_skb(skb);
2906 return NULL;
2907}
2908
Gustavo Padovan2d792812012-10-06 10:07:01 +01002909static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen,
2910 unsigned long *val)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002911{
2912 struct l2cap_conf_opt *opt = *ptr;
2913 int len;
2914
2915 len = L2CAP_CONF_OPT_SIZE + opt->len;
2916 *ptr += len;
2917
2918 *type = opt->type;
2919 *olen = opt->len;
2920
2921 switch (opt->len) {
2922 case 1:
2923 *val = *((u8 *) opt->val);
2924 break;
2925
2926 case 2:
steven miaobfaaeb32010-10-16 18:29:47 -04002927 *val = get_unaligned_le16(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002928 break;
2929
2930 case 4:
steven miaobfaaeb32010-10-16 18:29:47 -04002931 *val = get_unaligned_le32(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002932 break;
2933
2934 default:
2935 *val = (unsigned long) opt->val;
2936 break;
2937 }
2938
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002939 BT_DBG("type 0x%2.2x len %u val 0x%lx", *type, opt->len, *val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002940 return len;
2941}
2942
Linus Torvalds1da177e2005-04-16 15:20:36 -07002943static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2944{
2945 struct l2cap_conf_opt *opt = *ptr;
2946
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002947 BT_DBG("type 0x%2.2x len %u val 0x%lx", type, len, val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002948
2949 opt->type = type;
2950 opt->len = len;
2951
2952 switch (len) {
2953 case 1:
2954 *((u8 *) opt->val) = val;
2955 break;
2956
2957 case 2:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002958 put_unaligned_le16(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002959 break;
2960
2961 case 4:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002962 put_unaligned_le32(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002963 break;
2964
2965 default:
2966 memcpy(opt->val, (void *) val, len);
2967 break;
2968 }
2969
2970 *ptr += L2CAP_CONF_OPT_SIZE + len;
2971}
2972
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002973static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan)
2974{
2975 struct l2cap_conf_efs efs;
2976
Szymon Janc1ec918c2011-11-16 09:32:21 +01002977 switch (chan->mode) {
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002978 case L2CAP_MODE_ERTM:
2979 efs.id = chan->local_id;
2980 efs.stype = chan->local_stype;
2981 efs.msdu = cpu_to_le16(chan->local_msdu);
2982 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002983 efs.acc_lat = __constant_cpu_to_le32(L2CAP_DEFAULT_ACC_LAT);
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03002984 efs.flush_to = __constant_cpu_to_le32(L2CAP_EFS_DEFAULT_FLUSH_TO);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002985 break;
2986
2987 case L2CAP_MODE_STREAMING:
2988 efs.id = 1;
2989 efs.stype = L2CAP_SERV_BESTEFFORT;
2990 efs.msdu = cpu_to_le16(chan->local_msdu);
2991 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
2992 efs.acc_lat = 0;
2993 efs.flush_to = 0;
2994 break;
2995
2996 default:
2997 return;
2998 }
2999
3000 l2cap_add_conf_opt(ptr, L2CAP_CONF_EFS, sizeof(efs),
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03003001 (unsigned long) &efs);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003002}
3003
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003004static void l2cap_ack_timeout(struct work_struct *work)
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003005{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003006 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau03625202012-05-17 20:53:51 -07003007 ack_timer.work);
3008 u16 frames_to_ack;
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003009
Gustavo F. Padovan2fb9b3d2011-12-22 16:56:05 -02003010 BT_DBG("chan %p", chan);
3011
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003012 l2cap_chan_lock(chan);
3013
Mat Martineau03625202012-05-17 20:53:51 -07003014 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
3015 chan->last_acked_seq);
3016
3017 if (frames_to_ack)
3018 l2cap_send_rr_or_rnr(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003019
3020 l2cap_chan_unlock(chan);
Szymon Janc09bfb2e2012-01-11 10:59:49 +01003021 l2cap_chan_put(chan);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003022}
3023
Andrei Emeltchenko466f8002012-05-29 13:59:01 +03003024int l2cap_ertm_init(struct l2cap_chan *chan)
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003025{
Mat Martineau3c588192012-04-11 10:48:42 -07003026 int err;
3027
Mat Martineau105bdf92012-04-27 16:50:48 -07003028 chan->next_tx_seq = 0;
3029 chan->expected_tx_seq = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03003030 chan->expected_ack_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03003031 chan->unacked_frames = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03003032 chan->buffer_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03003033 chan->frames_sent = 0;
Mat Martineau105bdf92012-04-27 16:50:48 -07003034 chan->last_acked_seq = 0;
3035 chan->sdu = NULL;
3036 chan->sdu_last_frag = NULL;
3037 chan->sdu_len = 0;
3038
Mat Martineaud34c34f2012-05-14 14:49:27 -07003039 skb_queue_head_init(&chan->tx_q);
3040
Mat Martineau08333282012-10-23 15:24:06 -07003041 chan->local_amp_id = 0;
3042 chan->move_id = 0;
3043 chan->move_state = L2CAP_MOVE_STABLE;
3044 chan->move_role = L2CAP_MOVE_ROLE_NONE;
3045
Mat Martineau105bdf92012-04-27 16:50:48 -07003046 if (chan->mode != L2CAP_MODE_ERTM)
3047 return 0;
3048
3049 chan->rx_state = L2CAP_RX_STATE_RECV;
3050 chan->tx_state = L2CAP_TX_STATE_XMIT;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003051
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003052 INIT_DELAYED_WORK(&chan->retrans_timer, l2cap_retrans_timeout);
3053 INIT_DELAYED_WORK(&chan->monitor_timer, l2cap_monitor_timeout);
3054 INIT_DELAYED_WORK(&chan->ack_timer, l2cap_ack_timeout);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003055
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -03003056 skb_queue_head_init(&chan->srej_q);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003057
Mat Martineau3c588192012-04-11 10:48:42 -07003058 err = l2cap_seq_list_init(&chan->srej_list, chan->tx_win);
3059 if (err < 0)
3060 return err;
3061
Mat Martineau9dc9aff2012-05-17 16:20:14 -07003062 err = l2cap_seq_list_init(&chan->retrans_list, chan->remote_tx_win);
3063 if (err < 0)
3064 l2cap_seq_list_free(&chan->srej_list);
3065
3066 return err;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003067}
3068
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003069static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
3070{
3071 switch (mode) {
3072 case L2CAP_MODE_STREAMING:
3073 case L2CAP_MODE_ERTM:
3074 if (l2cap_mode_supported(mode, remote_feat_mask))
3075 return mode;
3076 /* fall through */
3077 default:
3078 return L2CAP_MODE_BASIC;
3079 }
3080}
3081
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003082static inline bool __l2cap_ews_supported(struct l2cap_chan *chan)
3083{
3084 return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_WINDOW;
3085}
3086
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003087static inline bool __l2cap_efs_supported(struct l2cap_chan *chan)
3088{
3089 return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_FLOW;
3090}
3091
Mat Martineau36c86c82012-10-23 15:24:20 -07003092static void __l2cap_set_ertm_timeouts(struct l2cap_chan *chan,
3093 struct l2cap_conf_rfc *rfc)
3094{
3095 if (chan->local_amp_id && chan->hs_hcon) {
3096 u64 ertm_to = chan->hs_hcon->hdev->amp_be_flush_to;
3097
3098 /* Class 1 devices have must have ERTM timeouts
3099 * exceeding the Link Supervision Timeout. The
3100 * default Link Supervision Timeout for AMP
3101 * controllers is 10 seconds.
3102 *
3103 * Class 1 devices use 0xffffffff for their
3104 * best-effort flush timeout, so the clamping logic
3105 * will result in a timeout that meets the above
3106 * requirement. ERTM timeouts are 16-bit values, so
3107 * the maximum timeout is 65.535 seconds.
3108 */
3109
3110 /* Convert timeout to milliseconds and round */
3111 ertm_to = DIV_ROUND_UP_ULL(ertm_to, 1000);
3112
3113 /* This is the recommended formula for class 2 devices
3114 * that start ERTM timers when packets are sent to the
3115 * controller.
3116 */
3117 ertm_to = 3 * ertm_to + 500;
3118
3119 if (ertm_to > 0xffff)
3120 ertm_to = 0xffff;
3121
3122 rfc->retrans_timeout = cpu_to_le16((u16) ertm_to);
3123 rfc->monitor_timeout = rfc->retrans_timeout;
3124 } else {
3125 rfc->retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
3126 rfc->monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
3127 }
3128}
3129
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003130static inline void l2cap_txwin_setup(struct l2cap_chan *chan)
3131{
3132 if (chan->tx_win > L2CAP_DEFAULT_TX_WINDOW &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003133 __l2cap_ews_supported(chan)) {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003134 /* use extended control field */
3135 set_bit(FLAG_EXT_CTRL, &chan->flags);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003136 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
3137 } else {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003138 chan->tx_win = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003139 L2CAP_DEFAULT_TX_WINDOW);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003140 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
3141 }
Mat Martineauc20f8e32012-07-10 05:47:07 -07003142 chan->ack_win = chan->tx_win;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003143}
3144
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003145static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003146{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003147 struct l2cap_conf_req *req = data;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003148 struct l2cap_conf_rfc rfc = { .mode = chan->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07003149 void *ptr = req->data;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003150 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003151
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03003152 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003153
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003154 if (chan->num_conf_req || chan->num_conf_rsp)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003155 goto done;
3156
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003157 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003158 case L2CAP_MODE_STREAMING:
3159 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003160 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state))
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003161 break;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003162
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003163 if (__l2cap_efs_supported(chan))
3164 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3165
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03003166 /* fall through */
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003167 default:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003168 chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003169 break;
3170 }
3171
3172done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003173 if (chan->imtu != L2CAP_DEFAULT_MTU)
3174 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovan7990681c2011-01-24 16:01:43 -02003175
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003176 switch (chan->mode) {
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003177 case L2CAP_MODE_BASIC:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003178 if (!(chan->conn->feat_mask & L2CAP_FEAT_ERTM) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003179 !(chan->conn->feat_mask & L2CAP_FEAT_STREAMING))
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003180 break;
3181
Gustavo F. Padovan62547752010-06-08 20:05:31 -03003182 rfc.mode = L2CAP_MODE_BASIC;
3183 rfc.txwin_size = 0;
3184 rfc.max_transmit = 0;
3185 rfc.retrans_timeout = 0;
3186 rfc.monitor_timeout = 0;
3187 rfc.max_pdu_size = 0;
3188
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003189 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003190 (unsigned long) &rfc);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003191 break;
3192
3193 case L2CAP_MODE_ERTM:
3194 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003195 rfc.max_transmit = chan->max_tx;
Mat Martineau36c86c82012-10-23 15:24:20 -07003196
3197 __l2cap_set_ertm_timeouts(chan, &rfc);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003198
3199 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003200 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3201 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003202 rfc.max_pdu_size = cpu_to_le16(size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003203
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003204 l2cap_txwin_setup(chan);
3205
3206 rfc.txwin_size = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003207 L2CAP_DEFAULT_TX_WINDOW);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003208
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003209 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003210 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003211
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003212 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3213 l2cap_add_opt_efs(&ptr, chan);
3214
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003215 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3216 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003217 chan->tx_win);
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003218
3219 if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
3220 if (chan->fcs == L2CAP_FCS_NONE ||
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003221 test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003222 chan->fcs = L2CAP_FCS_NONE;
3223 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
3224 chan->fcs);
3225 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003226 break;
3227
3228 case L2CAP_MODE_STREAMING:
Mat Martineau273759e2012-05-17 20:53:53 -07003229 l2cap_txwin_setup(chan);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003230 rfc.mode = L2CAP_MODE_STREAMING;
3231 rfc.txwin_size = 0;
3232 rfc.max_transmit = 0;
3233 rfc.retrans_timeout = 0;
3234 rfc.monitor_timeout = 0;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003235
3236 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003237 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3238 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003239 rfc.max_pdu_size = cpu_to_le16(size);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003240
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003241 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003242 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003243
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003244 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3245 l2cap_add_opt_efs(&ptr, chan);
3246
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003247 if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
3248 if (chan->fcs == L2CAP_FCS_NONE ||
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003249 test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003250 chan->fcs = L2CAP_FCS_NONE;
3251 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
3252 chan->fcs);
3253 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003254 break;
3255 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003256
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003257 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003258 req->flags = __constant_cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003259
3260 return ptr - data;
3261}
3262
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003263static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003264{
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003265 struct l2cap_conf_rsp *rsp = data;
3266 void *ptr = rsp->data;
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003267 void *req = chan->conf_req;
3268 int len = chan->conf_len;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003269 int type, hint, olen;
3270 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003271 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003272 struct l2cap_conf_efs efs;
3273 u8 remote_efs = 0;
Marcel Holtmann861d6882007-10-20 13:37:06 +02003274 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003275 u16 result = L2CAP_CONF_SUCCESS;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003276 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003277
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003278 BT_DBG("chan %p", chan);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01003279
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003280 while (len >= L2CAP_CONF_OPT_SIZE) {
3281 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003282
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03003283 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003284 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003285
3286 switch (type) {
3287 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02003288 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003289 break;
3290
3291 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003292 chan->flush_to = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003293 break;
3294
3295 case L2CAP_CONF_QOS:
3296 break;
3297
Marcel Holtmann6464f352007-10-20 13:39:51 +02003298 case L2CAP_CONF_RFC:
3299 if (olen == sizeof(rfc))
3300 memcpy(&rfc, (void *) val, olen);
3301 break;
3302
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003303 case L2CAP_CONF_FCS:
3304 if (val == L2CAP_FCS_NONE)
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003305 set_bit(CONF_RECV_NO_FCS, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003306 break;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003307
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003308 case L2CAP_CONF_EFS:
3309 remote_efs = 1;
3310 if (olen == sizeof(efs))
3311 memcpy(&efs, (void *) val, olen);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003312 break;
3313
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003314 case L2CAP_CONF_EWS:
3315 if (!enable_hs)
3316 return -ECONNREFUSED;
3317
3318 set_bit(FLAG_EXT_CTRL, &chan->flags);
3319 set_bit(CONF_EWS_RECV, &chan->conf_state);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003320 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003321 chan->remote_tx_win = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003322 break;
3323
3324 default:
3325 if (hint)
3326 break;
3327
3328 result = L2CAP_CONF_UNKNOWN;
3329 *((u8 *) ptr++) = type;
3330 break;
3331 }
3332 }
3333
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003334 if (chan->num_conf_rsp || chan->num_conf_req > 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003335 goto done;
3336
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003337 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003338 case L2CAP_MODE_STREAMING:
3339 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003340 if (!test_bit(CONF_STATE2_DEVICE, &chan->conf_state)) {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003341 chan->mode = l2cap_select_mode(rfc.mode,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003342 chan->conn->feat_mask);
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003343 break;
3344 }
3345
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003346 if (remote_efs) {
3347 if (__l2cap_efs_supported(chan))
3348 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3349 else
3350 return -ECONNREFUSED;
3351 }
3352
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003353 if (chan->mode != rfc.mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003354 return -ECONNREFUSED;
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03003355
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003356 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003357 }
3358
3359done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003360 if (chan->mode != rfc.mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003361 result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003362 rfc.mode = chan->mode;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003363
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003364 if (chan->num_conf_rsp == 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003365 return -ECONNREFUSED;
3366
Gustavo Padovan2d792812012-10-06 10:07:01 +01003367 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3368 (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003369 }
3370
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003371 if (result == L2CAP_CONF_SUCCESS) {
3372 /* Configure output options and let the other side know
3373 * which ones we don't like. */
3374
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003375 if (mtu < L2CAP_DEFAULT_MIN_MTU)
3376 result = L2CAP_CONF_UNACCEPT;
3377 else {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003378 chan->omtu = mtu;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003379 set_bit(CONF_MTU_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003380 }
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003381 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003382
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003383 if (remote_efs) {
3384 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003385 efs.stype != L2CAP_SERV_NOTRAFIC &&
3386 efs.stype != chan->local_stype) {
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003387
3388 result = L2CAP_CONF_UNACCEPT;
3389
3390 if (chan->num_conf_req >= 1)
3391 return -ECONNREFUSED;
3392
3393 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003394 sizeof(efs),
3395 (unsigned long) &efs);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003396 } else {
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003397 /* Send PENDING Conf Rsp */
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003398 result = L2CAP_CONF_PENDING;
3399 set_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003400 }
3401 }
3402
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003403 switch (rfc.mode) {
3404 case L2CAP_MODE_BASIC:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003405 chan->fcs = L2CAP_FCS_NONE;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003406 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003407 break;
3408
3409 case L2CAP_MODE_ERTM:
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003410 if (!test_bit(CONF_EWS_RECV, &chan->conf_state))
3411 chan->remote_tx_win = rfc.txwin_size;
3412 else
3413 rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW;
3414
Gustavo F. Padovan2c03a7a2011-03-25 20:15:28 -03003415 chan->remote_max_tx = rfc.max_transmit;
Mat Martineau86b1b262010-08-05 15:54:22 -07003416
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003417 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003418 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3419 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003420 rfc.max_pdu_size = cpu_to_le16(size);
3421 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003422
Mat Martineau36c86c82012-10-23 15:24:20 -07003423 __l2cap_set_ertm_timeouts(chan, &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003424
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003425 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003426
3427 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003428 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003429
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003430 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3431 chan->remote_id = efs.id;
3432 chan->remote_stype = efs.stype;
3433 chan->remote_msdu = le16_to_cpu(efs.msdu);
3434 chan->remote_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003435 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003436 chan->remote_acc_lat =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003437 le32_to_cpu(efs.acc_lat);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003438 chan->remote_sdu_itime =
3439 le32_to_cpu(efs.sdu_itime);
3440 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003441 sizeof(efs),
3442 (unsigned long) &efs);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003443 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003444 break;
3445
3446 case L2CAP_MODE_STREAMING:
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003447 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003448 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3449 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003450 rfc.max_pdu_size = cpu_to_le16(size);
3451 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003452
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003453 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003454
Gustavo Padovan2d792812012-10-06 10:07:01 +01003455 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3456 (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003457
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003458 break;
3459
3460 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02003461 result = L2CAP_CONF_UNACCEPT;
3462
3463 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003464 rfc.mode = chan->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003465 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003466
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003467 if (result == L2CAP_CONF_SUCCESS)
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003468 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003469 }
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003470 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003471 rsp->result = cpu_to_le16(result);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003472 rsp->flags = __constant_cpu_to_le16(0);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003473
3474 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003475}
3476
Gustavo Padovan2d792812012-10-06 10:07:01 +01003477static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len,
3478 void *data, u16 *result)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003479{
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003480 struct l2cap_conf_req *req = data;
3481 void *ptr = req->data;
3482 int type, olen;
3483 unsigned long val;
Mat Martineau36e999a2011-12-08 17:23:21 -08003484 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003485 struct l2cap_conf_efs efs;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003486
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003487 BT_DBG("chan %p, rsp %p, len %d, req %p", chan, rsp, len, data);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003488
3489 while (len >= L2CAP_CONF_OPT_SIZE) {
3490 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3491
3492 switch (type) {
3493 case L2CAP_CONF_MTU:
3494 if (val < L2CAP_DEFAULT_MIN_MTU) {
3495 *result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003496 chan->imtu = L2CAP_DEFAULT_MIN_MTU;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003497 } else
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003498 chan->imtu = val;
3499 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003500 break;
3501
3502 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003503 chan->flush_to = val;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003504 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003505 2, chan->flush_to);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003506 break;
3507
3508 case L2CAP_CONF_RFC:
3509 if (olen == sizeof(rfc))
3510 memcpy(&rfc, (void *)val, olen);
3511
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003512 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003513 rfc.mode != chan->mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003514 return -ECONNREFUSED;
3515
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003516 chan->fcs = 0;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003517
3518 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003519 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003520 break;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003521
3522 case L2CAP_CONF_EWS:
Mat Martineauc20f8e32012-07-10 05:47:07 -07003523 chan->ack_win = min_t(u16, val, chan->ack_win);
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003524 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Mat Martineauc20f8e32012-07-10 05:47:07 -07003525 chan->tx_win);
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003526 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003527
3528 case L2CAP_CONF_EFS:
3529 if (olen == sizeof(efs))
3530 memcpy(&efs, (void *)val, olen);
3531
3532 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003533 efs.stype != L2CAP_SERV_NOTRAFIC &&
3534 efs.stype != chan->local_stype)
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003535 return -ECONNREFUSED;
3536
Gustavo Padovan2d792812012-10-06 10:07:01 +01003537 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs),
3538 (unsigned long) &efs);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003539 break;
Andrei Emeltchenkocbabee72012-11-29 17:46:07 +02003540
3541 case L2CAP_CONF_FCS:
3542 if (*result == L2CAP_CONF_PENDING)
3543 if (val == L2CAP_FCS_NONE)
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003544 set_bit(CONF_RECV_NO_FCS,
Andrei Emeltchenkocbabee72012-11-29 17:46:07 +02003545 &chan->conf_state);
3546 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003547 }
3548 }
3549
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003550 if (chan->mode == L2CAP_MODE_BASIC && chan->mode != rfc.mode)
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003551 return -ECONNREFUSED;
3552
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003553 chan->mode = rfc.mode;
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003554
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003555 if (*result == L2CAP_CONF_SUCCESS || *result == L2CAP_CONF_PENDING) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003556 switch (rfc.mode) {
3557 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003558 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3559 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
3560 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003561 if (!test_bit(FLAG_EXT_CTRL, &chan->flags))
3562 chan->ack_win = min_t(u16, chan->ack_win,
3563 rfc.txwin_size);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003564
3565 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3566 chan->local_msdu = le16_to_cpu(efs.msdu);
3567 chan->local_sdu_itime =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003568 le32_to_cpu(efs.sdu_itime);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003569 chan->local_acc_lat = le32_to_cpu(efs.acc_lat);
3570 chan->local_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003571 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003572 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003573 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003574
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003575 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003576 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003577 }
3578 }
3579
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003580 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003581 req->flags = __constant_cpu_to_le16(0);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003582
3583 return ptr - data;
3584}
3585
Gustavo Padovan2d792812012-10-06 10:07:01 +01003586static int l2cap_build_conf_rsp(struct l2cap_chan *chan, void *data,
3587 u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003588{
3589 struct l2cap_conf_rsp *rsp = data;
3590 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003591
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003592 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003593
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003594 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003595 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003596 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003597
3598 return ptr - data;
3599}
3600
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003601void __l2cap_connect_rsp_defer(struct l2cap_chan *chan)
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003602{
3603 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003604 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003605 u8 buf[128];
Andrei Emeltchenko439f34a2012-10-31 15:46:28 +02003606 u8 rsp_code;
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003607
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003608 rsp.scid = cpu_to_le16(chan->dcid);
3609 rsp.dcid = cpu_to_le16(chan->scid);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003610 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
3611 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Andrei Emeltchenko439f34a2012-10-31 15:46:28 +02003612
3613 if (chan->hs_hcon)
3614 rsp_code = L2CAP_CREATE_CHAN_RSP;
3615 else
3616 rsp_code = L2CAP_CONN_RSP;
3617
3618 BT_DBG("chan %p rsp_code %u", chan, rsp_code);
3619
3620 l2cap_send_cmd(conn, chan->ident, rsp_code, sizeof(rsp), &rsp);
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003621
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003622 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003623 return;
3624
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003625 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003626 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003627 chan->num_conf_req++;
3628}
3629
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003630static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003631{
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003632 int type, olen;
3633 unsigned long val;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003634 /* Use sane default values in case a misbehaving remote device
3635 * did not send an RFC or extended window size option.
3636 */
3637 u16 txwin_ext = chan->ack_win;
3638 struct l2cap_conf_rfc rfc = {
3639 .mode = chan->mode,
3640 .retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO),
3641 .monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO),
3642 .max_pdu_size = cpu_to_le16(chan->imtu),
3643 .txwin_size = min_t(u16, chan->ack_win, L2CAP_DEFAULT_TX_WINDOW),
3644 };
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003645
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003646 BT_DBG("chan %p, rsp %p, len %d", chan, rsp, len);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003647
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003648 if ((chan->mode != L2CAP_MODE_ERTM) && (chan->mode != L2CAP_MODE_STREAMING))
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003649 return;
3650
3651 while (len >= L2CAP_CONF_OPT_SIZE) {
3652 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3653
Mat Martineauc20f8e32012-07-10 05:47:07 -07003654 switch (type) {
3655 case L2CAP_CONF_RFC:
3656 if (olen == sizeof(rfc))
3657 memcpy(&rfc, (void *)val, olen);
Szymon Janc8f321f82012-06-08 11:33:33 +02003658 break;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003659 case L2CAP_CONF_EWS:
3660 txwin_ext = val;
3661 break;
3662 }
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003663 }
3664
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003665 switch (rfc.mode) {
3666 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003667 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3668 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003669 chan->mps = le16_to_cpu(rfc.max_pdu_size);
3670 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3671 chan->ack_win = min_t(u16, chan->ack_win, txwin_ext);
3672 else
3673 chan->ack_win = min_t(u16, chan->ack_win,
3674 rfc.txwin_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003675 break;
3676 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003677 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003678 }
3679}
3680
Gustavo Padovan2d792812012-10-06 10:07:01 +01003681static inline int l2cap_command_rej(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003682 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3683 u8 *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003684{
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003685 struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003686
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003687 if (cmd_len < sizeof(*rej))
3688 return -EPROTO;
3689
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003690 if (rej->reason != L2CAP_REJ_NOT_UNDERSTOOD)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003691 return 0;
3692
3693 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003694 cmd->ident == conn->info_ident) {
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02003695 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01003696
3697 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003698 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003699
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003700 l2cap_conn_start(conn);
3701 }
3702
3703 return 0;
3704}
3705
Mat Martineau17009152012-10-23 15:24:07 -07003706static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
3707 struct l2cap_cmd_hdr *cmd,
3708 u8 *data, u8 rsp_code, u8 amp_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003709{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003710 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
3711 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003712 struct l2cap_chan *chan = NULL, *pchan;
Nathan Holsteind793fe82010-10-15 11:54:02 -04003713 struct sock *parent, *sk = NULL;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003714 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003715
3716 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003717 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003718
Andrei Emeltchenko097db762012-03-09 14:16:17 +02003719 BT_DBG("psm 0x%2.2x scid 0x%4.4x", __le16_to_cpu(psm), scid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003720
3721 /* Check if we have socket listening on psm */
Ido Yarivc2287682012-04-20 15:46:07 -03003722 pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003723 if (!pchan) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003724 result = L2CAP_CR_BAD_PSM;
3725 goto sendresp;
3726 }
3727
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003728 parent = pchan->sk;
3729
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003730 mutex_lock(&conn->chan_lock);
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003731 lock_sock(parent);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00003732
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003733 /* Check if the ACL is secure enough (if not SDP) */
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +03003734 if (psm != __constant_cpu_to_le16(L2CAP_PSM_SDP) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003735 !hci_conn_check_link_mode(conn->hcon)) {
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003736 conn->disc_reason = HCI_ERROR_AUTH_FAILURE;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003737 result = L2CAP_CR_SEC_BLOCK;
3738 goto response;
3739 }
3740
Linus Torvalds1da177e2005-04-16 15:20:36 -07003741 result = L2CAP_CR_NO_MEM;
3742
Gustavo Padovan2dfa1002012-05-27 22:27:58 -03003743 /* Check if we already have channel with that dcid */
3744 if (__l2cap_get_chan_by_dcid(conn, scid))
3745 goto response;
3746
Gustavo Padovan80b98022012-05-27 22:27:51 -03003747 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003748 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003749 goto response;
3750
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003751 sk = chan->sk;
3752
Linus Torvalds1da177e2005-04-16 15:20:36 -07003753 bacpy(&bt_sk(sk)->src, conn->src);
3754 bacpy(&bt_sk(sk)->dst, conn->dst);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003755 chan->psm = psm;
3756 chan->dcid = scid;
Mat Martineau17009152012-10-23 15:24:07 -07003757 chan->local_amp_id = amp_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003758
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003759 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003760
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003761 dcid = chan->scid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003762
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03003763 __set_chan_timer(chan, sk->sk_sndtimeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003764
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003765 chan->ident = cmd->ident;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003766
Marcel Holtmann984947d2009-02-06 23:35:19 +01003767 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02003768 if (l2cap_chan_check_security(chan)) {
Gustavo Padovanc5daa682012-05-16 12:17:10 -03003769 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003770 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003771 result = L2CAP_CR_PEND;
3772 status = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08003773 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003774 } else {
Mat Martineau17009152012-10-23 15:24:07 -07003775 /* Force pending result for AMP controllers.
3776 * The connection will succeed after the
3777 * physical link is up.
3778 */
3779 if (amp_id) {
3780 __l2cap_state_change(chan, BT_CONNECT2);
3781 result = L2CAP_CR_PEND;
3782 } else {
3783 __l2cap_state_change(chan, BT_CONFIG);
3784 result = L2CAP_CR_SUCCESS;
3785 }
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003786 status = L2CAP_CS_NO_INFO;
3787 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003788 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003789 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003790 result = L2CAP_CR_PEND;
3791 status = L2CAP_CS_AUTHEN_PEND;
3792 }
3793 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003794 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003795 result = L2CAP_CR_PEND;
3796 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003797 }
3798
Linus Torvalds1da177e2005-04-16 15:20:36 -07003799response:
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003800 release_sock(parent);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003801 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003802
3803sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003804 rsp.scid = cpu_to_le16(scid);
3805 rsp.dcid = cpu_to_le16(dcid);
3806 rsp.result = cpu_to_le16(result);
3807 rsp.status = cpu_to_le16(status);
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003808 l2cap_send_cmd(conn, cmd->ident, rsp_code, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003809
3810 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
3811 struct l2cap_info_req info;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003812 info.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003813
3814 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
3815 conn->info_ident = l2cap_get_ident(conn);
3816
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08003817 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003818
Gustavo Padovan2d792812012-10-06 10:07:01 +01003819 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
3820 sizeof(info), &info);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003821 }
3822
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003823 if (chan && !test_bit(CONF_REQ_SENT, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003824 result == L2CAP_CR_SUCCESS) {
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003825 u8 buf[128];
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003826 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003827 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003828 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003829 chan->num_conf_req++;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003830 }
Mat Martineau17009152012-10-23 15:24:07 -07003831
3832 return chan;
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003833}
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003834
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003835static int l2cap_connect_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003836 struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003837{
Jaganath Kanakkassery7b064ed2013-01-10 10:28:35 +05303838 struct hci_dev *hdev = conn->hcon->hdev;
3839 struct hci_conn *hcon = conn->hcon;
3840
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003841 if (cmd_len < sizeof(struct l2cap_conn_req))
3842 return -EPROTO;
3843
Jaganath Kanakkassery7b064ed2013-01-10 10:28:35 +05303844 hci_dev_lock(hdev);
3845 if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
3846 !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &hcon->flags))
3847 mgmt_device_connected(hdev, &hcon->dst, hcon->type,
3848 hcon->dst_type, 0, NULL, 0,
3849 hcon->dev_class);
3850 hci_dev_unlock(hdev);
3851
Gustavo Padovan300229f2012-10-12 19:40:40 +08003852 l2cap_connect(conn, cmd, data, L2CAP_CONN_RSP, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003853 return 0;
3854}
3855
Mat Martineau5909cf32012-10-23 15:24:08 -07003856static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003857 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3858 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003859{
3860 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
3861 u16 scid, dcid, result, status;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003862 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003863 u8 req[128];
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003864 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003865
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003866 if (cmd_len < sizeof(*rsp))
3867 return -EPROTO;
3868
Linus Torvalds1da177e2005-04-16 15:20:36 -07003869 scid = __le16_to_cpu(rsp->scid);
3870 dcid = __le16_to_cpu(rsp->dcid);
3871 result = __le16_to_cpu(rsp->result);
3872 status = __le16_to_cpu(rsp->status);
3873
Andrei Emeltchenko1b009c92012-02-21 12:54:54 +02003874 BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x",
Gustavo Padovan2d792812012-10-06 10:07:01 +01003875 dcid, scid, result, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003876
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003877 mutex_lock(&conn->chan_lock);
3878
Linus Torvalds1da177e2005-04-16 15:20:36 -07003879 if (scid) {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003880 chan = __l2cap_get_chan_by_scid(conn, scid);
3881 if (!chan) {
3882 err = -EFAULT;
3883 goto unlock;
3884 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003885 } else {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003886 chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
3887 if (!chan) {
3888 err = -EFAULT;
3889 goto unlock;
3890 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003891 }
3892
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003893 err = 0;
3894
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003895 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003896
Linus Torvalds1da177e2005-04-16 15:20:36 -07003897 switch (result) {
3898 case L2CAP_CR_SUCCESS:
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03003899 l2cap_state_change(chan, BT_CONFIG);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003900 chan->ident = 0;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003901 chan->dcid = dcid;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003902 clear_bit(CONF_CONNECT_PEND, &chan->conf_state);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003903
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003904 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003905 break;
3906
Linus Torvalds1da177e2005-04-16 15:20:36 -07003907 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003908 l2cap_build_conf_req(chan, req), req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003909 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003910 break;
3911
3912 case L2CAP_CR_PEND:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003913 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003914 break;
3915
3916 default:
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003917 l2cap_chan_del(chan, ECONNREFUSED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003918 break;
3919 }
3920
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003921 l2cap_chan_unlock(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003922
3923unlock:
3924 mutex_unlock(&conn->chan_lock);
3925
3926 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003927}
3928
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003929static inline void set_default_fcs(struct l2cap_chan *chan)
Mat Martineau8c462b62010-08-24 15:35:42 -07003930{
3931 /* FCS is enabled only in ERTM or streaming mode, if one or both
3932 * sides request it.
3933 */
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003934 if (chan->mode != L2CAP_MODE_ERTM && chan->mode != L2CAP_MODE_STREAMING)
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003935 chan->fcs = L2CAP_FCS_NONE;
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003936 else if (!test_bit(CONF_RECV_NO_FCS, &chan->conf_state))
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003937 chan->fcs = L2CAP_FCS_CRC16;
Mat Martineau8c462b62010-08-24 15:35:42 -07003938}
3939
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03003940static void l2cap_send_efs_conf_rsp(struct l2cap_chan *chan, void *data,
3941 u8 ident, u16 flags)
3942{
3943 struct l2cap_conn *conn = chan->conn;
3944
3945 BT_DBG("conn %p chan %p ident %d flags 0x%4.4x", conn, chan, ident,
3946 flags);
3947
3948 clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
3949 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
3950
3951 l2cap_send_cmd(conn, ident, L2CAP_CONF_RSP,
3952 l2cap_build_conf_rsp(chan, data,
3953 L2CAP_CONF_SUCCESS, flags), data);
3954}
3955
Gustavo Padovan2d792812012-10-06 10:07:01 +01003956static inline int l2cap_config_req(struct l2cap_conn *conn,
3957 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3958 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003959{
3960 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
3961 u16 dcid, flags;
3962 u8 rsp[64];
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003963 struct l2cap_chan *chan;
Mat Martineau3c588192012-04-11 10:48:42 -07003964 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003965
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003966 if (cmd_len < sizeof(*req))
3967 return -EPROTO;
3968
Linus Torvalds1da177e2005-04-16 15:20:36 -07003969 dcid = __le16_to_cpu(req->dcid);
3970 flags = __le16_to_cpu(req->flags);
3971
3972 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
3973
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03003974 chan = l2cap_get_chan_by_scid(conn, dcid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003975 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003976 return -ENOENT;
3977
David S. Miller033b1142011-07-21 13:38:42 -07003978 if (chan->state != BT_CONFIG && chan->state != BT_CONNECT2) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003979 struct l2cap_cmd_rej_cid rej;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003980
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003981 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_INVALID_CID);
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003982 rej.scid = cpu_to_le16(chan->scid);
3983 rej.dcid = cpu_to_le16(chan->dcid);
3984
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003985 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003986 sizeof(rej), &rej);
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003987 goto unlock;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003988 }
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003989
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003990 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07003991 len = cmd_len - sizeof(*req);
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003992 if (chan->conf_len + len > sizeof(chan->conf_req)) {
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003993 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003994 l2cap_build_conf_rsp(chan, rsp,
3995 L2CAP_CONF_REJECT, flags), rsp);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003996 goto unlock;
3997 }
3998
3999 /* Store config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004000 memcpy(chan->conf_req + chan->conf_len, req->data, len);
4001 chan->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004002
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03004003 if (flags & L2CAP_CONF_FLAG_CONTINUATION) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004004 /* Incomplete config. Send empty response. */
4005 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004006 l2cap_build_conf_rsp(chan, rsp,
4007 L2CAP_CONF_SUCCESS, flags), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004008 goto unlock;
4009 }
4010
4011 /* Complete config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004012 len = l2cap_parse_conf_req(chan, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004013 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004014 l2cap_send_disconn_req(chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004015 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004016 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004017
Mat Martineau1500109b2012-10-23 15:24:15 -07004018 chan->ident = cmd->ident;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004019 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004020 chan->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004021
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004022 /* Reset config buffer. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004023 chan->conf_len = 0;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004024
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004025 if (!test_bit(CONF_OUTPUT_DONE, &chan->conf_state))
Marcel Holtmann876d9482007-10-20 13:35:42 +02004026 goto unlock;
4027
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004028 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004029 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004030
Mat Martineau105bdf92012-04-27 16:50:48 -07004031 if (chan->mode == L2CAP_MODE_ERTM ||
4032 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07004033 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03004034
Mat Martineau3c588192012-04-11 10:48:42 -07004035 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004036 l2cap_send_disconn_req(chan, -err);
Mat Martineau3c588192012-04-11 10:48:42 -07004037 else
4038 l2cap_chan_ready(chan);
4039
Marcel Holtmann876d9482007-10-20 13:35:42 +02004040 goto unlock;
4041 }
4042
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004043 if (!test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004044 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004045 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004046 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004047 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004048 }
4049
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004050 /* Got Conf Rsp PENDING from remote side and asume we sent
4051 Conf Rsp PENDING in the code above */
4052 if (test_bit(CONF_REM_CONF_PEND, &chan->conf_state) &&
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03004053 test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004054
4055 /* check compatibility */
4056
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004057 /* Send rsp for BR/EDR channel */
Andrei Emeltchenkof351bc72012-10-31 15:46:35 +02004058 if (!chan->hs_hcon)
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004059 l2cap_send_efs_conf_rsp(chan, rsp, cmd->ident, flags);
4060 else
4061 chan->ident = cmd->ident;
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004062 }
4063
Linus Torvalds1da177e2005-04-16 15:20:36 -07004064unlock:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004065 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07004066 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004067}
4068
Gustavo Padovan2d792812012-10-06 10:07:01 +01004069static inline int l2cap_config_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004070 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4071 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004072{
4073 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
4074 u16 scid, flags, result;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004075 struct l2cap_chan *chan;
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004076 int len = cmd_len - sizeof(*rsp);
Mat Martineau3c588192012-04-11 10:48:42 -07004077 int err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004078
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004079 if (cmd_len < sizeof(*rsp))
4080 return -EPROTO;
4081
Linus Torvalds1da177e2005-04-16 15:20:36 -07004082 scid = __le16_to_cpu(rsp->scid);
4083 flags = __le16_to_cpu(rsp->flags);
4084 result = __le16_to_cpu(rsp->result);
4085
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02004086 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x len %d", scid, flags,
4087 result, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004088
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03004089 chan = l2cap_get_chan_by_scid(conn, scid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004090 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004091 return 0;
4092
4093 switch (result) {
4094 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004095 l2cap_conf_rfc_get(chan, rsp->data, len);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004096 clear_bit(CONF_REM_CONF_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004097 break;
4098
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004099 case L2CAP_CONF_PENDING:
4100 set_bit(CONF_REM_CONF_PEND, &chan->conf_state);
4101
4102 if (test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
4103 char buf[64];
4104
4105 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004106 buf, &result);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004107 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004108 l2cap_send_disconn_req(chan, ECONNRESET);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004109 goto done;
4110 }
4111
Andrei Emeltchenkof351bc72012-10-31 15:46:35 +02004112 if (!chan->hs_hcon) {
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004113 l2cap_send_efs_conf_rsp(chan, buf, cmd->ident,
4114 0);
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +02004115 } else {
4116 if (l2cap_check_efs(chan)) {
4117 amp_create_logical_link(chan);
4118 chan->ident = cmd->ident;
4119 }
4120 }
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004121 }
4122 goto done;
4123
Linus Torvalds1da177e2005-04-16 15:20:36 -07004124 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004125 if (chan->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004126 char req[64];
4127
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02004128 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004129 l2cap_send_disconn_req(chan, ECONNRESET);
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02004130 goto done;
4131 }
4132
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004133 /* throw out any old stored conf requests */
4134 result = L2CAP_CONF_SUCCESS;
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03004135 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004136 req, &result);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004137 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004138 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004139 goto done;
4140 }
4141
4142 l2cap_send_cmd(conn, l2cap_get_ident(conn),
Gustavo Padovan2d792812012-10-06 10:07:01 +01004143 L2CAP_CONF_REQ, len, req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004144 chan->num_conf_req++;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004145 if (result != L2CAP_CONF_SUCCESS)
4146 goto done;
4147 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004148 }
4149
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09004150 default:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004151 l2cap_chan_set_err(chan, ECONNRESET);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02004152
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08004153 __set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004154 l2cap_send_disconn_req(chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004155 goto done;
4156 }
4157
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03004158 if (flags & L2CAP_CONF_FLAG_CONTINUATION)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004159 goto done;
4160
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004161 set_bit(CONF_INPUT_DONE, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004162
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004163 if (test_bit(CONF_OUTPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004164 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004165
Mat Martineau105bdf92012-04-27 16:50:48 -07004166 if (chan->mode == L2CAP_MODE_ERTM ||
4167 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07004168 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03004169
Mat Martineau3c588192012-04-11 10:48:42 -07004170 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004171 l2cap_send_disconn_req(chan, -err);
Mat Martineau3c588192012-04-11 10:48:42 -07004172 else
4173 l2cap_chan_ready(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004174 }
4175
4176done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004177 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07004178 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004179}
4180
Gustavo Padovan2d792812012-10-06 10:07:01 +01004181static inline int l2cap_disconnect_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004182 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4183 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004184{
4185 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
4186 struct l2cap_disconn_rsp rsp;
4187 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004188 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004189 struct sock *sk;
4190
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004191 if (cmd_len != sizeof(*req))
4192 return -EPROTO;
4193
Linus Torvalds1da177e2005-04-16 15:20:36 -07004194 scid = __le16_to_cpu(req->scid);
4195 dcid = __le16_to_cpu(req->dcid);
4196
4197 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
4198
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004199 mutex_lock(&conn->chan_lock);
4200
4201 chan = __l2cap_get_chan_by_scid(conn, dcid);
4202 if (!chan) {
4203 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004204 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004205 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004206
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004207 l2cap_chan_lock(chan);
4208
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004209 sk = chan->sk;
4210
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03004211 rsp.dcid = cpu_to_le16(chan->scid);
4212 rsp.scid = cpu_to_le16(chan->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004213 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
4214
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004215 lock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004216 sk->sk_shutdown = SHUTDOWN_MASK;
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004217 release_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004218
Mat Martineau61d6ef32012-04-27 16:50:50 -07004219 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004220 l2cap_chan_del(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004221
4222 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004223
Gustavo Padovan80b98022012-05-27 22:27:51 -03004224 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004225 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004226
4227 mutex_unlock(&conn->chan_lock);
4228
Linus Torvalds1da177e2005-04-16 15:20:36 -07004229 return 0;
4230}
4231
Gustavo Padovan2d792812012-10-06 10:07:01 +01004232static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004233 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4234 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004235{
4236 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
4237 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004238 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004239
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004240 if (cmd_len != sizeof(*rsp))
4241 return -EPROTO;
4242
Linus Torvalds1da177e2005-04-16 15:20:36 -07004243 scid = __le16_to_cpu(rsp->scid);
4244 dcid = __le16_to_cpu(rsp->dcid);
4245
4246 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
4247
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004248 mutex_lock(&conn->chan_lock);
4249
4250 chan = __l2cap_get_chan_by_scid(conn, scid);
4251 if (!chan) {
4252 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004253 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004254 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004255
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004256 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004257
Mat Martineau61d6ef32012-04-27 16:50:50 -07004258 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004259 l2cap_chan_del(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004260
4261 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004262
Gustavo Padovan80b98022012-05-27 22:27:51 -03004263 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004264 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004265
4266 mutex_unlock(&conn->chan_lock);
4267
Linus Torvalds1da177e2005-04-16 15:20:36 -07004268 return 0;
4269}
4270
Gustavo Padovan2d792812012-10-06 10:07:01 +01004271static inline int l2cap_information_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004272 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4273 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004274{
4275 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004276 u16 type;
4277
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004278 if (cmd_len != sizeof(*req))
4279 return -EPROTO;
4280
Linus Torvalds1da177e2005-04-16 15:20:36 -07004281 type = __le16_to_cpu(req->type);
4282
4283 BT_DBG("type 0x%4.4x", type);
4284
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004285 if (type == L2CAP_IT_FEAT_MASK) {
4286 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07004287 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004288 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004289 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
4290 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03004291 if (!disable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004292 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
Gustavo Padovan2d792812012-10-06 10:07:01 +01004293 | L2CAP_FEAT_FCS;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03004294 if (enable_hs)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03004295 feat_mask |= L2CAP_FEAT_EXT_FLOW
Gustavo Padovan2d792812012-10-06 10:07:01 +01004296 | L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03004297
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03004298 put_unaligned_le32(feat_mask, rsp->data);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004299 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4300 buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004301 } else if (type == L2CAP_IT_FIXED_CHAN) {
4302 u8 buf[12];
4303 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Mat Martineau50a147c2011-11-02 16:18:34 -07004304
4305 if (enable_hs)
4306 l2cap_fixed_chan[0] |= L2CAP_FC_A2MP;
4307 else
4308 l2cap_fixed_chan[0] &= ~L2CAP_FC_A2MP;
4309
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004310 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
4311 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Andrei Emeltchenkoc6337ea2011-10-20 17:02:44 +03004312 memcpy(rsp->data, l2cap_fixed_chan, sizeof(l2cap_fixed_chan));
Gustavo Padovan2d792812012-10-06 10:07:01 +01004313 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4314 buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004315 } else {
4316 struct l2cap_info_rsp rsp;
4317 rsp.type = cpu_to_le16(type);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004318 rsp.result = __constant_cpu_to_le16(L2CAP_IR_NOTSUPP);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004319 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(rsp),
4320 &rsp);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004321 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004322
4323 return 0;
4324}
4325
Gustavo Padovan2d792812012-10-06 10:07:01 +01004326static inline int l2cap_information_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004327 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4328 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004329{
4330 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
4331 u16 type, result;
4332
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004333 if (cmd_len != sizeof(*rsp))
4334 return -EPROTO;
4335
Linus Torvalds1da177e2005-04-16 15:20:36 -07004336 type = __le16_to_cpu(rsp->type);
4337 result = __le16_to_cpu(rsp->result);
4338
4339 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
4340
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004341 /* L2CAP Info req/rsp are unbound to channels, add extra checks */
4342 if (cmd->ident != conn->info_ident ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01004343 conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004344 return 0;
4345
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02004346 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004347
Ville Tervoadb08ed2010-08-04 09:43:33 +03004348 if (result != L2CAP_IR_SUCCESS) {
4349 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4350 conn->info_ident = 0;
4351
4352 l2cap_conn_start(conn);
4353
4354 return 0;
4355 }
4356
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004357 switch (type) {
4358 case L2CAP_IT_FEAT_MASK:
Harvey Harrison83985312008-05-02 16:25:46 -07004359 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004360
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07004361 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004362 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004363 req.type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004364
4365 conn->info_ident = l2cap_get_ident(conn);
4366
4367 l2cap_send_cmd(conn, conn->info_ident,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004368 L2CAP_INFO_REQ, sizeof(req), &req);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004369 } else {
4370 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4371 conn->info_ident = 0;
4372
4373 l2cap_conn_start(conn);
4374 }
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004375 break;
4376
4377 case L2CAP_IT_FIXED_CHAN:
4378 conn->fixed_chan_mask = rsp->data[0];
Marcel Holtmann984947d2009-02-06 23:35:19 +01004379 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004380 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004381
4382 l2cap_conn_start(conn);
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004383 break;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004384 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004385
Linus Torvalds1da177e2005-04-16 15:20:36 -07004386 return 0;
4387}
4388
Mat Martineau17009152012-10-23 15:24:07 -07004389static int l2cap_create_channel_req(struct l2cap_conn *conn,
4390 struct l2cap_cmd_hdr *cmd,
4391 u16 cmd_len, void *data)
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004392{
4393 struct l2cap_create_chan_req *req = data;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004394 struct l2cap_create_chan_rsp rsp;
Mat Martineau17009152012-10-23 15:24:07 -07004395 struct l2cap_chan *chan;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004396 struct hci_dev *hdev;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004397 u16 psm, scid;
4398
4399 if (cmd_len != sizeof(*req))
4400 return -EPROTO;
4401
4402 if (!enable_hs)
4403 return -EINVAL;
4404
4405 psm = le16_to_cpu(req->psm);
4406 scid = le16_to_cpu(req->scid);
4407
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004408 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 -07004409
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004410 /* For controller id 0 make BR/EDR connection */
4411 if (req->amp_id == HCI_BREDR_ID) {
4412 l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4413 req->amp_id);
4414 return 0;
4415 }
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004416
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004417 /* Validate AMP controller id */
4418 hdev = hci_dev_get(req->amp_id);
4419 if (!hdev)
4420 goto error;
Mat Martineau17009152012-10-23 15:24:07 -07004421
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004422 if (hdev->dev_type != HCI_AMP || !test_bit(HCI_UP, &hdev->flags)) {
Mat Martineau17009152012-10-23 15:24:07 -07004423 hci_dev_put(hdev);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004424 goto error;
Mat Martineau17009152012-10-23 15:24:07 -07004425 }
4426
4427 chan = l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4428 req->amp_id);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004429 if (chan) {
4430 struct amp_mgr *mgr = conn->hcon->amp_mgr;
4431 struct hci_conn *hs_hcon;
4432
4433 hs_hcon = hci_conn_hash_lookup_ba(hdev, AMP_LINK, conn->dst);
4434 if (!hs_hcon) {
4435 hci_dev_put(hdev);
4436 return -EFAULT;
4437 }
4438
4439 BT_DBG("mgr %p bredr_chan %p hs_hcon %p", mgr, chan, hs_hcon);
4440
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004441 mgr->bredr_chan = chan;
4442 chan->hs_hcon = hs_hcon;
Andrei Emeltchenkofd45bf42012-11-20 17:16:22 +02004443 chan->fcs = L2CAP_FCS_NONE;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004444 conn->mtu = hdev->block_mtu;
4445 }
4446
4447 hci_dev_put(hdev);
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004448
4449 return 0;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004450
4451error:
4452 rsp.dcid = 0;
4453 rsp.scid = cpu_to_le16(scid);
4454 rsp.result = __constant_cpu_to_le16(L2CAP_CR_BAD_AMP);
4455 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
4456
4457 l2cap_send_cmd(conn, cmd->ident, L2CAP_CREATE_CHAN_RSP,
4458 sizeof(rsp), &rsp);
4459
4460 return -EFAULT;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004461}
4462
Mat Martineau8eb200b2012-10-23 15:24:17 -07004463static void l2cap_send_move_chan_req(struct l2cap_chan *chan, u8 dest_amp_id)
4464{
4465 struct l2cap_move_chan_req req;
4466 u8 ident;
4467
4468 BT_DBG("chan %p, dest_amp_id %d", chan, dest_amp_id);
4469
4470 ident = l2cap_get_ident(chan->conn);
4471 chan->ident = ident;
4472
4473 req.icid = cpu_to_le16(chan->scid);
4474 req.dest_amp_id = dest_amp_id;
4475
4476 l2cap_send_cmd(chan->conn, ident, L2CAP_MOVE_CHAN_REQ, sizeof(req),
4477 &req);
4478
4479 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4480}
4481
Mat Martineau1500109b2012-10-23 15:24:15 -07004482static void l2cap_send_move_chan_rsp(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004483{
4484 struct l2cap_move_chan_rsp rsp;
4485
Mat Martineau1500109b2012-10-23 15:24:15 -07004486 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004487
Mat Martineau1500109b2012-10-23 15:24:15 -07004488 rsp.icid = cpu_to_le16(chan->dcid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004489 rsp.result = cpu_to_le16(result);
4490
Mat Martineau1500109b2012-10-23 15:24:15 -07004491 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_RSP,
4492 sizeof(rsp), &rsp);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004493}
4494
Mat Martineau5b155ef2012-10-23 15:24:14 -07004495static void l2cap_send_move_chan_cfm(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004496{
4497 struct l2cap_move_chan_cfm cfm;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004498
Mat Martineau5b155ef2012-10-23 15:24:14 -07004499 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004500
Mat Martineau5b155ef2012-10-23 15:24:14 -07004501 chan->ident = l2cap_get_ident(chan->conn);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004502
Mat Martineau5b155ef2012-10-23 15:24:14 -07004503 cfm.icid = cpu_to_le16(chan->scid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004504 cfm.result = cpu_to_le16(result);
4505
Mat Martineau5b155ef2012-10-23 15:24:14 -07004506 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_CFM,
4507 sizeof(cfm), &cfm);
4508
4509 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4510}
4511
4512static void l2cap_send_move_chan_cfm_icid(struct l2cap_conn *conn, u16 icid)
4513{
4514 struct l2cap_move_chan_cfm cfm;
4515
4516 BT_DBG("conn %p, icid 0x%4.4x", conn, icid);
4517
4518 cfm.icid = cpu_to_le16(icid);
4519 cfm.result = __constant_cpu_to_le16(L2CAP_MC_UNCONFIRMED);
4520
4521 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_MOVE_CHAN_CFM,
4522 sizeof(cfm), &cfm);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004523}
4524
4525static void l2cap_send_move_chan_cfm_rsp(struct l2cap_conn *conn, u8 ident,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004526 u16 icid)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004527{
4528 struct l2cap_move_chan_cfm_rsp rsp;
4529
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004530 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004531
4532 rsp.icid = cpu_to_le16(icid);
4533 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM_RSP, sizeof(rsp), &rsp);
4534}
4535
Mat Martineau5f3847a2012-10-23 15:24:12 -07004536static void __release_logical_link(struct l2cap_chan *chan)
4537{
4538 chan->hs_hchan = NULL;
4539 chan->hs_hcon = NULL;
4540
4541 /* Placeholder - release the logical link */
4542}
4543
Mat Martineau1500109b2012-10-23 15:24:15 -07004544static void l2cap_logical_fail(struct l2cap_chan *chan)
4545{
4546 /* Logical link setup failed */
4547 if (chan->state != BT_CONNECTED) {
4548 /* Create channel failure, disconnect */
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004549 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineau1500109b2012-10-23 15:24:15 -07004550 return;
4551 }
4552
4553 switch (chan->move_role) {
4554 case L2CAP_MOVE_ROLE_RESPONDER:
4555 l2cap_move_done(chan);
4556 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_SUPP);
4557 break;
4558 case L2CAP_MOVE_ROLE_INITIATOR:
4559 if (chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_COMP ||
4560 chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_CFM) {
4561 /* Remote has only sent pending or
4562 * success responses, clean up
4563 */
4564 l2cap_move_done(chan);
4565 }
4566
4567 /* Other amp move states imply that the move
4568 * has already aborted
4569 */
4570 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4571 break;
4572 }
4573}
4574
4575static void l2cap_logical_finish_create(struct l2cap_chan *chan,
4576 struct hci_chan *hchan)
4577{
4578 struct l2cap_conf_rsp rsp;
Mat Martineau1500109b2012-10-23 15:24:15 -07004579
Andrei Emeltchenko336178a2012-10-31 15:46:27 +02004580 chan->hs_hchan = hchan;
Mat Martineau1500109b2012-10-23 15:24:15 -07004581 chan->hs_hcon->l2cap_data = chan->conn;
4582
Andrei Emeltchenko35ba9562012-10-25 15:20:43 +03004583 l2cap_send_efs_conf_rsp(chan, &rsp, chan->ident, 0);
Mat Martineau1500109b2012-10-23 15:24:15 -07004584
4585 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Andrei Emeltchenkofe79c6f2012-10-25 15:20:42 +03004586 int err;
Mat Martineau1500109b2012-10-23 15:24:15 -07004587
4588 set_default_fcs(chan);
4589
4590 err = l2cap_ertm_init(chan);
4591 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004592 l2cap_send_disconn_req(chan, -err);
Mat Martineau1500109b2012-10-23 15:24:15 -07004593 else
4594 l2cap_chan_ready(chan);
4595 }
4596}
4597
4598static void l2cap_logical_finish_move(struct l2cap_chan *chan,
4599 struct hci_chan *hchan)
4600{
4601 chan->hs_hcon = hchan->conn;
4602 chan->hs_hcon->l2cap_data = chan->conn;
4603
4604 BT_DBG("move_state %d", chan->move_state);
4605
4606 switch (chan->move_state) {
4607 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
4608 /* Move confirm will be sent after a success
4609 * response is received
4610 */
4611 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4612 break;
4613 case L2CAP_MOVE_WAIT_LOGICAL_CFM:
4614 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4615 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4616 } else if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
4617 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
4618 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4619 } else if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
4620 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4621 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
4622 }
4623 break;
4624 default:
4625 /* Move was not in expected state, free the channel */
4626 __release_logical_link(chan);
4627
4628 chan->move_state = L2CAP_MOVE_STABLE;
4629 }
4630}
4631
4632/* Call with chan locked */
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03004633void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan,
4634 u8 status)
Mat Martineau5b155ef2012-10-23 15:24:14 -07004635{
Mat Martineau1500109b2012-10-23 15:24:15 -07004636 BT_DBG("chan %p, hchan %p, status %d", chan, hchan, status);
4637
4638 if (status) {
4639 l2cap_logical_fail(chan);
4640 __release_logical_link(chan);
4641 return;
4642 }
4643
4644 if (chan->state != BT_CONNECTED) {
4645 /* Ignore logical link if channel is on BR/EDR */
4646 if (chan->local_amp_id)
4647 l2cap_logical_finish_create(chan, hchan);
4648 } else {
4649 l2cap_logical_finish_move(chan, hchan);
4650 }
Mat Martineau5b155ef2012-10-23 15:24:14 -07004651}
4652
Mat Martineau3f7a56c2012-10-23 15:24:23 -07004653void l2cap_move_start(struct l2cap_chan *chan)
4654{
4655 BT_DBG("chan %p", chan);
4656
4657 if (chan->local_amp_id == HCI_BREDR_ID) {
4658 if (chan->chan_policy != BT_CHANNEL_POLICY_AMP_PREFERRED)
4659 return;
4660 chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
4661 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
4662 /* Placeholder - start physical link setup */
4663 } else {
4664 chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
4665 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4666 chan->move_id = 0;
4667 l2cap_move_setup(chan);
4668 l2cap_send_move_chan_req(chan, 0);
4669 }
4670}
4671
Mat Martineau8eb200b2012-10-23 15:24:17 -07004672static void l2cap_do_create(struct l2cap_chan *chan, int result,
4673 u8 local_amp_id, u8 remote_amp_id)
4674{
Andrei Emeltchenko62748ca2012-11-20 17:16:19 +02004675 BT_DBG("chan %p state %s %u -> %u", chan, state_to_string(chan->state),
4676 local_amp_id, remote_amp_id);
4677
Andrei Emeltchenko12d6cc62012-11-14 17:39:31 +02004678 chan->fcs = L2CAP_FCS_NONE;
4679
Andrei Emeltchenko62748ca2012-11-20 17:16:19 +02004680 /* Outgoing channel on AMP */
4681 if (chan->state == BT_CONNECT) {
4682 if (result == L2CAP_CR_SUCCESS) {
4683 chan->local_amp_id = local_amp_id;
4684 l2cap_send_create_chan_req(chan, remote_amp_id);
4685 } else {
4686 /* Revert to BR/EDR connect */
4687 l2cap_send_conn_req(chan);
4688 }
4689
4690 return;
4691 }
4692
4693 /* Incoming channel on AMP */
4694 if (__l2cap_no_conn_pending(chan)) {
Mat Martineau8eb200b2012-10-23 15:24:17 -07004695 struct l2cap_conn_rsp rsp;
4696 char buf[128];
4697 rsp.scid = cpu_to_le16(chan->dcid);
4698 rsp.dcid = cpu_to_le16(chan->scid);
4699
Mat Martineau8eb200b2012-10-23 15:24:17 -07004700 if (result == L2CAP_CR_SUCCESS) {
4701 /* Send successful response */
Andrei Emeltchenko62cd50e2012-11-14 17:39:32 +02004702 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
4703 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004704 } else {
4705 /* Send negative response */
Andrei Emeltchenko62cd50e2012-11-14 17:39:32 +02004706 rsp.result = __constant_cpu_to_le16(L2CAP_CR_NO_MEM);
4707 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004708 }
4709
4710 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_RSP,
4711 sizeof(rsp), &rsp);
4712
4713 if (result == L2CAP_CR_SUCCESS) {
4714 __l2cap_state_change(chan, BT_CONFIG);
4715 set_bit(CONF_REQ_SENT, &chan->conf_state);
4716 l2cap_send_cmd(chan->conn, l2cap_get_ident(chan->conn),
4717 L2CAP_CONF_REQ,
4718 l2cap_build_conf_req(chan, buf), buf);
4719 chan->num_conf_req++;
4720 }
Mat Martineau8eb200b2012-10-23 15:24:17 -07004721 }
4722}
4723
4724static void l2cap_do_move_initiate(struct l2cap_chan *chan, u8 local_amp_id,
4725 u8 remote_amp_id)
4726{
4727 l2cap_move_setup(chan);
4728 chan->move_id = local_amp_id;
4729 chan->move_state = L2CAP_MOVE_WAIT_RSP;
4730
4731 l2cap_send_move_chan_req(chan, remote_amp_id);
4732}
4733
4734static void l2cap_do_move_respond(struct l2cap_chan *chan, int result)
4735{
4736 struct hci_chan *hchan = NULL;
4737
4738 /* Placeholder - get hci_chan for logical link */
4739
4740 if (hchan) {
4741 if (hchan->state == BT_CONNECTED) {
4742 /* Logical link is ready to go */
4743 chan->hs_hcon = hchan->conn;
4744 chan->hs_hcon->l2cap_data = chan->conn;
4745 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4746 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
4747
4748 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
4749 } else {
4750 /* Wait for logical link to be ready */
4751 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4752 }
4753 } else {
4754 /* Logical link not available */
4755 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_ALLOWED);
4756 }
4757}
4758
4759static void l2cap_do_move_cancel(struct l2cap_chan *chan, int result)
4760{
4761 if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
4762 u8 rsp_result;
4763 if (result == -EINVAL)
4764 rsp_result = L2CAP_MR_BAD_ID;
4765 else
4766 rsp_result = L2CAP_MR_NOT_ALLOWED;
4767
4768 l2cap_send_move_chan_rsp(chan, rsp_result);
4769 }
4770
4771 chan->move_role = L2CAP_MOVE_ROLE_NONE;
4772 chan->move_state = L2CAP_MOVE_STABLE;
4773
4774 /* Restart data transmission */
4775 l2cap_ertm_send(chan);
4776}
4777
Andrei Emeltchenkoa514b172012-11-14 17:39:30 +02004778/* Invoke with locked chan */
4779void __l2cap_physical_cfm(struct l2cap_chan *chan, int result)
Mat Martineau8eb200b2012-10-23 15:24:17 -07004780{
Andrei Emeltchenko770bfef2012-10-31 15:46:29 +02004781 u8 local_amp_id = chan->local_amp_id;
Andrei Emeltchenkofffadc02012-11-01 15:37:03 +02004782 u8 remote_amp_id = chan->remote_amp_id;
Andrei Emeltchenko770bfef2012-10-31 15:46:29 +02004783
Mat Martineau8eb200b2012-10-23 15:24:17 -07004784 BT_DBG("chan %p, result %d, local_amp_id %d, remote_amp_id %d",
4785 chan, result, local_amp_id, remote_amp_id);
4786
Mat Martineau8eb200b2012-10-23 15:24:17 -07004787 if (chan->state == BT_DISCONN || chan->state == BT_CLOSED) {
4788 l2cap_chan_unlock(chan);
4789 return;
4790 }
4791
4792 if (chan->state != BT_CONNECTED) {
4793 l2cap_do_create(chan, result, local_amp_id, remote_amp_id);
4794 } else if (result != L2CAP_MR_SUCCESS) {
4795 l2cap_do_move_cancel(chan, result);
4796 } else {
4797 switch (chan->move_role) {
4798 case L2CAP_MOVE_ROLE_INITIATOR:
4799 l2cap_do_move_initiate(chan, local_amp_id,
4800 remote_amp_id);
4801 break;
4802 case L2CAP_MOVE_ROLE_RESPONDER:
4803 l2cap_do_move_respond(chan, result);
4804 break;
4805 default:
4806 l2cap_do_move_cancel(chan, result);
4807 break;
4808 }
4809 }
Mat Martineau8eb200b2012-10-23 15:24:17 -07004810}
4811
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004812static inline int l2cap_move_channel_req(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004813 struct l2cap_cmd_hdr *cmd,
4814 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004815{
4816 struct l2cap_move_chan_req *req = data;
Mat Martineau1500109b2012-10-23 15:24:15 -07004817 struct l2cap_move_chan_rsp rsp;
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004818 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004819 u16 icid = 0;
4820 u16 result = L2CAP_MR_NOT_ALLOWED;
4821
4822 if (cmd_len != sizeof(*req))
4823 return -EPROTO;
4824
4825 icid = le16_to_cpu(req->icid);
4826
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004827 BT_DBG("icid 0x%4.4x, dest_amp_id %d", icid, req->dest_amp_id);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004828
4829 if (!enable_hs)
4830 return -EINVAL;
4831
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004832 chan = l2cap_get_chan_by_dcid(conn, icid);
4833 if (!chan) {
Mat Martineau1500109b2012-10-23 15:24:15 -07004834 rsp.icid = cpu_to_le16(icid);
4835 rsp.result = __constant_cpu_to_le16(L2CAP_MR_NOT_ALLOWED);
4836 l2cap_send_cmd(conn, cmd->ident, L2CAP_MOVE_CHAN_RSP,
4837 sizeof(rsp), &rsp);
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004838 return 0;
4839 }
4840
Mat Martineau1500109b2012-10-23 15:24:15 -07004841 chan->ident = cmd->ident;
4842
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004843 if (chan->scid < L2CAP_CID_DYN_START ||
4844 chan->chan_policy == BT_CHANNEL_POLICY_BREDR_ONLY ||
4845 (chan->mode != L2CAP_MODE_ERTM &&
4846 chan->mode != L2CAP_MODE_STREAMING)) {
4847 result = L2CAP_MR_NOT_ALLOWED;
4848 goto send_move_response;
4849 }
4850
4851 if (chan->local_amp_id == req->dest_amp_id) {
4852 result = L2CAP_MR_SAME_ID;
4853 goto send_move_response;
4854 }
4855
4856 if (req->dest_amp_id) {
4857 struct hci_dev *hdev;
4858 hdev = hci_dev_get(req->dest_amp_id);
4859 if (!hdev || hdev->dev_type != HCI_AMP ||
4860 !test_bit(HCI_UP, &hdev->flags)) {
4861 if (hdev)
4862 hci_dev_put(hdev);
4863
4864 result = L2CAP_MR_BAD_ID;
4865 goto send_move_response;
4866 }
4867 hci_dev_put(hdev);
4868 }
4869
4870 /* Detect a move collision. Only send a collision response
4871 * if this side has "lost", otherwise proceed with the move.
4872 * The winner has the larger bd_addr.
4873 */
4874 if ((__chan_is_moving(chan) ||
4875 chan->move_role != L2CAP_MOVE_ROLE_NONE) &&
4876 bacmp(conn->src, conn->dst) > 0) {
4877 result = L2CAP_MR_COLLISION;
4878 goto send_move_response;
4879 }
4880
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004881 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
4882 l2cap_move_setup(chan);
4883 chan->move_id = req->dest_amp_id;
4884 icid = chan->dcid;
4885
4886 if (!req->dest_amp_id) {
4887 /* Moving to BR/EDR */
4888 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4889 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4890 result = L2CAP_MR_PEND;
4891 } else {
4892 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4893 result = L2CAP_MR_SUCCESS;
4894 }
4895 } else {
4896 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
4897 /* Placeholder - uncomment when amp functions are available */
4898 /*amp_accept_physical(chan, req->dest_amp_id);*/
4899 result = L2CAP_MR_PEND;
4900 }
4901
4902send_move_response:
Mat Martineau1500109b2012-10-23 15:24:15 -07004903 l2cap_send_move_chan_rsp(chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004904
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004905 l2cap_chan_unlock(chan);
4906
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004907 return 0;
4908}
4909
Mat Martineau5b155ef2012-10-23 15:24:14 -07004910static void l2cap_move_continue(struct l2cap_conn *conn, u16 icid, u16 result)
4911{
4912 struct l2cap_chan *chan;
4913 struct hci_chan *hchan = NULL;
4914
4915 chan = l2cap_get_chan_by_scid(conn, icid);
4916 if (!chan) {
4917 l2cap_send_move_chan_cfm_icid(conn, icid);
4918 return;
4919 }
4920
4921 __clear_chan_timer(chan);
4922 if (result == L2CAP_MR_PEND)
4923 __set_chan_timer(chan, L2CAP_MOVE_ERTX_TIMEOUT);
4924
4925 switch (chan->move_state) {
4926 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
4927 /* Move confirm will be sent when logical link
4928 * is complete.
4929 */
4930 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4931 break;
4932 case L2CAP_MOVE_WAIT_RSP_SUCCESS:
4933 if (result == L2CAP_MR_PEND) {
4934 break;
4935 } else if (test_bit(CONN_LOCAL_BUSY,
4936 &chan->conn_state)) {
4937 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4938 } else {
4939 /* Logical link is up or moving to BR/EDR,
4940 * proceed with move
4941 */
4942 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
4943 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4944 }
4945 break;
4946 case L2CAP_MOVE_WAIT_RSP:
4947 /* Moving to AMP */
4948 if (result == L2CAP_MR_SUCCESS) {
4949 /* Remote is ready, send confirm immediately
4950 * after logical link is ready
4951 */
4952 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4953 } else {
4954 /* Both logical link and move success
4955 * are required to confirm
4956 */
4957 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_COMP;
4958 }
4959
4960 /* Placeholder - get hci_chan for logical link */
4961 if (!hchan) {
4962 /* Logical link not available */
4963 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4964 break;
4965 }
4966
4967 /* If the logical link is not yet connected, do not
4968 * send confirmation.
4969 */
4970 if (hchan->state != BT_CONNECTED)
4971 break;
4972
4973 /* Logical link is already ready to go */
4974
4975 chan->hs_hcon = hchan->conn;
4976 chan->hs_hcon->l2cap_data = chan->conn;
4977
4978 if (result == L2CAP_MR_SUCCESS) {
4979 /* Can confirm now */
4980 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4981 } else {
4982 /* Now only need move success
4983 * to confirm
4984 */
4985 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4986 }
4987
4988 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
4989 break;
4990 default:
4991 /* Any other amp move state means the move failed. */
4992 chan->move_id = chan->local_amp_id;
4993 l2cap_move_done(chan);
4994 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4995 }
4996
4997 l2cap_chan_unlock(chan);
4998}
4999
5000static void l2cap_move_fail(struct l2cap_conn *conn, u8 ident, u16 icid,
5001 u16 result)
5002{
5003 struct l2cap_chan *chan;
5004
5005 chan = l2cap_get_chan_by_ident(conn, ident);
5006 if (!chan) {
5007 /* Could not locate channel, icid is best guess */
5008 l2cap_send_move_chan_cfm_icid(conn, icid);
5009 return;
5010 }
5011
5012 __clear_chan_timer(chan);
5013
5014 if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
5015 if (result == L2CAP_MR_COLLISION) {
5016 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
5017 } else {
5018 /* Cleanup - cancel move */
5019 chan->move_id = chan->local_amp_id;
5020 l2cap_move_done(chan);
5021 }
5022 }
5023
5024 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
5025
5026 l2cap_chan_unlock(chan);
5027}
5028
5029static int l2cap_move_channel_rsp(struct l2cap_conn *conn,
5030 struct l2cap_cmd_hdr *cmd,
5031 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005032{
5033 struct l2cap_move_chan_rsp *rsp = data;
5034 u16 icid, result;
5035
5036 if (cmd_len != sizeof(*rsp))
5037 return -EPROTO;
5038
5039 icid = le16_to_cpu(rsp->icid);
5040 result = le16_to_cpu(rsp->result);
5041
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005042 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005043
Mat Martineau5b155ef2012-10-23 15:24:14 -07005044 if (result == L2CAP_MR_SUCCESS || result == L2CAP_MR_PEND)
5045 l2cap_move_continue(conn, icid, result);
5046 else
5047 l2cap_move_fail(conn, cmd->ident, icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005048
5049 return 0;
5050}
5051
Mat Martineau5f3847a2012-10-23 15:24:12 -07005052static int l2cap_move_channel_confirm(struct l2cap_conn *conn,
5053 struct l2cap_cmd_hdr *cmd,
5054 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005055{
5056 struct l2cap_move_chan_cfm *cfm = data;
Mat Martineau5f3847a2012-10-23 15:24:12 -07005057 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005058 u16 icid, result;
5059
5060 if (cmd_len != sizeof(*cfm))
5061 return -EPROTO;
5062
5063 icid = le16_to_cpu(cfm->icid);
5064 result = le16_to_cpu(cfm->result);
5065
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005066 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005067
Mat Martineau5f3847a2012-10-23 15:24:12 -07005068 chan = l2cap_get_chan_by_dcid(conn, icid);
5069 if (!chan) {
5070 /* Spec requires a response even if the icid was not found */
5071 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
5072 return 0;
5073 }
5074
5075 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM) {
5076 if (result == L2CAP_MC_CONFIRMED) {
5077 chan->local_amp_id = chan->move_id;
5078 if (!chan->local_amp_id)
5079 __release_logical_link(chan);
5080 } else {
5081 chan->move_id = chan->local_amp_id;
5082 }
5083
5084 l2cap_move_done(chan);
5085 }
5086
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005087 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
5088
Mat Martineau5f3847a2012-10-23 15:24:12 -07005089 l2cap_chan_unlock(chan);
5090
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005091 return 0;
5092}
5093
5094static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005095 struct l2cap_cmd_hdr *cmd,
5096 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005097{
5098 struct l2cap_move_chan_cfm_rsp *rsp = data;
Mat Martineau3fd71a02012-10-23 15:24:16 -07005099 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005100 u16 icid;
5101
5102 if (cmd_len != sizeof(*rsp))
5103 return -EPROTO;
5104
5105 icid = le16_to_cpu(rsp->icid);
5106
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005107 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005108
Mat Martineau3fd71a02012-10-23 15:24:16 -07005109 chan = l2cap_get_chan_by_scid(conn, icid);
5110 if (!chan)
5111 return 0;
5112
5113 __clear_chan_timer(chan);
5114
5115 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM_RSP) {
5116 chan->local_amp_id = chan->move_id;
5117
5118 if (!chan->local_amp_id && chan->hs_hchan)
5119 __release_logical_link(chan);
5120
5121 l2cap_move_done(chan);
5122 }
5123
5124 l2cap_chan_unlock(chan);
5125
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005126 return 0;
5127}
5128
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03005129static inline int l2cap_check_conn_param(u16 min, u16 max, u16 latency,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005130 u16 to_multiplier)
Claudio Takahaside731152011-02-11 19:28:55 -02005131{
5132 u16 max_latency;
5133
5134 if (min > max || min < 6 || max > 3200)
5135 return -EINVAL;
5136
5137 if (to_multiplier < 10 || to_multiplier > 3200)
5138 return -EINVAL;
5139
5140 if (max >= to_multiplier * 8)
5141 return -EINVAL;
5142
5143 max_latency = (to_multiplier * 8 / max) - 1;
5144 if (latency > 499 || latency > max_latency)
5145 return -EINVAL;
5146
5147 return 0;
5148}
5149
5150static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005151 struct l2cap_cmd_hdr *cmd,
5152 u8 *data)
Claudio Takahaside731152011-02-11 19:28:55 -02005153{
5154 struct hci_conn *hcon = conn->hcon;
5155 struct l2cap_conn_param_update_req *req;
5156 struct l2cap_conn_param_update_rsp rsp;
5157 u16 min, max, latency, to_multiplier, cmd_len;
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005158 int err;
Claudio Takahaside731152011-02-11 19:28:55 -02005159
5160 if (!(hcon->link_mode & HCI_LM_MASTER))
5161 return -EINVAL;
5162
5163 cmd_len = __le16_to_cpu(cmd->len);
5164 if (cmd_len != sizeof(struct l2cap_conn_param_update_req))
5165 return -EPROTO;
5166
5167 req = (struct l2cap_conn_param_update_req *) data;
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03005168 min = __le16_to_cpu(req->min);
5169 max = __le16_to_cpu(req->max);
Claudio Takahaside731152011-02-11 19:28:55 -02005170 latency = __le16_to_cpu(req->latency);
5171 to_multiplier = __le16_to_cpu(req->to_multiplier);
5172
5173 BT_DBG("min 0x%4.4x max 0x%4.4x latency: 0x%4.4x Timeout: 0x%4.4x",
Gustavo Padovan2d792812012-10-06 10:07:01 +01005174 min, max, latency, to_multiplier);
Claudio Takahaside731152011-02-11 19:28:55 -02005175
5176 memset(&rsp, 0, sizeof(rsp));
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005177
5178 err = l2cap_check_conn_param(min, max, latency, to_multiplier);
5179 if (err)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005180 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
Claudio Takahaside731152011-02-11 19:28:55 -02005181 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005182 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED);
Claudio Takahaside731152011-02-11 19:28:55 -02005183
5184 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005185 sizeof(rsp), &rsp);
Claudio Takahaside731152011-02-11 19:28:55 -02005186
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005187 if (!err)
5188 hci_le_conn_update(hcon, min, max, latency, to_multiplier);
5189
Claudio Takahaside731152011-02-11 19:28:55 -02005190 return 0;
5191}
5192
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005193static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005194 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5195 u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005196{
5197 int err = 0;
5198
5199 switch (cmd->code) {
5200 case L2CAP_COMMAND_REJ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005201 l2cap_command_rej(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005202 break;
5203
5204 case L2CAP_CONN_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005205 err = l2cap_connect_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005206 break;
5207
5208 case L2CAP_CONN_RSP:
Mat Martineauf5a25982012-10-11 17:48:21 +03005209 case L2CAP_CREATE_CHAN_RSP:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005210 err = l2cap_connect_create_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005211 break;
5212
5213 case L2CAP_CONF_REQ:
5214 err = l2cap_config_req(conn, cmd, cmd_len, data);
5215 break;
5216
5217 case L2CAP_CONF_RSP:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005218 err = l2cap_config_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005219 break;
5220
5221 case L2CAP_DISCONN_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005222 err = l2cap_disconnect_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005223 break;
5224
5225 case L2CAP_DISCONN_RSP:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005226 err = l2cap_disconnect_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005227 break;
5228
5229 case L2CAP_ECHO_REQ:
5230 l2cap_send_cmd(conn, cmd->ident, L2CAP_ECHO_RSP, cmd_len, data);
5231 break;
5232
5233 case L2CAP_ECHO_RSP:
5234 break;
5235
5236 case L2CAP_INFO_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005237 err = l2cap_information_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005238 break;
5239
5240 case L2CAP_INFO_RSP:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005241 err = l2cap_information_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005242 break;
5243
Mat Martineauf94ff6f2011-11-02 16:18:32 -07005244 case L2CAP_CREATE_CHAN_REQ:
5245 err = l2cap_create_channel_req(conn, cmd, cmd_len, data);
5246 break;
5247
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005248 case L2CAP_MOVE_CHAN_REQ:
5249 err = l2cap_move_channel_req(conn, cmd, cmd_len, data);
5250 break;
5251
5252 case L2CAP_MOVE_CHAN_RSP:
5253 err = l2cap_move_channel_rsp(conn, cmd, cmd_len, data);
5254 break;
5255
5256 case L2CAP_MOVE_CHAN_CFM:
5257 err = l2cap_move_channel_confirm(conn, cmd, cmd_len, data);
5258 break;
5259
5260 case L2CAP_MOVE_CHAN_CFM_RSP:
5261 err = l2cap_move_channel_confirm_rsp(conn, cmd, cmd_len, data);
5262 break;
5263
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005264 default:
5265 BT_ERR("Unknown BR/EDR signaling command 0x%2.2x", cmd->code);
5266 err = -EINVAL;
5267 break;
5268 }
5269
5270 return err;
5271}
5272
5273static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005274 struct l2cap_cmd_hdr *cmd, u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005275{
5276 switch (cmd->code) {
5277 case L2CAP_COMMAND_REJ:
5278 return 0;
5279
5280 case L2CAP_CONN_PARAM_UPDATE_REQ:
Claudio Takahaside731152011-02-11 19:28:55 -02005281 return l2cap_conn_param_update_req(conn, cmd, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005282
5283 case L2CAP_CONN_PARAM_UPDATE_RSP:
5284 return 0;
5285
5286 default:
5287 BT_ERR("Unknown LE signaling command 0x%2.2x", cmd->code);
5288 return -EINVAL;
5289 }
5290}
5291
Johan Hedbergc5623552013-04-29 19:35:33 +03005292static inline void l2cap_le_sig_channel(struct l2cap_conn *conn,
5293 struct sk_buff *skb)
5294{
5295 u8 *data = skb->data;
5296 int len = skb->len;
5297 struct l2cap_cmd_hdr cmd;
5298 int err;
5299
5300 l2cap_raw_recv(conn, skb);
5301
5302 while (len >= L2CAP_CMD_HDR_SIZE) {
5303 u16 cmd_len;
5304 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
5305 data += L2CAP_CMD_HDR_SIZE;
5306 len -= L2CAP_CMD_HDR_SIZE;
5307
5308 cmd_len = le16_to_cpu(cmd.len);
5309
5310 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len,
5311 cmd.ident);
5312
5313 if (cmd_len > len || !cmd.ident) {
5314 BT_DBG("corrupted command");
5315 break;
5316 }
5317
5318 err = l2cap_le_sig_cmd(conn, &cmd, data);
5319 if (err) {
5320 struct l2cap_cmd_rej_unk rej;
5321
5322 BT_ERR("Wrong link type (%d)", err);
5323
5324 /* FIXME: Map err to a valid reason */
5325 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
5326 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ,
5327 sizeof(rej), &rej);
5328 }
5329
5330 data += cmd_len;
5331 len -= cmd_len;
5332 }
5333
5334 kfree_skb(skb);
5335}
5336
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005337static inline void l2cap_sig_channel(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005338 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005339{
5340 u8 *data = skb->data;
5341 int len = skb->len;
5342 struct l2cap_cmd_hdr cmd;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005343 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005344
5345 l2cap_raw_recv(conn, skb);
5346
5347 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07005348 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005349 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
5350 data += L2CAP_CMD_HDR_SIZE;
5351 len -= L2CAP_CMD_HDR_SIZE;
5352
Al Viro88219a02007-07-29 00:17:25 -07005353 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005354
Gustavo Padovan2d792812012-10-06 10:07:01 +01005355 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len,
5356 cmd.ident);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005357
Al Viro88219a02007-07-29 00:17:25 -07005358 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005359 BT_DBG("corrupted command");
5360 break;
5361 }
5362
Johan Hedbergc5623552013-04-29 19:35:33 +03005363 err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005364 if (err) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03005365 struct l2cap_cmd_rej_unk rej;
Gustavo F. Padovan2c6d1a22011-03-23 14:38:32 -03005366
5367 BT_ERR("Wrong link type (%d)", err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005368
5369 /* FIXME: Map err to a valid reason */
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005370 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
Gustavo Padovan2d792812012-10-06 10:07:01 +01005371 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ,
5372 sizeof(rej), &rej);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005373 }
5374
Al Viro88219a02007-07-29 00:17:25 -07005375 data += cmd_len;
5376 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005377 }
5378
5379 kfree_skb(skb);
5380}
5381
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005382static int l2cap_check_fcs(struct l2cap_chan *chan, struct sk_buff *skb)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005383{
5384 u16 our_fcs, rcv_fcs;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03005385 int hdr_size;
5386
5387 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
5388 hdr_size = L2CAP_EXT_HDR_SIZE;
5389 else
5390 hdr_size = L2CAP_ENH_HDR_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005391
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005392 if (chan->fcs == L2CAP_FCS_CRC16) {
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005393 skb_trim(skb, skb->len - L2CAP_FCS_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005394 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
5395 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
5396
5397 if (our_fcs != rcv_fcs)
João Paulo Rechi Vita7a560e52010-06-22 13:56:27 -03005398 return -EBADMSG;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005399 }
5400 return 0;
5401}
5402
Mat Martineau6ea00482012-05-17 20:53:52 -07005403static void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan)
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005404{
Mat Martineaue31f7632012-05-17 20:53:41 -07005405 struct l2cap_ctrl control;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005406
Mat Martineaue31f7632012-05-17 20:53:41 -07005407 BT_DBG("chan %p", chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005408
Mat Martineaue31f7632012-05-17 20:53:41 -07005409 memset(&control, 0, sizeof(control));
5410 control.sframe = 1;
5411 control.final = 1;
5412 control.reqseq = chan->buffer_seq;
5413 set_bit(CONN_SEND_FBIT, &chan->conn_state);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005414
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03005415 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
Mat Martineaue31f7632012-05-17 20:53:41 -07005416 control.super = L2CAP_SUPER_RNR;
5417 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005418 }
5419
Mat Martineaue31f7632012-05-17 20:53:41 -07005420 if (test_and_clear_bit(CONN_REMOTE_BUSY, &chan->conn_state) &&
5421 chan->unacked_frames > 0)
5422 __set_retrans_timer(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005423
Mat Martineaue31f7632012-05-17 20:53:41 -07005424 /* Send pending iframes */
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03005425 l2cap_ertm_send(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005426
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03005427 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
Mat Martineaue31f7632012-05-17 20:53:41 -07005428 test_bit(CONN_SEND_FBIT, &chan->conn_state)) {
5429 /* F-bit wasn't sent in an s-frame or i-frame yet, so
5430 * send it now.
5431 */
5432 control.super = L2CAP_SUPER_RR;
5433 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005434 }
5435}
5436
Gustavo Padovan2d792812012-10-06 10:07:01 +01005437static void append_skb_frag(struct sk_buff *skb, struct sk_buff *new_frag,
5438 struct sk_buff **last_frag)
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005439{
Mat Martineau84084a32011-07-22 14:54:00 -07005440 /* skb->len reflects data in skb as well as all fragments
5441 * skb->data_len reflects only data in fragments
5442 */
5443 if (!skb_has_frag_list(skb))
5444 skb_shinfo(skb)->frag_list = new_frag;
5445
5446 new_frag->next = NULL;
5447
5448 (*last_frag)->next = new_frag;
5449 *last_frag = new_frag;
5450
5451 skb->len += new_frag->len;
5452 skb->data_len += new_frag->len;
5453 skb->truesize += new_frag->truesize;
5454}
5455
Mat Martineau4b51dae92012-05-17 20:53:37 -07005456static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb,
5457 struct l2cap_ctrl *control)
Mat Martineau84084a32011-07-22 14:54:00 -07005458{
5459 int err = -EINVAL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005460
Mat Martineau4b51dae92012-05-17 20:53:37 -07005461 switch (control->sar) {
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005462 case L2CAP_SAR_UNSEGMENTED:
Mat Martineau84084a32011-07-22 14:54:00 -07005463 if (chan->sdu)
5464 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005465
Gustavo Padovan80b98022012-05-27 22:27:51 -03005466 err = chan->ops->recv(chan, skb);
Mat Martineau84084a32011-07-22 14:54:00 -07005467 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005468
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005469 case L2CAP_SAR_START:
Mat Martineau84084a32011-07-22 14:54:00 -07005470 if (chan->sdu)
5471 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005472
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005473 chan->sdu_len = get_unaligned_le16(skb->data);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005474 skb_pull(skb, L2CAP_SDULEN_SIZE);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005475
Mat Martineau84084a32011-07-22 14:54:00 -07005476 if (chan->sdu_len > chan->imtu) {
5477 err = -EMSGSIZE;
5478 break;
5479 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005480
Mat Martineau84084a32011-07-22 14:54:00 -07005481 if (skb->len >= chan->sdu_len)
5482 break;
5483
5484 chan->sdu = skb;
5485 chan->sdu_last_frag = skb;
5486
5487 skb = NULL;
5488 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005489 break;
5490
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005491 case L2CAP_SAR_CONTINUE:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005492 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07005493 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005494
Mat Martineau84084a32011-07-22 14:54:00 -07005495 append_skb_frag(chan->sdu, skb,
5496 &chan->sdu_last_frag);
5497 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005498
Mat Martineau84084a32011-07-22 14:54:00 -07005499 if (chan->sdu->len >= chan->sdu_len)
5500 break;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03005501
Mat Martineau84084a32011-07-22 14:54:00 -07005502 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005503 break;
5504
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005505 case L2CAP_SAR_END:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005506 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07005507 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005508
Mat Martineau84084a32011-07-22 14:54:00 -07005509 append_skb_frag(chan->sdu, skb,
5510 &chan->sdu_last_frag);
5511 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005512
Mat Martineau84084a32011-07-22 14:54:00 -07005513 if (chan->sdu->len != chan->sdu_len)
5514 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005515
Gustavo Padovan80b98022012-05-27 22:27:51 -03005516 err = chan->ops->recv(chan, chan->sdu);
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03005517
Mat Martineau84084a32011-07-22 14:54:00 -07005518 if (!err) {
5519 /* Reassembly complete */
5520 chan->sdu = NULL;
5521 chan->sdu_last_frag = NULL;
5522 chan->sdu_len = 0;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03005523 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005524 break;
5525 }
5526
Mat Martineau84084a32011-07-22 14:54:00 -07005527 if (err) {
5528 kfree_skb(skb);
5529 kfree_skb(chan->sdu);
5530 chan->sdu = NULL;
5531 chan->sdu_last_frag = NULL;
5532 chan->sdu_len = 0;
5533 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005534
Mat Martineau84084a32011-07-22 14:54:00 -07005535 return err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005536}
5537
Mat Martineau32b32732012-10-23 15:24:11 -07005538static int l2cap_resegment(struct l2cap_chan *chan)
5539{
5540 /* Placeholder */
5541 return 0;
5542}
5543
Mat Martineaue3281402011-07-07 09:39:02 -07005544void l2cap_chan_busy(struct l2cap_chan *chan, int busy)
Gustavo F. Padovan712132eb2010-06-21 19:39:50 -03005545{
Mat Martineau61aa4f52012-05-17 20:53:40 -07005546 u8 event;
5547
5548 if (chan->mode != L2CAP_MODE_ERTM)
5549 return;
5550
5551 event = busy ? L2CAP_EV_LOCAL_BUSY_DETECTED : L2CAP_EV_LOCAL_BUSY_CLEAR;
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03005552 l2cap_tx(chan, NULL, NULL, event);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03005553}
5554
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005555static int l2cap_rx_queued_iframes(struct l2cap_chan *chan)
5556{
Mat Martineau63838722012-05-17 20:53:45 -07005557 int err = 0;
5558 /* Pass sequential frames to l2cap_reassemble_sdu()
5559 * until a gap is encountered.
5560 */
5561
5562 BT_DBG("chan %p", chan);
5563
5564 while (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5565 struct sk_buff *skb;
5566 BT_DBG("Searching for skb with txseq %d (queue len %d)",
5567 chan->buffer_seq, skb_queue_len(&chan->srej_q));
5568
5569 skb = l2cap_ertm_seq_in_queue(&chan->srej_q, chan->buffer_seq);
5570
5571 if (!skb)
5572 break;
5573
5574 skb_unlink(skb, &chan->srej_q);
5575 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
5576 err = l2cap_reassemble_sdu(chan, skb, &bt_cb(skb)->control);
5577 if (err)
5578 break;
5579 }
5580
5581 if (skb_queue_empty(&chan->srej_q)) {
5582 chan->rx_state = L2CAP_RX_STATE_RECV;
5583 l2cap_send_ack(chan);
5584 }
5585
5586 return err;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005587}
5588
5589static void l2cap_handle_srej(struct l2cap_chan *chan,
5590 struct l2cap_ctrl *control)
5591{
Mat Martineauf80842a2012-05-17 20:53:46 -07005592 struct sk_buff *skb;
5593
5594 BT_DBG("chan %p, control %p", chan, control);
5595
5596 if (control->reqseq == chan->next_tx_seq) {
5597 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005598 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineauf80842a2012-05-17 20:53:46 -07005599 return;
5600 }
5601
5602 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
5603
5604 if (skb == NULL) {
5605 BT_DBG("Seq %d not available for retransmission",
5606 control->reqseq);
5607 return;
5608 }
5609
5610 if (chan->max_tx != 0 && bt_cb(skb)->control.retries >= chan->max_tx) {
5611 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005612 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineauf80842a2012-05-17 20:53:46 -07005613 return;
5614 }
5615
5616 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5617
5618 if (control->poll) {
5619 l2cap_pass_to_tx(chan, control);
5620
5621 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5622 l2cap_retransmit(chan, control);
5623 l2cap_ertm_send(chan);
5624
5625 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
5626 set_bit(CONN_SREJ_ACT, &chan->conn_state);
5627 chan->srej_save_reqseq = control->reqseq;
5628 }
5629 } else {
5630 l2cap_pass_to_tx_fbit(chan, control);
5631
5632 if (control->final) {
5633 if (chan->srej_save_reqseq != control->reqseq ||
5634 !test_and_clear_bit(CONN_SREJ_ACT,
5635 &chan->conn_state))
5636 l2cap_retransmit(chan, control);
5637 } else {
5638 l2cap_retransmit(chan, control);
5639 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
5640 set_bit(CONN_SREJ_ACT, &chan->conn_state);
5641 chan->srej_save_reqseq = control->reqseq;
5642 }
5643 }
5644 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005645}
5646
5647static void l2cap_handle_rej(struct l2cap_chan *chan,
5648 struct l2cap_ctrl *control)
5649{
Mat Martineaufcd289d2012-05-17 20:53:47 -07005650 struct sk_buff *skb;
5651
5652 BT_DBG("chan %p, control %p", chan, control);
5653
5654 if (control->reqseq == chan->next_tx_seq) {
5655 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005656 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaufcd289d2012-05-17 20:53:47 -07005657 return;
5658 }
5659
5660 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
5661
5662 if (chan->max_tx && skb &&
5663 bt_cb(skb)->control.retries >= chan->max_tx) {
5664 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005665 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaufcd289d2012-05-17 20:53:47 -07005666 return;
5667 }
5668
5669 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5670
5671 l2cap_pass_to_tx(chan, control);
5672
5673 if (control->final) {
5674 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state))
5675 l2cap_retransmit_all(chan, control);
5676 } else {
5677 l2cap_retransmit_all(chan, control);
5678 l2cap_ertm_send(chan);
5679 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F)
5680 set_bit(CONN_REJ_ACT, &chan->conn_state);
5681 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005682}
5683
Mat Martineau4b51dae92012-05-17 20:53:37 -07005684static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq)
5685{
5686 BT_DBG("chan %p, txseq %d", chan, txseq);
5687
5688 BT_DBG("last_acked_seq %d, expected_tx_seq %d", chan->last_acked_seq,
5689 chan->expected_tx_seq);
5690
5691 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
5692 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
Gustavo Padovan2d792812012-10-06 10:07:01 +01005693 chan->tx_win) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07005694 /* See notes below regarding "double poll" and
5695 * invalid packets.
5696 */
5697 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
5698 BT_DBG("Invalid/Ignore - after SREJ");
5699 return L2CAP_TXSEQ_INVALID_IGNORE;
5700 } else {
5701 BT_DBG("Invalid - in window after SREJ sent");
5702 return L2CAP_TXSEQ_INVALID;
5703 }
5704 }
5705
5706 if (chan->srej_list.head == txseq) {
5707 BT_DBG("Expected SREJ");
5708 return L2CAP_TXSEQ_EXPECTED_SREJ;
5709 }
5710
5711 if (l2cap_ertm_seq_in_queue(&chan->srej_q, txseq)) {
5712 BT_DBG("Duplicate SREJ - txseq already stored");
5713 return L2CAP_TXSEQ_DUPLICATE_SREJ;
5714 }
5715
5716 if (l2cap_seq_list_contains(&chan->srej_list, txseq)) {
5717 BT_DBG("Unexpected SREJ - not requested");
5718 return L2CAP_TXSEQ_UNEXPECTED_SREJ;
5719 }
5720 }
5721
5722 if (chan->expected_tx_seq == txseq) {
5723 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
5724 chan->tx_win) {
5725 BT_DBG("Invalid - txseq outside tx window");
5726 return L2CAP_TXSEQ_INVALID;
5727 } else {
5728 BT_DBG("Expected");
5729 return L2CAP_TXSEQ_EXPECTED;
5730 }
5731 }
5732
5733 if (__seq_offset(chan, txseq, chan->last_acked_seq) <
Gustavo Padovan2d792812012-10-06 10:07:01 +01005734 __seq_offset(chan, chan->expected_tx_seq, chan->last_acked_seq)) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07005735 BT_DBG("Duplicate - expected_tx_seq later than txseq");
5736 return L2CAP_TXSEQ_DUPLICATE;
5737 }
5738
5739 if (__seq_offset(chan, txseq, chan->last_acked_seq) >= chan->tx_win) {
5740 /* A source of invalid packets is a "double poll" condition,
5741 * where delays cause us to send multiple poll packets. If
5742 * the remote stack receives and processes both polls,
5743 * sequence numbers can wrap around in such a way that a
5744 * resent frame has a sequence number that looks like new data
5745 * with a sequence gap. This would trigger an erroneous SREJ
5746 * request.
5747 *
5748 * Fortunately, this is impossible with a tx window that's
5749 * less than half of the maximum sequence number, which allows
5750 * invalid frames to be safely ignored.
5751 *
5752 * With tx window sizes greater than half of the tx window
5753 * maximum, the frame is invalid and cannot be ignored. This
5754 * causes a disconnect.
5755 */
5756
5757 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
5758 BT_DBG("Invalid/Ignore - txseq outside tx window");
5759 return L2CAP_TXSEQ_INVALID_IGNORE;
5760 } else {
5761 BT_DBG("Invalid - txseq outside tx window");
5762 return L2CAP_TXSEQ_INVALID;
5763 }
5764 } else {
5765 BT_DBG("Unexpected - txseq indicates missing frames");
5766 return L2CAP_TXSEQ_UNEXPECTED;
5767 }
5768}
5769
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005770static int l2cap_rx_state_recv(struct l2cap_chan *chan,
5771 struct l2cap_ctrl *control,
5772 struct sk_buff *skb, u8 event)
5773{
5774 int err = 0;
5775 bool skb_in_use = 0;
5776
5777 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
5778 event);
5779
5780 switch (event) {
5781 case L2CAP_EV_RECV_IFRAME:
5782 switch (l2cap_classify_txseq(chan, control->txseq)) {
5783 case L2CAP_TXSEQ_EXPECTED:
5784 l2cap_pass_to_tx(chan, control);
5785
5786 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5787 BT_DBG("Busy, discarding expected seq %d",
5788 control->txseq);
5789 break;
5790 }
5791
5792 chan->expected_tx_seq = __next_seq(chan,
5793 control->txseq);
5794
5795 chan->buffer_seq = chan->expected_tx_seq;
5796 skb_in_use = 1;
5797
5798 err = l2cap_reassemble_sdu(chan, skb, control);
5799 if (err)
5800 break;
5801
5802 if (control->final) {
5803 if (!test_and_clear_bit(CONN_REJ_ACT,
5804 &chan->conn_state)) {
5805 control->final = 0;
5806 l2cap_retransmit_all(chan, control);
5807 l2cap_ertm_send(chan);
5808 }
5809 }
5810
5811 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
5812 l2cap_send_ack(chan);
5813 break;
5814 case L2CAP_TXSEQ_UNEXPECTED:
5815 l2cap_pass_to_tx(chan, control);
5816
5817 /* Can't issue SREJ frames in the local busy state.
5818 * Drop this frame, it will be seen as missing
5819 * when local busy is exited.
5820 */
5821 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5822 BT_DBG("Busy, discarding unexpected seq %d",
5823 control->txseq);
5824 break;
5825 }
5826
5827 /* There was a gap in the sequence, so an SREJ
5828 * must be sent for each missing frame. The
5829 * current frame is stored for later use.
5830 */
5831 skb_queue_tail(&chan->srej_q, skb);
5832 skb_in_use = 1;
5833 BT_DBG("Queued %p (queue len %d)", skb,
5834 skb_queue_len(&chan->srej_q));
5835
5836 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
5837 l2cap_seq_list_clear(&chan->srej_list);
5838 l2cap_send_srej(chan, control->txseq);
5839
5840 chan->rx_state = L2CAP_RX_STATE_SREJ_SENT;
5841 break;
5842 case L2CAP_TXSEQ_DUPLICATE:
5843 l2cap_pass_to_tx(chan, control);
5844 break;
5845 case L2CAP_TXSEQ_INVALID_IGNORE:
5846 break;
5847 case L2CAP_TXSEQ_INVALID:
5848 default:
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005849 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005850 break;
5851 }
5852 break;
5853 case L2CAP_EV_RECV_RR:
5854 l2cap_pass_to_tx(chan, control);
5855 if (control->final) {
5856 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5857
Mat Martineaue6a3ee62012-10-23 15:24:22 -07005858 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state) &&
5859 !__chan_is_moving(chan)) {
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005860 control->final = 0;
5861 l2cap_retransmit_all(chan, control);
5862 }
5863
5864 l2cap_ertm_send(chan);
5865 } else if (control->poll) {
5866 l2cap_send_i_or_rr_or_rnr(chan);
5867 } else {
5868 if (test_and_clear_bit(CONN_REMOTE_BUSY,
5869 &chan->conn_state) &&
5870 chan->unacked_frames)
5871 __set_retrans_timer(chan);
5872
5873 l2cap_ertm_send(chan);
5874 }
5875 break;
5876 case L2CAP_EV_RECV_RNR:
5877 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5878 l2cap_pass_to_tx(chan, control);
5879 if (control && control->poll) {
5880 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5881 l2cap_send_rr_or_rnr(chan, 0);
5882 }
5883 __clear_retrans_timer(chan);
5884 l2cap_seq_list_clear(&chan->retrans_list);
5885 break;
5886 case L2CAP_EV_RECV_REJ:
5887 l2cap_handle_rej(chan, control);
5888 break;
5889 case L2CAP_EV_RECV_SREJ:
5890 l2cap_handle_srej(chan, control);
5891 break;
5892 default:
5893 break;
5894 }
5895
5896 if (skb && !skb_in_use) {
5897 BT_DBG("Freeing %p", skb);
5898 kfree_skb(skb);
5899 }
5900
5901 return err;
5902}
5903
5904static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan,
5905 struct l2cap_ctrl *control,
5906 struct sk_buff *skb, u8 event)
5907{
5908 int err = 0;
5909 u16 txseq = control->txseq;
5910 bool skb_in_use = 0;
5911
5912 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
5913 event);
5914
5915 switch (event) {
5916 case L2CAP_EV_RECV_IFRAME:
5917 switch (l2cap_classify_txseq(chan, txseq)) {
5918 case L2CAP_TXSEQ_EXPECTED:
5919 /* Keep frame for reassembly later */
5920 l2cap_pass_to_tx(chan, control);
5921 skb_queue_tail(&chan->srej_q, skb);
5922 skb_in_use = 1;
5923 BT_DBG("Queued %p (queue len %d)", skb,
5924 skb_queue_len(&chan->srej_q));
5925
5926 chan->expected_tx_seq = __next_seq(chan, txseq);
5927 break;
5928 case L2CAP_TXSEQ_EXPECTED_SREJ:
5929 l2cap_seq_list_pop(&chan->srej_list);
5930
5931 l2cap_pass_to_tx(chan, control);
5932 skb_queue_tail(&chan->srej_q, skb);
5933 skb_in_use = 1;
5934 BT_DBG("Queued %p (queue len %d)", skb,
5935 skb_queue_len(&chan->srej_q));
5936
5937 err = l2cap_rx_queued_iframes(chan);
5938 if (err)
5939 break;
5940
5941 break;
5942 case L2CAP_TXSEQ_UNEXPECTED:
5943 /* Got a frame that can't be reassembled yet.
5944 * Save it for later, and send SREJs to cover
5945 * the missing frames.
5946 */
5947 skb_queue_tail(&chan->srej_q, skb);
5948 skb_in_use = 1;
5949 BT_DBG("Queued %p (queue len %d)", skb,
5950 skb_queue_len(&chan->srej_q));
5951
5952 l2cap_pass_to_tx(chan, control);
5953 l2cap_send_srej(chan, control->txseq);
5954 break;
5955 case L2CAP_TXSEQ_UNEXPECTED_SREJ:
5956 /* This frame was requested with an SREJ, but
5957 * some expected retransmitted frames are
5958 * missing. Request retransmission of missing
5959 * SREJ'd frames.
5960 */
5961 skb_queue_tail(&chan->srej_q, skb);
5962 skb_in_use = 1;
5963 BT_DBG("Queued %p (queue len %d)", skb,
5964 skb_queue_len(&chan->srej_q));
5965
5966 l2cap_pass_to_tx(chan, control);
5967 l2cap_send_srej_list(chan, control->txseq);
5968 break;
5969 case L2CAP_TXSEQ_DUPLICATE_SREJ:
5970 /* We've already queued this frame. Drop this copy. */
5971 l2cap_pass_to_tx(chan, control);
5972 break;
5973 case L2CAP_TXSEQ_DUPLICATE:
5974 /* Expecting a later sequence number, so this frame
5975 * was already received. Ignore it completely.
5976 */
5977 break;
5978 case L2CAP_TXSEQ_INVALID_IGNORE:
5979 break;
5980 case L2CAP_TXSEQ_INVALID:
5981 default:
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005982 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005983 break;
5984 }
5985 break;
5986 case L2CAP_EV_RECV_RR:
5987 l2cap_pass_to_tx(chan, control);
5988 if (control->final) {
5989 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5990
5991 if (!test_and_clear_bit(CONN_REJ_ACT,
5992 &chan->conn_state)) {
5993 control->final = 0;
5994 l2cap_retransmit_all(chan, control);
5995 }
5996
5997 l2cap_ertm_send(chan);
5998 } else if (control->poll) {
5999 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6000 &chan->conn_state) &&
6001 chan->unacked_frames) {
6002 __set_retrans_timer(chan);
6003 }
6004
6005 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6006 l2cap_send_srej_tail(chan);
6007 } else {
6008 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6009 &chan->conn_state) &&
6010 chan->unacked_frames)
6011 __set_retrans_timer(chan);
6012
6013 l2cap_send_ack(chan);
6014 }
6015 break;
6016 case L2CAP_EV_RECV_RNR:
6017 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6018 l2cap_pass_to_tx(chan, control);
6019 if (control->poll) {
6020 l2cap_send_srej_tail(chan);
6021 } else {
6022 struct l2cap_ctrl rr_control;
6023 memset(&rr_control, 0, sizeof(rr_control));
6024 rr_control.sframe = 1;
6025 rr_control.super = L2CAP_SUPER_RR;
6026 rr_control.reqseq = chan->buffer_seq;
6027 l2cap_send_sframe(chan, &rr_control);
6028 }
6029
6030 break;
6031 case L2CAP_EV_RECV_REJ:
6032 l2cap_handle_rej(chan, control);
6033 break;
6034 case L2CAP_EV_RECV_SREJ:
6035 l2cap_handle_srej(chan, control);
6036 break;
6037 }
6038
6039 if (skb && !skb_in_use) {
6040 BT_DBG("Freeing %p", skb);
6041 kfree_skb(skb);
6042 }
6043
6044 return err;
6045}
6046
Mat Martineau32b32732012-10-23 15:24:11 -07006047static int l2cap_finish_move(struct l2cap_chan *chan)
6048{
6049 BT_DBG("chan %p", chan);
6050
6051 chan->rx_state = L2CAP_RX_STATE_RECV;
6052
6053 if (chan->hs_hcon)
6054 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
6055 else
6056 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
6057
6058 return l2cap_resegment(chan);
6059}
6060
6061static int l2cap_rx_state_wait_p(struct l2cap_chan *chan,
6062 struct l2cap_ctrl *control,
6063 struct sk_buff *skb, u8 event)
6064{
6065 int err;
6066
6067 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
6068 event);
6069
6070 if (!control->poll)
6071 return -EPROTO;
6072
6073 l2cap_process_reqseq(chan, control->reqseq);
6074
6075 if (!skb_queue_empty(&chan->tx_q))
6076 chan->tx_send_head = skb_peek(&chan->tx_q);
6077 else
6078 chan->tx_send_head = NULL;
6079
6080 /* Rewind next_tx_seq to the point expected
6081 * by the receiver.
6082 */
6083 chan->next_tx_seq = control->reqseq;
6084 chan->unacked_frames = 0;
6085
6086 err = l2cap_finish_move(chan);
6087 if (err)
6088 return err;
6089
6090 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6091 l2cap_send_i_or_rr_or_rnr(chan);
6092
6093 if (event == L2CAP_EV_RECV_IFRAME)
6094 return -EPROTO;
6095
6096 return l2cap_rx_state_recv(chan, control, NULL, event);
6097}
6098
6099static int l2cap_rx_state_wait_f(struct l2cap_chan *chan,
6100 struct l2cap_ctrl *control,
6101 struct sk_buff *skb, u8 event)
6102{
6103 int err;
6104
6105 if (!control->final)
6106 return -EPROTO;
6107
6108 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6109
6110 chan->rx_state = L2CAP_RX_STATE_RECV;
6111 l2cap_process_reqseq(chan, control->reqseq);
6112
6113 if (!skb_queue_empty(&chan->tx_q))
6114 chan->tx_send_head = skb_peek(&chan->tx_q);
6115 else
6116 chan->tx_send_head = NULL;
6117
6118 /* Rewind next_tx_seq to the point expected
6119 * by the receiver.
6120 */
6121 chan->next_tx_seq = control->reqseq;
6122 chan->unacked_frames = 0;
6123
6124 if (chan->hs_hcon)
6125 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
6126 else
6127 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
6128
6129 err = l2cap_resegment(chan);
6130
6131 if (!err)
6132 err = l2cap_rx_state_recv(chan, control, skb, event);
6133
6134 return err;
6135}
6136
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006137static bool __valid_reqseq(struct l2cap_chan *chan, u16 reqseq)
6138{
6139 /* Make sure reqseq is for a packet that has been sent but not acked */
6140 u16 unacked;
6141
6142 unacked = __seq_offset(chan, chan->next_tx_seq, chan->expected_ack_seq);
6143 return __seq_offset(chan, chan->next_tx_seq, reqseq) <= unacked;
6144}
6145
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006146static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
6147 struct sk_buff *skb, u8 event)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006148{
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006149 int err = 0;
6150
6151 BT_DBG("chan %p, control %p, skb %p, event %d, state %d", chan,
6152 control, skb, event, chan->rx_state);
6153
6154 if (__valid_reqseq(chan, control->reqseq)) {
6155 switch (chan->rx_state) {
6156 case L2CAP_RX_STATE_RECV:
6157 err = l2cap_rx_state_recv(chan, control, skb, event);
6158 break;
6159 case L2CAP_RX_STATE_SREJ_SENT:
6160 err = l2cap_rx_state_srej_sent(chan, control, skb,
6161 event);
6162 break;
Mat Martineau32b32732012-10-23 15:24:11 -07006163 case L2CAP_RX_STATE_WAIT_P:
6164 err = l2cap_rx_state_wait_p(chan, control, skb, event);
6165 break;
6166 case L2CAP_RX_STATE_WAIT_F:
6167 err = l2cap_rx_state_wait_f(chan, control, skb, event);
6168 break;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006169 default:
6170 /* shut it down */
6171 break;
6172 }
6173 } else {
6174 BT_DBG("Invalid reqseq %d (next_tx_seq %d, expected_ack_seq %d",
6175 control->reqseq, chan->next_tx_seq,
6176 chan->expected_ack_seq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006177 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006178 }
6179
6180 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006181}
6182
6183static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
6184 struct sk_buff *skb)
6185{
Mat Martineau4b51dae92012-05-17 20:53:37 -07006186 int err = 0;
6187
6188 BT_DBG("chan %p, control %p, skb %p, state %d", chan, control, skb,
6189 chan->rx_state);
6190
6191 if (l2cap_classify_txseq(chan, control->txseq) ==
6192 L2CAP_TXSEQ_EXPECTED) {
6193 l2cap_pass_to_tx(chan, control);
6194
6195 BT_DBG("buffer_seq %d->%d", chan->buffer_seq,
6196 __next_seq(chan, chan->buffer_seq));
6197
6198 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
6199
6200 l2cap_reassemble_sdu(chan, skb, control);
6201 } else {
6202 if (chan->sdu) {
6203 kfree_skb(chan->sdu);
6204 chan->sdu = NULL;
6205 }
6206 chan->sdu_last_frag = NULL;
6207 chan->sdu_len = 0;
6208
6209 if (skb) {
6210 BT_DBG("Freeing %p", skb);
6211 kfree_skb(skb);
6212 }
6213 }
6214
6215 chan->last_acked_seq = control->txseq;
6216 chan->expected_tx_seq = __next_seq(chan, control->txseq);
6217
6218 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006219}
6220
6221static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
6222{
6223 struct l2cap_ctrl *control = &bt_cb(skb)->control;
6224 u16 len;
6225 u8 event;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006226
Mat Martineaub76bbd62012-04-11 10:48:43 -07006227 __unpack_control(chan, skb);
6228
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006229 len = skb->len;
6230
6231 /*
6232 * We can just drop the corrupted I-frame here.
6233 * Receiver will miss it and start proper recovery
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006234 * procedures and ask for retransmission.
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006235 */
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006236 if (l2cap_check_fcs(chan, skb))
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006237 goto drop;
6238
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006239 if (!control->sframe && control->sar == L2CAP_SAR_START)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03006240 len -= L2CAP_SDULEN_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006241
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006242 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03006243 len -= L2CAP_FCS_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006244
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006245 if (len > chan->mps) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006246 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006247 goto drop;
6248 }
6249
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006250 if (!control->sframe) {
6251 int err;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006252
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006253 BT_DBG("iframe sar %d, reqseq %d, final %d, txseq %d",
6254 control->sar, control->reqseq, control->final,
6255 control->txseq);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03006256
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006257 /* Validate F-bit - F=0 always valid, F=1 only
6258 * valid in TX WAIT_F
6259 */
6260 if (control->final && chan->tx_state != L2CAP_TX_STATE_WAIT_F)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006261 goto drop;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006262
6263 if (chan->mode != L2CAP_MODE_STREAMING) {
6264 event = L2CAP_EV_RECV_IFRAME;
6265 err = l2cap_rx(chan, control, skb, event);
6266 } else {
6267 err = l2cap_stream_rx(chan, control, skb);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006268 }
6269
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006270 if (err)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006271 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006272 } else {
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006273 const u8 rx_func_to_event[4] = {
6274 L2CAP_EV_RECV_RR, L2CAP_EV_RECV_REJ,
6275 L2CAP_EV_RECV_RNR, L2CAP_EV_RECV_SREJ
6276 };
6277
6278 /* Only I-frames are expected in streaming mode */
6279 if (chan->mode == L2CAP_MODE_STREAMING)
6280 goto drop;
6281
6282 BT_DBG("sframe reqseq %d, final %d, poll %d, super %d",
6283 control->reqseq, control->final, control->poll,
6284 control->super);
6285
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006286 if (len != 0) {
Andrei Emeltchenko1bb166e2012-11-20 17:16:21 +02006287 BT_ERR("Trailing bytes: %d in sframe", len);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006288 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006289 goto drop;
6290 }
6291
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006292 /* Validate F and P bits */
6293 if (control->final && (control->poll ||
6294 chan->tx_state != L2CAP_TX_STATE_WAIT_F))
6295 goto drop;
6296
6297 event = rx_func_to_event[control->super];
6298 if (l2cap_rx(chan, control, skb, event))
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006299 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006300 }
6301
6302 return 0;
6303
6304drop:
6305 kfree_skb(skb);
6306 return 0;
6307}
6308
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006309static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid,
6310 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006311{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006312 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006313
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03006314 chan = l2cap_get_chan_by_scid(conn, cid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006315 if (!chan) {
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006316 if (cid == L2CAP_CID_A2MP) {
6317 chan = a2mp_channel_create(conn, skb);
6318 if (!chan) {
6319 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006320 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006321 }
6322
6323 l2cap_chan_lock(chan);
6324 } else {
6325 BT_DBG("unknown cid 0x%4.4x", cid);
6326 /* Drop packet and return */
6327 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006328 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006329 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006330 }
6331
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03006332 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006333
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03006334 if (chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006335 goto drop;
6336
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006337 switch (chan->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006338 case L2CAP_MODE_BASIC:
6339 /* If socket recv buffers overflows we drop data here
6340 * which is *bad* because L2CAP has to be reliable.
6341 * But we don't have any other choice. L2CAP doesn't
6342 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006343
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006344 if (chan->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006345 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006346
Gustavo Padovan80b98022012-05-27 22:27:51 -03006347 if (!chan->ops->recv(chan, skb))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006348 goto done;
6349 break;
6350
6351 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03006352 case L2CAP_MODE_STREAMING:
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006353 l2cap_data_rcv(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03006354 goto done;
6355
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006356 default:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006357 BT_DBG("chan %p: bad mode 0x%2.2x", chan, chan->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006358 break;
6359 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006360
6361drop:
6362 kfree_skb(skb);
6363
6364done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006365 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006366}
6367
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03006368static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm,
6369 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006370{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006371 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006372
Ido Yarivc2287682012-04-20 15:46:07 -03006373 chan = l2cap_global_chan_by_psm(0, psm, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006374 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006375 goto drop;
6376
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02006377 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006378
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03006379 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006380 goto drop;
6381
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03006382 if (chan->imtu < skb->len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006383 goto drop;
6384
Gustavo Padovan80b98022012-05-27 22:27:51 -03006385 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03006386 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006387
6388drop:
6389 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006390}
6391
Marcel Holtmann72f78352013-04-23 00:59:00 -07006392static void l2cap_att_channel(struct l2cap_conn *conn,
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03006393 struct sk_buff *skb)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006394{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006395 struct l2cap_chan *chan;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006396
Johan Hedbergaf1c0132013-04-29 19:35:42 +03006397 chan = l2cap_global_chan_by_scid(BT_CONNECTED, L2CAP_CID_ATT,
Marcel Holtmann72f78352013-04-23 00:59:00 -07006398 conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006399 if (!chan)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006400 goto drop;
6401
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02006402 BT_DBG("chan %p, len %d", chan, skb->len);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006403
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03006404 if (chan->imtu < skb->len)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006405 goto drop;
6406
Gustavo Padovan80b98022012-05-27 22:27:51 -03006407 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03006408 return;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006409
6410drop:
6411 kfree_skb(skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006412}
6413
Linus Torvalds1da177e2005-04-16 15:20:36 -07006414static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
6415{
6416 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07006417 u16 cid, len;
6418 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006419
6420 skb_pull(skb, L2CAP_HDR_SIZE);
6421 cid = __le16_to_cpu(lh->cid);
6422 len = __le16_to_cpu(lh->len);
6423
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006424 if (len != skb->len) {
6425 kfree_skb(skb);
6426 return;
6427 }
6428
Linus Torvalds1da177e2005-04-16 15:20:36 -07006429 BT_DBG("len %d, cid 0x%4.4x", len, cid);
6430
6431 switch (cid) {
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02006432 case L2CAP_CID_LE_SIGNALING:
Johan Hedbergc5623552013-04-29 19:35:33 +03006433 l2cap_le_sig_channel(conn, skb);
6434 break;
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03006435 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006436 l2cap_sig_channel(conn, skb);
6437 break;
6438
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03006439 case L2CAP_CID_CONN_LESS:
Andrei Emeltchenko097db762012-03-09 14:16:17 +02006440 psm = get_unaligned((__le16 *) skb->data);
Andrei Emeltchenko0181a702012-05-29 10:04:05 +03006441 skb_pull(skb, L2CAP_PSMLEN_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006442 l2cap_conless_channel(conn, psm, skb);
6443 break;
6444
Johan Hedberg073d1cf2013-04-29 19:35:35 +03006445 case L2CAP_CID_ATT:
Marcel Holtmann72f78352013-04-23 00:59:00 -07006446 l2cap_att_channel(conn, skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006447 break;
6448
Anderson Brigliab501d6a2011-06-07 18:46:31 -03006449 case L2CAP_CID_SMP:
6450 if (smp_sig_channel(conn, skb))
6451 l2cap_conn_del(conn->hcon, EACCES);
6452 break;
6453
Linus Torvalds1da177e2005-04-16 15:20:36 -07006454 default:
6455 l2cap_data_channel(conn, cid, skb);
6456 break;
6457 }
6458}
6459
6460/* ---- L2CAP interface with lower layer (HCI) ---- */
6461
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006462int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006463{
6464 int exact = 0, lm1 = 0, lm2 = 0;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006465 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006466
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03006467 BT_DBG("hdev %s, bdaddr %pMR", hdev->name, bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006468
6469 /* Find listening sockets and check their link_mode */
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006470 read_lock(&chan_list_lock);
6471 list_for_each_entry(c, &chan_list, global_l) {
6472 struct sock *sk = c->sk;
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006473
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03006474 if (c->state != BT_LISTEN)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006475 continue;
6476
6477 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006478 lm1 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03006479 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006480 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006481 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006482 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
6483 lm2 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03006484 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006485 lm2 |= HCI_LM_MASTER;
6486 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006487 }
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006488 read_unlock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006489
6490 return exact ? lm1 : lm2;
6491}
6492
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03006493void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006494{
Marcel Holtmann01394182006-07-03 10:02:46 +02006495 struct l2cap_conn *conn;
6496
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03006497 BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006498
Linus Torvalds1da177e2005-04-16 15:20:36 -07006499 if (!status) {
Claudio Takahasibaf43252013-04-11 13:55:50 -03006500 conn = l2cap_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006501 if (conn)
6502 l2cap_conn_ready(conn);
Andrei Emeltchenkoba6fc312012-10-31 15:46:26 +02006503 } else {
Joe Perchese1750722011-06-29 18:18:29 -07006504 l2cap_conn_del(hcon, bt_to_errno(status));
Andrei Emeltchenkoba6fc312012-10-31 15:46:26 +02006505 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006506}
6507
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006508int l2cap_disconn_ind(struct hci_conn *hcon)
Marcel Holtmann2950f212009-02-12 14:02:50 +01006509{
6510 struct l2cap_conn *conn = hcon->l2cap_data;
6511
6512 BT_DBG("hcon %p", hcon);
6513
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006514 if (!conn)
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02006515 return HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01006516 return conn->disc_reason;
6517}
6518
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03006519void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006520{
6521 BT_DBG("hcon %p reason %d", hcon, reason);
6522
Joe Perchese1750722011-06-29 18:18:29 -07006523 l2cap_conn_del(hcon, bt_to_errno(reason));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006524}
6525
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006526static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006527{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03006528 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED)
Marcel Holtmann255c7602009-02-04 21:07:19 +01006529 return;
6530
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006531 if (encrypt == 0x00) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006532 if (chan->sec_level == BT_SECURITY_MEDIUM) {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006533 __set_chan_timer(chan, L2CAP_ENC_TIMEOUT);
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006534 } else if (chan->sec_level == BT_SECURITY_HIGH)
Gustavo F. Padovan0f852722011-05-04 19:42:50 -03006535 l2cap_chan_close(chan, ECONNREFUSED);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006536 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006537 if (chan->sec_level == BT_SECURITY_MEDIUM)
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03006538 __clear_chan_timer(chan);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006539 }
6540}
6541
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006542int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006543{
Marcel Holtmann40be4922008-07-14 20:13:50 +02006544 struct l2cap_conn *conn = hcon->l2cap_data;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006545 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006546
Marcel Holtmann01394182006-07-03 10:02:46 +02006547 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006548 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02006549
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03006550 BT_DBG("conn %p status 0x%2.2x encrypt %u", conn, status, encrypt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006551
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03006552 if (hcon->type == LE_LINK) {
Hemant Gupta35d4adcc2012-04-18 14:46:26 +05306553 if (!status && encrypt)
6554 smp_distribute_keys(conn, 0);
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02006555 cancel_delayed_work(&conn->security_timer);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03006556 }
6557
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006558 mutex_lock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006559
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006560 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006561 l2cap_chan_lock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006562
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03006563 BT_DBG("chan %p scid 0x%4.4x state %s", chan, chan->scid,
6564 state_to_string(chan->state));
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006565
Andrei Emeltchenko78eb2f92012-07-19 17:03:47 +03006566 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
6567 l2cap_chan_unlock(chan);
6568 continue;
6569 }
6570
Johan Hedberg073d1cf2013-04-29 19:35:35 +03006571 if (chan->scid == L2CAP_CID_ATT) {
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006572 if (!status && encrypt) {
6573 chan->sec_level = hcon->sec_level;
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02006574 l2cap_chan_ready(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006575 }
6576
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006577 l2cap_chan_unlock(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006578 continue;
6579 }
6580
Andrei Emeltchenko96eff462012-11-15 18:14:53 +02006581 if (!__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006582 l2cap_chan_unlock(chan);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01006583 continue;
6584 }
6585
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03006586 if (!status && (chan->state == BT_CONNECTED ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01006587 chan->state == BT_CONFIG)) {
Gustavo Padovana7d77232012-05-13 03:20:07 -03006588 struct sock *sk = chan->sk;
6589
Gustavo Padovanc5daa682012-05-16 12:17:10 -03006590 clear_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags);
Gustavo Padovana7d77232012-05-13 03:20:07 -03006591 sk->sk_state_change(sk);
6592
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006593 l2cap_check_encryption(chan, encrypt);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006594 l2cap_chan_unlock(chan);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02006595 continue;
6596 }
6597
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03006598 if (chan->state == BT_CONNECT) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006599 if (!status) {
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03006600 l2cap_start_connection(chan);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006601 } else {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006602 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006603 }
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03006604 } else if (chan->state == BT_CONNECT2) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006605 struct sock *sk = chan->sk;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006606 struct l2cap_conn_rsp rsp;
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006607 __u16 res, stat;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006608
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006609 lock_sock(sk);
6610
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006611 if (!status) {
Gustavo Padovanc5daa682012-05-16 12:17:10 -03006612 if (test_bit(BT_SK_DEFER_SETUP,
6613 &bt_sk(sk)->flags)) {
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006614 res = L2CAP_CR_PEND;
6615 stat = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08006616 chan->ops->defer(chan);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006617 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02006618 __l2cap_state_change(chan, BT_CONFIG);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006619 res = L2CAP_CR_SUCCESS;
6620 stat = L2CAP_CS_NO_INFO;
6621 }
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006622 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02006623 __l2cap_state_change(chan, BT_DISCONN);
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006624 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006625 res = L2CAP_CR_SEC_BLOCK;
6626 stat = L2CAP_CS_NO_INFO;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006627 }
6628
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006629 release_sock(sk);
6630
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03006631 rsp.scid = cpu_to_le16(chan->dcid);
6632 rsp.dcid = cpu_to_le16(chan->scid);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006633 rsp.result = cpu_to_le16(res);
6634 rsp.status = cpu_to_le16(stat);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03006635 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01006636 sizeof(rsp), &rsp);
Mat Martineau2d369352012-05-23 14:59:30 -07006637
6638 if (!test_bit(CONF_REQ_SENT, &chan->conf_state) &&
6639 res == L2CAP_CR_SUCCESS) {
6640 char buf[128];
6641 set_bit(CONF_REQ_SENT, &chan->conf_state);
6642 l2cap_send_cmd(conn, l2cap_get_ident(conn),
6643 L2CAP_CONF_REQ,
6644 l2cap_build_conf_req(chan, buf),
6645 buf);
6646 chan->num_conf_req++;
6647 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006648 }
6649
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006650 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006651 }
6652
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006653 mutex_unlock(&conn->chan_lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006654
Linus Torvalds1da177e2005-04-16 15:20:36 -07006655 return 0;
6656}
6657
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006658int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006659{
6660 struct l2cap_conn *conn = hcon->l2cap_data;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006661 struct l2cap_hdr *hdr;
6662 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006663
Andrei Emeltchenko1d13a252012-10-15 11:58:41 +03006664 /* For AMP controller do not create l2cap conn */
6665 if (!conn && hcon->hdev->dev_type != HCI_BREDR)
6666 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006667
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02006668 if (!conn)
Claudio Takahasibaf43252013-04-11 13:55:50 -03006669 conn = l2cap_conn_add(hcon);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02006670
6671 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006672 goto drop;
6673
6674 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
6675
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006676 switch (flags) {
6677 case ACL_START:
6678 case ACL_START_NO_FLUSH:
6679 case ACL_COMPLETE:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006680 if (conn->rx_len) {
6681 BT_ERR("Unexpected start frame (len %d)", skb->len);
6682 kfree_skb(conn->rx_skb);
6683 conn->rx_skb = NULL;
6684 conn->rx_len = 0;
6685 l2cap_conn_unreliable(conn, ECOMM);
6686 }
6687
Andrei Emeltchenkoaae7fe22010-09-15 14:28:43 +03006688 /* Start fragment always begin with Basic L2CAP header */
6689 if (skb->len < L2CAP_HDR_SIZE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006690 BT_ERR("Frame is too short (len %d)", skb->len);
6691 l2cap_conn_unreliable(conn, ECOMM);
6692 goto drop;
6693 }
6694
6695 hdr = (struct l2cap_hdr *) skb->data;
6696 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
6697
6698 if (len == skb->len) {
6699 /* Complete frame received */
6700 l2cap_recv_frame(conn, skb);
6701 return 0;
6702 }
6703
6704 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
6705
6706 if (skb->len > len) {
6707 BT_ERR("Frame is too long (len %d, expected len %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01006708 skb->len, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006709 l2cap_conn_unreliable(conn, ECOMM);
6710 goto drop;
6711 }
6712
6713 /* Allocate skb for the complete frame (with header) */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03006714 conn->rx_skb = bt_skb_alloc(len, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03006715 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006716 goto drop;
6717
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03006718 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01006719 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006720 conn->rx_len = len - skb->len;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006721 break;
6722
6723 case ACL_CONT:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006724 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
6725
6726 if (!conn->rx_len) {
6727 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
6728 l2cap_conn_unreliable(conn, ECOMM);
6729 goto drop;
6730 }
6731
6732 if (skb->len > conn->rx_len) {
6733 BT_ERR("Fragment is too long (len %d, expected %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01006734 skb->len, conn->rx_len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006735 kfree_skb(conn->rx_skb);
6736 conn->rx_skb = NULL;
6737 conn->rx_len = 0;
6738 l2cap_conn_unreliable(conn, ECOMM);
6739 goto drop;
6740 }
6741
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03006742 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01006743 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006744 conn->rx_len -= skb->len;
6745
6746 if (!conn->rx_len) {
6747 /* Complete frame received */
6748 l2cap_recv_frame(conn, conn->rx_skb);
6749 conn->rx_skb = NULL;
6750 }
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006751 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006752 }
6753
6754drop:
6755 kfree_skb(skb);
6756 return 0;
6757}
6758
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006759static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006760{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006761 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006762
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02006763 read_lock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006764
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006765 list_for_each_entry(c, &chan_list, global_l) {
6766 struct sock *sk = c->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006767
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +03006768 seq_printf(f, "%pMR %pMR %d %d 0x%4.4x 0x%4.4x %d %d %d %d\n",
6769 &bt_sk(sk)->src, &bt_sk(sk)->dst,
6770 c->state, __le16_to_cpu(c->psm),
6771 c->scid, c->dcid, c->imtu, c->omtu,
6772 c->sec_level, c->mode);
Andrei Emeltchenko61e1b4b2012-01-19 11:19:50 +02006773 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006774
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02006775 read_unlock(&chan_list_lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08006776
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006777 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006778}
6779
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006780static int l2cap_debugfs_open(struct inode *inode, struct file *file)
6781{
6782 return single_open(file, l2cap_debugfs_show, inode->i_private);
6783}
6784
6785static const struct file_operations l2cap_debugfs_fops = {
6786 .open = l2cap_debugfs_open,
6787 .read = seq_read,
6788 .llseek = seq_lseek,
6789 .release = single_release,
6790};
6791
6792static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006793
Gustavo F. Padovan64274512011-02-07 20:08:52 -02006794int __init l2cap_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006795{
6796 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08006797
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02006798 err = l2cap_init_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006799 if (err < 0)
6800 return err;
6801
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006802 if (bt_debugfs) {
Gustavo Padovan2d792812012-10-06 10:07:01 +01006803 l2cap_debugfs = debugfs_create_file("l2cap", 0444, bt_debugfs,
6804 NULL, &l2cap_debugfs_fops);
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006805 if (!l2cap_debugfs)
6806 BT_ERR("Failed to create L2CAP debug file");
6807 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006808
Linus Torvalds1da177e2005-04-16 15:20:36 -07006809 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006810}
6811
Gustavo F. Padovan64274512011-02-07 20:08:52 -02006812void l2cap_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006813{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006814 debugfs_remove(l2cap_debugfs);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02006815 l2cap_cleanup_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006816}
6817
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03006818module_param(disable_ertm, bool, 0644);
6819MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode");