blob: 8b5437c44c7b297a1000b182a818843df22c38cb [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>
Marcel Holtmann7ef9fbf2013-10-10 14:54:14 -070039
Marcel Holtmannac4b7232013-10-10 14:54:16 -070040#include "smp.h"
Marcel Holtmann70247282013-10-10 14:54:15 -070041#include "a2mp.h"
Marcel Holtmann7ef9fbf2013-10-10 14:54:14 -070042#include "amp.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070043
Mat Martineaud1de6d42012-05-17 20:53:55 -070044bool disable_ertm;
Marcel Holtmannf0709e02007-10-20 13:38:51 +020045
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -070046static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN;
Marcel Holtmannd40bffb2013-10-12 08:18:18 -070047static u8 l2cap_fixed_chan[8] = { L2CAP_FC_L2CAP | L2CAP_FC_CONNLESS, };
Linus Torvalds1da177e2005-04-16 15:20:36 -070048
Johannes Bergb5ad8b72011-06-01 08:54:45 +020049static LIST_HEAD(chan_list);
50static DEFINE_RWLOCK(chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -070051
Linus Torvalds1da177e2005-04-16 15:20:36 -070052static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +010053 u8 code, u8 ident, u16 dlen, void *data);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -030054static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
Gustavo Padovan2d792812012-10-06 10:07:01 +010055 void *data);
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -030056static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +020057static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err);
Linus Torvalds1da177e2005-04-16 15:20:36 -070058
Gustavo Padovand6603662012-05-21 13:58:22 -030059static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
Gustavo Padovan2d792812012-10-06 10:07:01 +010060 struct sk_buff_head *skbs, u8 event);
Mat Martineau608bcc62012-05-17 20:53:32 -070061
Marcel Holtmann01394182006-07-03 10:02:46 +020062/* ---- L2CAP channels ---- */
Gustavo F. Padovan71ba0e52011-05-17 14:34:52 -030063
Gustavo Padovan2d792812012-10-06 10:07:01 +010064static struct l2cap_chan *__l2cap_get_chan_by_dcid(struct l2cap_conn *conn,
65 u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +020066{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020067 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030068
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020069 list_for_each_entry(c, &conn->chan_l, list) {
70 if (c->dcid == cid)
71 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +020072 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020073 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +020074}
75
Gustavo Padovan2d792812012-10-06 10:07:01 +010076static struct l2cap_chan *__l2cap_get_chan_by_scid(struct l2cap_conn *conn,
77 u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +020078{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020079 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030080
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020081 list_for_each_entry(c, &conn->chan_l, list) {
82 if (c->scid == cid)
83 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +020084 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020085 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +020086}
87
88/* Find channel with given SCID.
Mat Martineauef191ad2012-05-02 09:42:00 -070089 * Returns locked channel. */
Gustavo Padovan2d792812012-10-06 10:07:01 +010090static struct l2cap_chan *l2cap_get_chan_by_scid(struct l2cap_conn *conn,
91 u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +020092{
Gustavo F. Padovan48454072011-03-25 00:22:30 -030093 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030094
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020095 mutex_lock(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030096 c = __l2cap_get_chan_by_scid(conn, cid);
Mat Martineauef191ad2012-05-02 09:42:00 -070097 if (c)
98 l2cap_chan_lock(c);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020099 mutex_unlock(&conn->chan_lock);
100
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300101 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +0200102}
103
Mat Martineaub1a130b2012-10-23 15:24:09 -0700104/* Find channel with given DCID.
105 * Returns locked channel.
106 */
107static struct l2cap_chan *l2cap_get_chan_by_dcid(struct l2cap_conn *conn,
108 u16 cid)
109{
110 struct l2cap_chan *c;
111
112 mutex_lock(&conn->chan_lock);
113 c = __l2cap_get_chan_by_dcid(conn, cid);
114 if (c)
115 l2cap_chan_lock(c);
116 mutex_unlock(&conn->chan_lock);
117
118 return c;
119}
120
Gustavo Padovan2d792812012-10-06 10:07:01 +0100121static struct l2cap_chan *__l2cap_get_chan_by_ident(struct l2cap_conn *conn,
122 u8 ident)
Marcel Holtmann01394182006-07-03 10:02:46 +0200123{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200124 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300125
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200126 list_for_each_entry(c, &conn->chan_l, list) {
127 if (c->ident == ident)
128 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +0200129 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200130 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200131}
132
Mat Martineau5b155ef2012-10-23 15:24:14 -0700133static struct l2cap_chan *l2cap_get_chan_by_ident(struct l2cap_conn *conn,
134 u8 ident)
135{
136 struct l2cap_chan *c;
137
138 mutex_lock(&conn->chan_lock);
139 c = __l2cap_get_chan_by_ident(conn, ident);
140 if (c)
141 l2cap_chan_lock(c);
142 mutex_unlock(&conn->chan_lock);
143
144 return c;
145}
146
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300147static struct l2cap_chan *__l2cap_global_chan_by_addr(__le16 psm, bdaddr_t *src)
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300148{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300149 struct l2cap_chan *c;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300150
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300151 list_for_each_entry(c, &chan_list, global_l) {
152 if (c->sport == psm && !bacmp(&bt_sk(c->sk)->src, src))
Szymon Janc250938c2011-11-16 09:32:22 +0100153 return c;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300154 }
Szymon Janc250938c2011-11-16 09:32:22 +0100155 return NULL;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300156}
157
158int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm)
159{
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300160 int err;
161
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200162 write_lock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300163
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300164 if (psm && __l2cap_global_chan_by_addr(psm, src)) {
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300165 err = -EADDRINUSE;
166 goto done;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300167 }
168
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300169 if (psm) {
170 chan->psm = psm;
171 chan->sport = psm;
172 err = 0;
173 } else {
174 u16 p;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300175
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300176 err = -EINVAL;
177 for (p = 0x1001; p < 0x1100; p += 2)
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300178 if (!__l2cap_global_chan_by_addr(cpu_to_le16(p), src)) {
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300179 chan->psm = cpu_to_le16(p);
180 chan->sport = cpu_to_le16(p);
181 err = 0;
182 break;
183 }
184 }
185
186done:
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200187 write_unlock(&chan_list_lock);
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300188 return err;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300189}
190
191int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid)
192{
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200193 write_lock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300194
195 chan->scid = scid;
196
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200197 write_unlock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300198
199 return 0;
200}
201
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300202static u16 l2cap_alloc_cid(struct l2cap_conn *conn)
Marcel Holtmann01394182006-07-03 10:02:46 +0200203{
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300204 u16 cid = L2CAP_CID_DYN_START;
Marcel Holtmann01394182006-07-03 10:02:46 +0200205
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300206 for (; cid < L2CAP_CID_DYN_END; cid++) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300207 if (!__l2cap_get_chan_by_scid(conn, cid))
Marcel Holtmann01394182006-07-03 10:02:46 +0200208 return cid;
209 }
210
211 return 0;
212}
213
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +0200214static void __l2cap_state_change(struct l2cap_chan *chan, int state)
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300215{
Andrei Emeltchenko42d2d872012-02-17 11:40:57 +0200216 BT_DBG("chan %p %s -> %s", chan, state_to_string(chan->state),
Gustavo Padovan2d792812012-10-06 10:07:01 +0100217 state_to_string(state));
Gustavo F. Padovanbadaaa02011-11-23 20:11:46 -0200218
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300219 chan->state = state;
Gustavo Padovan80b98022012-05-27 22:27:51 -0300220 chan->ops->state_change(chan, state);
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300221}
222
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +0200223static void l2cap_state_change(struct l2cap_chan *chan, int state)
224{
225 struct sock *sk = chan->sk;
226
227 lock_sock(sk);
228 __l2cap_state_change(chan, state);
229 release_sock(sk);
230}
231
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +0200232static inline void __l2cap_chan_set_err(struct l2cap_chan *chan, int err)
233{
234 struct sock *sk = chan->sk;
235
236 sk->sk_err = err;
237}
238
239static inline void l2cap_chan_set_err(struct l2cap_chan *chan, int err)
240{
241 struct sock *sk = chan->sk;
242
243 lock_sock(sk);
244 __l2cap_chan_set_err(chan, err);
245 release_sock(sk);
246}
247
Mat Martineau4239d162012-05-17 20:53:49 -0700248static void __set_retrans_timer(struct l2cap_chan *chan)
249{
250 if (!delayed_work_pending(&chan->monitor_timer) &&
251 chan->retrans_timeout) {
252 l2cap_set_timer(chan, &chan->retrans_timer,
253 msecs_to_jiffies(chan->retrans_timeout));
254 }
255}
256
257static void __set_monitor_timer(struct l2cap_chan *chan)
258{
259 __clear_retrans_timer(chan);
260 if (chan->monitor_timeout) {
261 l2cap_set_timer(chan, &chan->monitor_timer,
262 msecs_to_jiffies(chan->monitor_timeout));
263 }
264}
265
Mat Martineau608bcc62012-05-17 20:53:32 -0700266static struct sk_buff *l2cap_ertm_seq_in_queue(struct sk_buff_head *head,
267 u16 seq)
268{
269 struct sk_buff *skb;
270
271 skb_queue_walk(head, skb) {
272 if (bt_cb(skb)->control.txseq == seq)
273 return skb;
274 }
275
276 return NULL;
277}
278
Mat Martineau3c588192012-04-11 10:48:42 -0700279/* ---- L2CAP sequence number lists ---- */
280
281/* For ERTM, ordered lists of sequence numbers must be tracked for
282 * SREJ requests that are received and for frames that are to be
283 * retransmitted. These seq_list functions implement a singly-linked
284 * list in an array, where membership in the list can also be checked
285 * in constant time. Items can also be added to the tail of the list
286 * and removed from the head in constant time, without further memory
287 * allocs or frees.
288 */
289
290static int l2cap_seq_list_init(struct l2cap_seq_list *seq_list, u16 size)
291{
292 size_t alloc_size, i;
293
294 /* Allocated size is a power of 2 to map sequence numbers
295 * (which may be up to 14 bits) in to a smaller array that is
296 * sized for the negotiated ERTM transmit windows.
297 */
298 alloc_size = roundup_pow_of_two(size);
299
300 seq_list->list = kmalloc(sizeof(u16) * alloc_size, GFP_KERNEL);
301 if (!seq_list->list)
302 return -ENOMEM;
303
304 seq_list->mask = alloc_size - 1;
305 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
306 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
307 for (i = 0; i < alloc_size; i++)
308 seq_list->list[i] = L2CAP_SEQ_LIST_CLEAR;
309
310 return 0;
311}
312
313static inline void l2cap_seq_list_free(struct l2cap_seq_list *seq_list)
314{
315 kfree(seq_list->list);
316}
317
318static inline bool l2cap_seq_list_contains(struct l2cap_seq_list *seq_list,
319 u16 seq)
320{
321 /* Constant-time check for list membership */
322 return seq_list->list[seq & seq_list->mask] != L2CAP_SEQ_LIST_CLEAR;
323}
324
325static u16 l2cap_seq_list_remove(struct l2cap_seq_list *seq_list, u16 seq)
326{
327 u16 mask = seq_list->mask;
328
329 if (seq_list->head == L2CAP_SEQ_LIST_CLEAR) {
330 /* In case someone tries to pop the head of an empty list */
331 return L2CAP_SEQ_LIST_CLEAR;
332 } else if (seq_list->head == seq) {
333 /* Head can be removed in constant time */
334 seq_list->head = seq_list->list[seq & mask];
335 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_CLEAR;
336
337 if (seq_list->head == L2CAP_SEQ_LIST_TAIL) {
338 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
339 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
340 }
341 } else {
342 /* Walk the list to find the sequence number */
343 u16 prev = seq_list->head;
344 while (seq_list->list[prev & mask] != seq) {
345 prev = seq_list->list[prev & mask];
346 if (prev == L2CAP_SEQ_LIST_TAIL)
347 return L2CAP_SEQ_LIST_CLEAR;
348 }
349
350 /* Unlink the number from the list and clear it */
351 seq_list->list[prev & mask] = seq_list->list[seq & mask];
352 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_CLEAR;
353 if (seq_list->tail == seq)
354 seq_list->tail = prev;
355 }
356 return seq;
357}
358
359static inline u16 l2cap_seq_list_pop(struct l2cap_seq_list *seq_list)
360{
361 /* Remove the head in constant time */
362 return l2cap_seq_list_remove(seq_list, seq_list->head);
363}
364
365static void l2cap_seq_list_clear(struct l2cap_seq_list *seq_list)
366{
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300367 u16 i;
Mat Martineau3c588192012-04-11 10:48:42 -0700368
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300369 if (seq_list->head == L2CAP_SEQ_LIST_CLEAR)
370 return;
371
372 for (i = 0; i <= seq_list->mask; i++)
373 seq_list->list[i] = L2CAP_SEQ_LIST_CLEAR;
374
375 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
376 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
Mat Martineau3c588192012-04-11 10:48:42 -0700377}
378
379static void l2cap_seq_list_append(struct l2cap_seq_list *seq_list, u16 seq)
380{
381 u16 mask = seq_list->mask;
382
383 /* All appends happen in constant time */
384
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300385 if (seq_list->list[seq & mask] != L2CAP_SEQ_LIST_CLEAR)
386 return;
Mat Martineau3c588192012-04-11 10:48:42 -0700387
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300388 if (seq_list->tail == L2CAP_SEQ_LIST_CLEAR)
389 seq_list->head = seq;
390 else
391 seq_list->list[seq_list->tail & mask] = seq;
392
393 seq_list->tail = seq;
394 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_TAIL;
Mat Martineau3c588192012-04-11 10:48:42 -0700395}
396
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300397static void l2cap_chan_timeout(struct work_struct *work)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300398{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300399 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100400 chan_timer.work);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200401 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300402 int reason;
403
Andrei Emeltchenkoe05dcc32012-02-17 11:40:56 +0200404 BT_DBG("chan %p state %s", chan, state_to_string(chan->state));
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300405
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200406 mutex_lock(&conn->chan_lock);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200407 l2cap_chan_lock(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300408
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300409 if (chan->state == BT_CONNECTED || chan->state == BT_CONFIG)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300410 reason = ECONNREFUSED;
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300411 else if (chan->state == BT_CONNECT &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100412 chan->sec_level != BT_SECURITY_SDP)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300413 reason = ECONNREFUSED;
414 else
415 reason = ETIMEDOUT;
416
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300417 l2cap_chan_close(chan, reason);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300418
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200419 l2cap_chan_unlock(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300420
Gustavo Padovan80b98022012-05-27 22:27:51 -0300421 chan->ops->close(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200422 mutex_unlock(&conn->chan_lock);
423
Ulisses Furquim371fd832011-12-21 20:02:36 -0200424 l2cap_chan_put(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300425}
426
Gustavo Padovaneef1d9b2012-03-25 13:59:16 -0300427struct l2cap_chan *l2cap_chan_create(void)
Marcel Holtmann01394182006-07-03 10:02:46 +0200428{
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300429 struct l2cap_chan *chan;
Marcel Holtmann01394182006-07-03 10:02:46 +0200430
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300431 chan = kzalloc(sizeof(*chan), GFP_ATOMIC);
432 if (!chan)
433 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200434
Andrei Emeltchenkoc03b3552012-02-21 12:54:56 +0200435 mutex_init(&chan->lock);
436
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200437 write_lock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300438 list_add(&chan->global_l, &chan_list);
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200439 write_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300440
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300441 INIT_DELAYED_WORK(&chan->chan_timer, l2cap_chan_timeout);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300442
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300443 chan->state = BT_OPEN;
444
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530445 kref_init(&chan->kref);
Gustavo F. Padovan71ba0e52011-05-17 14:34:52 -0300446
Mat Martineau28270112012-05-17 21:14:09 -0700447 /* This flag is cleared in l2cap_chan_ready() */
448 set_bit(CONF_NOT_COMPLETE, &chan->conf_state);
449
Gustavo Padovaneef1d9b2012-03-25 13:59:16 -0300450 BT_DBG("chan %p", chan);
Szymon Jancabc545b2011-11-03 16:05:44 +0100451
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300452 return chan;
Marcel Holtmann01394182006-07-03 10:02:46 +0200453}
454
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530455static void l2cap_chan_destroy(struct kref *kref)
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300456{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530457 struct l2cap_chan *chan = container_of(kref, struct l2cap_chan, kref);
458
Jaganath Kanakkassery4af66c62012-07-13 18:17:55 +0530459 BT_DBG("chan %p", chan);
460
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200461 write_lock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300462 list_del(&chan->global_l);
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200463 write_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300464
Jaganath Kanakkassery4af66c62012-07-13 18:17:55 +0530465 kfree(chan);
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300466}
467
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530468void l2cap_chan_hold(struct l2cap_chan *c)
469{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530470 BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->kref.refcount));
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530471
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530472 kref_get(&c->kref);
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530473}
474
475void l2cap_chan_put(struct l2cap_chan *c)
476{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530477 BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->kref.refcount));
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530478
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530479 kref_put(&c->kref, l2cap_chan_destroy);
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530480}
481
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +0300482void l2cap_chan_set_defaults(struct l2cap_chan *chan)
483{
484 chan->fcs = L2CAP_FCS_CRC16;
485 chan->max_tx = L2CAP_DEFAULT_MAX_TX;
486 chan->tx_win = L2CAP_DEFAULT_TX_WINDOW;
487 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
Mat Martineauc20f8e32012-07-10 05:47:07 -0700488 chan->ack_win = L2CAP_DEFAULT_TX_WINDOW;
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +0300489 chan->sec_level = BT_SECURITY_LOW;
490
491 set_bit(FLAG_FORCE_ACTIVE, &chan->flags);
492}
493
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +0300494void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Marcel Holtmann01394182006-07-03 10:02:46 +0200495{
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300496 BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
Andrei Emeltchenko097db762012-03-09 14:16:17 +0200497 __le16_to_cpu(chan->psm), chan->dcid);
Marcel Holtmann01394182006-07-03 10:02:46 +0200498
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +0200499 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +0100500
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300501 chan->conn = conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200502
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200503 switch (chan->chan_type) {
504 case L2CAP_CHAN_CONN_ORIENTED:
Ville Tervob62f3282011-02-10 22:38:50 -0300505 if (conn->hcon->type == LE_LINK) {
506 /* LE connection */
Andre Guedes6fcb06a2012-05-31 17:01:33 -0300507 chan->omtu = L2CAP_DEFAULT_MTU;
Johan Hedberg9f22398c2013-04-29 19:35:38 +0300508 if (chan->dcid == L2CAP_CID_ATT)
509 chan->scid = L2CAP_CID_ATT;
510 else
511 chan->scid = l2cap_alloc_cid(conn);
Ville Tervob62f3282011-02-10 22:38:50 -0300512 } else {
513 /* Alloc CID for connection-oriented socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300514 chan->scid = l2cap_alloc_cid(conn);
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300515 chan->omtu = L2CAP_DEFAULT_MTU;
Ville Tervob62f3282011-02-10 22:38:50 -0300516 }
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200517 break;
518
519 case L2CAP_CHAN_CONN_LESS:
Marcel Holtmann01394182006-07-03 10:02:46 +0200520 /* Connectionless socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300521 chan->scid = L2CAP_CID_CONN_LESS;
522 chan->dcid = L2CAP_CID_CONN_LESS;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300523 chan->omtu = L2CAP_DEFAULT_MTU;
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200524 break;
525
Andrei Emeltchenko416fa752012-05-29 13:59:16 +0300526 case L2CAP_CHAN_CONN_FIX_A2MP:
527 chan->scid = L2CAP_CID_A2MP;
528 chan->dcid = L2CAP_CID_A2MP;
529 chan->omtu = L2CAP_A2MP_DEFAULT_MTU;
530 chan->imtu = L2CAP_A2MP_DEFAULT_MTU;
531 break;
532
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200533 default:
Marcel Holtmann01394182006-07-03 10:02:46 +0200534 /* Raw socket can send/recv signalling messages only */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300535 chan->scid = L2CAP_CID_SIGNALING;
536 chan->dcid = L2CAP_CID_SIGNALING;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300537 chan->omtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann01394182006-07-03 10:02:46 +0200538 }
539
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300540 chan->local_id = L2CAP_BESTEFFORT_ID;
541 chan->local_stype = L2CAP_SERV_BESTEFFORT;
542 chan->local_msdu = L2CAP_DEFAULT_MAX_SDU_SIZE;
543 chan->local_sdu_itime = L2CAP_DEFAULT_SDU_ITIME;
544 chan->local_acc_lat = L2CAP_DEFAULT_ACC_LAT;
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +0300545 chan->local_flush_to = L2CAP_EFS_DEFAULT_FLUSH_TO;
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300546
Ulisses Furquim371fd832011-12-21 20:02:36 -0200547 l2cap_chan_hold(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300548
Johan Hedberg5ee98912013-04-29 19:35:43 +0300549 hci_conn_hold(conn->hcon);
550
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200551 list_add(&chan->list, &conn->chan_l);
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200552}
553
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300554void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200555{
556 mutex_lock(&conn->chan_lock);
557 __l2cap_chan_add(conn, chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200558 mutex_unlock(&conn->chan_lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200559}
560
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300561void l2cap_chan_del(struct l2cap_chan *chan, int err)
Marcel Holtmann01394182006-07-03 10:02:46 +0200562{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300563 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200564
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300565 __clear_chan_timer(chan);
Marcel Holtmann01394182006-07-03 10:02:46 +0200566
Gustavo F. Padovan49208c92011-04-04 15:59:54 -0300567 BT_DBG("chan %p, conn %p, err %d", chan, conn, err);
Marcel Holtmann01394182006-07-03 10:02:46 +0200568
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900569 if (conn) {
Andrei Emeltchenko56f60982012-10-15 11:58:44 +0300570 struct amp_mgr *mgr = conn->hcon->amp_mgr;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300571 /* Delete from channel list */
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200572 list_del(&chan->list);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -0200573
Ulisses Furquim371fd832011-12-21 20:02:36 -0200574 l2cap_chan_put(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300575
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300576 chan->conn = NULL;
Andrei Emeltchenko3cabbfd2012-05-31 11:01:37 +0300577
578 if (chan->chan_type != L2CAP_CHAN_CONN_FIX_A2MP)
David Herrmann76a68ba2013-04-06 20:28:37 +0200579 hci_conn_drop(conn->hcon);
Andrei Emeltchenko56f60982012-10-15 11:58:44 +0300580
581 if (mgr && mgr->bredr_chan == chan)
582 mgr->bredr_chan = NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200583 }
584
Andrei Emeltchenko419e08c2012-10-31 15:46:34 +0200585 if (chan->hs_hchan) {
586 struct hci_chan *hs_hchan = chan->hs_hchan;
587
588 BT_DBG("chan %p disconnect hs_hchan %p", chan, hs_hchan);
589 amp_disconnect_logical_link(hs_hchan);
590 }
591
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100592 chan->ops->teardown(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200593
Mat Martineau28270112012-05-17 21:14:09 -0700594 if (test_bit(CONF_NOT_COMPLETE, &chan->conf_state))
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300595 return;
Gustavo F. Padovan2ead70b2011-04-01 15:13:36 -0300596
Gustavo Padovanee556f62012-05-18 20:22:38 -0300597 switch(chan->mode) {
598 case L2CAP_MODE_BASIC:
599 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300600
Gustavo Padovanee556f62012-05-18 20:22:38 -0300601 case L2CAP_MODE_ERTM:
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -0300602 __clear_retrans_timer(chan);
603 __clear_monitor_timer(chan);
604 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300605
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -0300606 skb_queue_purge(&chan->srej_q);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300607
Mat Martineau3c588192012-04-11 10:48:42 -0700608 l2cap_seq_list_free(&chan->srej_list);
609 l2cap_seq_list_free(&chan->retrans_list);
Gustavo Padovanee556f62012-05-18 20:22:38 -0300610
611 /* fall through */
612
613 case L2CAP_MODE_STREAMING:
614 skb_queue_purge(&chan->tx_q);
615 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300616 }
Gustavo Padovanee556f62012-05-18 20:22:38 -0300617
618 return;
Marcel Holtmann01394182006-07-03 10:02:46 +0200619}
620
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300621void l2cap_chan_close(struct l2cap_chan *chan, int reason)
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300622{
623 struct l2cap_conn *conn = chan->conn;
624 struct sock *sk = chan->sk;
625
Gustavo Padovan2d792812012-10-06 10:07:01 +0100626 BT_DBG("chan %p state %s sk %p", chan, state_to_string(chan->state),
627 sk);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300628
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300629 switch (chan->state) {
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300630 case BT_LISTEN:
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100631 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300632 break;
633
634 case BT_CONNECTED:
635 case BT_CONFIG:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300636 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100637 conn->hcon->type == ACL_LINK) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300638 __set_chan_timer(chan, sk->sk_sndtimeo);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +0200639 l2cap_send_disconn_req(chan, reason);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300640 } else
641 l2cap_chan_del(chan, reason);
642 break;
643
644 case BT_CONNECT2:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300645 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100646 conn->hcon->type == ACL_LINK) {
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300647 struct l2cap_conn_rsp rsp;
648 __u16 result;
649
Gustavo Padovanc5daa682012-05-16 12:17:10 -0300650 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags))
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300651 result = L2CAP_CR_SEC_BLOCK;
652 else
653 result = L2CAP_CR_BAD_PSM;
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300654 l2cap_state_change(chan, BT_DISCONN);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300655
656 rsp.scid = cpu_to_le16(chan->dcid);
657 rsp.dcid = cpu_to_le16(chan->scid);
658 rsp.result = cpu_to_le16(result);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +0300659 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300660 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100661 sizeof(rsp), &rsp);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300662 }
663
664 l2cap_chan_del(chan, reason);
665 break;
666
667 case BT_CONNECT:
668 case BT_DISCONN:
669 l2cap_chan_del(chan, reason);
670 break;
671
672 default:
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100673 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300674 break;
675 }
676}
677
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300678static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530679{
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700680 switch (chan->chan_type) {
681 case L2CAP_CHAN_RAW:
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300682 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530683 case BT_SECURITY_HIGH:
684 return HCI_AT_DEDICATED_BONDING_MITM;
685 case BT_SECURITY_MEDIUM:
686 return HCI_AT_DEDICATED_BONDING;
687 default:
688 return HCI_AT_NO_BONDING;
689 }
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700690 break;
Marcel Holtmann3124b842013-10-12 07:19:32 -0700691 case L2CAP_CHAN_CONN_LESS:
692 if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_3DSP)) {
693 if (chan->sec_level == BT_SECURITY_LOW)
694 chan->sec_level = BT_SECURITY_SDP;
695 }
696 if (chan->sec_level == BT_SECURITY_HIGH)
697 return HCI_AT_NO_BONDING_MITM;
698 else
699 return HCI_AT_NO_BONDING;
700 break;
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700701 case L2CAP_CHAN_CONN_ORIENTED:
702 if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_SDP)) {
703 if (chan->sec_level == BT_SECURITY_LOW)
704 chan->sec_level = BT_SECURITY_SDP;
Johan Hedberg8556edd32011-01-19 12:06:50 +0530705
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700706 if (chan->sec_level == BT_SECURITY_HIGH)
707 return HCI_AT_NO_BONDING_MITM;
708 else
709 return HCI_AT_NO_BONDING;
710 }
711 /* fall through */
712 default:
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300713 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530714 case BT_SECURITY_HIGH:
715 return HCI_AT_GENERAL_BONDING_MITM;
716 case BT_SECURITY_MEDIUM:
717 return HCI_AT_GENERAL_BONDING;
718 default:
719 return HCI_AT_NO_BONDING;
720 }
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700721 break;
Johan Hedberg8556edd32011-01-19 12:06:50 +0530722 }
723}
724
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200725/* Service level security */
Gustavo F. Padovand45fc422011-11-05 19:54:24 -0200726int l2cap_chan_check_security(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200727{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300728 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100729 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200730
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300731 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100732
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300733 return hci_conn_security(conn->hcon, chan->sec_level, auth_type);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200734}
735
Johannes Bergb5ad8b72011-06-01 08:54:45 +0200736static u8 l2cap_get_ident(struct l2cap_conn *conn)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200737{
738 u8 id;
739
740 /* Get next available identificator.
741 * 1 - 128 are used by kernel.
742 * 129 - 199 are reserved.
743 * 200 - 254 are used by utilities like l2ping, etc.
744 */
745
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200746 spin_lock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200747
748 if (++conn->tx_ident > 128)
749 conn->tx_ident = 1;
750
751 id = conn->tx_ident;
752
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200753 spin_unlock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200754
755 return id;
756}
757
Gustavo Padovan2d792812012-10-06 10:07:01 +0100758static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
759 void *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200760{
761 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200762 u8 flags;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200763
764 BT_DBG("code 0x%2.2x", code);
765
766 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300767 return;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200768
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200769 if (lmp_no_flush_capable(conn->hcon->hdev))
770 flags = ACL_START_NO_FLUSH;
771 else
772 flags = ACL_START;
773
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700774 bt_cb(skb)->force_active = BT_POWER_FORCE_ACTIVE_ON;
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +0200775 skb->priority = HCI_PRIO_MAX;
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700776
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200777 hci_send_acl(conn->hchan, skb, flags);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200778}
779
Mat Martineau02b0fbb2012-10-23 15:24:10 -0700780static bool __chan_is_moving(struct l2cap_chan *chan)
781{
782 return chan->move_state != L2CAP_MOVE_STABLE &&
783 chan->move_state != L2CAP_MOVE_WAIT_PREPARE;
784}
785
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200786static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb)
787{
788 struct hci_conn *hcon = chan->conn->hcon;
789 u16 flags;
790
791 BT_DBG("chan %p, skb %p len %d priority %u", chan, skb, skb->len,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100792 skb->priority);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200793
Mat Martineaud5f8a752012-10-23 15:24:18 -0700794 if (chan->hs_hcon && !__chan_is_moving(chan)) {
795 if (chan->hs_hchan)
796 hci_send_acl(chan->hs_hchan, skb, ACL_COMPLETE);
797 else
798 kfree_skb(skb);
799
800 return;
801 }
802
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200803 if (!test_bit(FLAG_FLUSHABLE, &chan->flags) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100804 lmp_no_flush_capable(hcon->hdev))
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200805 flags = ACL_START_NO_FLUSH;
806 else
807 flags = ACL_START;
808
809 bt_cb(skb)->force_active = test_bit(FLAG_FORCE_ACTIVE, &chan->flags);
810 hci_send_acl(chan->conn->hchan, skb, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700811}
812
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700813static void __unpack_enhanced_control(u16 enh, struct l2cap_ctrl *control)
814{
815 control->reqseq = (enh & L2CAP_CTRL_REQSEQ) >> L2CAP_CTRL_REQSEQ_SHIFT;
816 control->final = (enh & L2CAP_CTRL_FINAL) >> L2CAP_CTRL_FINAL_SHIFT;
817
818 if (enh & L2CAP_CTRL_FRAME_TYPE) {
819 /* S-Frame */
820 control->sframe = 1;
821 control->poll = (enh & L2CAP_CTRL_POLL) >> L2CAP_CTRL_POLL_SHIFT;
822 control->super = (enh & L2CAP_CTRL_SUPERVISE) >> L2CAP_CTRL_SUPER_SHIFT;
823
824 control->sar = 0;
825 control->txseq = 0;
826 } else {
827 /* I-Frame */
828 control->sframe = 0;
829 control->sar = (enh & L2CAP_CTRL_SAR) >> L2CAP_CTRL_SAR_SHIFT;
830 control->txseq = (enh & L2CAP_CTRL_TXSEQ) >> L2CAP_CTRL_TXSEQ_SHIFT;
831
832 control->poll = 0;
833 control->super = 0;
834 }
835}
836
837static void __unpack_extended_control(u32 ext, struct l2cap_ctrl *control)
838{
839 control->reqseq = (ext & L2CAP_EXT_CTRL_REQSEQ) >> L2CAP_EXT_CTRL_REQSEQ_SHIFT;
840 control->final = (ext & L2CAP_EXT_CTRL_FINAL) >> L2CAP_EXT_CTRL_FINAL_SHIFT;
841
842 if (ext & L2CAP_EXT_CTRL_FRAME_TYPE) {
843 /* S-Frame */
844 control->sframe = 1;
845 control->poll = (ext & L2CAP_EXT_CTRL_POLL) >> L2CAP_EXT_CTRL_POLL_SHIFT;
846 control->super = (ext & L2CAP_EXT_CTRL_SUPERVISE) >> L2CAP_EXT_CTRL_SUPER_SHIFT;
847
848 control->sar = 0;
849 control->txseq = 0;
850 } else {
851 /* I-Frame */
852 control->sframe = 0;
853 control->sar = (ext & L2CAP_EXT_CTRL_SAR) >> L2CAP_EXT_CTRL_SAR_SHIFT;
854 control->txseq = (ext & L2CAP_EXT_CTRL_TXSEQ) >> L2CAP_EXT_CTRL_TXSEQ_SHIFT;
855
856 control->poll = 0;
857 control->super = 0;
858 }
859}
860
861static inline void __unpack_control(struct l2cap_chan *chan,
862 struct sk_buff *skb)
863{
864 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
865 __unpack_extended_control(get_unaligned_le32(skb->data),
866 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700867 skb_pull(skb, L2CAP_EXT_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700868 } else {
869 __unpack_enhanced_control(get_unaligned_le16(skb->data),
870 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700871 skb_pull(skb, L2CAP_ENH_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700872 }
873}
874
875static u32 __pack_extended_control(struct l2cap_ctrl *control)
876{
877 u32 packed;
878
879 packed = control->reqseq << L2CAP_EXT_CTRL_REQSEQ_SHIFT;
880 packed |= control->final << L2CAP_EXT_CTRL_FINAL_SHIFT;
881
882 if (control->sframe) {
883 packed |= control->poll << L2CAP_EXT_CTRL_POLL_SHIFT;
884 packed |= control->super << L2CAP_EXT_CTRL_SUPER_SHIFT;
885 packed |= L2CAP_EXT_CTRL_FRAME_TYPE;
886 } else {
887 packed |= control->sar << L2CAP_EXT_CTRL_SAR_SHIFT;
888 packed |= control->txseq << L2CAP_EXT_CTRL_TXSEQ_SHIFT;
889 }
890
891 return packed;
892}
893
894static u16 __pack_enhanced_control(struct l2cap_ctrl *control)
895{
896 u16 packed;
897
898 packed = control->reqseq << L2CAP_CTRL_REQSEQ_SHIFT;
899 packed |= control->final << L2CAP_CTRL_FINAL_SHIFT;
900
901 if (control->sframe) {
902 packed |= control->poll << L2CAP_CTRL_POLL_SHIFT;
903 packed |= control->super << L2CAP_CTRL_SUPER_SHIFT;
904 packed |= L2CAP_CTRL_FRAME_TYPE;
905 } else {
906 packed |= control->sar << L2CAP_CTRL_SAR_SHIFT;
907 packed |= control->txseq << L2CAP_CTRL_TXSEQ_SHIFT;
908 }
909
910 return packed;
911}
912
913static inline void __pack_control(struct l2cap_chan *chan,
914 struct l2cap_ctrl *control,
915 struct sk_buff *skb)
916{
917 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
918 put_unaligned_le32(__pack_extended_control(control),
919 skb->data + L2CAP_HDR_SIZE);
920 } else {
921 put_unaligned_le16(__pack_enhanced_control(control),
922 skb->data + L2CAP_HDR_SIZE);
923 }
924}
925
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300926static inline unsigned int __ertm_hdr_size(struct l2cap_chan *chan)
927{
928 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
929 return L2CAP_EXT_HDR_SIZE;
930 else
931 return L2CAP_ENH_HDR_SIZE;
932}
933
Mat Martineaua67d7f62012-05-17 20:53:35 -0700934static struct sk_buff *l2cap_create_sframe_pdu(struct l2cap_chan *chan,
935 u32 control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300936{
937 struct sk_buff *skb;
938 struct l2cap_hdr *lh;
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300939 int hlen = __ertm_hdr_size(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300940
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300941 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300942 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300943
Mat Martineaua67d7f62012-05-17 20:53:35 -0700944 skb = bt_skb_alloc(hlen, GFP_KERNEL);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300945
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300946 if (!skb)
Mat Martineaua67d7f62012-05-17 20:53:35 -0700947 return ERR_PTR(-ENOMEM);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300948
949 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300950 lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300951 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +0300952
Mat Martineaua67d7f62012-05-17 20:53:35 -0700953 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
954 put_unaligned_le32(control, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
955 else
956 put_unaligned_le16(control, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300957
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -0300958 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineaua67d7f62012-05-17 20:53:35 -0700959 u16 fcs = crc16(0, (u8 *)skb->data, skb->len);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300960 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300961 }
962
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200963 skb->priority = HCI_PRIO_MAX;
Mat Martineaua67d7f62012-05-17 20:53:35 -0700964 return skb;
965}
966
967static void l2cap_send_sframe(struct l2cap_chan *chan,
968 struct l2cap_ctrl *control)
969{
970 struct sk_buff *skb;
971 u32 control_field;
972
973 BT_DBG("chan %p, control %p", chan, control);
974
975 if (!control->sframe)
976 return;
977
Mat Martineaub99e13a2012-10-23 15:24:19 -0700978 if (__chan_is_moving(chan))
979 return;
980
Mat Martineaua67d7f62012-05-17 20:53:35 -0700981 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state) &&
982 !control->poll)
983 control->final = 1;
984
985 if (control->super == L2CAP_SUPER_RR)
986 clear_bit(CONN_RNR_SENT, &chan->conn_state);
987 else if (control->super == L2CAP_SUPER_RNR)
988 set_bit(CONN_RNR_SENT, &chan->conn_state);
989
990 if (control->super != L2CAP_SUPER_SREJ) {
991 chan->last_acked_seq = control->reqseq;
992 __clear_ack_timer(chan);
993 }
994
995 BT_DBG("reqseq %d, final %d, poll %d, super %d", control->reqseq,
996 control->final, control->poll, control->super);
997
998 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
999 control_field = __pack_extended_control(control);
1000 else
1001 control_field = __pack_enhanced_control(control);
1002
1003 skb = l2cap_create_sframe_pdu(chan, control_field);
1004 if (!IS_ERR(skb))
1005 l2cap_do_send(chan, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001006}
1007
Mat Martineauc9e3d5e2012-05-17 20:53:48 -07001008static void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, bool poll)
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001009{
Mat Martineauc9e3d5e2012-05-17 20:53:48 -07001010 struct l2cap_ctrl control;
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001011
Mat Martineauc9e3d5e2012-05-17 20:53:48 -07001012 BT_DBG("chan %p, poll %d", chan, poll);
1013
1014 memset(&control, 0, sizeof(control));
1015 control.sframe = 1;
1016 control.poll = poll;
1017
1018 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
1019 control.super = L2CAP_SUPER_RNR;
1020 else
1021 control.super = L2CAP_SUPER_RR;
1022
1023 control.reqseq = chan->buffer_seq;
1024 l2cap_send_sframe(chan, &control);
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001025}
1026
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03001027static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan)
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03001028{
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001029 return !test_bit(CONF_CONNECT_PEND, &chan->conf_state);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03001030}
1031
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001032static bool __amp_capable(struct l2cap_chan *chan)
1033{
1034 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann1df7b172013-10-05 11:47:49 -07001035 struct hci_dev *hdev;
1036 bool amp_available = false;
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001037
Marcel Holtmann1df7b172013-10-05 11:47:49 -07001038 if (!conn->hs_enabled)
1039 return false;
1040
1041 if (!(conn->fixed_chan_mask & L2CAP_FC_A2MP))
1042 return false;
1043
1044 read_lock(&hci_dev_list_lock);
1045 list_for_each_entry(hdev, &hci_dev_list, list) {
1046 if (hdev->amp_type != AMP_TYPE_BREDR &&
1047 test_bit(HCI_UP, &hdev->flags)) {
1048 amp_available = true;
1049 break;
1050 }
1051 }
1052 read_unlock(&hci_dev_list_lock);
1053
1054 if (chan->chan_policy == BT_CHANNEL_POLICY_AMP_PREFERRED)
1055 return amp_available;
Marcel Holtmann848566b2013-10-01 22:59:22 -07001056
1057 return false;
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001058}
1059
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +02001060static bool l2cap_check_efs(struct l2cap_chan *chan)
1061{
1062 /* Check EFS parameters */
1063 return true;
1064}
1065
Andrei Emeltchenko2766be42012-09-27 17:26:21 +03001066void l2cap_send_conn_req(struct l2cap_chan *chan)
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +02001067{
1068 struct l2cap_conn *conn = chan->conn;
1069 struct l2cap_conn_req req;
1070
1071 req.scid = cpu_to_le16(chan->scid);
1072 req.psm = chan->psm;
1073
1074 chan->ident = l2cap_get_ident(conn);
1075
1076 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
1077
1078 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, sizeof(req), &req);
1079}
1080
Mat Martineau8eb200b2012-10-23 15:24:17 -07001081static void l2cap_send_create_chan_req(struct l2cap_chan *chan, u8 amp_id)
1082{
1083 struct l2cap_create_chan_req req;
1084 req.scid = cpu_to_le16(chan->scid);
1085 req.psm = chan->psm;
1086 req.amp_id = amp_id;
1087
1088 chan->ident = l2cap_get_ident(chan->conn);
1089
1090 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_REQ,
1091 sizeof(req), &req);
1092}
1093
Mat Martineau02b0fbb2012-10-23 15:24:10 -07001094static void l2cap_move_setup(struct l2cap_chan *chan)
1095{
1096 struct sk_buff *skb;
1097
1098 BT_DBG("chan %p", chan);
1099
1100 if (chan->mode != L2CAP_MODE_ERTM)
1101 return;
1102
1103 __clear_retrans_timer(chan);
1104 __clear_monitor_timer(chan);
1105 __clear_ack_timer(chan);
1106
1107 chan->retry_count = 0;
1108 skb_queue_walk(&chan->tx_q, skb) {
1109 if (bt_cb(skb)->control.retries)
1110 bt_cb(skb)->control.retries = 1;
1111 else
1112 break;
1113 }
1114
1115 chan->expected_tx_seq = chan->buffer_seq;
1116
1117 clear_bit(CONN_REJ_ACT, &chan->conn_state);
1118 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
1119 l2cap_seq_list_clear(&chan->retrans_list);
1120 l2cap_seq_list_clear(&chan->srej_list);
1121 skb_queue_purge(&chan->srej_q);
1122
1123 chan->tx_state = L2CAP_TX_STATE_XMIT;
1124 chan->rx_state = L2CAP_RX_STATE_MOVE;
1125
1126 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
1127}
1128
Mat Martineau5f3847a2012-10-23 15:24:12 -07001129static void l2cap_move_done(struct l2cap_chan *chan)
1130{
1131 u8 move_role = chan->move_role;
1132 BT_DBG("chan %p", chan);
1133
1134 chan->move_state = L2CAP_MOVE_STABLE;
1135 chan->move_role = L2CAP_MOVE_ROLE_NONE;
1136
1137 if (chan->mode != L2CAP_MODE_ERTM)
1138 return;
1139
1140 switch (move_role) {
1141 case L2CAP_MOVE_ROLE_INITIATOR:
1142 l2cap_tx(chan, NULL, NULL, L2CAP_EV_EXPLICIT_POLL);
1143 chan->rx_state = L2CAP_RX_STATE_WAIT_F;
1144 break;
1145 case L2CAP_MOVE_ROLE_RESPONDER:
1146 chan->rx_state = L2CAP_RX_STATE_WAIT_P;
1147 break;
1148 }
1149}
1150
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001151static void l2cap_chan_ready(struct l2cap_chan *chan)
1152{
Mat Martineau28270112012-05-17 21:14:09 -07001153 /* This clears all conf flags, including CONF_NOT_COMPLETE */
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001154 chan->conf_state = 0;
1155 __clear_chan_timer(chan);
1156
Andrei Emeltchenko54a59aa2012-05-27 22:27:53 -03001157 chan->state = BT_CONNECTED;
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001158
Andrei Emeltchenkofd83e2c2012-05-30 09:55:32 +03001159 chan->ops->ready(chan);
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001160}
1161
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001162static void l2cap_start_connection(struct l2cap_chan *chan)
1163{
1164 if (__amp_capable(chan)) {
1165 BT_DBG("chan %p AMP capable: discover AMPs", chan);
1166 a2mp_discover_amp(chan);
1167 } else {
1168 l2cap_send_conn_req(chan);
1169 }
1170}
1171
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001172static void l2cap_do_start(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001173{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001174 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001175
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001176 if (conn->hcon->type == LE_LINK) {
1177 l2cap_chan_ready(chan);
1178 return;
1179 }
1180
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001181 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01001182 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
1183 return;
1184
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001185 if (l2cap_chan_check_security(chan) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01001186 __l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001187 l2cap_start_connection(chan);
1188 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001189 } else {
1190 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001191 req.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001192
1193 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
1194 conn->info_ident = l2cap_get_ident(conn);
1195
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08001196 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001197
Gustavo Padovan2d792812012-10-06 10:07:01 +01001198 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
1199 sizeof(req), &req);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001200 }
1201}
1202
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001203static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
1204{
1205 u32 local_feat_mask = l2cap_feat_mask;
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03001206 if (!disable_ertm)
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001207 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
1208
1209 switch (mode) {
1210 case L2CAP_MODE_ERTM:
1211 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
1212 case L2CAP_MODE_STREAMING:
1213 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
1214 default:
1215 return 0x00;
1216 }
1217}
1218
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02001219static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err)
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001220{
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001221 struct sock *sk = chan->sk;
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02001222 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001223 struct l2cap_disconn_req req;
1224
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001225 if (!conn)
1226 return;
1227
Andrei Emeltchenkoaad3d0e2012-09-06 15:05:42 +03001228 if (chan->mode == L2CAP_MODE_ERTM && chan->state == BT_CONNECTED) {
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03001229 __clear_retrans_timer(chan);
1230 __clear_monitor_timer(chan);
1231 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001232 }
1233
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001234 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
Gustavo Padovand1177732012-10-06 11:47:38 +01001235 l2cap_state_change(chan, BT_DISCONN);
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001236 return;
1237 }
1238
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001239 req.dcid = cpu_to_le16(chan->dcid);
1240 req.scid = cpu_to_le16(chan->scid);
Gustavo Padovan2d792812012-10-06 10:07:01 +01001241 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_DISCONN_REQ,
1242 sizeof(req), &req);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001243
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001244 lock_sock(sk);
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001245 __l2cap_state_change(chan, BT_DISCONN);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02001246 __l2cap_chan_set_err(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001247 release_sock(sk);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001248}
1249
Linus Torvalds1da177e2005-04-16 15:20:36 -07001250/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001251static void l2cap_conn_start(struct l2cap_conn *conn)
1252{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001253 struct l2cap_chan *chan, *tmp;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001254
1255 BT_DBG("conn %p", conn);
1256
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001257 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001258
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001259 list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001260 struct sock *sk = chan->sk;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001261
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001262 l2cap_chan_lock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001263
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001264 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001265 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001266 continue;
1267 }
1268
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001269 if (chan->state == BT_CONNECT) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001270 if (!l2cap_chan_check_security(chan) ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001271 !__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001272 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001273 continue;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02001274 }
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001275
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001276 if (!l2cap_mode_supported(chan->mode, conn->feat_mask)
Gustavo Padovan2d792812012-10-06 10:07:01 +01001277 && test_bit(CONF_STATE2_DEVICE,
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001278 &chan->conf_state)) {
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001279 l2cap_chan_close(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001280 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001281 continue;
1282 }
1283
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001284 l2cap_start_connection(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001285
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001286 } else if (chan->state == BT_CONNECT2) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001287 struct l2cap_conn_rsp rsp;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001288 char buf[128];
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001289 rsp.scid = cpu_to_le16(chan->dcid);
1290 rsp.dcid = cpu_to_le16(chan->scid);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001291
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001292 if (l2cap_chan_check_security(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001293 lock_sock(sk);
Gustavo Padovanc5daa682012-05-16 12:17:10 -03001294 if (test_bit(BT_SK_DEFER_SETUP,
1295 &bt_sk(sk)->flags)) {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001296 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1297 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08001298 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001299
1300 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001301 __l2cap_state_change(chan, BT_CONFIG);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001302 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
1303 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001304 }
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001305 release_sock(sk);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001306 } else {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001307 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1308 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001309 }
1310
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001311 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001312 sizeof(rsp), &rsp);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001313
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001314 if (test_bit(CONF_REQ_SENT, &chan->conf_state) ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001315 rsp.result != L2CAP_CR_SUCCESS) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001316 l2cap_chan_unlock(chan);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001317 continue;
1318 }
1319
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001320 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001321 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001322 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03001323 chan->num_conf_req++;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001324 }
1325
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001326 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001327 }
1328
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001329 mutex_unlock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001330}
1331
Ido Yarivc2287682012-04-20 15:46:07 -03001332/* Find socket with cid and source/destination bdaddr.
Ville Tervob62f3282011-02-10 22:38:50 -03001333 * Returns closest match, locked.
1334 */
Andrei Emeltchenkod9b88702012-03-12 12:13:08 +02001335static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid,
Ido Yarivc2287682012-04-20 15:46:07 -03001336 bdaddr_t *src,
1337 bdaddr_t *dst)
Ville Tervob62f3282011-02-10 22:38:50 -03001338{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001339 struct l2cap_chan *c, *c1 = NULL;
Ville Tervob62f3282011-02-10 22:38:50 -03001340
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001341 read_lock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001342
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001343 list_for_each_entry(c, &chan_list, global_l) {
1344 struct sock *sk = c->sk;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001345
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001346 if (state && c->state != state)
Ville Tervob62f3282011-02-10 22:38:50 -03001347 continue;
1348
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001349 if (c->scid == cid) {
Ido Yarivc2287682012-04-20 15:46:07 -03001350 int src_match, dst_match;
1351 int src_any, dst_any;
1352
Ville Tervob62f3282011-02-10 22:38:50 -03001353 /* Exact match. */
Ido Yarivc2287682012-04-20 15:46:07 -03001354 src_match = !bacmp(&bt_sk(sk)->src, src);
1355 dst_match = !bacmp(&bt_sk(sk)->dst, dst);
1356 if (src_match && dst_match) {
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001357 read_unlock(&chan_list_lock);
1358 return c;
1359 }
Ville Tervob62f3282011-02-10 22:38:50 -03001360
1361 /* Closest match */
Ido Yarivc2287682012-04-20 15:46:07 -03001362 src_any = !bacmp(&bt_sk(sk)->src, BDADDR_ANY);
1363 dst_any = !bacmp(&bt_sk(sk)->dst, BDADDR_ANY);
1364 if ((src_match && dst_any) || (src_any && dst_match) ||
1365 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001366 c1 = c;
Ville Tervob62f3282011-02-10 22:38:50 -03001367 }
1368 }
Gustavo F. Padovan280f2942011-04-13 19:01:22 -03001369
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001370 read_unlock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001371
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001372 return c1;
Ville Tervob62f3282011-02-10 22:38:50 -03001373}
1374
1375static void l2cap_le_conn_ready(struct l2cap_conn *conn)
1376{
Johan Hedberg60bac182013-04-29 19:35:41 +03001377 struct sock *parent;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001378 struct l2cap_chan *chan, *pchan;
Ville Tervob62f3282011-02-10 22:38:50 -03001379
1380 BT_DBG("");
1381
1382 /* Check if we have socket listening on cid */
Johan Hedberg073d1cf2013-04-29 19:35:35 +03001383 pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_ATT,
Ido Yarivc2287682012-04-20 15:46:07 -03001384 conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001385 if (!pchan)
Ville Tervob62f3282011-02-10 22:38:50 -03001386 return;
1387
Johan Hedberg44f3b0f2013-04-29 19:35:45 +03001388 /* Client ATT sockets should override the server one */
1389 if (__l2cap_get_chan_by_dcid(conn, L2CAP_CID_ATT))
1390 return;
1391
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001392 parent = pchan->sk;
1393
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03001394 lock_sock(parent);
Gustavo F. Padovan62f3a2c2011-04-14 18:34:34 -03001395
Gustavo Padovan80b98022012-05-27 22:27:51 -03001396 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001397 if (!chan)
Ville Tervob62f3282011-02-10 22:38:50 -03001398 goto clean;
1399
Johan Hedberg9f22398c2013-04-29 19:35:38 +03001400 chan->dcid = L2CAP_CID_ATT;
1401
Johan Hedberg60bac182013-04-29 19:35:41 +03001402 bacpy(&bt_sk(chan->sk)->src, conn->src);
1403 bacpy(&bt_sk(chan->sk)->dst, conn->dst);
Ville Tervob62f3282011-02-10 22:38:50 -03001404
Johan Hedberg44f3b0f2013-04-29 19:35:45 +03001405 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001406
Ville Tervob62f3282011-02-10 22:38:50 -03001407clean:
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03001408 release_sock(parent);
Ville Tervob62f3282011-02-10 22:38:50 -03001409}
1410
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001411static void l2cap_conn_ready(struct l2cap_conn *conn)
1412{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001413 struct l2cap_chan *chan;
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001414 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001415
1416 BT_DBG("conn %p", conn);
1417
Johan Hedbergd8729922013-04-29 19:35:39 +03001418 /* For outgoing pairing which doesn't necessarily have an
1419 * associated socket (e.g. mgmt_pair_device).
1420 */
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001421 if (hcon->out && hcon->type == LE_LINK)
1422 smp_conn_security(hcon, hcon->pending_sec_level);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03001423
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001424 mutex_lock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001425
Johan Hedberg44f3b0f2013-04-29 19:35:45 +03001426 if (hcon->type == LE_LINK)
1427 l2cap_le_conn_ready(conn);
1428
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001429 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001430
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001431 l2cap_chan_lock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001432
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001433 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
1434 l2cap_chan_unlock(chan);
1435 continue;
1436 }
1437
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001438 if (hcon->type == LE_LINK) {
1439 if (smp_conn_security(hcon, chan->sec_level))
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02001440 l2cap_chan_ready(chan);
Ville Tervoacd7d372011-02-10 22:38:49 -03001441
Vinicius Costa Gomes63128452011-06-17 22:46:26 -03001442 } else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001443 struct sock *sk = chan->sk;
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001444 __clear_chan_timer(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001445 lock_sock(sk);
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001446 __l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001447 sk->sk_state_change(sk);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001448 release_sock(sk);
Anderson Brigliab501d6a2011-06-07 18:46:31 -03001449
Gustavo Padovan1c244f72012-12-07 03:29:10 -02001450 } else if (chan->state == BT_CONNECT) {
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001451 l2cap_do_start(chan);
Gustavo Padovan1c244f72012-12-07 03:29:10 -02001452 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001453
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001454 l2cap_chan_unlock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001455 }
1456
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001457 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001458}
1459
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001460/* Notify sockets that we cannot guaranty reliability anymore */
1461static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
1462{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001463 struct l2cap_chan *chan;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001464
1465 BT_DBG("conn %p", conn);
1466
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001467 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001468
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001469 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenkoecf61bd2011-10-11 14:04:32 +03001470 if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags))
Gustavo Padovan1d8b1fd2012-10-06 11:34:52 +01001471 l2cap_chan_set_err(chan, err);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001472 }
1473
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001474 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001475}
1476
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001477static void l2cap_info_timeout(struct work_struct *work)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001478{
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001479 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001480 info_timer.work);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001481
Marcel Holtmann984947d2009-02-06 23:35:19 +01001482 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01001483 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01001484
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001485 l2cap_conn_start(conn);
1486}
1487
David Herrmann2c8e1412013-04-06 20:28:45 +02001488/*
1489 * l2cap_user
1490 * External modules can register l2cap_user objects on l2cap_conn. The ->probe
1491 * callback is called during registration. The ->remove callback is called
1492 * during unregistration.
1493 * An l2cap_user object can either be explicitly unregistered or when the
1494 * underlying l2cap_conn object is deleted. This guarantees that l2cap->hcon,
1495 * l2cap->hchan, .. are valid as long as the remove callback hasn't been called.
1496 * External modules must own a reference to the l2cap_conn object if they intend
1497 * to call l2cap_unregister_user(). The l2cap_conn object might get destroyed at
1498 * any time if they don't.
1499 */
1500
1501int l2cap_register_user(struct l2cap_conn *conn, struct l2cap_user *user)
1502{
1503 struct hci_dev *hdev = conn->hcon->hdev;
1504 int ret;
1505
1506 /* We need to check whether l2cap_conn is registered. If it is not, we
1507 * must not register the l2cap_user. l2cap_conn_del() is unregisters
1508 * l2cap_conn objects, but doesn't provide its own locking. Instead, it
1509 * relies on the parent hci_conn object to be locked. This itself relies
1510 * on the hci_dev object to be locked. So we must lock the hci device
1511 * here, too. */
1512
1513 hci_dev_lock(hdev);
1514
1515 if (user->list.next || user->list.prev) {
1516 ret = -EINVAL;
1517 goto out_unlock;
1518 }
1519
1520 /* conn->hchan is NULL after l2cap_conn_del() was called */
1521 if (!conn->hchan) {
1522 ret = -ENODEV;
1523 goto out_unlock;
1524 }
1525
1526 ret = user->probe(conn, user);
1527 if (ret)
1528 goto out_unlock;
1529
1530 list_add(&user->list, &conn->users);
1531 ret = 0;
1532
1533out_unlock:
1534 hci_dev_unlock(hdev);
1535 return ret;
1536}
1537EXPORT_SYMBOL(l2cap_register_user);
1538
1539void l2cap_unregister_user(struct l2cap_conn *conn, struct l2cap_user *user)
1540{
1541 struct hci_dev *hdev = conn->hcon->hdev;
1542
1543 hci_dev_lock(hdev);
1544
1545 if (!user->list.next || !user->list.prev)
1546 goto out_unlock;
1547
1548 list_del(&user->list);
1549 user->list.next = NULL;
1550 user->list.prev = NULL;
1551 user->remove(conn, user);
1552
1553out_unlock:
1554 hci_dev_unlock(hdev);
1555}
1556EXPORT_SYMBOL(l2cap_unregister_user);
1557
1558static void l2cap_unregister_all_users(struct l2cap_conn *conn)
1559{
1560 struct l2cap_user *user;
1561
1562 while (!list_empty(&conn->users)) {
1563 user = list_first_entry(&conn->users, struct l2cap_user, list);
1564 list_del(&user->list);
1565 user->list.next = NULL;
1566 user->list.prev = NULL;
1567 user->remove(conn, user);
1568 }
1569}
1570
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001571static void l2cap_conn_del(struct hci_conn *hcon, int err)
1572{
1573 struct l2cap_conn *conn = hcon->l2cap_data;
1574 struct l2cap_chan *chan, *l;
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001575
1576 if (!conn)
1577 return;
1578
1579 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
1580
1581 kfree_skb(conn->rx_skb);
1582
David Herrmann2c8e1412013-04-06 20:28:45 +02001583 l2cap_unregister_all_users(conn);
1584
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001585 mutex_lock(&conn->chan_lock);
1586
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001587 /* Kill channels */
1588 list_for_each_entry_safe(chan, l, &conn->chan_l, list) {
Mat Martineau61d6ef32012-04-27 16:50:50 -07001589 l2cap_chan_hold(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001590 l2cap_chan_lock(chan);
1591
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001592 l2cap_chan_del(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001593
1594 l2cap_chan_unlock(chan);
1595
Gustavo Padovan80b98022012-05-27 22:27:51 -03001596 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07001597 l2cap_chan_put(chan);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001598 }
1599
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001600 mutex_unlock(&conn->chan_lock);
1601
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001602 hci_chan_del(conn->hchan);
1603
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001604 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
Ulisses Furquim127074b2012-01-30 18:26:29 -02001605 cancel_delayed_work_sync(&conn->info_timer);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001606
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001607 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) {
Ulisses Furquim127074b2012-01-30 18:26:29 -02001608 cancel_delayed_work_sync(&conn->security_timer);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -03001609 smp_chan_destroy(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001610 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001611
1612 hcon->l2cap_data = NULL;
David Herrmann9c903e32013-04-06 20:28:44 +02001613 conn->hchan = NULL;
1614 l2cap_conn_put(conn);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001615}
1616
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001617static void security_timeout(struct work_struct *work)
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001618{
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001619 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001620 security_timer.work);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001621
Johan Hedbergd06cc412012-06-06 18:44:11 +08001622 BT_DBG("conn %p", conn);
1623
1624 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) {
1625 smp_chan_destroy(conn);
1626 l2cap_conn_del(conn->hcon, ETIMEDOUT);
1627 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001628}
1629
Claudio Takahasibaf43252013-04-11 13:55:50 -03001630static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001631{
Marcel Holtmann01394182006-07-03 10:02:46 +02001632 struct l2cap_conn *conn = hcon->l2cap_data;
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001633 struct hci_chan *hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001634
Claudio Takahasibaf43252013-04-11 13:55:50 -03001635 if (conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001636 return conn;
1637
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001638 hchan = hci_chan_create(hcon);
1639 if (!hchan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001640 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001641
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03001642 conn = kzalloc(sizeof(struct l2cap_conn), GFP_KERNEL);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001643 if (!conn) {
1644 hci_chan_del(hchan);
1645 return NULL;
1646 }
1647
David Herrmann9c903e32013-04-06 20:28:44 +02001648 kref_init(&conn->ref);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001649 hcon->l2cap_data = conn;
1650 conn->hcon = hcon;
David Herrmann9c903e32013-04-06 20:28:44 +02001651 hci_conn_get(conn->hcon);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001652 conn->hchan = hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001653
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001654 BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan);
Marcel Holtmann01394182006-07-03 10:02:46 +02001655
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001656 switch (hcon->type) {
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001657 case LE_LINK:
1658 if (hcon->hdev->le_mtu) {
1659 conn->mtu = hcon->hdev->le_mtu;
1660 break;
1661 }
1662 /* fall through */
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001663 default:
Ville Tervoacd7d372011-02-10 22:38:49 -03001664 conn->mtu = hcon->hdev->acl_mtu;
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001665 break;
1666 }
Ville Tervoacd7d372011-02-10 22:38:49 -03001667
Linus Torvalds1da177e2005-04-16 15:20:36 -07001668 conn->src = &hcon->hdev->bdaddr;
1669 conn->dst = &hcon->dst;
1670
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001671 conn->feat_mask = 0;
1672
Marcel Holtmann848566b2013-10-01 22:59:22 -07001673 if (hcon->type == ACL_LINK)
1674 conn->hs_enabled = test_bit(HCI_HS_ENABLED,
1675 &hcon->hdev->dev_flags);
1676
Linus Torvalds1da177e2005-04-16 15:20:36 -07001677 spin_lock_init(&conn->lock);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001678 mutex_init(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001679
1680 INIT_LIST_HEAD(&conn->chan_l);
David Herrmann2c8e1412013-04-06 20:28:45 +02001681 INIT_LIST_HEAD(&conn->users);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001682
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001683 if (hcon->type == LE_LINK)
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001684 INIT_DELAYED_WORK(&conn->security_timer, security_timeout);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001685 else
Gustavo F. Padovan030013d2011-12-20 10:57:28 -02001686 INIT_DELAYED_WORK(&conn->info_timer, l2cap_info_timeout);
Dave Young45054dc2009-10-18 20:28:30 +00001687
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001688 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01001689
Linus Torvalds1da177e2005-04-16 15:20:36 -07001690 return conn;
1691}
1692
David Herrmann9c903e32013-04-06 20:28:44 +02001693static void l2cap_conn_free(struct kref *ref)
1694{
1695 struct l2cap_conn *conn = container_of(ref, struct l2cap_conn, ref);
1696
1697 hci_conn_put(conn->hcon);
1698 kfree(conn);
1699}
1700
1701void l2cap_conn_get(struct l2cap_conn *conn)
1702{
1703 kref_get(&conn->ref);
1704}
1705EXPORT_SYMBOL(l2cap_conn_get);
1706
1707void l2cap_conn_put(struct l2cap_conn *conn)
1708{
1709 kref_put(&conn->ref, l2cap_conn_free);
1710}
1711EXPORT_SYMBOL(l2cap_conn_put);
1712
Linus Torvalds1da177e2005-04-16 15:20:36 -07001713/* ---- Socket interface ---- */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001714
Ido Yarivc2287682012-04-20 15:46:07 -03001715/* Find socket with psm and source / destination bdaddr.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001716 * Returns closest match.
1717 */
Ido Yarivc2287682012-04-20 15:46:07 -03001718static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
1719 bdaddr_t *src,
1720 bdaddr_t *dst)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001721{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001722 struct l2cap_chan *c, *c1 = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001723
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001724 read_lock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001725
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001726 list_for_each_entry(c, &chan_list, global_l) {
1727 struct sock *sk = c->sk;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001728
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001729 if (state && c->state != state)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001730 continue;
1731
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001732 if (c->psm == psm) {
Ido Yarivc2287682012-04-20 15:46:07 -03001733 int src_match, dst_match;
1734 int src_any, dst_any;
1735
Linus Torvalds1da177e2005-04-16 15:20:36 -07001736 /* Exact match. */
Ido Yarivc2287682012-04-20 15:46:07 -03001737 src_match = !bacmp(&bt_sk(sk)->src, src);
1738 dst_match = !bacmp(&bt_sk(sk)->dst, dst);
1739 if (src_match && dst_match) {
Johannes Berga7567b22011-06-01 08:29:54 +02001740 read_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001741 return c;
1742 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001743
1744 /* Closest match */
Ido Yarivc2287682012-04-20 15:46:07 -03001745 src_any = !bacmp(&bt_sk(sk)->src, BDADDR_ANY);
1746 dst_any = !bacmp(&bt_sk(sk)->dst, BDADDR_ANY);
1747 if ((src_match && dst_any) || (src_any && dst_match) ||
1748 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001749 c1 = c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001750 }
1751 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001752
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001753 read_unlock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001754
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001755 return c1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001756}
1757
Andre Guedes8e9f9892012-04-24 21:02:55 -03001758int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
1759 bdaddr_t *dst, u8 dst_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001760{
Gustavo F. Padovan5d41ce12011-04-08 15:40:02 -03001761 struct sock *sk = chan->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001762 bdaddr_t *src = &bt_sk(sk)->src;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001763 struct l2cap_conn *conn;
1764 struct hci_conn *hcon;
1765 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001766 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +02001767 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001768
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001769 BT_DBG("%pMR -> %pMR (type %u) psm 0x%2.2x", src, dst,
Syam Sidhardhanab195162012-07-27 23:51:22 +05301770 dst_type, __le16_to_cpu(psm));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001771
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001772 hdev = hci_get_route(dst, src);
1773 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001774 return -EHOSTUNREACH;
1775
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001776 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001777
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001778 l2cap_chan_lock(chan);
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001779
1780 /* PSM must be odd and lsb of upper byte must be 0 */
1781 if ((__le16_to_cpu(psm) & 0x0101) != 0x0001 && !cid &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01001782 chan->chan_type != L2CAP_CHAN_RAW) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001783 err = -EINVAL;
1784 goto done;
1785 }
1786
1787 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && !(psm || cid)) {
1788 err = -EINVAL;
1789 goto done;
1790 }
1791
1792 switch (chan->mode) {
1793 case L2CAP_MODE_BASIC:
1794 break;
1795 case L2CAP_MODE_ERTM:
1796 case L2CAP_MODE_STREAMING:
1797 if (!disable_ertm)
1798 break;
1799 /* fall through */
1800 default:
1801 err = -ENOTSUPP;
1802 goto done;
1803 }
1804
Gustavo Padovan0797e012012-05-27 22:27:54 -03001805 switch (chan->state) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001806 case BT_CONNECT:
1807 case BT_CONNECT2:
1808 case BT_CONFIG:
1809 /* Already connecting */
1810 err = 0;
1811 goto done;
1812
1813 case BT_CONNECTED:
1814 /* Already connected */
1815 err = -EISCONN;
1816 goto done;
1817
1818 case BT_OPEN:
1819 case BT_BOUND:
1820 /* Can connect */
1821 break;
1822
1823 default:
1824 err = -EBADFD;
1825 goto done;
1826 }
1827
1828 /* Set destination address and psm */
Gustavo Padovan0797e012012-05-27 22:27:54 -03001829 lock_sock(sk);
Gustavo F. Padovan9219b2a2012-01-02 20:08:04 -02001830 bacpy(&bt_sk(sk)->dst, dst);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001831 release_sock(sk);
1832
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001833 chan->psm = psm;
1834 chan->dcid = cid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001835
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001836 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001837
Johan Hedbergf224ca52013-04-29 19:35:36 +03001838 if (bdaddr_type_is_le(dst_type))
Andre Guedes8e9f9892012-04-24 21:02:55 -03001839 hcon = hci_connect(hdev, LE_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001840 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001841 else
Andre Guedes8e9f9892012-04-24 21:02:55 -03001842 hcon = hci_connect(hdev, ACL_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001843 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001844
Ville Tervo30e76272011-02-22 16:10:53 -03001845 if (IS_ERR(hcon)) {
1846 err = PTR_ERR(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001847 goto done;
Ville Tervo30e76272011-02-22 16:10:53 -03001848 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001849
Claudio Takahasibaf43252013-04-11 13:55:50 -03001850 conn = l2cap_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001851 if (!conn) {
David Herrmann76a68ba2013-04-06 20:28:37 +02001852 hci_conn_drop(hcon);
Ville Tervo30e76272011-02-22 16:10:53 -03001853 err = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001854 goto done;
1855 }
1856
Johan Hedberg141d5702013-04-29 19:35:37 +03001857 if (cid && __l2cap_get_chan_by_dcid(conn, cid)) {
1858 hci_conn_drop(hcon);
1859 err = -EBUSY;
1860 goto done;
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001861 }
1862
Linus Torvalds1da177e2005-04-16 15:20:36 -07001863 /* Update source addr of the socket */
1864 bacpy(src, conn->src);
1865
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001866 l2cap_chan_unlock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001867 l2cap_chan_add(conn, chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001868 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001869
Johan Hedberg5ee98912013-04-29 19:35:43 +03001870 /* l2cap_chan_add takes its own ref so we can drop this one */
1871 hci_conn_drop(hcon);
1872
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001873 l2cap_state_change(chan, BT_CONNECT);
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001874 __set_chan_timer(chan, sk->sk_sndtimeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001875
1876 if (hcon->state == BT_CONNECTED) {
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001877 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001878 __clear_chan_timer(chan);
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001879 if (l2cap_chan_check_security(chan))
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001880 l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001881 } else
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001882 l2cap_do_start(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001883 }
1884
Ville Tervo30e76272011-02-22 16:10:53 -03001885 err = 0;
1886
Linus Torvalds1da177e2005-04-16 15:20:36 -07001887done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001888 l2cap_chan_unlock(chan);
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001889 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001890 hci_dev_put(hdev);
1891 return err;
1892}
1893
Gustavo F. Padovandcba0db2011-02-04 03:08:36 -02001894int __l2cap_wait_ack(struct sock *sk)
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001895{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001896 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001897 DECLARE_WAITQUEUE(wait, current);
1898 int err = 0;
1899 int timeo = HZ/5;
1900
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001901 add_wait_queue(sk_sleep(sk), &wait);
Peter Hurleya71a0cf2011-07-25 18:36:26 -04001902 set_current_state(TASK_INTERRUPTIBLE);
1903 while (chan->unacked_frames > 0 && chan->conn) {
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001904 if (!timeo)
1905 timeo = HZ/5;
1906
1907 if (signal_pending(current)) {
1908 err = sock_intr_errno(timeo);
1909 break;
1910 }
1911
1912 release_sock(sk);
1913 timeo = schedule_timeout(timeo);
1914 lock_sock(sk);
Peter Hurleya71a0cf2011-07-25 18:36:26 -04001915 set_current_state(TASK_INTERRUPTIBLE);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001916
1917 err = sock_error(sk);
1918 if (err)
1919 break;
1920 }
1921 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001922 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001923 return err;
1924}
1925
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001926static void l2cap_monitor_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001927{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001928 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001929 monitor_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001930
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03001931 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001932
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001933 l2cap_chan_lock(chan);
1934
Mat Martineau80909e02012-05-17 20:53:50 -07001935 if (!chan->conn) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001936 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001937 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001938 return;
1939 }
1940
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001941 l2cap_tx(chan, NULL, NULL, L2CAP_EV_MONITOR_TO);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001942
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001943 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001944 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001945}
1946
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001947static void l2cap_retrans_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001948{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001949 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001950 retrans_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001951
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03001952 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001953
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001954 l2cap_chan_lock(chan);
1955
Mat Martineau80909e02012-05-17 20:53:50 -07001956 if (!chan->conn) {
1957 l2cap_chan_unlock(chan);
1958 l2cap_chan_put(chan);
1959 return;
1960 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001961
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001962 l2cap_tx(chan, NULL, NULL, L2CAP_EV_RETRANS_TO);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001963 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001964 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001965}
1966
Gustavo Padovand6603662012-05-21 13:58:22 -03001967static void l2cap_streaming_send(struct l2cap_chan *chan,
1968 struct sk_buff_head *skbs)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001969{
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001970 struct sk_buff *skb;
Mat Martineau37339372012-05-17 20:53:33 -07001971 struct l2cap_ctrl *control;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001972
Mat Martineau37339372012-05-17 20:53:33 -07001973 BT_DBG("chan %p, skbs %p", chan, skbs);
1974
Mat Martineaub99e13a2012-10-23 15:24:19 -07001975 if (__chan_is_moving(chan))
1976 return;
1977
Mat Martineau37339372012-05-17 20:53:33 -07001978 skb_queue_splice_tail_init(skbs, &chan->tx_q);
1979
1980 while (!skb_queue_empty(&chan->tx_q)) {
1981
1982 skb = skb_dequeue(&chan->tx_q);
1983
1984 bt_cb(skb)->control.retries = 1;
1985 control = &bt_cb(skb)->control;
1986
1987 control->reqseq = 0;
1988 control->txseq = chan->next_tx_seq;
1989
1990 __pack_control(chan, control, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001991
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001992 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau37339372012-05-17 20:53:33 -07001993 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
1994 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001995 }
1996
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001997 l2cap_do_send(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001998
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001999 BT_DBG("Sent txseq %u", control->txseq);
Mat Martineau37339372012-05-17 20:53:33 -07002000
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002001 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau37339372012-05-17 20:53:33 -07002002 chan->frames_sent++;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002003 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002004}
2005
Szymon Janc67c9e842011-07-28 16:24:33 +02002006static int l2cap_ertm_send(struct l2cap_chan *chan)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002007{
2008 struct sk_buff *skb, *tx_skb;
Mat Martineau18a48e72012-05-17 20:53:34 -07002009 struct l2cap_ctrl *control;
2010 int sent = 0;
2011
2012 BT_DBG("chan %p", chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002013
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03002014 if (chan->state != BT_CONNECTED)
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03002015 return -ENOTCONN;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002016
Mat Martineau94122bb2012-05-02 09:42:02 -07002017 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2018 return 0;
2019
Mat Martineaub99e13a2012-10-23 15:24:19 -07002020 if (__chan_is_moving(chan))
2021 return 0;
2022
Mat Martineau18a48e72012-05-17 20:53:34 -07002023 while (chan->tx_send_head &&
2024 chan->unacked_frames < chan->remote_tx_win &&
2025 chan->tx_state == L2CAP_TX_STATE_XMIT) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002026
Mat Martineau18a48e72012-05-17 20:53:34 -07002027 skb = chan->tx_send_head;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002028
Mat Martineau18a48e72012-05-17 20:53:34 -07002029 bt_cb(skb)->control.retries = 1;
2030 control = &bt_cb(skb)->control;
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03002031
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03002032 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
Mat Martineau18a48e72012-05-17 20:53:34 -07002033 control->final = 1;
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03002034
Mat Martineau18a48e72012-05-17 20:53:34 -07002035 control->reqseq = chan->buffer_seq;
2036 chan->last_acked_seq = chan->buffer_seq;
2037 control->txseq = chan->next_tx_seq;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002038
Mat Martineau18a48e72012-05-17 20:53:34 -07002039 __pack_control(chan, control, skb);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002040
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002041 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau18a48e72012-05-17 20:53:34 -07002042 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
2043 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002044 }
2045
Mat Martineau18a48e72012-05-17 20:53:34 -07002046 /* Clone after data has been modified. Data is assumed to be
2047 read-only (for locking purposes) on cloned sk_buffs.
2048 */
2049 tx_skb = skb_clone(skb, GFP_KERNEL);
2050
2051 if (!tx_skb)
2052 break;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03002053
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03002054 __set_retrans_timer(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002055
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002056 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau18a48e72012-05-17 20:53:34 -07002057 chan->unacked_frames++;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03002058 chan->frames_sent++;
Mat Martineau18a48e72012-05-17 20:53:34 -07002059 sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002060
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03002061 if (skb_queue_is_last(&chan->tx_q, skb))
2062 chan->tx_send_head = NULL;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002063 else
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03002064 chan->tx_send_head = skb_queue_next(&chan->tx_q, skb);
Mat Martineau18a48e72012-05-17 20:53:34 -07002065
2066 l2cap_do_send(chan, tx_skb);
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002067 BT_DBG("Sent txseq %u", control->txseq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002068 }
2069
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002070 BT_DBG("Sent %d, %u unacked, %u in ERTM queue", sent,
2071 chan->unacked_frames, skb_queue_len(&chan->tx_q));
Mat Martineau18a48e72012-05-17 20:53:34 -07002072
2073 return sent;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03002074}
2075
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002076static void l2cap_ertm_resend(struct l2cap_chan *chan)
2077{
2078 struct l2cap_ctrl control;
2079 struct sk_buff *skb;
2080 struct sk_buff *tx_skb;
2081 u16 seq;
2082
2083 BT_DBG("chan %p", chan);
2084
2085 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2086 return;
2087
Mat Martineaub99e13a2012-10-23 15:24:19 -07002088 if (__chan_is_moving(chan))
2089 return;
2090
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002091 while (chan->retrans_list.head != L2CAP_SEQ_LIST_CLEAR) {
2092 seq = l2cap_seq_list_pop(&chan->retrans_list);
2093
2094 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, seq);
2095 if (!skb) {
2096 BT_DBG("Error: Can't retransmit seq %d, frame missing",
Gustavo Padovan2d792812012-10-06 10:07:01 +01002097 seq);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002098 continue;
2099 }
2100
2101 bt_cb(skb)->control.retries++;
2102 control = bt_cb(skb)->control;
2103
2104 if (chan->max_tx != 0 &&
2105 bt_cb(skb)->control.retries > chan->max_tx) {
2106 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02002107 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002108 l2cap_seq_list_clear(&chan->retrans_list);
2109 break;
2110 }
2111
2112 control.reqseq = chan->buffer_seq;
2113 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
2114 control.final = 1;
2115 else
2116 control.final = 0;
2117
2118 if (skb_cloned(skb)) {
2119 /* Cloned sk_buffs are read-only, so we need a
2120 * writeable copy
2121 */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002122 tx_skb = skb_copy(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002123 } else {
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002124 tx_skb = skb_clone(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002125 }
2126
2127 if (!tx_skb) {
2128 l2cap_seq_list_clear(&chan->retrans_list);
2129 break;
2130 }
2131
2132 /* Update skb contents */
2133 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
2134 put_unaligned_le32(__pack_extended_control(&control),
2135 tx_skb->data + L2CAP_HDR_SIZE);
2136 } else {
2137 put_unaligned_le16(__pack_enhanced_control(&control),
2138 tx_skb->data + L2CAP_HDR_SIZE);
2139 }
2140
2141 if (chan->fcs == L2CAP_FCS_CRC16) {
2142 u16 fcs = crc16(0, (u8 *) tx_skb->data, tx_skb->len);
2143 put_unaligned_le16(fcs, skb_put(tx_skb,
2144 L2CAP_FCS_SIZE));
2145 }
2146
2147 l2cap_do_send(chan, tx_skb);
2148
2149 BT_DBG("Resent txseq %d", control.txseq);
2150
2151 chan->last_acked_seq = chan->buffer_seq;
2152 }
2153}
2154
Mat Martineauf80842a2012-05-17 20:53:46 -07002155static void l2cap_retransmit(struct l2cap_chan *chan,
2156 struct l2cap_ctrl *control)
2157{
2158 BT_DBG("chan %p, control %p", chan, control);
2159
2160 l2cap_seq_list_append(&chan->retrans_list, control->reqseq);
2161 l2cap_ertm_resend(chan);
2162}
2163
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002164static void l2cap_retransmit_all(struct l2cap_chan *chan,
2165 struct l2cap_ctrl *control)
2166{
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002167 struct sk_buff *skb;
2168
2169 BT_DBG("chan %p, control %p", chan, control);
2170
2171 if (control->poll)
2172 set_bit(CONN_SEND_FBIT, &chan->conn_state);
2173
2174 l2cap_seq_list_clear(&chan->retrans_list);
2175
2176 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2177 return;
2178
2179 if (chan->unacked_frames) {
2180 skb_queue_walk(&chan->tx_q, skb) {
2181 if (bt_cb(skb)->control.txseq == control->reqseq ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01002182 skb == chan->tx_send_head)
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002183 break;
2184 }
2185
2186 skb_queue_walk_from(&chan->tx_q, skb) {
2187 if (skb == chan->tx_send_head)
2188 break;
2189
2190 l2cap_seq_list_append(&chan->retrans_list,
2191 bt_cb(skb)->control.txseq);
2192 }
2193
2194 l2cap_ertm_resend(chan);
2195 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002196}
2197
Szymon Jancb17e73b2012-01-11 10:59:47 +01002198static void l2cap_send_ack(struct l2cap_chan *chan)
2199{
Mat Martineau0a0aba42012-05-17 20:53:39 -07002200 struct l2cap_ctrl control;
2201 u16 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
2202 chan->last_acked_seq);
2203 int threshold;
2204
2205 BT_DBG("chan %p last_acked_seq %d buffer_seq %d",
2206 chan, chan->last_acked_seq, chan->buffer_seq);
2207
2208 memset(&control, 0, sizeof(control));
2209 control.sframe = 1;
2210
2211 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
2212 chan->rx_state == L2CAP_RX_STATE_RECV) {
2213 __clear_ack_timer(chan);
2214 control.super = L2CAP_SUPER_RNR;
2215 control.reqseq = chan->buffer_seq;
2216 l2cap_send_sframe(chan, &control);
2217 } else {
2218 if (!test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) {
2219 l2cap_ertm_send(chan);
2220 /* If any i-frames were sent, they included an ack */
2221 if (chan->buffer_seq == chan->last_acked_seq)
2222 frames_to_ack = 0;
2223 }
2224
Mat Martineauc20f8e32012-07-10 05:47:07 -07002225 /* Ack now if the window is 3/4ths full.
Mat Martineau0a0aba42012-05-17 20:53:39 -07002226 * Calculate without mul or div
2227 */
Mat Martineauc20f8e32012-07-10 05:47:07 -07002228 threshold = chan->ack_win;
Mat Martineau0a0aba42012-05-17 20:53:39 -07002229 threshold += threshold << 1;
2230 threshold >>= 2;
2231
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002232 BT_DBG("frames_to_ack %u, threshold %d", frames_to_ack,
Mat Martineau0a0aba42012-05-17 20:53:39 -07002233 threshold);
2234
2235 if (frames_to_ack >= threshold) {
2236 __clear_ack_timer(chan);
2237 control.super = L2CAP_SUPER_RR;
2238 control.reqseq = chan->buffer_seq;
2239 l2cap_send_sframe(chan, &control);
2240 frames_to_ack = 0;
2241 }
2242
2243 if (frames_to_ack)
2244 __set_ack_timer(chan);
2245 }
Szymon Jancb17e73b2012-01-11 10:59:47 +01002246}
2247
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002248static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
2249 struct msghdr *msg, int len,
2250 int count, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002251{
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002252 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002253 struct sk_buff **frag;
Gustavo Padovan90338942012-04-06 20:15:47 -03002254 int sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002255
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03002256 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002257 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002258
2259 sent += count;
2260 len -= count;
2261
2262 /* Continuation fragments (no L2CAP header) */
2263 frag = &skb_shinfo(skb)->frag_list;
2264 while (len) {
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002265 struct sk_buff *tmp;
2266
Linus Torvalds1da177e2005-04-16 15:20:36 -07002267 count = min_t(unsigned int, conn->mtu, len);
2268
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002269 tmp = chan->ops->alloc_skb(chan, count,
2270 msg->msg_flags & MSG_DONTWAIT);
2271 if (IS_ERR(tmp))
2272 return PTR_ERR(tmp);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002273
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002274 *frag = tmp;
2275
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002276 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
2277 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002278
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002279 (*frag)->priority = skb->priority;
2280
Linus Torvalds1da177e2005-04-16 15:20:36 -07002281 sent += count;
2282 len -= count;
2283
Gustavo Padovan2d0ed3d2012-05-11 13:16:12 -03002284 skb->len += (*frag)->len;
2285 skb->data_len += (*frag)->len;
2286
Linus Torvalds1da177e2005-04-16 15:20:36 -07002287 frag = &(*frag)->next;
2288 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002289
2290 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002291}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002292
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002293static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002294 struct msghdr *msg, size_t len,
2295 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002296{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002297 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002298 struct sk_buff *skb;
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002299 int err, count, hlen = L2CAP_HDR_SIZE + L2CAP_PSMLEN_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002300 struct l2cap_hdr *lh;
2301
Marcel Holtmann43b1b8d2013-10-12 06:01:26 -07002302 BT_DBG("chan %p psm 0x%2.2x len %zu priority %u", chan,
2303 __le16_to_cpu(chan->psm), len, priority);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002304
2305 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002306
2307 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002308 msg->msg_flags & MSG_DONTWAIT);
2309 if (IS_ERR(skb))
2310 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002311
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002312 skb->priority = priority;
2313
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002314 /* Create L2CAP header */
2315 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002316 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenkodaf6a78c2012-05-03 10:55:52 +03002317 lh->len = cpu_to_le16(len + L2CAP_PSMLEN_SIZE);
Marcel Holtmann43b1b8d2013-10-12 06:01:26 -07002318 put_unaligned(chan->psm, (__le16 *) skb_put(skb, L2CAP_PSMLEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002319
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002320 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002321 if (unlikely(err < 0)) {
2322 kfree_skb(skb);
2323 return ERR_PTR(err);
2324 }
2325 return skb;
2326}
2327
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002328static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002329 struct msghdr *msg, size_t len,
2330 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002331{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002332 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002333 struct sk_buff *skb;
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002334 int err, count;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002335 struct l2cap_hdr *lh;
2336
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002337 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002338
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002339 count = min_t(unsigned int, (conn->mtu - L2CAP_HDR_SIZE), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002340
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002341 skb = chan->ops->alloc_skb(chan, count + L2CAP_HDR_SIZE,
Gustavo Padovan90338942012-04-06 20:15:47 -03002342 msg->msg_flags & MSG_DONTWAIT);
2343 if (IS_ERR(skb))
2344 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002345
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002346 skb->priority = priority;
2347
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002348 /* 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 Padovan6ff9b5e2012-05-02 11:56:17 -03002351 lh->len = cpu_to_le16(len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002352
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002353 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002354 if (unlikely(err < 0)) {
2355 kfree_skb(skb);
2356 return ERR_PTR(err);
2357 }
2358 return skb;
2359}
2360
Luiz Augusto von Dentzab0ff762011-09-12 20:00:50 +03002361static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002362 struct msghdr *msg, size_t len,
2363 u16 sdulen)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002364{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002365 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002366 struct sk_buff *skb;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002367 int err, count, hlen;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002368 struct l2cap_hdr *lh;
2369
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002370 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002371
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03002372 if (!conn)
2373 return ERR_PTR(-ENOTCONN);
2374
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002375 hlen = __ertm_hdr_size(chan);
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002376
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002377 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002378 hlen += L2CAP_SDULEN_SIZE;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002379
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002380 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002381 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002382
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002383 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002384
2385 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002386 msg->msg_flags & MSG_DONTWAIT);
2387 if (IS_ERR(skb))
2388 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002389
2390 /* Create L2CAP header */
2391 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002392 lh->cid = cpu_to_le16(chan->dcid);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002393 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002394
Mat Martineau18a48e72012-05-17 20:53:34 -07002395 /* Control header is populated later */
2396 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
2397 put_unaligned_le32(0, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
2398 else
2399 put_unaligned_le16(0, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002400
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002401 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002402 put_unaligned_le16(sdulen, skb_put(skb, L2CAP_SDULEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002403
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002404 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002405 if (unlikely(err < 0)) {
2406 kfree_skb(skb);
2407 return ERR_PTR(err);
2408 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002409
Mat Martineau18a48e72012-05-17 20:53:34 -07002410 bt_cb(skb)->control.fcs = chan->fcs;
Mat Martineau3ce35142012-04-25 16:36:14 -07002411 bt_cb(skb)->control.retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002412 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002413}
2414
Mat Martineau94122bb2012-05-02 09:42:02 -07002415static int l2cap_segment_sdu(struct l2cap_chan *chan,
2416 struct sk_buff_head *seg_queue,
2417 struct msghdr *msg, size_t len)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002418{
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002419 struct sk_buff *skb;
Mat Martineau94122bb2012-05-02 09:42:02 -07002420 u16 sdu_len;
2421 size_t pdu_len;
Mat Martineau94122bb2012-05-02 09:42:02 -07002422 u8 sar;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002423
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002424 BT_DBG("chan %p, msg %p, len %zu", chan, msg, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002425
Mat Martineau94122bb2012-05-02 09:42:02 -07002426 /* It is critical that ERTM PDUs fit in a single HCI fragment,
2427 * so fragmented skbs are not used. The HCI layer's handling
2428 * of fragmented skbs is not compatible with ERTM's queueing.
2429 */
2430
2431 /* PDU size is derived from the HCI MTU */
2432 pdu_len = chan->conn->mtu;
2433
Mat Martineaua5495742012-10-23 15:24:21 -07002434 /* Constrain PDU size for BR/EDR connections */
2435 if (!chan->hs_hcon)
2436 pdu_len = min_t(size_t, pdu_len, L2CAP_BREDR_MAX_PAYLOAD);
Mat Martineau94122bb2012-05-02 09:42:02 -07002437
2438 /* Adjust for largest possible L2CAP overhead. */
Gustavo Padovan35d401d2012-05-25 18:57:05 -03002439 if (chan->fcs)
2440 pdu_len -= L2CAP_FCS_SIZE;
2441
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002442 pdu_len -= __ertm_hdr_size(chan);
Mat Martineau94122bb2012-05-02 09:42:02 -07002443
2444 /* Remote device may have requested smaller PDUs */
2445 pdu_len = min_t(size_t, pdu_len, chan->remote_mps);
2446
2447 if (len <= pdu_len) {
2448 sar = L2CAP_SAR_UNSEGMENTED;
2449 sdu_len = 0;
2450 pdu_len = len;
2451 } else {
2452 sar = L2CAP_SAR_START;
2453 sdu_len = len;
2454 pdu_len -= L2CAP_SDULEN_SIZE;
2455 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002456
2457 while (len > 0) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002458 skb = l2cap_create_iframe_pdu(chan, msg, pdu_len, sdu_len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002459
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002460 if (IS_ERR(skb)) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002461 __skb_queue_purge(seg_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002462 return PTR_ERR(skb);
2463 }
2464
Mat Martineau94122bb2012-05-02 09:42:02 -07002465 bt_cb(skb)->control.sar = sar;
2466 __skb_queue_tail(seg_queue, skb);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002467
Mat Martineau94122bb2012-05-02 09:42:02 -07002468 len -= pdu_len;
2469 if (sdu_len) {
2470 sdu_len = 0;
2471 pdu_len += L2CAP_SDULEN_SIZE;
2472 }
2473
2474 if (len <= pdu_len) {
2475 sar = L2CAP_SAR_END;
2476 pdu_len = len;
2477 } else {
2478 sar = L2CAP_SAR_CONTINUE;
2479 }
2480 }
2481
Gustavo Padovanf0f62792012-05-29 13:29:17 -03002482 return 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002483}
2484
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002485int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01002486 u32 priority)
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002487{
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002488 struct sk_buff *skb;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002489 int err;
Mat Martineau94122bb2012-05-02 09:42:02 -07002490 struct sk_buff_head seg_queue;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002491
2492 /* Connectionless channel */
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002493 if (chan->chan_type == L2CAP_CHAN_CONN_LESS) {
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002494 skb = l2cap_create_connless_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002495 if (IS_ERR(skb))
2496 return PTR_ERR(skb);
2497
2498 l2cap_do_send(chan, skb);
2499 return len;
2500 }
2501
2502 switch (chan->mode) {
2503 case L2CAP_MODE_BASIC:
2504 /* Check outgoing MTU */
2505 if (len > chan->omtu)
2506 return -EMSGSIZE;
2507
2508 /* Create a basic PDU */
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002509 skb = l2cap_create_basic_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002510 if (IS_ERR(skb))
2511 return PTR_ERR(skb);
2512
2513 l2cap_do_send(chan, skb);
2514 err = len;
2515 break;
2516
2517 case L2CAP_MODE_ERTM:
2518 case L2CAP_MODE_STREAMING:
Mat Martineau94122bb2012-05-02 09:42:02 -07002519 /* Check outgoing MTU */
2520 if (len > chan->omtu) {
2521 err = -EMSGSIZE;
2522 break;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002523 }
2524
Mat Martineau94122bb2012-05-02 09:42:02 -07002525 __skb_queue_head_init(&seg_queue);
2526
2527 /* Do segmentation before calling in to the state machine,
2528 * since it's possible to block while waiting for memory
2529 * allocation.
2530 */
2531 err = l2cap_segment_sdu(chan, &seg_queue, msg, len);
2532
2533 /* The channel could have been closed while segmenting,
2534 * check that it is still connected.
2535 */
2536 if (chan->state != BT_CONNECTED) {
2537 __skb_queue_purge(&seg_queue);
2538 err = -ENOTCONN;
2539 }
2540
2541 if (err)
2542 break;
2543
Mat Martineau37339372012-05-17 20:53:33 -07002544 if (chan->mode == L2CAP_MODE_ERTM)
Gustavo Padovand6603662012-05-21 13:58:22 -03002545 l2cap_tx(chan, NULL, &seg_queue, L2CAP_EV_DATA_REQUEST);
Mat Martineau37339372012-05-17 20:53:33 -07002546 else
Gustavo Padovand6603662012-05-21 13:58:22 -03002547 l2cap_streaming_send(chan, &seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002548
Gustavo Padovand6603662012-05-21 13:58:22 -03002549 err = len;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002550
Mat Martineau94122bb2012-05-02 09:42:02 -07002551 /* If the skbs were not queued for sending, they'll still be in
2552 * seg_queue and need to be purged.
2553 */
2554 __skb_queue_purge(&seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002555 break;
2556
2557 default:
2558 BT_DBG("bad state %1.1x", chan->mode);
2559 err = -EBADFD;
2560 }
2561
2562 return err;
2563}
2564
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002565static void l2cap_send_srej(struct l2cap_chan *chan, u16 txseq)
2566{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002567 struct l2cap_ctrl control;
2568 u16 seq;
2569
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002570 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002571
2572 memset(&control, 0, sizeof(control));
2573 control.sframe = 1;
2574 control.super = L2CAP_SUPER_SREJ;
2575
2576 for (seq = chan->expected_tx_seq; seq != txseq;
2577 seq = __next_seq(chan, seq)) {
2578 if (!l2cap_ertm_seq_in_queue(&chan->srej_q, seq)) {
2579 control.reqseq = seq;
2580 l2cap_send_sframe(chan, &control);
2581 l2cap_seq_list_append(&chan->srej_list, seq);
2582 }
2583 }
2584
2585 chan->expected_tx_seq = __next_seq(chan, txseq);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002586}
2587
2588static void l2cap_send_srej_tail(struct l2cap_chan *chan)
2589{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002590 struct l2cap_ctrl control;
2591
2592 BT_DBG("chan %p", chan);
2593
2594 if (chan->srej_list.tail == L2CAP_SEQ_LIST_CLEAR)
2595 return;
2596
2597 memset(&control, 0, sizeof(control));
2598 control.sframe = 1;
2599 control.super = L2CAP_SUPER_SREJ;
2600 control.reqseq = chan->srej_list.tail;
2601 l2cap_send_sframe(chan, &control);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002602}
2603
2604static void l2cap_send_srej_list(struct l2cap_chan *chan, u16 txseq)
2605{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002606 struct l2cap_ctrl control;
2607 u16 initial_head;
2608 u16 seq;
2609
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002610 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002611
2612 memset(&control, 0, sizeof(control));
2613 control.sframe = 1;
2614 control.super = L2CAP_SUPER_SREJ;
2615
2616 /* Capture initial list head to allow only one pass through the list. */
2617 initial_head = chan->srej_list.head;
2618
2619 do {
2620 seq = l2cap_seq_list_pop(&chan->srej_list);
2621 if (seq == txseq || seq == L2CAP_SEQ_LIST_CLEAR)
2622 break;
2623
2624 control.reqseq = seq;
2625 l2cap_send_sframe(chan, &control);
2626 l2cap_seq_list_append(&chan->srej_list, seq);
2627 } while (chan->srej_list.head != initial_head);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002628}
2629
Mat Martineau608bcc62012-05-17 20:53:32 -07002630static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq)
2631{
2632 struct sk_buff *acked_skb;
2633 u16 ackseq;
2634
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002635 BT_DBG("chan %p, reqseq %u", chan, reqseq);
Mat Martineau608bcc62012-05-17 20:53:32 -07002636
2637 if (chan->unacked_frames == 0 || reqseq == chan->expected_ack_seq)
2638 return;
2639
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002640 BT_DBG("expected_ack_seq %u, unacked_frames %u",
Mat Martineau608bcc62012-05-17 20:53:32 -07002641 chan->expected_ack_seq, chan->unacked_frames);
2642
2643 for (ackseq = chan->expected_ack_seq; ackseq != reqseq;
2644 ackseq = __next_seq(chan, ackseq)) {
2645
2646 acked_skb = l2cap_ertm_seq_in_queue(&chan->tx_q, ackseq);
2647 if (acked_skb) {
2648 skb_unlink(acked_skb, &chan->tx_q);
2649 kfree_skb(acked_skb);
2650 chan->unacked_frames--;
2651 }
2652 }
2653
2654 chan->expected_ack_seq = reqseq;
2655
2656 if (chan->unacked_frames == 0)
2657 __clear_retrans_timer(chan);
2658
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002659 BT_DBG("unacked_frames %u", chan->unacked_frames);
Mat Martineau608bcc62012-05-17 20:53:32 -07002660}
2661
2662static void l2cap_abort_rx_srej_sent(struct l2cap_chan *chan)
2663{
2664 BT_DBG("chan %p", chan);
2665
2666 chan->expected_tx_seq = chan->buffer_seq;
2667 l2cap_seq_list_clear(&chan->srej_list);
2668 skb_queue_purge(&chan->srej_q);
2669 chan->rx_state = L2CAP_RX_STATE_RECV;
2670}
2671
Gustavo Padovand6603662012-05-21 13:58:22 -03002672static void l2cap_tx_state_xmit(struct l2cap_chan *chan,
2673 struct l2cap_ctrl *control,
2674 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002675{
Mat Martineau608bcc62012-05-17 20:53:32 -07002676 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2677 event);
2678
2679 switch (event) {
2680 case L2CAP_EV_DATA_REQUEST:
2681 if (chan->tx_send_head == NULL)
2682 chan->tx_send_head = skb_peek(skbs);
2683
2684 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2685 l2cap_ertm_send(chan);
2686 break;
2687 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2688 BT_DBG("Enter LOCAL_BUSY");
2689 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2690
2691 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2692 /* The SREJ_SENT state must be aborted if we are to
2693 * enter the LOCAL_BUSY state.
2694 */
2695 l2cap_abort_rx_srej_sent(chan);
2696 }
2697
2698 l2cap_send_ack(chan);
2699
2700 break;
2701 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2702 BT_DBG("Exit LOCAL_BUSY");
2703 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2704
2705 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2706 struct l2cap_ctrl local_control;
2707
2708 memset(&local_control, 0, sizeof(local_control));
2709 local_control.sframe = 1;
2710 local_control.super = L2CAP_SUPER_RR;
2711 local_control.poll = 1;
2712 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002713 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002714
2715 chan->retry_count = 1;
2716 __set_monitor_timer(chan);
2717 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2718 }
2719 break;
2720 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2721 l2cap_process_reqseq(chan, control->reqseq);
2722 break;
2723 case L2CAP_EV_EXPLICIT_POLL:
2724 l2cap_send_rr_or_rnr(chan, 1);
2725 chan->retry_count = 1;
2726 __set_monitor_timer(chan);
2727 __clear_ack_timer(chan);
2728 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2729 break;
2730 case L2CAP_EV_RETRANS_TO:
2731 l2cap_send_rr_or_rnr(chan, 1);
2732 chan->retry_count = 1;
2733 __set_monitor_timer(chan);
2734 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2735 break;
2736 case L2CAP_EV_RECV_FBIT:
2737 /* Nothing to process */
2738 break;
2739 default:
2740 break;
2741 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002742}
2743
Gustavo Padovand6603662012-05-21 13:58:22 -03002744static void l2cap_tx_state_wait_f(struct l2cap_chan *chan,
2745 struct l2cap_ctrl *control,
2746 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002747{
Mat Martineau608bcc62012-05-17 20:53:32 -07002748 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2749 event);
2750
2751 switch (event) {
2752 case L2CAP_EV_DATA_REQUEST:
2753 if (chan->tx_send_head == NULL)
2754 chan->tx_send_head = skb_peek(skbs);
2755 /* Queue data, but don't send. */
2756 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2757 break;
2758 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2759 BT_DBG("Enter LOCAL_BUSY");
2760 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2761
2762 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2763 /* The SREJ_SENT state must be aborted if we are to
2764 * enter the LOCAL_BUSY state.
2765 */
2766 l2cap_abort_rx_srej_sent(chan);
2767 }
2768
2769 l2cap_send_ack(chan);
2770
2771 break;
2772 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2773 BT_DBG("Exit LOCAL_BUSY");
2774 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2775
2776 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2777 struct l2cap_ctrl local_control;
2778 memset(&local_control, 0, sizeof(local_control));
2779 local_control.sframe = 1;
2780 local_control.super = L2CAP_SUPER_RR;
2781 local_control.poll = 1;
2782 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002783 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002784
2785 chan->retry_count = 1;
2786 __set_monitor_timer(chan);
2787 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2788 }
2789 break;
2790 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2791 l2cap_process_reqseq(chan, control->reqseq);
2792
2793 /* Fall through */
2794
2795 case L2CAP_EV_RECV_FBIT:
2796 if (control && control->final) {
2797 __clear_monitor_timer(chan);
2798 if (chan->unacked_frames > 0)
2799 __set_retrans_timer(chan);
2800 chan->retry_count = 0;
2801 chan->tx_state = L2CAP_TX_STATE_XMIT;
2802 BT_DBG("recv fbit tx_state 0x2.2%x", chan->tx_state);
2803 }
2804 break;
2805 case L2CAP_EV_EXPLICIT_POLL:
2806 /* Ignore */
2807 break;
2808 case L2CAP_EV_MONITOR_TO:
2809 if (chan->max_tx == 0 || chan->retry_count < chan->max_tx) {
2810 l2cap_send_rr_or_rnr(chan, 1);
2811 __set_monitor_timer(chan);
2812 chan->retry_count++;
2813 } else {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02002814 l2cap_send_disconn_req(chan, ECONNABORTED);
Mat Martineau608bcc62012-05-17 20:53:32 -07002815 }
2816 break;
2817 default:
2818 break;
2819 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002820}
2821
Gustavo Padovand6603662012-05-21 13:58:22 -03002822static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
2823 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002824{
Mat Martineau608bcc62012-05-17 20:53:32 -07002825 BT_DBG("chan %p, control %p, skbs %p, event %d, state %d",
2826 chan, control, skbs, event, chan->tx_state);
2827
2828 switch (chan->tx_state) {
2829 case L2CAP_TX_STATE_XMIT:
Gustavo Padovand6603662012-05-21 13:58:22 -03002830 l2cap_tx_state_xmit(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002831 break;
2832 case L2CAP_TX_STATE_WAIT_F:
Gustavo Padovand6603662012-05-21 13:58:22 -03002833 l2cap_tx_state_wait_f(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002834 break;
2835 default:
2836 /* Ignore event */
2837 break;
2838 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002839}
2840
Mat Martineau4b51dae92012-05-17 20:53:37 -07002841static void l2cap_pass_to_tx(struct l2cap_chan *chan,
2842 struct l2cap_ctrl *control)
2843{
2844 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002845 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_REQSEQ_AND_FBIT);
Mat Martineau4b51dae92012-05-17 20:53:37 -07002846}
2847
Mat Martineauf80842a2012-05-17 20:53:46 -07002848static void l2cap_pass_to_tx_fbit(struct l2cap_chan *chan,
2849 struct l2cap_ctrl *control)
2850{
2851 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002852 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_FBIT);
Mat Martineauf80842a2012-05-17 20:53:46 -07002853}
2854
Linus Torvalds1da177e2005-04-16 15:20:36 -07002855/* Copy frame to all raw sockets on that connection */
2856static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2857{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002858 struct sk_buff *nskb;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002859 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002860
2861 BT_DBG("conn %p", conn);
2862
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002863 mutex_lock(&conn->chan_lock);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002864
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002865 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002866 struct sock *sk = chan->sk;
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002867 if (chan->chan_type != L2CAP_CHAN_RAW)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002868 continue;
2869
2870 /* Don't send frame to the socket it came from */
2871 if (skb->sk == sk)
2872 continue;
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002873 nskb = skb_clone(skb, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002874 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002875 continue;
2876
Gustavo Padovan80b98022012-05-27 22:27:51 -03002877 if (chan->ops->recv(chan, nskb))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002878 kfree_skb(nskb);
2879 }
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002880
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002881 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002882}
2883
2884/* ---- L2CAP signalling commands ---- */
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002885static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code,
2886 u8 ident, u16 dlen, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002887{
2888 struct sk_buff *skb, **frag;
2889 struct l2cap_cmd_hdr *cmd;
2890 struct l2cap_hdr *lh;
2891 int len, count;
2892
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002893 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %u",
2894 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002895
Anderson Lizardo300b9622013-06-02 16:30:40 -04002896 if (conn->mtu < L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE)
2897 return NULL;
2898
Linus Torvalds1da177e2005-04-16 15:20:36 -07002899 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2900 count = min_t(unsigned int, conn->mtu, len);
2901
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002902 skb = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002903 if (!skb)
2904 return NULL;
2905
2906 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002907 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002908
2909 if (conn->hcon->type == LE_LINK)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002910 lh->cid = __constant_cpu_to_le16(L2CAP_CID_LE_SIGNALING);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002911 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002912 lh->cid = __constant_cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002913
2914 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2915 cmd->code = code;
2916 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002917 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002918
2919 if (dlen) {
2920 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2921 memcpy(skb_put(skb, count), data, count);
2922 data += count;
2923 }
2924
2925 len -= skb->len;
2926
2927 /* Continuation fragments (no L2CAP header) */
2928 frag = &skb_shinfo(skb)->frag_list;
2929 while (len) {
2930 count = min_t(unsigned int, conn->mtu, len);
2931
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002932 *frag = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002933 if (!*frag)
2934 goto fail;
2935
2936 memcpy(skb_put(*frag, count), data, count);
2937
2938 len -= count;
2939 data += count;
2940
2941 frag = &(*frag)->next;
2942 }
2943
2944 return skb;
2945
2946fail:
2947 kfree_skb(skb);
2948 return NULL;
2949}
2950
Gustavo Padovan2d792812012-10-06 10:07:01 +01002951static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen,
2952 unsigned long *val)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002953{
2954 struct l2cap_conf_opt *opt = *ptr;
2955 int len;
2956
2957 len = L2CAP_CONF_OPT_SIZE + opt->len;
2958 *ptr += len;
2959
2960 *type = opt->type;
2961 *olen = opt->len;
2962
2963 switch (opt->len) {
2964 case 1:
2965 *val = *((u8 *) opt->val);
2966 break;
2967
2968 case 2:
steven miaobfaaeb32010-10-16 18:29:47 -04002969 *val = get_unaligned_le16(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002970 break;
2971
2972 case 4:
steven miaobfaaeb32010-10-16 18:29:47 -04002973 *val = get_unaligned_le32(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002974 break;
2975
2976 default:
2977 *val = (unsigned long) opt->val;
2978 break;
2979 }
2980
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002981 BT_DBG("type 0x%2.2x len %u val 0x%lx", *type, opt->len, *val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002982 return len;
2983}
2984
Linus Torvalds1da177e2005-04-16 15:20:36 -07002985static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2986{
2987 struct l2cap_conf_opt *opt = *ptr;
2988
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002989 BT_DBG("type 0x%2.2x len %u val 0x%lx", type, len, val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002990
2991 opt->type = type;
2992 opt->len = len;
2993
2994 switch (len) {
2995 case 1:
2996 *((u8 *) opt->val) = val;
2997 break;
2998
2999 case 2:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02003000 put_unaligned_le16(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003001 break;
3002
3003 case 4:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02003004 put_unaligned_le32(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003005 break;
3006
3007 default:
3008 memcpy(opt->val, (void *) val, len);
3009 break;
3010 }
3011
3012 *ptr += L2CAP_CONF_OPT_SIZE + len;
3013}
3014
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003015static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan)
3016{
3017 struct l2cap_conf_efs efs;
3018
Szymon Janc1ec918c2011-11-16 09:32:21 +01003019 switch (chan->mode) {
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003020 case L2CAP_MODE_ERTM:
3021 efs.id = chan->local_id;
3022 efs.stype = chan->local_stype;
3023 efs.msdu = cpu_to_le16(chan->local_msdu);
3024 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003025 efs.acc_lat = __constant_cpu_to_le32(L2CAP_DEFAULT_ACC_LAT);
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03003026 efs.flush_to = __constant_cpu_to_le32(L2CAP_EFS_DEFAULT_FLUSH_TO);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003027 break;
3028
3029 case L2CAP_MODE_STREAMING:
3030 efs.id = 1;
3031 efs.stype = L2CAP_SERV_BESTEFFORT;
3032 efs.msdu = cpu_to_le16(chan->local_msdu);
3033 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
3034 efs.acc_lat = 0;
3035 efs.flush_to = 0;
3036 break;
3037
3038 default:
3039 return;
3040 }
3041
3042 l2cap_add_conf_opt(ptr, L2CAP_CONF_EFS, sizeof(efs),
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03003043 (unsigned long) &efs);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003044}
3045
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003046static void l2cap_ack_timeout(struct work_struct *work)
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003047{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003048 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau03625202012-05-17 20:53:51 -07003049 ack_timer.work);
3050 u16 frames_to_ack;
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003051
Gustavo F. Padovan2fb9b3d2011-12-22 16:56:05 -02003052 BT_DBG("chan %p", chan);
3053
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003054 l2cap_chan_lock(chan);
3055
Mat Martineau03625202012-05-17 20:53:51 -07003056 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
3057 chan->last_acked_seq);
3058
3059 if (frames_to_ack)
3060 l2cap_send_rr_or_rnr(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003061
3062 l2cap_chan_unlock(chan);
Szymon Janc09bfb2e2012-01-11 10:59:49 +01003063 l2cap_chan_put(chan);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003064}
3065
Andrei Emeltchenko466f8002012-05-29 13:59:01 +03003066int l2cap_ertm_init(struct l2cap_chan *chan)
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003067{
Mat Martineau3c588192012-04-11 10:48:42 -07003068 int err;
3069
Mat Martineau105bdf92012-04-27 16:50:48 -07003070 chan->next_tx_seq = 0;
3071 chan->expected_tx_seq = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03003072 chan->expected_ack_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03003073 chan->unacked_frames = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03003074 chan->buffer_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03003075 chan->frames_sent = 0;
Mat Martineau105bdf92012-04-27 16:50:48 -07003076 chan->last_acked_seq = 0;
3077 chan->sdu = NULL;
3078 chan->sdu_last_frag = NULL;
3079 chan->sdu_len = 0;
3080
Mat Martineaud34c34f2012-05-14 14:49:27 -07003081 skb_queue_head_init(&chan->tx_q);
3082
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003083 chan->local_amp_id = AMP_ID_BREDR;
3084 chan->move_id = AMP_ID_BREDR;
Mat Martineau08333282012-10-23 15:24:06 -07003085 chan->move_state = L2CAP_MOVE_STABLE;
3086 chan->move_role = L2CAP_MOVE_ROLE_NONE;
3087
Mat Martineau105bdf92012-04-27 16:50:48 -07003088 if (chan->mode != L2CAP_MODE_ERTM)
3089 return 0;
3090
3091 chan->rx_state = L2CAP_RX_STATE_RECV;
3092 chan->tx_state = L2CAP_TX_STATE_XMIT;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003093
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003094 INIT_DELAYED_WORK(&chan->retrans_timer, l2cap_retrans_timeout);
3095 INIT_DELAYED_WORK(&chan->monitor_timer, l2cap_monitor_timeout);
3096 INIT_DELAYED_WORK(&chan->ack_timer, l2cap_ack_timeout);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003097
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -03003098 skb_queue_head_init(&chan->srej_q);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003099
Mat Martineau3c588192012-04-11 10:48:42 -07003100 err = l2cap_seq_list_init(&chan->srej_list, chan->tx_win);
3101 if (err < 0)
3102 return err;
3103
Mat Martineau9dc9aff2012-05-17 16:20:14 -07003104 err = l2cap_seq_list_init(&chan->retrans_list, chan->remote_tx_win);
3105 if (err < 0)
3106 l2cap_seq_list_free(&chan->srej_list);
3107
3108 return err;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003109}
3110
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003111static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
3112{
3113 switch (mode) {
3114 case L2CAP_MODE_STREAMING:
3115 case L2CAP_MODE_ERTM:
3116 if (l2cap_mode_supported(mode, remote_feat_mask))
3117 return mode;
3118 /* fall through */
3119 default:
3120 return L2CAP_MODE_BASIC;
3121 }
3122}
3123
Marcel Holtmann848566b2013-10-01 22:59:22 -07003124static inline bool __l2cap_ews_supported(struct l2cap_conn *conn)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003125{
Marcel Holtmann848566b2013-10-01 22:59:22 -07003126 return conn->hs_enabled && conn->feat_mask & L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003127}
3128
Marcel Holtmann848566b2013-10-01 22:59:22 -07003129static inline bool __l2cap_efs_supported(struct l2cap_conn *conn)
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003130{
Marcel Holtmann848566b2013-10-01 22:59:22 -07003131 return conn->hs_enabled && conn->feat_mask & L2CAP_FEAT_EXT_FLOW;
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003132}
3133
Mat Martineau36c86c82012-10-23 15:24:20 -07003134static void __l2cap_set_ertm_timeouts(struct l2cap_chan *chan,
3135 struct l2cap_conf_rfc *rfc)
3136{
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003137 if (chan->local_amp_id != AMP_ID_BREDR && chan->hs_hcon) {
Mat Martineau36c86c82012-10-23 15:24:20 -07003138 u64 ertm_to = chan->hs_hcon->hdev->amp_be_flush_to;
3139
3140 /* Class 1 devices have must have ERTM timeouts
3141 * exceeding the Link Supervision Timeout. The
3142 * default Link Supervision Timeout for AMP
3143 * controllers is 10 seconds.
3144 *
3145 * Class 1 devices use 0xffffffff for their
3146 * best-effort flush timeout, so the clamping logic
3147 * will result in a timeout that meets the above
3148 * requirement. ERTM timeouts are 16-bit values, so
3149 * the maximum timeout is 65.535 seconds.
3150 */
3151
3152 /* Convert timeout to milliseconds and round */
3153 ertm_to = DIV_ROUND_UP_ULL(ertm_to, 1000);
3154
3155 /* This is the recommended formula for class 2 devices
3156 * that start ERTM timers when packets are sent to the
3157 * controller.
3158 */
3159 ertm_to = 3 * ertm_to + 500;
3160
3161 if (ertm_to > 0xffff)
3162 ertm_to = 0xffff;
3163
3164 rfc->retrans_timeout = cpu_to_le16((u16) ertm_to);
3165 rfc->monitor_timeout = rfc->retrans_timeout;
3166 } else {
3167 rfc->retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
3168 rfc->monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
3169 }
3170}
3171
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003172static inline void l2cap_txwin_setup(struct l2cap_chan *chan)
3173{
3174 if (chan->tx_win > L2CAP_DEFAULT_TX_WINDOW &&
Marcel Holtmann848566b2013-10-01 22:59:22 -07003175 __l2cap_ews_supported(chan->conn)) {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003176 /* use extended control field */
3177 set_bit(FLAG_EXT_CTRL, &chan->flags);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003178 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
3179 } else {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003180 chan->tx_win = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003181 L2CAP_DEFAULT_TX_WINDOW);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003182 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
3183 }
Mat Martineauc20f8e32012-07-10 05:47:07 -07003184 chan->ack_win = chan->tx_win;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003185}
3186
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003187static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003188{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003189 struct l2cap_conf_req *req = data;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003190 struct l2cap_conf_rfc rfc = { .mode = chan->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07003191 void *ptr = req->data;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003192 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003193
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03003194 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003195
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003196 if (chan->num_conf_req || chan->num_conf_rsp)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003197 goto done;
3198
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003199 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003200 case L2CAP_MODE_STREAMING:
3201 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003202 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state))
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003203 break;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003204
Marcel Holtmann848566b2013-10-01 22:59:22 -07003205 if (__l2cap_efs_supported(chan->conn))
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003206 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3207
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03003208 /* fall through */
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003209 default:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003210 chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003211 break;
3212 }
3213
3214done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003215 if (chan->imtu != L2CAP_DEFAULT_MTU)
3216 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovan7990681c2011-01-24 16:01:43 -02003217
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003218 switch (chan->mode) {
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003219 case L2CAP_MODE_BASIC:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003220 if (!(chan->conn->feat_mask & L2CAP_FEAT_ERTM) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003221 !(chan->conn->feat_mask & L2CAP_FEAT_STREAMING))
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003222 break;
3223
Gustavo F. Padovan62547752010-06-08 20:05:31 -03003224 rfc.mode = L2CAP_MODE_BASIC;
3225 rfc.txwin_size = 0;
3226 rfc.max_transmit = 0;
3227 rfc.retrans_timeout = 0;
3228 rfc.monitor_timeout = 0;
3229 rfc.max_pdu_size = 0;
3230
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003231 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003232 (unsigned long) &rfc);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003233 break;
3234
3235 case L2CAP_MODE_ERTM:
3236 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003237 rfc.max_transmit = chan->max_tx;
Mat Martineau36c86c82012-10-23 15:24:20 -07003238
3239 __l2cap_set_ertm_timeouts(chan, &rfc);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003240
3241 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003242 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3243 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003244 rfc.max_pdu_size = cpu_to_le16(size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003245
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003246 l2cap_txwin_setup(chan);
3247
3248 rfc.txwin_size = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003249 L2CAP_DEFAULT_TX_WINDOW);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003250
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003251 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003252 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003253
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003254 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3255 l2cap_add_opt_efs(&ptr, chan);
3256
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003257 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3258 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003259 chan->tx_win);
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003260
3261 if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
3262 if (chan->fcs == L2CAP_FCS_NONE ||
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003263 test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003264 chan->fcs = L2CAP_FCS_NONE;
3265 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
3266 chan->fcs);
3267 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003268 break;
3269
3270 case L2CAP_MODE_STREAMING:
Mat Martineau273759e2012-05-17 20:53:53 -07003271 l2cap_txwin_setup(chan);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003272 rfc.mode = L2CAP_MODE_STREAMING;
3273 rfc.txwin_size = 0;
3274 rfc.max_transmit = 0;
3275 rfc.retrans_timeout = 0;
3276 rfc.monitor_timeout = 0;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003277
3278 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003279 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3280 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003281 rfc.max_pdu_size = cpu_to_le16(size);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003282
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003283 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003284 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003285
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003286 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3287 l2cap_add_opt_efs(&ptr, chan);
3288
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003289 if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
3290 if (chan->fcs == L2CAP_FCS_NONE ||
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003291 test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003292 chan->fcs = L2CAP_FCS_NONE;
3293 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
3294 chan->fcs);
3295 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003296 break;
3297 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003298
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003299 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003300 req->flags = __constant_cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003301
3302 return ptr - data;
3303}
3304
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003305static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003306{
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003307 struct l2cap_conf_rsp *rsp = data;
3308 void *ptr = rsp->data;
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003309 void *req = chan->conf_req;
3310 int len = chan->conf_len;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003311 int type, hint, olen;
3312 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003313 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003314 struct l2cap_conf_efs efs;
3315 u8 remote_efs = 0;
Marcel Holtmann861d6882007-10-20 13:37:06 +02003316 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003317 u16 result = L2CAP_CONF_SUCCESS;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003318 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003319
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003320 BT_DBG("chan %p", chan);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01003321
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003322 while (len >= L2CAP_CONF_OPT_SIZE) {
3323 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003324
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03003325 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003326 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003327
3328 switch (type) {
3329 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02003330 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003331 break;
3332
3333 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003334 chan->flush_to = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003335 break;
3336
3337 case L2CAP_CONF_QOS:
3338 break;
3339
Marcel Holtmann6464f352007-10-20 13:39:51 +02003340 case L2CAP_CONF_RFC:
3341 if (olen == sizeof(rfc))
3342 memcpy(&rfc, (void *) val, olen);
3343 break;
3344
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003345 case L2CAP_CONF_FCS:
3346 if (val == L2CAP_FCS_NONE)
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003347 set_bit(CONF_RECV_NO_FCS, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003348 break;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003349
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003350 case L2CAP_CONF_EFS:
3351 remote_efs = 1;
3352 if (olen == sizeof(efs))
3353 memcpy(&efs, (void *) val, olen);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003354 break;
3355
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003356 case L2CAP_CONF_EWS:
Marcel Holtmann848566b2013-10-01 22:59:22 -07003357 if (!chan->conn->hs_enabled)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003358 return -ECONNREFUSED;
3359
3360 set_bit(FLAG_EXT_CTRL, &chan->flags);
3361 set_bit(CONF_EWS_RECV, &chan->conf_state);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003362 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003363 chan->remote_tx_win = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003364 break;
3365
3366 default:
3367 if (hint)
3368 break;
3369
3370 result = L2CAP_CONF_UNKNOWN;
3371 *((u8 *) ptr++) = type;
3372 break;
3373 }
3374 }
3375
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003376 if (chan->num_conf_rsp || chan->num_conf_req > 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003377 goto done;
3378
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003379 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003380 case L2CAP_MODE_STREAMING:
3381 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003382 if (!test_bit(CONF_STATE2_DEVICE, &chan->conf_state)) {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003383 chan->mode = l2cap_select_mode(rfc.mode,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003384 chan->conn->feat_mask);
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003385 break;
3386 }
3387
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003388 if (remote_efs) {
Marcel Holtmann848566b2013-10-01 22:59:22 -07003389 if (__l2cap_efs_supported(chan->conn))
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003390 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3391 else
3392 return -ECONNREFUSED;
3393 }
3394
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003395 if (chan->mode != rfc.mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003396 return -ECONNREFUSED;
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03003397
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003398 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003399 }
3400
3401done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003402 if (chan->mode != rfc.mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003403 result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003404 rfc.mode = chan->mode;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003405
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003406 if (chan->num_conf_rsp == 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003407 return -ECONNREFUSED;
3408
Gustavo Padovan2d792812012-10-06 10:07:01 +01003409 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3410 (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003411 }
3412
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003413 if (result == L2CAP_CONF_SUCCESS) {
3414 /* Configure output options and let the other side know
3415 * which ones we don't like. */
3416
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003417 if (mtu < L2CAP_DEFAULT_MIN_MTU)
3418 result = L2CAP_CONF_UNACCEPT;
3419 else {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003420 chan->omtu = mtu;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003421 set_bit(CONF_MTU_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003422 }
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003423 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003424
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003425 if (remote_efs) {
3426 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003427 efs.stype != L2CAP_SERV_NOTRAFIC &&
3428 efs.stype != chan->local_stype) {
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003429
3430 result = L2CAP_CONF_UNACCEPT;
3431
3432 if (chan->num_conf_req >= 1)
3433 return -ECONNREFUSED;
3434
3435 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003436 sizeof(efs),
3437 (unsigned long) &efs);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003438 } else {
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003439 /* Send PENDING Conf Rsp */
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003440 result = L2CAP_CONF_PENDING;
3441 set_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003442 }
3443 }
3444
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003445 switch (rfc.mode) {
3446 case L2CAP_MODE_BASIC:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003447 chan->fcs = L2CAP_FCS_NONE;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003448 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003449 break;
3450
3451 case L2CAP_MODE_ERTM:
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003452 if (!test_bit(CONF_EWS_RECV, &chan->conf_state))
3453 chan->remote_tx_win = rfc.txwin_size;
3454 else
3455 rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW;
3456
Gustavo F. Padovan2c03a7a2011-03-25 20:15:28 -03003457 chan->remote_max_tx = rfc.max_transmit;
Mat Martineau86b1b262010-08-05 15:54:22 -07003458
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003459 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003460 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3461 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003462 rfc.max_pdu_size = cpu_to_le16(size);
3463 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003464
Mat Martineau36c86c82012-10-23 15:24:20 -07003465 __l2cap_set_ertm_timeouts(chan, &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003466
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003467 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003468
3469 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003470 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003471
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003472 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3473 chan->remote_id = efs.id;
3474 chan->remote_stype = efs.stype;
3475 chan->remote_msdu = le16_to_cpu(efs.msdu);
3476 chan->remote_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003477 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003478 chan->remote_acc_lat =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003479 le32_to_cpu(efs.acc_lat);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003480 chan->remote_sdu_itime =
3481 le32_to_cpu(efs.sdu_itime);
3482 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003483 sizeof(efs),
3484 (unsigned long) &efs);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003485 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003486 break;
3487
3488 case L2CAP_MODE_STREAMING:
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003489 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003490 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3491 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003492 rfc.max_pdu_size = cpu_to_le16(size);
3493 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003494
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003495 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003496
Gustavo Padovan2d792812012-10-06 10:07:01 +01003497 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3498 (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003499
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003500 break;
3501
3502 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02003503 result = L2CAP_CONF_UNACCEPT;
3504
3505 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003506 rfc.mode = chan->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003507 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003508
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003509 if (result == L2CAP_CONF_SUCCESS)
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003510 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003511 }
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003512 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003513 rsp->result = cpu_to_le16(result);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003514 rsp->flags = __constant_cpu_to_le16(0);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003515
3516 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003517}
3518
Gustavo Padovan2d792812012-10-06 10:07:01 +01003519static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len,
3520 void *data, u16 *result)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003521{
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003522 struct l2cap_conf_req *req = data;
3523 void *ptr = req->data;
3524 int type, olen;
3525 unsigned long val;
Mat Martineau36e999a2011-12-08 17:23:21 -08003526 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003527 struct l2cap_conf_efs efs;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003528
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003529 BT_DBG("chan %p, rsp %p, len %d, req %p", chan, rsp, len, data);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003530
3531 while (len >= L2CAP_CONF_OPT_SIZE) {
3532 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3533
3534 switch (type) {
3535 case L2CAP_CONF_MTU:
3536 if (val < L2CAP_DEFAULT_MIN_MTU) {
3537 *result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003538 chan->imtu = L2CAP_DEFAULT_MIN_MTU;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003539 } else
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003540 chan->imtu = val;
3541 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003542 break;
3543
3544 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003545 chan->flush_to = val;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003546 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003547 2, chan->flush_to);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003548 break;
3549
3550 case L2CAP_CONF_RFC:
3551 if (olen == sizeof(rfc))
3552 memcpy(&rfc, (void *)val, olen);
3553
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003554 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003555 rfc.mode != chan->mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003556 return -ECONNREFUSED;
3557
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003558 chan->fcs = 0;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003559
3560 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003561 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003562 break;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003563
3564 case L2CAP_CONF_EWS:
Mat Martineauc20f8e32012-07-10 05:47:07 -07003565 chan->ack_win = min_t(u16, val, chan->ack_win);
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003566 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Mat Martineauc20f8e32012-07-10 05:47:07 -07003567 chan->tx_win);
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003568 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003569
3570 case L2CAP_CONF_EFS:
3571 if (olen == sizeof(efs))
3572 memcpy(&efs, (void *)val, olen);
3573
3574 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003575 efs.stype != L2CAP_SERV_NOTRAFIC &&
3576 efs.stype != chan->local_stype)
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003577 return -ECONNREFUSED;
3578
Gustavo Padovan2d792812012-10-06 10:07:01 +01003579 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs),
3580 (unsigned long) &efs);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003581 break;
Andrei Emeltchenkocbabee72012-11-29 17:46:07 +02003582
3583 case L2CAP_CONF_FCS:
3584 if (*result == L2CAP_CONF_PENDING)
3585 if (val == L2CAP_FCS_NONE)
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003586 set_bit(CONF_RECV_NO_FCS,
Andrei Emeltchenkocbabee72012-11-29 17:46:07 +02003587 &chan->conf_state);
3588 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003589 }
3590 }
3591
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003592 if (chan->mode == L2CAP_MODE_BASIC && chan->mode != rfc.mode)
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003593 return -ECONNREFUSED;
3594
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003595 chan->mode = rfc.mode;
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003596
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003597 if (*result == L2CAP_CONF_SUCCESS || *result == L2CAP_CONF_PENDING) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003598 switch (rfc.mode) {
3599 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003600 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3601 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
3602 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003603 if (!test_bit(FLAG_EXT_CTRL, &chan->flags))
3604 chan->ack_win = min_t(u16, chan->ack_win,
3605 rfc.txwin_size);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003606
3607 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3608 chan->local_msdu = le16_to_cpu(efs.msdu);
3609 chan->local_sdu_itime =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003610 le32_to_cpu(efs.sdu_itime);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003611 chan->local_acc_lat = le32_to_cpu(efs.acc_lat);
3612 chan->local_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003613 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003614 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003615 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003616
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003617 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003618 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003619 }
3620 }
3621
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003622 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003623 req->flags = __constant_cpu_to_le16(0);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003624
3625 return ptr - data;
3626}
3627
Gustavo Padovan2d792812012-10-06 10:07:01 +01003628static int l2cap_build_conf_rsp(struct l2cap_chan *chan, void *data,
3629 u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003630{
3631 struct l2cap_conf_rsp *rsp = data;
3632 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003633
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003634 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003635
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003636 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003637 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003638 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003639
3640 return ptr - data;
3641}
3642
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003643void __l2cap_connect_rsp_defer(struct l2cap_chan *chan)
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003644{
3645 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003646 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003647 u8 buf[128];
Andrei Emeltchenko439f34a2012-10-31 15:46:28 +02003648 u8 rsp_code;
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003649
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003650 rsp.scid = cpu_to_le16(chan->dcid);
3651 rsp.dcid = cpu_to_le16(chan->scid);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003652 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
3653 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Andrei Emeltchenko439f34a2012-10-31 15:46:28 +02003654
3655 if (chan->hs_hcon)
3656 rsp_code = L2CAP_CREATE_CHAN_RSP;
3657 else
3658 rsp_code = L2CAP_CONN_RSP;
3659
3660 BT_DBG("chan %p rsp_code %u", chan, rsp_code);
3661
3662 l2cap_send_cmd(conn, chan->ident, rsp_code, sizeof(rsp), &rsp);
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003663
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003664 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003665 return;
3666
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003667 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003668 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003669 chan->num_conf_req++;
3670}
3671
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003672static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003673{
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003674 int type, olen;
3675 unsigned long val;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003676 /* Use sane default values in case a misbehaving remote device
3677 * did not send an RFC or extended window size option.
3678 */
3679 u16 txwin_ext = chan->ack_win;
3680 struct l2cap_conf_rfc rfc = {
3681 .mode = chan->mode,
3682 .retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO),
3683 .monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO),
3684 .max_pdu_size = cpu_to_le16(chan->imtu),
3685 .txwin_size = min_t(u16, chan->ack_win, L2CAP_DEFAULT_TX_WINDOW),
3686 };
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003687
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003688 BT_DBG("chan %p, rsp %p, len %d", chan, rsp, len);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003689
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003690 if ((chan->mode != L2CAP_MODE_ERTM) && (chan->mode != L2CAP_MODE_STREAMING))
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003691 return;
3692
3693 while (len >= L2CAP_CONF_OPT_SIZE) {
3694 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3695
Mat Martineauc20f8e32012-07-10 05:47:07 -07003696 switch (type) {
3697 case L2CAP_CONF_RFC:
3698 if (olen == sizeof(rfc))
3699 memcpy(&rfc, (void *)val, olen);
Szymon Janc8f321f82012-06-08 11:33:33 +02003700 break;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003701 case L2CAP_CONF_EWS:
3702 txwin_ext = val;
3703 break;
3704 }
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003705 }
3706
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003707 switch (rfc.mode) {
3708 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003709 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3710 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003711 chan->mps = le16_to_cpu(rfc.max_pdu_size);
3712 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3713 chan->ack_win = min_t(u16, chan->ack_win, txwin_ext);
3714 else
3715 chan->ack_win = min_t(u16, chan->ack_win,
3716 rfc.txwin_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003717 break;
3718 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003719 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003720 }
3721}
3722
Gustavo Padovan2d792812012-10-06 10:07:01 +01003723static inline int l2cap_command_rej(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003724 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3725 u8 *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003726{
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003727 struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003728
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003729 if (cmd_len < sizeof(*rej))
3730 return -EPROTO;
3731
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003732 if (rej->reason != L2CAP_REJ_NOT_UNDERSTOOD)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003733 return 0;
3734
3735 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003736 cmd->ident == conn->info_ident) {
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02003737 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01003738
3739 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003740 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003741
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003742 l2cap_conn_start(conn);
3743 }
3744
3745 return 0;
3746}
3747
Mat Martineau17009152012-10-23 15:24:07 -07003748static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
3749 struct l2cap_cmd_hdr *cmd,
3750 u8 *data, u8 rsp_code, u8 amp_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003751{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003752 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
3753 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003754 struct l2cap_chan *chan = NULL, *pchan;
Nathan Holsteind793fe82010-10-15 11:54:02 -04003755 struct sock *parent, *sk = NULL;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003756 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003757
3758 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003759 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003760
Andrei Emeltchenko097db762012-03-09 14:16:17 +02003761 BT_DBG("psm 0x%2.2x scid 0x%4.4x", __le16_to_cpu(psm), scid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003762
3763 /* Check if we have socket listening on psm */
Ido Yarivc2287682012-04-20 15:46:07 -03003764 pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003765 if (!pchan) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003766 result = L2CAP_CR_BAD_PSM;
3767 goto sendresp;
3768 }
3769
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003770 parent = pchan->sk;
3771
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003772 mutex_lock(&conn->chan_lock);
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003773 lock_sock(parent);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00003774
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003775 /* Check if the ACL is secure enough (if not SDP) */
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +03003776 if (psm != __constant_cpu_to_le16(L2CAP_PSM_SDP) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003777 !hci_conn_check_link_mode(conn->hcon)) {
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003778 conn->disc_reason = HCI_ERROR_AUTH_FAILURE;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003779 result = L2CAP_CR_SEC_BLOCK;
3780 goto response;
3781 }
3782
Linus Torvalds1da177e2005-04-16 15:20:36 -07003783 result = L2CAP_CR_NO_MEM;
3784
Gustavo Padovan2dfa1002012-05-27 22:27:58 -03003785 /* Check if we already have channel with that dcid */
3786 if (__l2cap_get_chan_by_dcid(conn, scid))
3787 goto response;
3788
Gustavo Padovan80b98022012-05-27 22:27:51 -03003789 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003790 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003791 goto response;
3792
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003793 sk = chan->sk;
3794
Syam Sidhardhan330b6c12013-08-06 01:59:12 +09003795 /* For certain devices (ex: HID mouse), support for authentication,
3796 * pairing and bonding is optional. For such devices, inorder to avoid
3797 * the ACL alive for too long after L2CAP disconnection, reset the ACL
3798 * disc_timeout back to HCI_DISCONN_TIMEOUT during L2CAP connect.
3799 */
3800 conn->hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
3801
Linus Torvalds1da177e2005-04-16 15:20:36 -07003802 bacpy(&bt_sk(sk)->src, conn->src);
3803 bacpy(&bt_sk(sk)->dst, conn->dst);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003804 chan->psm = psm;
3805 chan->dcid = scid;
Mat Martineau17009152012-10-23 15:24:07 -07003806 chan->local_amp_id = amp_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003807
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003808 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003809
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003810 dcid = chan->scid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003811
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03003812 __set_chan_timer(chan, sk->sk_sndtimeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003813
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003814 chan->ident = cmd->ident;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003815
Marcel Holtmann984947d2009-02-06 23:35:19 +01003816 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02003817 if (l2cap_chan_check_security(chan)) {
Gustavo Padovanc5daa682012-05-16 12:17:10 -03003818 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003819 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003820 result = L2CAP_CR_PEND;
3821 status = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08003822 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003823 } else {
Mat Martineau17009152012-10-23 15:24:07 -07003824 /* Force pending result for AMP controllers.
3825 * The connection will succeed after the
3826 * physical link is up.
3827 */
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003828 if (amp_id == AMP_ID_BREDR) {
Mat Martineau17009152012-10-23 15:24:07 -07003829 __l2cap_state_change(chan, BT_CONFIG);
3830 result = L2CAP_CR_SUCCESS;
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003831 } else {
3832 __l2cap_state_change(chan, BT_CONNECT2);
3833 result = L2CAP_CR_PEND;
Mat Martineau17009152012-10-23 15:24:07 -07003834 }
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003835 status = L2CAP_CS_NO_INFO;
3836 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003837 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003838 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003839 result = L2CAP_CR_PEND;
3840 status = L2CAP_CS_AUTHEN_PEND;
3841 }
3842 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003843 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003844 result = L2CAP_CR_PEND;
3845 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003846 }
3847
Linus Torvalds1da177e2005-04-16 15:20:36 -07003848response:
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003849 release_sock(parent);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003850 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003851
3852sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003853 rsp.scid = cpu_to_le16(scid);
3854 rsp.dcid = cpu_to_le16(dcid);
3855 rsp.result = cpu_to_le16(result);
3856 rsp.status = cpu_to_le16(status);
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003857 l2cap_send_cmd(conn, cmd->ident, rsp_code, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003858
3859 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
3860 struct l2cap_info_req info;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003861 info.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003862
3863 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
3864 conn->info_ident = l2cap_get_ident(conn);
3865
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08003866 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003867
Gustavo Padovan2d792812012-10-06 10:07:01 +01003868 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
3869 sizeof(info), &info);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003870 }
3871
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003872 if (chan && !test_bit(CONF_REQ_SENT, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003873 result == L2CAP_CR_SUCCESS) {
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003874 u8 buf[128];
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003875 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003876 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003877 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003878 chan->num_conf_req++;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003879 }
Mat Martineau17009152012-10-23 15:24:07 -07003880
3881 return chan;
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003882}
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003883
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003884static int l2cap_connect_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003885 struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003886{
Jaganath Kanakkassery7b064ed2013-01-10 10:28:35 +05303887 struct hci_dev *hdev = conn->hcon->hdev;
3888 struct hci_conn *hcon = conn->hcon;
3889
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003890 if (cmd_len < sizeof(struct l2cap_conn_req))
3891 return -EPROTO;
3892
Jaganath Kanakkassery7b064ed2013-01-10 10:28:35 +05303893 hci_dev_lock(hdev);
3894 if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
3895 !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &hcon->flags))
3896 mgmt_device_connected(hdev, &hcon->dst, hcon->type,
3897 hcon->dst_type, 0, NULL, 0,
3898 hcon->dev_class);
3899 hci_dev_unlock(hdev);
3900
Gustavo Padovan300229f2012-10-12 19:40:40 +08003901 l2cap_connect(conn, cmd, data, L2CAP_CONN_RSP, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003902 return 0;
3903}
3904
Mat Martineau5909cf32012-10-23 15:24:08 -07003905static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003906 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3907 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003908{
3909 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
3910 u16 scid, dcid, result, status;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003911 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003912 u8 req[128];
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003913 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003914
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003915 if (cmd_len < sizeof(*rsp))
3916 return -EPROTO;
3917
Linus Torvalds1da177e2005-04-16 15:20:36 -07003918 scid = __le16_to_cpu(rsp->scid);
3919 dcid = __le16_to_cpu(rsp->dcid);
3920 result = __le16_to_cpu(rsp->result);
3921 status = __le16_to_cpu(rsp->status);
3922
Andrei Emeltchenko1b009c92012-02-21 12:54:54 +02003923 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 +01003924 dcid, scid, result, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003925
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003926 mutex_lock(&conn->chan_lock);
3927
Linus Torvalds1da177e2005-04-16 15:20:36 -07003928 if (scid) {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003929 chan = __l2cap_get_chan_by_scid(conn, scid);
3930 if (!chan) {
Johan Hedberg21870b52013-09-16 13:05:14 +03003931 err = -EBADSLT;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003932 goto unlock;
3933 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003934 } else {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003935 chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
3936 if (!chan) {
Johan Hedberg21870b52013-09-16 13:05:14 +03003937 err = -EBADSLT;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003938 goto unlock;
3939 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003940 }
3941
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003942 err = 0;
3943
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003944 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003945
Linus Torvalds1da177e2005-04-16 15:20:36 -07003946 switch (result) {
3947 case L2CAP_CR_SUCCESS:
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03003948 l2cap_state_change(chan, BT_CONFIG);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003949 chan->ident = 0;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003950 chan->dcid = dcid;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003951 clear_bit(CONF_CONNECT_PEND, &chan->conf_state);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003952
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003953 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003954 break;
3955
Linus Torvalds1da177e2005-04-16 15:20:36 -07003956 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003957 l2cap_build_conf_req(chan, req), req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003958 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003959 break;
3960
3961 case L2CAP_CR_PEND:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003962 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003963 break;
3964
3965 default:
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003966 l2cap_chan_del(chan, ECONNREFUSED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003967 break;
3968 }
3969
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003970 l2cap_chan_unlock(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003971
3972unlock:
3973 mutex_unlock(&conn->chan_lock);
3974
3975 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003976}
3977
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003978static inline void set_default_fcs(struct l2cap_chan *chan)
Mat Martineau8c462b62010-08-24 15:35:42 -07003979{
3980 /* FCS is enabled only in ERTM or streaming mode, if one or both
3981 * sides request it.
3982 */
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003983 if (chan->mode != L2CAP_MODE_ERTM && chan->mode != L2CAP_MODE_STREAMING)
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003984 chan->fcs = L2CAP_FCS_NONE;
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003985 else if (!test_bit(CONF_RECV_NO_FCS, &chan->conf_state))
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003986 chan->fcs = L2CAP_FCS_CRC16;
Mat Martineau8c462b62010-08-24 15:35:42 -07003987}
3988
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03003989static void l2cap_send_efs_conf_rsp(struct l2cap_chan *chan, void *data,
3990 u8 ident, u16 flags)
3991{
3992 struct l2cap_conn *conn = chan->conn;
3993
3994 BT_DBG("conn %p chan %p ident %d flags 0x%4.4x", conn, chan, ident,
3995 flags);
3996
3997 clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
3998 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
3999
4000 l2cap_send_cmd(conn, ident, L2CAP_CONF_RSP,
4001 l2cap_build_conf_rsp(chan, data,
4002 L2CAP_CONF_SUCCESS, flags), data);
4003}
4004
Gustavo Padovan2d792812012-10-06 10:07:01 +01004005static inline int l2cap_config_req(struct l2cap_conn *conn,
4006 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4007 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004008{
4009 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
4010 u16 dcid, flags;
4011 u8 rsp[64];
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004012 struct l2cap_chan *chan;
Mat Martineau3c588192012-04-11 10:48:42 -07004013 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004014
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004015 if (cmd_len < sizeof(*req))
4016 return -EPROTO;
4017
Linus Torvalds1da177e2005-04-16 15:20:36 -07004018 dcid = __le16_to_cpu(req->dcid);
4019 flags = __le16_to_cpu(req->flags);
4020
4021 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
4022
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03004023 chan = l2cap_get_chan_by_scid(conn, dcid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004024 if (!chan)
Johan Hedberg21870b52013-09-16 13:05:14 +03004025 return -EBADSLT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004026
David S. Miller033b1142011-07-21 13:38:42 -07004027 if (chan->state != BT_CONFIG && chan->state != BT_CONNECT2) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03004028 struct l2cap_cmd_rej_cid rej;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03004029
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004030 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_INVALID_CID);
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03004031 rej.scid = cpu_to_le16(chan->scid);
4032 rej.dcid = cpu_to_le16(chan->dcid);
4033
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03004034 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004035 sizeof(rej), &rej);
Marcel Holtmann354f60a2006-11-18 22:15:20 +01004036 goto unlock;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03004037 }
Marcel Holtmann354f60a2006-11-18 22:15:20 +01004038
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004039 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07004040 len = cmd_len - sizeof(*req);
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004041 if (chan->conf_len + len > sizeof(chan->conf_req)) {
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004042 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004043 l2cap_build_conf_rsp(chan, rsp,
4044 L2CAP_CONF_REJECT, flags), rsp);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004045 goto unlock;
4046 }
4047
4048 /* Store config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004049 memcpy(chan->conf_req + chan->conf_len, req->data, len);
4050 chan->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004051
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03004052 if (flags & L2CAP_CONF_FLAG_CONTINUATION) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004053 /* Incomplete config. Send empty response. */
4054 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004055 l2cap_build_conf_rsp(chan, rsp,
4056 L2CAP_CONF_SUCCESS, flags), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004057 goto unlock;
4058 }
4059
4060 /* Complete config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004061 len = l2cap_parse_conf_req(chan, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004062 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004063 l2cap_send_disconn_req(chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004064 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004065 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004066
Mat Martineau1500109b2012-10-23 15:24:15 -07004067 chan->ident = cmd->ident;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004068 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004069 chan->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004070
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004071 /* Reset config buffer. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004072 chan->conf_len = 0;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004073
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004074 if (!test_bit(CONF_OUTPUT_DONE, &chan->conf_state))
Marcel Holtmann876d9482007-10-20 13:35:42 +02004075 goto unlock;
4076
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004077 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004078 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004079
Mat Martineau105bdf92012-04-27 16:50:48 -07004080 if (chan->mode == L2CAP_MODE_ERTM ||
4081 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07004082 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03004083
Mat Martineau3c588192012-04-11 10:48:42 -07004084 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004085 l2cap_send_disconn_req(chan, -err);
Mat Martineau3c588192012-04-11 10:48:42 -07004086 else
4087 l2cap_chan_ready(chan);
4088
Marcel Holtmann876d9482007-10-20 13:35:42 +02004089 goto unlock;
4090 }
4091
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004092 if (!test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004093 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004094 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004095 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004096 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004097 }
4098
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004099 /* Got Conf Rsp PENDING from remote side and asume we sent
4100 Conf Rsp PENDING in the code above */
4101 if (test_bit(CONF_REM_CONF_PEND, &chan->conf_state) &&
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03004102 test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004103
4104 /* check compatibility */
4105
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004106 /* Send rsp for BR/EDR channel */
Andrei Emeltchenkof351bc72012-10-31 15:46:35 +02004107 if (!chan->hs_hcon)
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004108 l2cap_send_efs_conf_rsp(chan, rsp, cmd->ident, flags);
4109 else
4110 chan->ident = cmd->ident;
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004111 }
4112
Linus Torvalds1da177e2005-04-16 15:20:36 -07004113unlock:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004114 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07004115 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004116}
4117
Gustavo Padovan2d792812012-10-06 10:07:01 +01004118static inline int l2cap_config_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004119 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4120 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004121{
4122 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
4123 u16 scid, flags, result;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004124 struct l2cap_chan *chan;
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004125 int len = cmd_len - sizeof(*rsp);
Mat Martineau3c588192012-04-11 10:48:42 -07004126 int err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004127
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004128 if (cmd_len < sizeof(*rsp))
4129 return -EPROTO;
4130
Linus Torvalds1da177e2005-04-16 15:20:36 -07004131 scid = __le16_to_cpu(rsp->scid);
4132 flags = __le16_to_cpu(rsp->flags);
4133 result = __le16_to_cpu(rsp->result);
4134
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02004135 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x len %d", scid, flags,
4136 result, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004137
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03004138 chan = l2cap_get_chan_by_scid(conn, scid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004139 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004140 return 0;
4141
4142 switch (result) {
4143 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004144 l2cap_conf_rfc_get(chan, rsp->data, len);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004145 clear_bit(CONF_REM_CONF_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004146 break;
4147
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004148 case L2CAP_CONF_PENDING:
4149 set_bit(CONF_REM_CONF_PEND, &chan->conf_state);
4150
4151 if (test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
4152 char buf[64];
4153
4154 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004155 buf, &result);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004156 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004157 l2cap_send_disconn_req(chan, ECONNRESET);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004158 goto done;
4159 }
4160
Andrei Emeltchenkof351bc72012-10-31 15:46:35 +02004161 if (!chan->hs_hcon) {
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004162 l2cap_send_efs_conf_rsp(chan, buf, cmd->ident,
4163 0);
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +02004164 } else {
4165 if (l2cap_check_efs(chan)) {
4166 amp_create_logical_link(chan);
4167 chan->ident = cmd->ident;
4168 }
4169 }
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004170 }
4171 goto done;
4172
Linus Torvalds1da177e2005-04-16 15:20:36 -07004173 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004174 if (chan->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004175 char req[64];
4176
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02004177 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004178 l2cap_send_disconn_req(chan, ECONNRESET);
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02004179 goto done;
4180 }
4181
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004182 /* throw out any old stored conf requests */
4183 result = L2CAP_CONF_SUCCESS;
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03004184 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004185 req, &result);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004186 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004187 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004188 goto done;
4189 }
4190
4191 l2cap_send_cmd(conn, l2cap_get_ident(conn),
Gustavo Padovan2d792812012-10-06 10:07:01 +01004192 L2CAP_CONF_REQ, len, req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004193 chan->num_conf_req++;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004194 if (result != L2CAP_CONF_SUCCESS)
4195 goto done;
4196 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004197 }
4198
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09004199 default:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004200 l2cap_chan_set_err(chan, ECONNRESET);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02004201
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08004202 __set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004203 l2cap_send_disconn_req(chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004204 goto done;
4205 }
4206
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03004207 if (flags & L2CAP_CONF_FLAG_CONTINUATION)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004208 goto done;
4209
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004210 set_bit(CONF_INPUT_DONE, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004211
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004212 if (test_bit(CONF_OUTPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004213 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004214
Mat Martineau105bdf92012-04-27 16:50:48 -07004215 if (chan->mode == L2CAP_MODE_ERTM ||
4216 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07004217 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03004218
Mat Martineau3c588192012-04-11 10:48:42 -07004219 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004220 l2cap_send_disconn_req(chan, -err);
Mat Martineau3c588192012-04-11 10:48:42 -07004221 else
4222 l2cap_chan_ready(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004223 }
4224
4225done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004226 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07004227 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004228}
4229
Gustavo Padovan2d792812012-10-06 10:07:01 +01004230static inline int l2cap_disconnect_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004231 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4232 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004233{
4234 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
4235 struct l2cap_disconn_rsp rsp;
4236 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004237 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004238 struct sock *sk;
4239
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004240 if (cmd_len != sizeof(*req))
4241 return -EPROTO;
4242
Linus Torvalds1da177e2005-04-16 15:20:36 -07004243 scid = __le16_to_cpu(req->scid);
4244 dcid = __le16_to_cpu(req->dcid);
4245
4246 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
4247
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004248 mutex_lock(&conn->chan_lock);
4249
4250 chan = __l2cap_get_chan_by_scid(conn, dcid);
4251 if (!chan) {
4252 mutex_unlock(&conn->chan_lock);
Johan Hedbergc4ea2492013-09-16 13:05:15 +03004253 return -EBADSLT;
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);
4257
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004258 sk = chan->sk;
4259
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03004260 rsp.dcid = cpu_to_le16(chan->scid);
4261 rsp.scid = cpu_to_le16(chan->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004262 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
4263
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004264 lock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004265 sk->sk_shutdown = SHUTDOWN_MASK;
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004266 release_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004267
Mat Martineau61d6ef32012-04-27 16:50:50 -07004268 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004269 l2cap_chan_del(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004270
4271 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004272
Gustavo Padovan80b98022012-05-27 22:27:51 -03004273 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004274 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004275
4276 mutex_unlock(&conn->chan_lock);
4277
Linus Torvalds1da177e2005-04-16 15:20:36 -07004278 return 0;
4279}
4280
Gustavo Padovan2d792812012-10-06 10:07:01 +01004281static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004282 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4283 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004284{
4285 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
4286 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004287 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004288
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004289 if (cmd_len != sizeof(*rsp))
4290 return -EPROTO;
4291
Linus Torvalds1da177e2005-04-16 15:20:36 -07004292 scid = __le16_to_cpu(rsp->scid);
4293 dcid = __le16_to_cpu(rsp->dcid);
4294
4295 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
4296
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004297 mutex_lock(&conn->chan_lock);
4298
4299 chan = __l2cap_get_chan_by_scid(conn, scid);
4300 if (!chan) {
4301 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004302 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004303 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004304
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004305 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004306
Mat Martineau61d6ef32012-04-27 16:50:50 -07004307 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004308 l2cap_chan_del(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004309
4310 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004311
Gustavo Padovan80b98022012-05-27 22:27:51 -03004312 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004313 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004314
4315 mutex_unlock(&conn->chan_lock);
4316
Linus Torvalds1da177e2005-04-16 15:20:36 -07004317 return 0;
4318}
4319
Gustavo Padovan2d792812012-10-06 10:07:01 +01004320static inline int l2cap_information_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004321 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4322 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004323{
4324 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004325 u16 type;
4326
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004327 if (cmd_len != sizeof(*req))
4328 return -EPROTO;
4329
Linus Torvalds1da177e2005-04-16 15:20:36 -07004330 type = __le16_to_cpu(req->type);
4331
4332 BT_DBG("type 0x%4.4x", type);
4333
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004334 if (type == L2CAP_IT_FEAT_MASK) {
4335 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07004336 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004337 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004338 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
4339 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03004340 if (!disable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004341 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
Gustavo Padovan2d792812012-10-06 10:07:01 +01004342 | L2CAP_FEAT_FCS;
Marcel Holtmann848566b2013-10-01 22:59:22 -07004343 if (conn->hs_enabled)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03004344 feat_mask |= L2CAP_FEAT_EXT_FLOW
Gustavo Padovan2d792812012-10-06 10:07:01 +01004345 | L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03004346
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03004347 put_unaligned_le32(feat_mask, rsp->data);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004348 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4349 buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004350 } else if (type == L2CAP_IT_FIXED_CHAN) {
4351 u8 buf[12];
4352 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Mat Martineau50a147c2011-11-02 16:18:34 -07004353
Marcel Holtmann848566b2013-10-01 22:59:22 -07004354 if (conn->hs_enabled)
Mat Martineau50a147c2011-11-02 16:18:34 -07004355 l2cap_fixed_chan[0] |= L2CAP_FC_A2MP;
4356 else
4357 l2cap_fixed_chan[0] &= ~L2CAP_FC_A2MP;
4358
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004359 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
4360 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Andrei Emeltchenkoc6337ea2011-10-20 17:02:44 +03004361 memcpy(rsp->data, l2cap_fixed_chan, sizeof(l2cap_fixed_chan));
Gustavo Padovan2d792812012-10-06 10:07:01 +01004362 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4363 buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004364 } else {
4365 struct l2cap_info_rsp rsp;
4366 rsp.type = cpu_to_le16(type);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004367 rsp.result = __constant_cpu_to_le16(L2CAP_IR_NOTSUPP);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004368 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(rsp),
4369 &rsp);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004370 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004371
4372 return 0;
4373}
4374
Gustavo Padovan2d792812012-10-06 10:07:01 +01004375static inline int l2cap_information_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004376 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4377 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004378{
4379 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
4380 u16 type, result;
4381
Jaganath Kanakkassery3f6fa3d2013-06-21 19:55:11 +05304382 if (cmd_len < sizeof(*rsp))
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004383 return -EPROTO;
4384
Linus Torvalds1da177e2005-04-16 15:20:36 -07004385 type = __le16_to_cpu(rsp->type);
4386 result = __le16_to_cpu(rsp->result);
4387
4388 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
4389
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004390 /* L2CAP Info req/rsp are unbound to channels, add extra checks */
4391 if (cmd->ident != conn->info_ident ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01004392 conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004393 return 0;
4394
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02004395 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004396
Ville Tervoadb08ed2010-08-04 09:43:33 +03004397 if (result != L2CAP_IR_SUCCESS) {
4398 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4399 conn->info_ident = 0;
4400
4401 l2cap_conn_start(conn);
4402
4403 return 0;
4404 }
4405
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004406 switch (type) {
4407 case L2CAP_IT_FEAT_MASK:
Harvey Harrison83985312008-05-02 16:25:46 -07004408 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004409
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07004410 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004411 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004412 req.type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004413
4414 conn->info_ident = l2cap_get_ident(conn);
4415
4416 l2cap_send_cmd(conn, conn->info_ident,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004417 L2CAP_INFO_REQ, sizeof(req), &req);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004418 } else {
4419 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4420 conn->info_ident = 0;
4421
4422 l2cap_conn_start(conn);
4423 }
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004424 break;
4425
4426 case L2CAP_IT_FIXED_CHAN:
4427 conn->fixed_chan_mask = rsp->data[0];
Marcel Holtmann984947d2009-02-06 23:35:19 +01004428 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004429 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004430
4431 l2cap_conn_start(conn);
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004432 break;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004433 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004434
Linus Torvalds1da177e2005-04-16 15:20:36 -07004435 return 0;
4436}
4437
Mat Martineau17009152012-10-23 15:24:07 -07004438static int l2cap_create_channel_req(struct l2cap_conn *conn,
4439 struct l2cap_cmd_hdr *cmd,
4440 u16 cmd_len, void *data)
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004441{
4442 struct l2cap_create_chan_req *req = data;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004443 struct l2cap_create_chan_rsp rsp;
Mat Martineau17009152012-10-23 15:24:07 -07004444 struct l2cap_chan *chan;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004445 struct hci_dev *hdev;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004446 u16 psm, scid;
4447
4448 if (cmd_len != sizeof(*req))
4449 return -EPROTO;
4450
Marcel Holtmann848566b2013-10-01 22:59:22 -07004451 if (!conn->hs_enabled)
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004452 return -EINVAL;
4453
4454 psm = le16_to_cpu(req->psm);
4455 scid = le16_to_cpu(req->scid);
4456
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004457 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 -07004458
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004459 /* For controller id 0 make BR/EDR connection */
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004460 if (req->amp_id == AMP_ID_BREDR) {
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004461 l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4462 req->amp_id);
4463 return 0;
4464 }
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004465
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004466 /* Validate AMP controller id */
4467 hdev = hci_dev_get(req->amp_id);
4468 if (!hdev)
4469 goto error;
Mat Martineau17009152012-10-23 15:24:07 -07004470
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004471 if (hdev->dev_type != HCI_AMP || !test_bit(HCI_UP, &hdev->flags)) {
Mat Martineau17009152012-10-23 15:24:07 -07004472 hci_dev_put(hdev);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004473 goto error;
Mat Martineau17009152012-10-23 15:24:07 -07004474 }
4475
4476 chan = l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4477 req->amp_id);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004478 if (chan) {
4479 struct amp_mgr *mgr = conn->hcon->amp_mgr;
4480 struct hci_conn *hs_hcon;
4481
4482 hs_hcon = hci_conn_hash_lookup_ba(hdev, AMP_LINK, conn->dst);
4483 if (!hs_hcon) {
4484 hci_dev_put(hdev);
Johan Hedberg21870b52013-09-16 13:05:14 +03004485 return -EBADSLT;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004486 }
4487
4488 BT_DBG("mgr %p bredr_chan %p hs_hcon %p", mgr, chan, hs_hcon);
4489
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004490 mgr->bredr_chan = chan;
4491 chan->hs_hcon = hs_hcon;
Andrei Emeltchenkofd45bf42012-11-20 17:16:22 +02004492 chan->fcs = L2CAP_FCS_NONE;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004493 conn->mtu = hdev->block_mtu;
4494 }
4495
4496 hci_dev_put(hdev);
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004497
4498 return 0;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004499
4500error:
4501 rsp.dcid = 0;
4502 rsp.scid = cpu_to_le16(scid);
4503 rsp.result = __constant_cpu_to_le16(L2CAP_CR_BAD_AMP);
4504 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
4505
4506 l2cap_send_cmd(conn, cmd->ident, L2CAP_CREATE_CHAN_RSP,
4507 sizeof(rsp), &rsp);
4508
Johan Hedbergdc280802013-09-16 13:05:13 +03004509 return 0;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004510}
4511
Mat Martineau8eb200b2012-10-23 15:24:17 -07004512static void l2cap_send_move_chan_req(struct l2cap_chan *chan, u8 dest_amp_id)
4513{
4514 struct l2cap_move_chan_req req;
4515 u8 ident;
4516
4517 BT_DBG("chan %p, dest_amp_id %d", chan, dest_amp_id);
4518
4519 ident = l2cap_get_ident(chan->conn);
4520 chan->ident = ident;
4521
4522 req.icid = cpu_to_le16(chan->scid);
4523 req.dest_amp_id = dest_amp_id;
4524
4525 l2cap_send_cmd(chan->conn, ident, L2CAP_MOVE_CHAN_REQ, sizeof(req),
4526 &req);
4527
4528 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4529}
4530
Mat Martineau1500109b2012-10-23 15:24:15 -07004531static void l2cap_send_move_chan_rsp(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004532{
4533 struct l2cap_move_chan_rsp rsp;
4534
Mat Martineau1500109b2012-10-23 15:24:15 -07004535 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004536
Mat Martineau1500109b2012-10-23 15:24:15 -07004537 rsp.icid = cpu_to_le16(chan->dcid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004538 rsp.result = cpu_to_le16(result);
4539
Mat Martineau1500109b2012-10-23 15:24:15 -07004540 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_RSP,
4541 sizeof(rsp), &rsp);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004542}
4543
Mat Martineau5b155ef2012-10-23 15:24:14 -07004544static void l2cap_send_move_chan_cfm(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004545{
4546 struct l2cap_move_chan_cfm cfm;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004547
Mat Martineau5b155ef2012-10-23 15:24:14 -07004548 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004549
Mat Martineau5b155ef2012-10-23 15:24:14 -07004550 chan->ident = l2cap_get_ident(chan->conn);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004551
Mat Martineau5b155ef2012-10-23 15:24:14 -07004552 cfm.icid = cpu_to_le16(chan->scid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004553 cfm.result = cpu_to_le16(result);
4554
Mat Martineau5b155ef2012-10-23 15:24:14 -07004555 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_CFM,
4556 sizeof(cfm), &cfm);
4557
4558 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4559}
4560
4561static void l2cap_send_move_chan_cfm_icid(struct l2cap_conn *conn, u16 icid)
4562{
4563 struct l2cap_move_chan_cfm cfm;
4564
4565 BT_DBG("conn %p, icid 0x%4.4x", conn, icid);
4566
4567 cfm.icid = cpu_to_le16(icid);
4568 cfm.result = __constant_cpu_to_le16(L2CAP_MC_UNCONFIRMED);
4569
4570 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_MOVE_CHAN_CFM,
4571 sizeof(cfm), &cfm);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004572}
4573
4574static void l2cap_send_move_chan_cfm_rsp(struct l2cap_conn *conn, u8 ident,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004575 u16 icid)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004576{
4577 struct l2cap_move_chan_cfm_rsp rsp;
4578
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004579 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004580
4581 rsp.icid = cpu_to_le16(icid);
4582 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM_RSP, sizeof(rsp), &rsp);
4583}
4584
Mat Martineau5f3847a2012-10-23 15:24:12 -07004585static void __release_logical_link(struct l2cap_chan *chan)
4586{
4587 chan->hs_hchan = NULL;
4588 chan->hs_hcon = NULL;
4589
4590 /* Placeholder - release the logical link */
4591}
4592
Mat Martineau1500109b2012-10-23 15:24:15 -07004593static void l2cap_logical_fail(struct l2cap_chan *chan)
4594{
4595 /* Logical link setup failed */
4596 if (chan->state != BT_CONNECTED) {
4597 /* Create channel failure, disconnect */
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004598 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineau1500109b2012-10-23 15:24:15 -07004599 return;
4600 }
4601
4602 switch (chan->move_role) {
4603 case L2CAP_MOVE_ROLE_RESPONDER:
4604 l2cap_move_done(chan);
4605 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_SUPP);
4606 break;
4607 case L2CAP_MOVE_ROLE_INITIATOR:
4608 if (chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_COMP ||
4609 chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_CFM) {
4610 /* Remote has only sent pending or
4611 * success responses, clean up
4612 */
4613 l2cap_move_done(chan);
4614 }
4615
4616 /* Other amp move states imply that the move
4617 * has already aborted
4618 */
4619 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4620 break;
4621 }
4622}
4623
4624static void l2cap_logical_finish_create(struct l2cap_chan *chan,
4625 struct hci_chan *hchan)
4626{
4627 struct l2cap_conf_rsp rsp;
Mat Martineau1500109b2012-10-23 15:24:15 -07004628
Andrei Emeltchenko336178a2012-10-31 15:46:27 +02004629 chan->hs_hchan = hchan;
Mat Martineau1500109b2012-10-23 15:24:15 -07004630 chan->hs_hcon->l2cap_data = chan->conn;
4631
Andrei Emeltchenko35ba9562012-10-25 15:20:43 +03004632 l2cap_send_efs_conf_rsp(chan, &rsp, chan->ident, 0);
Mat Martineau1500109b2012-10-23 15:24:15 -07004633
4634 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Andrei Emeltchenkofe79c6f2012-10-25 15:20:42 +03004635 int err;
Mat Martineau1500109b2012-10-23 15:24:15 -07004636
4637 set_default_fcs(chan);
4638
4639 err = l2cap_ertm_init(chan);
4640 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004641 l2cap_send_disconn_req(chan, -err);
Mat Martineau1500109b2012-10-23 15:24:15 -07004642 else
4643 l2cap_chan_ready(chan);
4644 }
4645}
4646
4647static void l2cap_logical_finish_move(struct l2cap_chan *chan,
4648 struct hci_chan *hchan)
4649{
4650 chan->hs_hcon = hchan->conn;
4651 chan->hs_hcon->l2cap_data = chan->conn;
4652
4653 BT_DBG("move_state %d", chan->move_state);
4654
4655 switch (chan->move_state) {
4656 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
4657 /* Move confirm will be sent after a success
4658 * response is received
4659 */
4660 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4661 break;
4662 case L2CAP_MOVE_WAIT_LOGICAL_CFM:
4663 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4664 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4665 } else if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
4666 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
4667 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4668 } else if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
4669 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4670 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
4671 }
4672 break;
4673 default:
4674 /* Move was not in expected state, free the channel */
4675 __release_logical_link(chan);
4676
4677 chan->move_state = L2CAP_MOVE_STABLE;
4678 }
4679}
4680
4681/* Call with chan locked */
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03004682void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan,
4683 u8 status)
Mat Martineau5b155ef2012-10-23 15:24:14 -07004684{
Mat Martineau1500109b2012-10-23 15:24:15 -07004685 BT_DBG("chan %p, hchan %p, status %d", chan, hchan, status);
4686
4687 if (status) {
4688 l2cap_logical_fail(chan);
4689 __release_logical_link(chan);
4690 return;
4691 }
4692
4693 if (chan->state != BT_CONNECTED) {
4694 /* Ignore logical link if channel is on BR/EDR */
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004695 if (chan->local_amp_id != AMP_ID_BREDR)
Mat Martineau1500109b2012-10-23 15:24:15 -07004696 l2cap_logical_finish_create(chan, hchan);
4697 } else {
4698 l2cap_logical_finish_move(chan, hchan);
4699 }
Mat Martineau5b155ef2012-10-23 15:24:14 -07004700}
4701
Mat Martineau3f7a56c2012-10-23 15:24:23 -07004702void l2cap_move_start(struct l2cap_chan *chan)
4703{
4704 BT_DBG("chan %p", chan);
4705
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004706 if (chan->local_amp_id == AMP_ID_BREDR) {
Mat Martineau3f7a56c2012-10-23 15:24:23 -07004707 if (chan->chan_policy != BT_CHANNEL_POLICY_AMP_PREFERRED)
4708 return;
4709 chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
4710 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
4711 /* Placeholder - start physical link setup */
4712 } else {
4713 chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
4714 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4715 chan->move_id = 0;
4716 l2cap_move_setup(chan);
4717 l2cap_send_move_chan_req(chan, 0);
4718 }
4719}
4720
Mat Martineau8eb200b2012-10-23 15:24:17 -07004721static void l2cap_do_create(struct l2cap_chan *chan, int result,
4722 u8 local_amp_id, u8 remote_amp_id)
4723{
Andrei Emeltchenko62748ca2012-11-20 17:16:19 +02004724 BT_DBG("chan %p state %s %u -> %u", chan, state_to_string(chan->state),
4725 local_amp_id, remote_amp_id);
4726
Andrei Emeltchenko12d6cc62012-11-14 17:39:31 +02004727 chan->fcs = L2CAP_FCS_NONE;
4728
Andrei Emeltchenko62748ca2012-11-20 17:16:19 +02004729 /* Outgoing channel on AMP */
4730 if (chan->state == BT_CONNECT) {
4731 if (result == L2CAP_CR_SUCCESS) {
4732 chan->local_amp_id = local_amp_id;
4733 l2cap_send_create_chan_req(chan, remote_amp_id);
4734 } else {
4735 /* Revert to BR/EDR connect */
4736 l2cap_send_conn_req(chan);
4737 }
4738
4739 return;
4740 }
4741
4742 /* Incoming channel on AMP */
4743 if (__l2cap_no_conn_pending(chan)) {
Mat Martineau8eb200b2012-10-23 15:24:17 -07004744 struct l2cap_conn_rsp rsp;
4745 char buf[128];
4746 rsp.scid = cpu_to_le16(chan->dcid);
4747 rsp.dcid = cpu_to_le16(chan->scid);
4748
Mat Martineau8eb200b2012-10-23 15:24:17 -07004749 if (result == L2CAP_CR_SUCCESS) {
4750 /* Send successful response */
Andrei Emeltchenko62cd50e2012-11-14 17:39:32 +02004751 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
4752 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004753 } else {
4754 /* Send negative response */
Andrei Emeltchenko62cd50e2012-11-14 17:39:32 +02004755 rsp.result = __constant_cpu_to_le16(L2CAP_CR_NO_MEM);
4756 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004757 }
4758
4759 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_RSP,
4760 sizeof(rsp), &rsp);
4761
4762 if (result == L2CAP_CR_SUCCESS) {
4763 __l2cap_state_change(chan, BT_CONFIG);
4764 set_bit(CONF_REQ_SENT, &chan->conf_state);
4765 l2cap_send_cmd(chan->conn, l2cap_get_ident(chan->conn),
4766 L2CAP_CONF_REQ,
4767 l2cap_build_conf_req(chan, buf), buf);
4768 chan->num_conf_req++;
4769 }
Mat Martineau8eb200b2012-10-23 15:24:17 -07004770 }
4771}
4772
4773static void l2cap_do_move_initiate(struct l2cap_chan *chan, u8 local_amp_id,
4774 u8 remote_amp_id)
4775{
4776 l2cap_move_setup(chan);
4777 chan->move_id = local_amp_id;
4778 chan->move_state = L2CAP_MOVE_WAIT_RSP;
4779
4780 l2cap_send_move_chan_req(chan, remote_amp_id);
4781}
4782
4783static void l2cap_do_move_respond(struct l2cap_chan *chan, int result)
4784{
4785 struct hci_chan *hchan = NULL;
4786
4787 /* Placeholder - get hci_chan for logical link */
4788
4789 if (hchan) {
4790 if (hchan->state == BT_CONNECTED) {
4791 /* Logical link is ready to go */
4792 chan->hs_hcon = hchan->conn;
4793 chan->hs_hcon->l2cap_data = chan->conn;
4794 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4795 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
4796
4797 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
4798 } else {
4799 /* Wait for logical link to be ready */
4800 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4801 }
4802 } else {
4803 /* Logical link not available */
4804 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_ALLOWED);
4805 }
4806}
4807
4808static void l2cap_do_move_cancel(struct l2cap_chan *chan, int result)
4809{
4810 if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
4811 u8 rsp_result;
4812 if (result == -EINVAL)
4813 rsp_result = L2CAP_MR_BAD_ID;
4814 else
4815 rsp_result = L2CAP_MR_NOT_ALLOWED;
4816
4817 l2cap_send_move_chan_rsp(chan, rsp_result);
4818 }
4819
4820 chan->move_role = L2CAP_MOVE_ROLE_NONE;
4821 chan->move_state = L2CAP_MOVE_STABLE;
4822
4823 /* Restart data transmission */
4824 l2cap_ertm_send(chan);
4825}
4826
Andrei Emeltchenkoa514b172012-11-14 17:39:30 +02004827/* Invoke with locked chan */
4828void __l2cap_physical_cfm(struct l2cap_chan *chan, int result)
Mat Martineau8eb200b2012-10-23 15:24:17 -07004829{
Andrei Emeltchenko770bfef2012-10-31 15:46:29 +02004830 u8 local_amp_id = chan->local_amp_id;
Andrei Emeltchenkofffadc02012-11-01 15:37:03 +02004831 u8 remote_amp_id = chan->remote_amp_id;
Andrei Emeltchenko770bfef2012-10-31 15:46:29 +02004832
Mat Martineau8eb200b2012-10-23 15:24:17 -07004833 BT_DBG("chan %p, result %d, local_amp_id %d, remote_amp_id %d",
4834 chan, result, local_amp_id, remote_amp_id);
4835
Mat Martineau8eb200b2012-10-23 15:24:17 -07004836 if (chan->state == BT_DISCONN || chan->state == BT_CLOSED) {
4837 l2cap_chan_unlock(chan);
4838 return;
4839 }
4840
4841 if (chan->state != BT_CONNECTED) {
4842 l2cap_do_create(chan, result, local_amp_id, remote_amp_id);
4843 } else if (result != L2CAP_MR_SUCCESS) {
4844 l2cap_do_move_cancel(chan, result);
4845 } else {
4846 switch (chan->move_role) {
4847 case L2CAP_MOVE_ROLE_INITIATOR:
4848 l2cap_do_move_initiate(chan, local_amp_id,
4849 remote_amp_id);
4850 break;
4851 case L2CAP_MOVE_ROLE_RESPONDER:
4852 l2cap_do_move_respond(chan, result);
4853 break;
4854 default:
4855 l2cap_do_move_cancel(chan, result);
4856 break;
4857 }
4858 }
Mat Martineau8eb200b2012-10-23 15:24:17 -07004859}
4860
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004861static inline int l2cap_move_channel_req(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004862 struct l2cap_cmd_hdr *cmd,
4863 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004864{
4865 struct l2cap_move_chan_req *req = data;
Mat Martineau1500109b2012-10-23 15:24:15 -07004866 struct l2cap_move_chan_rsp rsp;
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004867 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004868 u16 icid = 0;
4869 u16 result = L2CAP_MR_NOT_ALLOWED;
4870
4871 if (cmd_len != sizeof(*req))
4872 return -EPROTO;
4873
4874 icid = le16_to_cpu(req->icid);
4875
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004876 BT_DBG("icid 0x%4.4x, dest_amp_id %d", icid, req->dest_amp_id);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004877
Marcel Holtmann848566b2013-10-01 22:59:22 -07004878 if (!conn->hs_enabled)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004879 return -EINVAL;
4880
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004881 chan = l2cap_get_chan_by_dcid(conn, icid);
4882 if (!chan) {
Mat Martineau1500109b2012-10-23 15:24:15 -07004883 rsp.icid = cpu_to_le16(icid);
4884 rsp.result = __constant_cpu_to_le16(L2CAP_MR_NOT_ALLOWED);
4885 l2cap_send_cmd(conn, cmd->ident, L2CAP_MOVE_CHAN_RSP,
4886 sizeof(rsp), &rsp);
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004887 return 0;
4888 }
4889
Mat Martineau1500109b2012-10-23 15:24:15 -07004890 chan->ident = cmd->ident;
4891
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004892 if (chan->scid < L2CAP_CID_DYN_START ||
4893 chan->chan_policy == BT_CHANNEL_POLICY_BREDR_ONLY ||
4894 (chan->mode != L2CAP_MODE_ERTM &&
4895 chan->mode != L2CAP_MODE_STREAMING)) {
4896 result = L2CAP_MR_NOT_ALLOWED;
4897 goto send_move_response;
4898 }
4899
4900 if (chan->local_amp_id == req->dest_amp_id) {
4901 result = L2CAP_MR_SAME_ID;
4902 goto send_move_response;
4903 }
4904
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004905 if (req->dest_amp_id != AMP_ID_BREDR) {
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004906 struct hci_dev *hdev;
4907 hdev = hci_dev_get(req->dest_amp_id);
4908 if (!hdev || hdev->dev_type != HCI_AMP ||
4909 !test_bit(HCI_UP, &hdev->flags)) {
4910 if (hdev)
4911 hci_dev_put(hdev);
4912
4913 result = L2CAP_MR_BAD_ID;
4914 goto send_move_response;
4915 }
4916 hci_dev_put(hdev);
4917 }
4918
4919 /* Detect a move collision. Only send a collision response
4920 * if this side has "lost", otherwise proceed with the move.
4921 * The winner has the larger bd_addr.
4922 */
4923 if ((__chan_is_moving(chan) ||
4924 chan->move_role != L2CAP_MOVE_ROLE_NONE) &&
4925 bacmp(conn->src, conn->dst) > 0) {
4926 result = L2CAP_MR_COLLISION;
4927 goto send_move_response;
4928 }
4929
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004930 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
4931 l2cap_move_setup(chan);
4932 chan->move_id = req->dest_amp_id;
4933 icid = chan->dcid;
4934
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004935 if (req->dest_amp_id == AMP_ID_BREDR) {
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004936 /* Moving to BR/EDR */
4937 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4938 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4939 result = L2CAP_MR_PEND;
4940 } else {
4941 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4942 result = L2CAP_MR_SUCCESS;
4943 }
4944 } else {
4945 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
4946 /* Placeholder - uncomment when amp functions are available */
4947 /*amp_accept_physical(chan, req->dest_amp_id);*/
4948 result = L2CAP_MR_PEND;
4949 }
4950
4951send_move_response:
Mat Martineau1500109b2012-10-23 15:24:15 -07004952 l2cap_send_move_chan_rsp(chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004953
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004954 l2cap_chan_unlock(chan);
4955
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004956 return 0;
4957}
4958
Mat Martineau5b155ef2012-10-23 15:24:14 -07004959static void l2cap_move_continue(struct l2cap_conn *conn, u16 icid, u16 result)
4960{
4961 struct l2cap_chan *chan;
4962 struct hci_chan *hchan = NULL;
4963
4964 chan = l2cap_get_chan_by_scid(conn, icid);
4965 if (!chan) {
4966 l2cap_send_move_chan_cfm_icid(conn, icid);
4967 return;
4968 }
4969
4970 __clear_chan_timer(chan);
4971 if (result == L2CAP_MR_PEND)
4972 __set_chan_timer(chan, L2CAP_MOVE_ERTX_TIMEOUT);
4973
4974 switch (chan->move_state) {
4975 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
4976 /* Move confirm will be sent when logical link
4977 * is complete.
4978 */
4979 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4980 break;
4981 case L2CAP_MOVE_WAIT_RSP_SUCCESS:
4982 if (result == L2CAP_MR_PEND) {
4983 break;
4984 } else if (test_bit(CONN_LOCAL_BUSY,
4985 &chan->conn_state)) {
4986 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4987 } else {
4988 /* Logical link is up or moving to BR/EDR,
4989 * proceed with move
4990 */
4991 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
4992 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4993 }
4994 break;
4995 case L2CAP_MOVE_WAIT_RSP:
4996 /* Moving to AMP */
4997 if (result == L2CAP_MR_SUCCESS) {
4998 /* Remote is ready, send confirm immediately
4999 * after logical link is ready
5000 */
5001 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
5002 } else {
5003 /* Both logical link and move success
5004 * are required to confirm
5005 */
5006 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_COMP;
5007 }
5008
5009 /* Placeholder - get hci_chan for logical link */
5010 if (!hchan) {
5011 /* Logical link not available */
5012 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
5013 break;
5014 }
5015
5016 /* If the logical link is not yet connected, do not
5017 * send confirmation.
5018 */
5019 if (hchan->state != BT_CONNECTED)
5020 break;
5021
5022 /* Logical link is already ready to go */
5023
5024 chan->hs_hcon = hchan->conn;
5025 chan->hs_hcon->l2cap_data = chan->conn;
5026
5027 if (result == L2CAP_MR_SUCCESS) {
5028 /* Can confirm now */
5029 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
5030 } else {
5031 /* Now only need move success
5032 * to confirm
5033 */
5034 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
5035 }
5036
5037 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
5038 break;
5039 default:
5040 /* Any other amp move state means the move failed. */
5041 chan->move_id = chan->local_amp_id;
5042 l2cap_move_done(chan);
5043 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
5044 }
5045
5046 l2cap_chan_unlock(chan);
5047}
5048
5049static void l2cap_move_fail(struct l2cap_conn *conn, u8 ident, u16 icid,
5050 u16 result)
5051{
5052 struct l2cap_chan *chan;
5053
5054 chan = l2cap_get_chan_by_ident(conn, ident);
5055 if (!chan) {
5056 /* Could not locate channel, icid is best guess */
5057 l2cap_send_move_chan_cfm_icid(conn, icid);
5058 return;
5059 }
5060
5061 __clear_chan_timer(chan);
5062
5063 if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
5064 if (result == L2CAP_MR_COLLISION) {
5065 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
5066 } else {
5067 /* Cleanup - cancel move */
5068 chan->move_id = chan->local_amp_id;
5069 l2cap_move_done(chan);
5070 }
5071 }
5072
5073 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
5074
5075 l2cap_chan_unlock(chan);
5076}
5077
5078static int l2cap_move_channel_rsp(struct l2cap_conn *conn,
5079 struct l2cap_cmd_hdr *cmd,
5080 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005081{
5082 struct l2cap_move_chan_rsp *rsp = data;
5083 u16 icid, result;
5084
5085 if (cmd_len != sizeof(*rsp))
5086 return -EPROTO;
5087
5088 icid = le16_to_cpu(rsp->icid);
5089 result = le16_to_cpu(rsp->result);
5090
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005091 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005092
Mat Martineau5b155ef2012-10-23 15:24:14 -07005093 if (result == L2CAP_MR_SUCCESS || result == L2CAP_MR_PEND)
5094 l2cap_move_continue(conn, icid, result);
5095 else
5096 l2cap_move_fail(conn, cmd->ident, icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005097
5098 return 0;
5099}
5100
Mat Martineau5f3847a2012-10-23 15:24:12 -07005101static int l2cap_move_channel_confirm(struct l2cap_conn *conn,
5102 struct l2cap_cmd_hdr *cmd,
5103 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005104{
5105 struct l2cap_move_chan_cfm *cfm = data;
Mat Martineau5f3847a2012-10-23 15:24:12 -07005106 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005107 u16 icid, result;
5108
5109 if (cmd_len != sizeof(*cfm))
5110 return -EPROTO;
5111
5112 icid = le16_to_cpu(cfm->icid);
5113 result = le16_to_cpu(cfm->result);
5114
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005115 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005116
Mat Martineau5f3847a2012-10-23 15:24:12 -07005117 chan = l2cap_get_chan_by_dcid(conn, icid);
5118 if (!chan) {
5119 /* Spec requires a response even if the icid was not found */
5120 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
5121 return 0;
5122 }
5123
5124 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM) {
5125 if (result == L2CAP_MC_CONFIRMED) {
5126 chan->local_amp_id = chan->move_id;
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07005127 if (chan->local_amp_id == AMP_ID_BREDR)
Mat Martineau5f3847a2012-10-23 15:24:12 -07005128 __release_logical_link(chan);
5129 } else {
5130 chan->move_id = chan->local_amp_id;
5131 }
5132
5133 l2cap_move_done(chan);
5134 }
5135
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005136 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
5137
Mat Martineau5f3847a2012-10-23 15:24:12 -07005138 l2cap_chan_unlock(chan);
5139
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005140 return 0;
5141}
5142
5143static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005144 struct l2cap_cmd_hdr *cmd,
5145 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005146{
5147 struct l2cap_move_chan_cfm_rsp *rsp = data;
Mat Martineau3fd71a02012-10-23 15:24:16 -07005148 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005149 u16 icid;
5150
5151 if (cmd_len != sizeof(*rsp))
5152 return -EPROTO;
5153
5154 icid = le16_to_cpu(rsp->icid);
5155
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005156 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005157
Mat Martineau3fd71a02012-10-23 15:24:16 -07005158 chan = l2cap_get_chan_by_scid(conn, icid);
5159 if (!chan)
5160 return 0;
5161
5162 __clear_chan_timer(chan);
5163
5164 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM_RSP) {
5165 chan->local_amp_id = chan->move_id;
5166
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07005167 if (chan->local_amp_id == AMP_ID_BREDR && chan->hs_hchan)
Mat Martineau3fd71a02012-10-23 15:24:16 -07005168 __release_logical_link(chan);
5169
5170 l2cap_move_done(chan);
5171 }
5172
5173 l2cap_chan_unlock(chan);
5174
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005175 return 0;
5176}
5177
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03005178static inline int l2cap_check_conn_param(u16 min, u16 max, u16 latency,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005179 u16 to_multiplier)
Claudio Takahaside731152011-02-11 19:28:55 -02005180{
5181 u16 max_latency;
5182
5183 if (min > max || min < 6 || max > 3200)
5184 return -EINVAL;
5185
5186 if (to_multiplier < 10 || to_multiplier > 3200)
5187 return -EINVAL;
5188
5189 if (max >= to_multiplier * 8)
5190 return -EINVAL;
5191
5192 max_latency = (to_multiplier * 8 / max) - 1;
5193 if (latency > 499 || latency > max_latency)
5194 return -EINVAL;
5195
5196 return 0;
5197}
5198
5199static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005200 struct l2cap_cmd_hdr *cmd,
5201 u8 *data)
Claudio Takahaside731152011-02-11 19:28:55 -02005202{
5203 struct hci_conn *hcon = conn->hcon;
5204 struct l2cap_conn_param_update_req *req;
5205 struct l2cap_conn_param_update_rsp rsp;
5206 u16 min, max, latency, to_multiplier, cmd_len;
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005207 int err;
Claudio Takahaside731152011-02-11 19:28:55 -02005208
5209 if (!(hcon->link_mode & HCI_LM_MASTER))
5210 return -EINVAL;
5211
5212 cmd_len = __le16_to_cpu(cmd->len);
5213 if (cmd_len != sizeof(struct l2cap_conn_param_update_req))
5214 return -EPROTO;
5215
5216 req = (struct l2cap_conn_param_update_req *) data;
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03005217 min = __le16_to_cpu(req->min);
5218 max = __le16_to_cpu(req->max);
Claudio Takahaside731152011-02-11 19:28:55 -02005219 latency = __le16_to_cpu(req->latency);
5220 to_multiplier = __le16_to_cpu(req->to_multiplier);
5221
5222 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 +01005223 min, max, latency, to_multiplier);
Claudio Takahaside731152011-02-11 19:28:55 -02005224
5225 memset(&rsp, 0, sizeof(rsp));
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005226
5227 err = l2cap_check_conn_param(min, max, latency, to_multiplier);
5228 if (err)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005229 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
Claudio Takahaside731152011-02-11 19:28:55 -02005230 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005231 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED);
Claudio Takahaside731152011-02-11 19:28:55 -02005232
5233 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005234 sizeof(rsp), &rsp);
Claudio Takahaside731152011-02-11 19:28:55 -02005235
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005236 if (!err)
5237 hci_le_conn_update(hcon, min, max, latency, to_multiplier);
5238
Claudio Takahaside731152011-02-11 19:28:55 -02005239 return 0;
5240}
5241
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005242static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005243 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5244 u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005245{
5246 int err = 0;
5247
5248 switch (cmd->code) {
5249 case L2CAP_COMMAND_REJ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005250 l2cap_command_rej(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005251 break;
5252
5253 case L2CAP_CONN_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005254 err = l2cap_connect_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005255 break;
5256
5257 case L2CAP_CONN_RSP:
Mat Martineauf5a25982012-10-11 17:48:21 +03005258 case L2CAP_CREATE_CHAN_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005259 l2cap_connect_create_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005260 break;
5261
5262 case L2CAP_CONF_REQ:
5263 err = l2cap_config_req(conn, cmd, cmd_len, data);
5264 break;
5265
5266 case L2CAP_CONF_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005267 l2cap_config_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005268 break;
5269
5270 case L2CAP_DISCONN_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005271 err = l2cap_disconnect_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005272 break;
5273
5274 case L2CAP_DISCONN_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005275 l2cap_disconnect_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005276 break;
5277
5278 case L2CAP_ECHO_REQ:
5279 l2cap_send_cmd(conn, cmd->ident, L2CAP_ECHO_RSP, cmd_len, data);
5280 break;
5281
5282 case L2CAP_ECHO_RSP:
5283 break;
5284
5285 case L2CAP_INFO_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005286 err = l2cap_information_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005287 break;
5288
5289 case L2CAP_INFO_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005290 l2cap_information_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005291 break;
5292
Mat Martineauf94ff6f2011-11-02 16:18:32 -07005293 case L2CAP_CREATE_CHAN_REQ:
5294 err = l2cap_create_channel_req(conn, cmd, cmd_len, data);
5295 break;
5296
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005297 case L2CAP_MOVE_CHAN_REQ:
5298 err = l2cap_move_channel_req(conn, cmd, cmd_len, data);
5299 break;
5300
5301 case L2CAP_MOVE_CHAN_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005302 l2cap_move_channel_rsp(conn, cmd, cmd_len, data);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005303 break;
5304
5305 case L2CAP_MOVE_CHAN_CFM:
5306 err = l2cap_move_channel_confirm(conn, cmd, cmd_len, data);
5307 break;
5308
5309 case L2CAP_MOVE_CHAN_CFM_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005310 l2cap_move_channel_confirm_rsp(conn, cmd, cmd_len, data);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005311 break;
5312
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005313 default:
5314 BT_ERR("Unknown BR/EDR signaling command 0x%2.2x", cmd->code);
5315 err = -EINVAL;
5316 break;
5317 }
5318
5319 return err;
5320}
5321
5322static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005323 struct l2cap_cmd_hdr *cmd, u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005324{
5325 switch (cmd->code) {
5326 case L2CAP_COMMAND_REJ:
5327 return 0;
5328
5329 case L2CAP_CONN_PARAM_UPDATE_REQ:
Claudio Takahaside731152011-02-11 19:28:55 -02005330 return l2cap_conn_param_update_req(conn, cmd, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005331
5332 case L2CAP_CONN_PARAM_UPDATE_RSP:
5333 return 0;
5334
5335 default:
5336 BT_ERR("Unknown LE signaling command 0x%2.2x", cmd->code);
5337 return -EINVAL;
5338 }
5339}
5340
Johan Hedberg7c2005d2013-09-16 13:05:16 +03005341static __le16 l2cap_err_to_reason(int err)
5342{
5343 switch (err) {
5344 case -EBADSLT:
5345 return __constant_cpu_to_le16(L2CAP_REJ_INVALID_CID);
5346 case -EMSGSIZE:
5347 return __constant_cpu_to_le16(L2CAP_REJ_MTU_EXCEEDED);
5348 case -EINVAL:
5349 case -EPROTO:
5350 default:
5351 return __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
5352 }
5353}
5354
Johan Hedbergc5623552013-04-29 19:35:33 +03005355static inline void l2cap_le_sig_channel(struct l2cap_conn *conn,
5356 struct sk_buff *skb)
5357{
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005358 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005359 struct l2cap_cmd_hdr *cmd;
5360 u16 len;
Johan Hedbergc5623552013-04-29 19:35:33 +03005361 int err;
5362
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005363 if (hcon->type != LE_LINK)
Marcel Holtmann3b166292013-10-02 08:28:21 -07005364 goto drop;
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005365
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005366 if (skb->len < L2CAP_CMD_HDR_SIZE)
5367 goto drop;
Johan Hedbergc5623552013-04-29 19:35:33 +03005368
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005369 cmd = (void *) skb->data;
5370 skb_pull(skb, L2CAP_CMD_HDR_SIZE);
Johan Hedbergc5623552013-04-29 19:35:33 +03005371
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005372 len = le16_to_cpu(cmd->len);
Johan Hedbergc5623552013-04-29 19:35:33 +03005373
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005374 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd->code, len, cmd->ident);
Johan Hedbergc5623552013-04-29 19:35:33 +03005375
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005376 if (len != skb->len || !cmd->ident) {
5377 BT_DBG("corrupted command");
5378 goto drop;
5379 }
Johan Hedbergc5623552013-04-29 19:35:33 +03005380
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005381 err = l2cap_le_sig_cmd(conn, cmd, skb->data);
5382 if (err) {
5383 struct l2cap_cmd_rej_unk rej;
Johan Hedbergc5623552013-04-29 19:35:33 +03005384
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005385 BT_ERR("Wrong link type (%d)", err);
Johan Hedbergc5623552013-04-29 19:35:33 +03005386
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005387 rej.reason = l2cap_err_to_reason(err);
5388 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
5389 sizeof(rej), &rej);
Johan Hedbergc5623552013-04-29 19:35:33 +03005390 }
5391
Marcel Holtmann3b166292013-10-02 08:28:21 -07005392drop:
Johan Hedbergc5623552013-04-29 19:35:33 +03005393 kfree_skb(skb);
5394}
5395
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005396static inline void l2cap_sig_channel(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005397 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005398{
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005399 struct hci_conn *hcon = conn->hcon;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005400 u8 *data = skb->data;
5401 int len = skb->len;
5402 struct l2cap_cmd_hdr cmd;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005403 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005404
5405 l2cap_raw_recv(conn, skb);
5406
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005407 if (hcon->type != ACL_LINK)
Marcel Holtmann3b166292013-10-02 08:28:21 -07005408 goto drop;
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005409
Linus Torvalds1da177e2005-04-16 15:20:36 -07005410 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07005411 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005412 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
5413 data += L2CAP_CMD_HDR_SIZE;
5414 len -= L2CAP_CMD_HDR_SIZE;
5415
Al Viro88219a02007-07-29 00:17:25 -07005416 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005417
Gustavo Padovan2d792812012-10-06 10:07:01 +01005418 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len,
5419 cmd.ident);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005420
Al Viro88219a02007-07-29 00:17:25 -07005421 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005422 BT_DBG("corrupted command");
5423 break;
5424 }
5425
Johan Hedbergc5623552013-04-29 19:35:33 +03005426 err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005427 if (err) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03005428 struct l2cap_cmd_rej_unk rej;
Gustavo F. Padovan2c6d1a22011-03-23 14:38:32 -03005429
5430 BT_ERR("Wrong link type (%d)", err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005431
Johan Hedberg7c2005d2013-09-16 13:05:16 +03005432 rej.reason = l2cap_err_to_reason(err);
Gustavo Padovan2d792812012-10-06 10:07:01 +01005433 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ,
5434 sizeof(rej), &rej);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005435 }
5436
Al Viro88219a02007-07-29 00:17:25 -07005437 data += cmd_len;
5438 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005439 }
5440
Marcel Holtmann3b166292013-10-02 08:28:21 -07005441drop:
Linus Torvalds1da177e2005-04-16 15:20:36 -07005442 kfree_skb(skb);
5443}
5444
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005445static int l2cap_check_fcs(struct l2cap_chan *chan, struct sk_buff *skb)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005446{
5447 u16 our_fcs, rcv_fcs;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03005448 int hdr_size;
5449
5450 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
5451 hdr_size = L2CAP_EXT_HDR_SIZE;
5452 else
5453 hdr_size = L2CAP_ENH_HDR_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005454
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005455 if (chan->fcs == L2CAP_FCS_CRC16) {
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005456 skb_trim(skb, skb->len - L2CAP_FCS_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005457 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
5458 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
5459
5460 if (our_fcs != rcv_fcs)
João Paulo Rechi Vita7a560e52010-06-22 13:56:27 -03005461 return -EBADMSG;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005462 }
5463 return 0;
5464}
5465
Mat Martineau6ea00482012-05-17 20:53:52 -07005466static void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan)
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005467{
Mat Martineaue31f7632012-05-17 20:53:41 -07005468 struct l2cap_ctrl control;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005469
Mat Martineaue31f7632012-05-17 20:53:41 -07005470 BT_DBG("chan %p", chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005471
Mat Martineaue31f7632012-05-17 20:53:41 -07005472 memset(&control, 0, sizeof(control));
5473 control.sframe = 1;
5474 control.final = 1;
5475 control.reqseq = chan->buffer_seq;
5476 set_bit(CONN_SEND_FBIT, &chan->conn_state);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005477
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03005478 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
Mat Martineaue31f7632012-05-17 20:53:41 -07005479 control.super = L2CAP_SUPER_RNR;
5480 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005481 }
5482
Mat Martineaue31f7632012-05-17 20:53:41 -07005483 if (test_and_clear_bit(CONN_REMOTE_BUSY, &chan->conn_state) &&
5484 chan->unacked_frames > 0)
5485 __set_retrans_timer(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005486
Mat Martineaue31f7632012-05-17 20:53:41 -07005487 /* Send pending iframes */
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03005488 l2cap_ertm_send(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005489
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03005490 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
Mat Martineaue31f7632012-05-17 20:53:41 -07005491 test_bit(CONN_SEND_FBIT, &chan->conn_state)) {
5492 /* F-bit wasn't sent in an s-frame or i-frame yet, so
5493 * send it now.
5494 */
5495 control.super = L2CAP_SUPER_RR;
5496 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005497 }
5498}
5499
Gustavo Padovan2d792812012-10-06 10:07:01 +01005500static void append_skb_frag(struct sk_buff *skb, struct sk_buff *new_frag,
5501 struct sk_buff **last_frag)
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005502{
Mat Martineau84084a32011-07-22 14:54:00 -07005503 /* skb->len reflects data in skb as well as all fragments
5504 * skb->data_len reflects only data in fragments
5505 */
5506 if (!skb_has_frag_list(skb))
5507 skb_shinfo(skb)->frag_list = new_frag;
5508
5509 new_frag->next = NULL;
5510
5511 (*last_frag)->next = new_frag;
5512 *last_frag = new_frag;
5513
5514 skb->len += new_frag->len;
5515 skb->data_len += new_frag->len;
5516 skb->truesize += new_frag->truesize;
5517}
5518
Mat Martineau4b51dae92012-05-17 20:53:37 -07005519static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb,
5520 struct l2cap_ctrl *control)
Mat Martineau84084a32011-07-22 14:54:00 -07005521{
5522 int err = -EINVAL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005523
Mat Martineau4b51dae92012-05-17 20:53:37 -07005524 switch (control->sar) {
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005525 case L2CAP_SAR_UNSEGMENTED:
Mat Martineau84084a32011-07-22 14:54:00 -07005526 if (chan->sdu)
5527 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005528
Gustavo Padovan80b98022012-05-27 22:27:51 -03005529 err = chan->ops->recv(chan, skb);
Mat Martineau84084a32011-07-22 14:54:00 -07005530 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005531
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005532 case L2CAP_SAR_START:
Mat Martineau84084a32011-07-22 14:54:00 -07005533 if (chan->sdu)
5534 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005535
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005536 chan->sdu_len = get_unaligned_le16(skb->data);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005537 skb_pull(skb, L2CAP_SDULEN_SIZE);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005538
Mat Martineau84084a32011-07-22 14:54:00 -07005539 if (chan->sdu_len > chan->imtu) {
5540 err = -EMSGSIZE;
5541 break;
5542 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005543
Mat Martineau84084a32011-07-22 14:54:00 -07005544 if (skb->len >= chan->sdu_len)
5545 break;
5546
5547 chan->sdu = skb;
5548 chan->sdu_last_frag = skb;
5549
5550 skb = NULL;
5551 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005552 break;
5553
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005554 case L2CAP_SAR_CONTINUE:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005555 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07005556 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005557
Mat Martineau84084a32011-07-22 14:54:00 -07005558 append_skb_frag(chan->sdu, skb,
5559 &chan->sdu_last_frag);
5560 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005561
Mat Martineau84084a32011-07-22 14:54:00 -07005562 if (chan->sdu->len >= chan->sdu_len)
5563 break;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03005564
Mat Martineau84084a32011-07-22 14:54:00 -07005565 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005566 break;
5567
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005568 case L2CAP_SAR_END:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005569 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07005570 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005571
Mat Martineau84084a32011-07-22 14:54:00 -07005572 append_skb_frag(chan->sdu, skb,
5573 &chan->sdu_last_frag);
5574 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005575
Mat Martineau84084a32011-07-22 14:54:00 -07005576 if (chan->sdu->len != chan->sdu_len)
5577 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005578
Gustavo Padovan80b98022012-05-27 22:27:51 -03005579 err = chan->ops->recv(chan, chan->sdu);
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03005580
Mat Martineau84084a32011-07-22 14:54:00 -07005581 if (!err) {
5582 /* Reassembly complete */
5583 chan->sdu = NULL;
5584 chan->sdu_last_frag = NULL;
5585 chan->sdu_len = 0;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03005586 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005587 break;
5588 }
5589
Mat Martineau84084a32011-07-22 14:54:00 -07005590 if (err) {
5591 kfree_skb(skb);
5592 kfree_skb(chan->sdu);
5593 chan->sdu = NULL;
5594 chan->sdu_last_frag = NULL;
5595 chan->sdu_len = 0;
5596 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005597
Mat Martineau84084a32011-07-22 14:54:00 -07005598 return err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005599}
5600
Mat Martineau32b32732012-10-23 15:24:11 -07005601static int l2cap_resegment(struct l2cap_chan *chan)
5602{
5603 /* Placeholder */
5604 return 0;
5605}
5606
Mat Martineaue3281402011-07-07 09:39:02 -07005607void l2cap_chan_busy(struct l2cap_chan *chan, int busy)
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03005608{
Mat Martineau61aa4f52012-05-17 20:53:40 -07005609 u8 event;
5610
5611 if (chan->mode != L2CAP_MODE_ERTM)
5612 return;
5613
5614 event = busy ? L2CAP_EV_LOCAL_BUSY_DETECTED : L2CAP_EV_LOCAL_BUSY_CLEAR;
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03005615 l2cap_tx(chan, NULL, NULL, event);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03005616}
5617
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005618static int l2cap_rx_queued_iframes(struct l2cap_chan *chan)
5619{
Mat Martineau63838722012-05-17 20:53:45 -07005620 int err = 0;
5621 /* Pass sequential frames to l2cap_reassemble_sdu()
5622 * until a gap is encountered.
5623 */
5624
5625 BT_DBG("chan %p", chan);
5626
5627 while (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5628 struct sk_buff *skb;
5629 BT_DBG("Searching for skb with txseq %d (queue len %d)",
5630 chan->buffer_seq, skb_queue_len(&chan->srej_q));
5631
5632 skb = l2cap_ertm_seq_in_queue(&chan->srej_q, chan->buffer_seq);
5633
5634 if (!skb)
5635 break;
5636
5637 skb_unlink(skb, &chan->srej_q);
5638 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
5639 err = l2cap_reassemble_sdu(chan, skb, &bt_cb(skb)->control);
5640 if (err)
5641 break;
5642 }
5643
5644 if (skb_queue_empty(&chan->srej_q)) {
5645 chan->rx_state = L2CAP_RX_STATE_RECV;
5646 l2cap_send_ack(chan);
5647 }
5648
5649 return err;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005650}
5651
5652static void l2cap_handle_srej(struct l2cap_chan *chan,
5653 struct l2cap_ctrl *control)
5654{
Mat Martineauf80842a2012-05-17 20:53:46 -07005655 struct sk_buff *skb;
5656
5657 BT_DBG("chan %p, control %p", chan, control);
5658
5659 if (control->reqseq == chan->next_tx_seq) {
5660 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005661 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineauf80842a2012-05-17 20:53:46 -07005662 return;
5663 }
5664
5665 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
5666
5667 if (skb == NULL) {
5668 BT_DBG("Seq %d not available for retransmission",
5669 control->reqseq);
5670 return;
5671 }
5672
5673 if (chan->max_tx != 0 && bt_cb(skb)->control.retries >= chan->max_tx) {
5674 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005675 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineauf80842a2012-05-17 20:53:46 -07005676 return;
5677 }
5678
5679 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5680
5681 if (control->poll) {
5682 l2cap_pass_to_tx(chan, control);
5683
5684 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5685 l2cap_retransmit(chan, control);
5686 l2cap_ertm_send(chan);
5687
5688 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
5689 set_bit(CONN_SREJ_ACT, &chan->conn_state);
5690 chan->srej_save_reqseq = control->reqseq;
5691 }
5692 } else {
5693 l2cap_pass_to_tx_fbit(chan, control);
5694
5695 if (control->final) {
5696 if (chan->srej_save_reqseq != control->reqseq ||
5697 !test_and_clear_bit(CONN_SREJ_ACT,
5698 &chan->conn_state))
5699 l2cap_retransmit(chan, control);
5700 } else {
5701 l2cap_retransmit(chan, control);
5702 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
5703 set_bit(CONN_SREJ_ACT, &chan->conn_state);
5704 chan->srej_save_reqseq = control->reqseq;
5705 }
5706 }
5707 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005708}
5709
5710static void l2cap_handle_rej(struct l2cap_chan *chan,
5711 struct l2cap_ctrl *control)
5712{
Mat Martineaufcd289d2012-05-17 20:53:47 -07005713 struct sk_buff *skb;
5714
5715 BT_DBG("chan %p, control %p", chan, control);
5716
5717 if (control->reqseq == chan->next_tx_seq) {
5718 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005719 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaufcd289d2012-05-17 20:53:47 -07005720 return;
5721 }
5722
5723 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
5724
5725 if (chan->max_tx && skb &&
5726 bt_cb(skb)->control.retries >= chan->max_tx) {
5727 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005728 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaufcd289d2012-05-17 20:53:47 -07005729 return;
5730 }
5731
5732 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5733
5734 l2cap_pass_to_tx(chan, control);
5735
5736 if (control->final) {
5737 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state))
5738 l2cap_retransmit_all(chan, control);
5739 } else {
5740 l2cap_retransmit_all(chan, control);
5741 l2cap_ertm_send(chan);
5742 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F)
5743 set_bit(CONN_REJ_ACT, &chan->conn_state);
5744 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005745}
5746
Mat Martineau4b51dae92012-05-17 20:53:37 -07005747static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq)
5748{
5749 BT_DBG("chan %p, txseq %d", chan, txseq);
5750
5751 BT_DBG("last_acked_seq %d, expected_tx_seq %d", chan->last_acked_seq,
5752 chan->expected_tx_seq);
5753
5754 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
5755 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
Gustavo Padovan2d792812012-10-06 10:07:01 +01005756 chan->tx_win) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07005757 /* See notes below regarding "double poll" and
5758 * invalid packets.
5759 */
5760 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
5761 BT_DBG("Invalid/Ignore - after SREJ");
5762 return L2CAP_TXSEQ_INVALID_IGNORE;
5763 } else {
5764 BT_DBG("Invalid - in window after SREJ sent");
5765 return L2CAP_TXSEQ_INVALID;
5766 }
5767 }
5768
5769 if (chan->srej_list.head == txseq) {
5770 BT_DBG("Expected SREJ");
5771 return L2CAP_TXSEQ_EXPECTED_SREJ;
5772 }
5773
5774 if (l2cap_ertm_seq_in_queue(&chan->srej_q, txseq)) {
5775 BT_DBG("Duplicate SREJ - txseq already stored");
5776 return L2CAP_TXSEQ_DUPLICATE_SREJ;
5777 }
5778
5779 if (l2cap_seq_list_contains(&chan->srej_list, txseq)) {
5780 BT_DBG("Unexpected SREJ - not requested");
5781 return L2CAP_TXSEQ_UNEXPECTED_SREJ;
5782 }
5783 }
5784
5785 if (chan->expected_tx_seq == txseq) {
5786 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
5787 chan->tx_win) {
5788 BT_DBG("Invalid - txseq outside tx window");
5789 return L2CAP_TXSEQ_INVALID;
5790 } else {
5791 BT_DBG("Expected");
5792 return L2CAP_TXSEQ_EXPECTED;
5793 }
5794 }
5795
5796 if (__seq_offset(chan, txseq, chan->last_acked_seq) <
Gustavo Padovan2d792812012-10-06 10:07:01 +01005797 __seq_offset(chan, chan->expected_tx_seq, chan->last_acked_seq)) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07005798 BT_DBG("Duplicate - expected_tx_seq later than txseq");
5799 return L2CAP_TXSEQ_DUPLICATE;
5800 }
5801
5802 if (__seq_offset(chan, txseq, chan->last_acked_seq) >= chan->tx_win) {
5803 /* A source of invalid packets is a "double poll" condition,
5804 * where delays cause us to send multiple poll packets. If
5805 * the remote stack receives and processes both polls,
5806 * sequence numbers can wrap around in such a way that a
5807 * resent frame has a sequence number that looks like new data
5808 * with a sequence gap. This would trigger an erroneous SREJ
5809 * request.
5810 *
5811 * Fortunately, this is impossible with a tx window that's
5812 * less than half of the maximum sequence number, which allows
5813 * invalid frames to be safely ignored.
5814 *
5815 * With tx window sizes greater than half of the tx window
5816 * maximum, the frame is invalid and cannot be ignored. This
5817 * causes a disconnect.
5818 */
5819
5820 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
5821 BT_DBG("Invalid/Ignore - txseq outside tx window");
5822 return L2CAP_TXSEQ_INVALID_IGNORE;
5823 } else {
5824 BT_DBG("Invalid - txseq outside tx window");
5825 return L2CAP_TXSEQ_INVALID;
5826 }
5827 } else {
5828 BT_DBG("Unexpected - txseq indicates missing frames");
5829 return L2CAP_TXSEQ_UNEXPECTED;
5830 }
5831}
5832
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005833static int l2cap_rx_state_recv(struct l2cap_chan *chan,
5834 struct l2cap_ctrl *control,
5835 struct sk_buff *skb, u8 event)
5836{
5837 int err = 0;
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005838 bool skb_in_use = false;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005839
5840 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
5841 event);
5842
5843 switch (event) {
5844 case L2CAP_EV_RECV_IFRAME:
5845 switch (l2cap_classify_txseq(chan, control->txseq)) {
5846 case L2CAP_TXSEQ_EXPECTED:
5847 l2cap_pass_to_tx(chan, control);
5848
5849 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5850 BT_DBG("Busy, discarding expected seq %d",
5851 control->txseq);
5852 break;
5853 }
5854
5855 chan->expected_tx_seq = __next_seq(chan,
5856 control->txseq);
5857
5858 chan->buffer_seq = chan->expected_tx_seq;
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005859 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005860
5861 err = l2cap_reassemble_sdu(chan, skb, control);
5862 if (err)
5863 break;
5864
5865 if (control->final) {
5866 if (!test_and_clear_bit(CONN_REJ_ACT,
5867 &chan->conn_state)) {
5868 control->final = 0;
5869 l2cap_retransmit_all(chan, control);
5870 l2cap_ertm_send(chan);
5871 }
5872 }
5873
5874 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
5875 l2cap_send_ack(chan);
5876 break;
5877 case L2CAP_TXSEQ_UNEXPECTED:
5878 l2cap_pass_to_tx(chan, control);
5879
5880 /* Can't issue SREJ frames in the local busy state.
5881 * Drop this frame, it will be seen as missing
5882 * when local busy is exited.
5883 */
5884 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5885 BT_DBG("Busy, discarding unexpected seq %d",
5886 control->txseq);
5887 break;
5888 }
5889
5890 /* There was a gap in the sequence, so an SREJ
5891 * must be sent for each missing frame. The
5892 * current frame is stored for later use.
5893 */
5894 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005895 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005896 BT_DBG("Queued %p (queue len %d)", skb,
5897 skb_queue_len(&chan->srej_q));
5898
5899 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
5900 l2cap_seq_list_clear(&chan->srej_list);
5901 l2cap_send_srej(chan, control->txseq);
5902
5903 chan->rx_state = L2CAP_RX_STATE_SREJ_SENT;
5904 break;
5905 case L2CAP_TXSEQ_DUPLICATE:
5906 l2cap_pass_to_tx(chan, control);
5907 break;
5908 case L2CAP_TXSEQ_INVALID_IGNORE:
5909 break;
5910 case L2CAP_TXSEQ_INVALID:
5911 default:
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005912 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005913 break;
5914 }
5915 break;
5916 case L2CAP_EV_RECV_RR:
5917 l2cap_pass_to_tx(chan, control);
5918 if (control->final) {
5919 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5920
Mat Martineaue6a3ee62012-10-23 15:24:22 -07005921 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state) &&
5922 !__chan_is_moving(chan)) {
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005923 control->final = 0;
5924 l2cap_retransmit_all(chan, control);
5925 }
5926
5927 l2cap_ertm_send(chan);
5928 } else if (control->poll) {
5929 l2cap_send_i_or_rr_or_rnr(chan);
5930 } else {
5931 if (test_and_clear_bit(CONN_REMOTE_BUSY,
5932 &chan->conn_state) &&
5933 chan->unacked_frames)
5934 __set_retrans_timer(chan);
5935
5936 l2cap_ertm_send(chan);
5937 }
5938 break;
5939 case L2CAP_EV_RECV_RNR:
5940 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5941 l2cap_pass_to_tx(chan, control);
5942 if (control && control->poll) {
5943 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5944 l2cap_send_rr_or_rnr(chan, 0);
5945 }
5946 __clear_retrans_timer(chan);
5947 l2cap_seq_list_clear(&chan->retrans_list);
5948 break;
5949 case L2CAP_EV_RECV_REJ:
5950 l2cap_handle_rej(chan, control);
5951 break;
5952 case L2CAP_EV_RECV_SREJ:
5953 l2cap_handle_srej(chan, control);
5954 break;
5955 default:
5956 break;
5957 }
5958
5959 if (skb && !skb_in_use) {
5960 BT_DBG("Freeing %p", skb);
5961 kfree_skb(skb);
5962 }
5963
5964 return err;
5965}
5966
5967static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan,
5968 struct l2cap_ctrl *control,
5969 struct sk_buff *skb, u8 event)
5970{
5971 int err = 0;
5972 u16 txseq = control->txseq;
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005973 bool skb_in_use = false;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005974
5975 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
5976 event);
5977
5978 switch (event) {
5979 case L2CAP_EV_RECV_IFRAME:
5980 switch (l2cap_classify_txseq(chan, txseq)) {
5981 case L2CAP_TXSEQ_EXPECTED:
5982 /* Keep frame for reassembly later */
5983 l2cap_pass_to_tx(chan, control);
5984 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005985 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005986 BT_DBG("Queued %p (queue len %d)", skb,
5987 skb_queue_len(&chan->srej_q));
5988
5989 chan->expected_tx_seq = __next_seq(chan, txseq);
5990 break;
5991 case L2CAP_TXSEQ_EXPECTED_SREJ:
5992 l2cap_seq_list_pop(&chan->srej_list);
5993
5994 l2cap_pass_to_tx(chan, control);
5995 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005996 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005997 BT_DBG("Queued %p (queue len %d)", skb,
5998 skb_queue_len(&chan->srej_q));
5999
6000 err = l2cap_rx_queued_iframes(chan);
6001 if (err)
6002 break;
6003
6004 break;
6005 case L2CAP_TXSEQ_UNEXPECTED:
6006 /* Got a frame that can't be reassembled yet.
6007 * Save it for later, and send SREJs to cover
6008 * the missing frames.
6009 */
6010 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006011 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006012 BT_DBG("Queued %p (queue len %d)", skb,
6013 skb_queue_len(&chan->srej_q));
6014
6015 l2cap_pass_to_tx(chan, control);
6016 l2cap_send_srej(chan, control->txseq);
6017 break;
6018 case L2CAP_TXSEQ_UNEXPECTED_SREJ:
6019 /* This frame was requested with an SREJ, but
6020 * some expected retransmitted frames are
6021 * missing. Request retransmission of missing
6022 * SREJ'd frames.
6023 */
6024 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006025 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006026 BT_DBG("Queued %p (queue len %d)", skb,
6027 skb_queue_len(&chan->srej_q));
6028
6029 l2cap_pass_to_tx(chan, control);
6030 l2cap_send_srej_list(chan, control->txseq);
6031 break;
6032 case L2CAP_TXSEQ_DUPLICATE_SREJ:
6033 /* We've already queued this frame. Drop this copy. */
6034 l2cap_pass_to_tx(chan, control);
6035 break;
6036 case L2CAP_TXSEQ_DUPLICATE:
6037 /* Expecting a later sequence number, so this frame
6038 * was already received. Ignore it completely.
6039 */
6040 break;
6041 case L2CAP_TXSEQ_INVALID_IGNORE:
6042 break;
6043 case L2CAP_TXSEQ_INVALID:
6044 default:
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006045 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006046 break;
6047 }
6048 break;
6049 case L2CAP_EV_RECV_RR:
6050 l2cap_pass_to_tx(chan, control);
6051 if (control->final) {
6052 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6053
6054 if (!test_and_clear_bit(CONN_REJ_ACT,
6055 &chan->conn_state)) {
6056 control->final = 0;
6057 l2cap_retransmit_all(chan, control);
6058 }
6059
6060 l2cap_ertm_send(chan);
6061 } else if (control->poll) {
6062 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6063 &chan->conn_state) &&
6064 chan->unacked_frames) {
6065 __set_retrans_timer(chan);
6066 }
6067
6068 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6069 l2cap_send_srej_tail(chan);
6070 } else {
6071 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6072 &chan->conn_state) &&
6073 chan->unacked_frames)
6074 __set_retrans_timer(chan);
6075
6076 l2cap_send_ack(chan);
6077 }
6078 break;
6079 case L2CAP_EV_RECV_RNR:
6080 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6081 l2cap_pass_to_tx(chan, control);
6082 if (control->poll) {
6083 l2cap_send_srej_tail(chan);
6084 } else {
6085 struct l2cap_ctrl rr_control;
6086 memset(&rr_control, 0, sizeof(rr_control));
6087 rr_control.sframe = 1;
6088 rr_control.super = L2CAP_SUPER_RR;
6089 rr_control.reqseq = chan->buffer_seq;
6090 l2cap_send_sframe(chan, &rr_control);
6091 }
6092
6093 break;
6094 case L2CAP_EV_RECV_REJ:
6095 l2cap_handle_rej(chan, control);
6096 break;
6097 case L2CAP_EV_RECV_SREJ:
6098 l2cap_handle_srej(chan, control);
6099 break;
6100 }
6101
6102 if (skb && !skb_in_use) {
6103 BT_DBG("Freeing %p", skb);
6104 kfree_skb(skb);
6105 }
6106
6107 return err;
6108}
6109
Mat Martineau32b32732012-10-23 15:24:11 -07006110static int l2cap_finish_move(struct l2cap_chan *chan)
6111{
6112 BT_DBG("chan %p", chan);
6113
6114 chan->rx_state = L2CAP_RX_STATE_RECV;
6115
6116 if (chan->hs_hcon)
6117 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
6118 else
6119 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
6120
6121 return l2cap_resegment(chan);
6122}
6123
6124static int l2cap_rx_state_wait_p(struct l2cap_chan *chan,
6125 struct l2cap_ctrl *control,
6126 struct sk_buff *skb, u8 event)
6127{
6128 int err;
6129
6130 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
6131 event);
6132
6133 if (!control->poll)
6134 return -EPROTO;
6135
6136 l2cap_process_reqseq(chan, control->reqseq);
6137
6138 if (!skb_queue_empty(&chan->tx_q))
6139 chan->tx_send_head = skb_peek(&chan->tx_q);
6140 else
6141 chan->tx_send_head = NULL;
6142
6143 /* Rewind next_tx_seq to the point expected
6144 * by the receiver.
6145 */
6146 chan->next_tx_seq = control->reqseq;
6147 chan->unacked_frames = 0;
6148
6149 err = l2cap_finish_move(chan);
6150 if (err)
6151 return err;
6152
6153 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6154 l2cap_send_i_or_rr_or_rnr(chan);
6155
6156 if (event == L2CAP_EV_RECV_IFRAME)
6157 return -EPROTO;
6158
6159 return l2cap_rx_state_recv(chan, control, NULL, event);
6160}
6161
6162static int l2cap_rx_state_wait_f(struct l2cap_chan *chan,
6163 struct l2cap_ctrl *control,
6164 struct sk_buff *skb, u8 event)
6165{
6166 int err;
6167
6168 if (!control->final)
6169 return -EPROTO;
6170
6171 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6172
6173 chan->rx_state = L2CAP_RX_STATE_RECV;
6174 l2cap_process_reqseq(chan, control->reqseq);
6175
6176 if (!skb_queue_empty(&chan->tx_q))
6177 chan->tx_send_head = skb_peek(&chan->tx_q);
6178 else
6179 chan->tx_send_head = NULL;
6180
6181 /* Rewind next_tx_seq to the point expected
6182 * by the receiver.
6183 */
6184 chan->next_tx_seq = control->reqseq;
6185 chan->unacked_frames = 0;
6186
6187 if (chan->hs_hcon)
6188 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
6189 else
6190 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
6191
6192 err = l2cap_resegment(chan);
6193
6194 if (!err)
6195 err = l2cap_rx_state_recv(chan, control, skb, event);
6196
6197 return err;
6198}
6199
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006200static bool __valid_reqseq(struct l2cap_chan *chan, u16 reqseq)
6201{
6202 /* Make sure reqseq is for a packet that has been sent but not acked */
6203 u16 unacked;
6204
6205 unacked = __seq_offset(chan, chan->next_tx_seq, chan->expected_ack_seq);
6206 return __seq_offset(chan, chan->next_tx_seq, reqseq) <= unacked;
6207}
6208
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006209static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
6210 struct sk_buff *skb, u8 event)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006211{
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006212 int err = 0;
6213
6214 BT_DBG("chan %p, control %p, skb %p, event %d, state %d", chan,
6215 control, skb, event, chan->rx_state);
6216
6217 if (__valid_reqseq(chan, control->reqseq)) {
6218 switch (chan->rx_state) {
6219 case L2CAP_RX_STATE_RECV:
6220 err = l2cap_rx_state_recv(chan, control, skb, event);
6221 break;
6222 case L2CAP_RX_STATE_SREJ_SENT:
6223 err = l2cap_rx_state_srej_sent(chan, control, skb,
6224 event);
6225 break;
Mat Martineau32b32732012-10-23 15:24:11 -07006226 case L2CAP_RX_STATE_WAIT_P:
6227 err = l2cap_rx_state_wait_p(chan, control, skb, event);
6228 break;
6229 case L2CAP_RX_STATE_WAIT_F:
6230 err = l2cap_rx_state_wait_f(chan, control, skb, event);
6231 break;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006232 default:
6233 /* shut it down */
6234 break;
6235 }
6236 } else {
6237 BT_DBG("Invalid reqseq %d (next_tx_seq %d, expected_ack_seq %d",
6238 control->reqseq, chan->next_tx_seq,
6239 chan->expected_ack_seq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006240 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006241 }
6242
6243 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006244}
6245
6246static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
6247 struct sk_buff *skb)
6248{
Mat Martineau4b51dae92012-05-17 20:53:37 -07006249 int err = 0;
6250
6251 BT_DBG("chan %p, control %p, skb %p, state %d", chan, control, skb,
6252 chan->rx_state);
6253
6254 if (l2cap_classify_txseq(chan, control->txseq) ==
6255 L2CAP_TXSEQ_EXPECTED) {
6256 l2cap_pass_to_tx(chan, control);
6257
6258 BT_DBG("buffer_seq %d->%d", chan->buffer_seq,
6259 __next_seq(chan, chan->buffer_seq));
6260
6261 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
6262
6263 l2cap_reassemble_sdu(chan, skb, control);
6264 } else {
6265 if (chan->sdu) {
6266 kfree_skb(chan->sdu);
6267 chan->sdu = NULL;
6268 }
6269 chan->sdu_last_frag = NULL;
6270 chan->sdu_len = 0;
6271
6272 if (skb) {
6273 BT_DBG("Freeing %p", skb);
6274 kfree_skb(skb);
6275 }
6276 }
6277
6278 chan->last_acked_seq = control->txseq;
6279 chan->expected_tx_seq = __next_seq(chan, control->txseq);
6280
6281 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006282}
6283
6284static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
6285{
6286 struct l2cap_ctrl *control = &bt_cb(skb)->control;
6287 u16 len;
6288 u8 event;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006289
Mat Martineaub76bbd62012-04-11 10:48:43 -07006290 __unpack_control(chan, skb);
6291
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006292 len = skb->len;
6293
6294 /*
6295 * We can just drop the corrupted I-frame here.
6296 * Receiver will miss it and start proper recovery
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006297 * procedures and ask for retransmission.
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006298 */
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006299 if (l2cap_check_fcs(chan, skb))
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006300 goto drop;
6301
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006302 if (!control->sframe && control->sar == L2CAP_SAR_START)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03006303 len -= L2CAP_SDULEN_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006304
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006305 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03006306 len -= L2CAP_FCS_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006307
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006308 if (len > chan->mps) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006309 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006310 goto drop;
6311 }
6312
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006313 if (!control->sframe) {
6314 int err;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006315
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006316 BT_DBG("iframe sar %d, reqseq %d, final %d, txseq %d",
6317 control->sar, control->reqseq, control->final,
6318 control->txseq);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03006319
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006320 /* Validate F-bit - F=0 always valid, F=1 only
6321 * valid in TX WAIT_F
6322 */
6323 if (control->final && chan->tx_state != L2CAP_TX_STATE_WAIT_F)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006324 goto drop;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006325
6326 if (chan->mode != L2CAP_MODE_STREAMING) {
6327 event = L2CAP_EV_RECV_IFRAME;
6328 err = l2cap_rx(chan, control, skb, event);
6329 } else {
6330 err = l2cap_stream_rx(chan, control, skb);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006331 }
6332
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006333 if (err)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006334 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006335 } else {
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006336 const u8 rx_func_to_event[4] = {
6337 L2CAP_EV_RECV_RR, L2CAP_EV_RECV_REJ,
6338 L2CAP_EV_RECV_RNR, L2CAP_EV_RECV_SREJ
6339 };
6340
6341 /* Only I-frames are expected in streaming mode */
6342 if (chan->mode == L2CAP_MODE_STREAMING)
6343 goto drop;
6344
6345 BT_DBG("sframe reqseq %d, final %d, poll %d, super %d",
6346 control->reqseq, control->final, control->poll,
6347 control->super);
6348
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006349 if (len != 0) {
Andrei Emeltchenko1bb166e2012-11-20 17:16:21 +02006350 BT_ERR("Trailing bytes: %d in sframe", len);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006351 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006352 goto drop;
6353 }
6354
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006355 /* Validate F and P bits */
6356 if (control->final && (control->poll ||
6357 chan->tx_state != L2CAP_TX_STATE_WAIT_F))
6358 goto drop;
6359
6360 event = rx_func_to_event[control->super];
6361 if (l2cap_rx(chan, control, skb, event))
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006362 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006363 }
6364
6365 return 0;
6366
6367drop:
6368 kfree_skb(skb);
6369 return 0;
6370}
6371
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006372static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid,
6373 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006374{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006375 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006376
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03006377 chan = l2cap_get_chan_by_scid(conn, cid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006378 if (!chan) {
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006379 if (cid == L2CAP_CID_A2MP) {
6380 chan = a2mp_channel_create(conn, skb);
6381 if (!chan) {
6382 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006383 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006384 }
6385
6386 l2cap_chan_lock(chan);
6387 } else {
6388 BT_DBG("unknown cid 0x%4.4x", cid);
6389 /* Drop packet and return */
6390 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006391 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006392 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006393 }
6394
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03006395 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006396
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006397 if (chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006398 goto drop;
6399
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006400 switch (chan->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006401 case L2CAP_MODE_BASIC:
6402 /* If socket recv buffers overflows we drop data here
6403 * which is *bad* because L2CAP has to be reliable.
6404 * But we don't have any other choice. L2CAP doesn't
6405 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006406
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006407 if (chan->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006408 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006409
Gustavo Padovan80b98022012-05-27 22:27:51 -03006410 if (!chan->ops->recv(chan, skb))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006411 goto done;
6412 break;
6413
6414 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03006415 case L2CAP_MODE_STREAMING:
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006416 l2cap_data_rcv(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03006417 goto done;
6418
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006419 default:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006420 BT_DBG("chan %p: bad mode 0x%2.2x", chan, chan->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006421 break;
6422 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006423
6424drop:
6425 kfree_skb(skb);
6426
6427done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006428 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006429}
6430
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03006431static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm,
6432 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006433{
Marcel Holtmannae4fd2d2013-10-03 00:03:39 -07006434 struct hci_conn *hcon = conn->hcon;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006435 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006436
Marcel Holtmannae4fd2d2013-10-03 00:03:39 -07006437 if (hcon->type != ACL_LINK)
6438 goto drop;
6439
Ido Yarivc2287682012-04-20 15:46:07 -03006440 chan = l2cap_global_chan_by_psm(0, psm, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006441 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006442 goto drop;
6443
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02006444 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006445
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006446 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006447 goto drop;
6448
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03006449 if (chan->imtu < skb->len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006450 goto drop;
6451
Gustavo Padovan80b98022012-05-27 22:27:51 -03006452 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03006453 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006454
6455drop:
6456 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006457}
6458
Marcel Holtmann72f78352013-04-23 00:59:00 -07006459static void l2cap_att_channel(struct l2cap_conn *conn,
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03006460 struct sk_buff *skb)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006461{
Marcel Holtmannb99707d2013-10-03 02:54:11 -07006462 struct hci_conn *hcon = conn->hcon;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006463 struct l2cap_chan *chan;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006464
Marcel Holtmannb99707d2013-10-03 02:54:11 -07006465 if (hcon->type != LE_LINK)
6466 goto drop;
6467
Johan Hedbergaf1c0132013-04-29 19:35:42 +03006468 chan = l2cap_global_chan_by_scid(BT_CONNECTED, L2CAP_CID_ATT,
Marcel Holtmann72f78352013-04-23 00:59:00 -07006469 conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006470 if (!chan)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006471 goto drop;
6472
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02006473 BT_DBG("chan %p, len %d", chan, skb->len);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006474
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03006475 if (chan->imtu < skb->len)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006476 goto drop;
6477
Gustavo Padovan80b98022012-05-27 22:27:51 -03006478 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03006479 return;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006480
6481drop:
6482 kfree_skb(skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006483}
6484
Linus Torvalds1da177e2005-04-16 15:20:36 -07006485static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
6486{
6487 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07006488 u16 cid, len;
6489 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006490
6491 skb_pull(skb, L2CAP_HDR_SIZE);
6492 cid = __le16_to_cpu(lh->cid);
6493 len = __le16_to_cpu(lh->len);
6494
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006495 if (len != skb->len) {
6496 kfree_skb(skb);
6497 return;
6498 }
6499
Linus Torvalds1da177e2005-04-16 15:20:36 -07006500 BT_DBG("len %d, cid 0x%4.4x", len, cid);
6501
6502 switch (cid) {
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03006503 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006504 l2cap_sig_channel(conn, skb);
6505 break;
6506
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03006507 case L2CAP_CID_CONN_LESS:
Andrei Emeltchenko097db762012-03-09 14:16:17 +02006508 psm = get_unaligned((__le16 *) skb->data);
Andrei Emeltchenko0181a702012-05-29 10:04:05 +03006509 skb_pull(skb, L2CAP_PSMLEN_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006510 l2cap_conless_channel(conn, psm, skb);
6511 break;
6512
Johan Hedberg073d1cf2013-04-29 19:35:35 +03006513 case L2CAP_CID_ATT:
Marcel Holtmann72f78352013-04-23 00:59:00 -07006514 l2cap_att_channel(conn, skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006515 break;
6516
Marcel Holtmanna2877622013-10-02 23:46:54 -07006517 case L2CAP_CID_LE_SIGNALING:
6518 l2cap_le_sig_channel(conn, skb);
6519 break;
6520
Anderson Brigliab501d6a2011-06-07 18:46:31 -03006521 case L2CAP_CID_SMP:
6522 if (smp_sig_channel(conn, skb))
6523 l2cap_conn_del(conn->hcon, EACCES);
6524 break;
6525
Linus Torvalds1da177e2005-04-16 15:20:36 -07006526 default:
6527 l2cap_data_channel(conn, cid, skb);
6528 break;
6529 }
6530}
6531
6532/* ---- L2CAP interface with lower layer (HCI) ---- */
6533
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006534int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006535{
6536 int exact = 0, lm1 = 0, lm2 = 0;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006537 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006538
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03006539 BT_DBG("hdev %s, bdaddr %pMR", hdev->name, bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006540
6541 /* Find listening sockets and check their link_mode */
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006542 read_lock(&chan_list_lock);
6543 list_for_each_entry(c, &chan_list, global_l) {
6544 struct sock *sk = c->sk;
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006545
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006546 if (c->state != BT_LISTEN)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006547 continue;
6548
6549 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006550 lm1 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03006551 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006552 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006553 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006554 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
6555 lm2 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03006556 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006557 lm2 |= HCI_LM_MASTER;
6558 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006559 }
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006560 read_unlock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006561
6562 return exact ? lm1 : lm2;
6563}
6564
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03006565void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006566{
Marcel Holtmann01394182006-07-03 10:02:46 +02006567 struct l2cap_conn *conn;
6568
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03006569 BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006570
Linus Torvalds1da177e2005-04-16 15:20:36 -07006571 if (!status) {
Claudio Takahasibaf43252013-04-11 13:55:50 -03006572 conn = l2cap_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006573 if (conn)
6574 l2cap_conn_ready(conn);
Andrei Emeltchenkoba6fc312012-10-31 15:46:26 +02006575 } else {
Joe Perchese1750722011-06-29 18:18:29 -07006576 l2cap_conn_del(hcon, bt_to_errno(status));
Andrei Emeltchenkoba6fc312012-10-31 15:46:26 +02006577 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006578}
6579
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006580int l2cap_disconn_ind(struct hci_conn *hcon)
Marcel Holtmann2950f212009-02-12 14:02:50 +01006581{
6582 struct l2cap_conn *conn = hcon->l2cap_data;
6583
6584 BT_DBG("hcon %p", hcon);
6585
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006586 if (!conn)
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02006587 return HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01006588 return conn->disc_reason;
6589}
6590
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03006591void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006592{
6593 BT_DBG("hcon %p reason %d", hcon, reason);
6594
Joe Perchese1750722011-06-29 18:18:29 -07006595 l2cap_conn_del(hcon, bt_to_errno(reason));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006596}
6597
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006598static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006599{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03006600 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED)
Marcel Holtmann255c7602009-02-04 21:07:19 +01006601 return;
6602
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006603 if (encrypt == 0x00) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006604 if (chan->sec_level == BT_SECURITY_MEDIUM) {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006605 __set_chan_timer(chan, L2CAP_ENC_TIMEOUT);
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006606 } else if (chan->sec_level == BT_SECURITY_HIGH)
Gustavo F. Padovan0f852722011-05-04 19:42:50 -03006607 l2cap_chan_close(chan, ECONNREFUSED);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006608 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006609 if (chan->sec_level == BT_SECURITY_MEDIUM)
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03006610 __clear_chan_timer(chan);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006611 }
6612}
6613
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006614int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006615{
Marcel Holtmann40be4922008-07-14 20:13:50 +02006616 struct l2cap_conn *conn = hcon->l2cap_data;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006617 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006618
Marcel Holtmann01394182006-07-03 10:02:46 +02006619 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006620 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02006621
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03006622 BT_DBG("conn %p status 0x%2.2x encrypt %u", conn, status, encrypt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006623
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03006624 if (hcon->type == LE_LINK) {
Hemant Gupta35d4adcc2012-04-18 14:46:26 +05306625 if (!status && encrypt)
6626 smp_distribute_keys(conn, 0);
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02006627 cancel_delayed_work(&conn->security_timer);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03006628 }
6629
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006630 mutex_lock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006631
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006632 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006633 l2cap_chan_lock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006634
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03006635 BT_DBG("chan %p scid 0x%4.4x state %s", chan, chan->scid,
6636 state_to_string(chan->state));
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006637
Andrei Emeltchenko78eb2f92012-07-19 17:03:47 +03006638 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
6639 l2cap_chan_unlock(chan);
6640 continue;
6641 }
6642
Johan Hedberg073d1cf2013-04-29 19:35:35 +03006643 if (chan->scid == L2CAP_CID_ATT) {
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006644 if (!status && encrypt) {
6645 chan->sec_level = hcon->sec_level;
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02006646 l2cap_chan_ready(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006647 }
6648
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006649 l2cap_chan_unlock(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006650 continue;
6651 }
6652
Andrei Emeltchenko96eff462012-11-15 18:14:53 +02006653 if (!__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006654 l2cap_chan_unlock(chan);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01006655 continue;
6656 }
6657
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006658 if (!status && (chan->state == BT_CONNECTED ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01006659 chan->state == BT_CONFIG)) {
Gustavo Padovana7d77232012-05-13 03:20:07 -03006660 struct sock *sk = chan->sk;
6661
Gustavo Padovanc5daa682012-05-16 12:17:10 -03006662 clear_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags);
Gustavo Padovana7d77232012-05-13 03:20:07 -03006663 sk->sk_state_change(sk);
6664
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006665 l2cap_check_encryption(chan, encrypt);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006666 l2cap_chan_unlock(chan);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02006667 continue;
6668 }
6669
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006670 if (chan->state == BT_CONNECT) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006671 if (!status) {
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03006672 l2cap_start_connection(chan);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006673 } else {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006674 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006675 }
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006676 } else if (chan->state == BT_CONNECT2) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006677 struct sock *sk = chan->sk;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006678 struct l2cap_conn_rsp rsp;
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006679 __u16 res, stat;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006680
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006681 lock_sock(sk);
6682
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006683 if (!status) {
Gustavo Padovanc5daa682012-05-16 12:17:10 -03006684 if (test_bit(BT_SK_DEFER_SETUP,
6685 &bt_sk(sk)->flags)) {
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006686 res = L2CAP_CR_PEND;
6687 stat = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08006688 chan->ops->defer(chan);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006689 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02006690 __l2cap_state_change(chan, BT_CONFIG);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006691 res = L2CAP_CR_SUCCESS;
6692 stat = L2CAP_CS_NO_INFO;
6693 }
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006694 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02006695 __l2cap_state_change(chan, BT_DISCONN);
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006696 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006697 res = L2CAP_CR_SEC_BLOCK;
6698 stat = L2CAP_CS_NO_INFO;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006699 }
6700
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006701 release_sock(sk);
6702
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03006703 rsp.scid = cpu_to_le16(chan->dcid);
6704 rsp.dcid = cpu_to_le16(chan->scid);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006705 rsp.result = cpu_to_le16(res);
6706 rsp.status = cpu_to_le16(stat);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03006707 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01006708 sizeof(rsp), &rsp);
Mat Martineau2d369352012-05-23 14:59:30 -07006709
6710 if (!test_bit(CONF_REQ_SENT, &chan->conf_state) &&
6711 res == L2CAP_CR_SUCCESS) {
6712 char buf[128];
6713 set_bit(CONF_REQ_SENT, &chan->conf_state);
6714 l2cap_send_cmd(conn, l2cap_get_ident(conn),
6715 L2CAP_CONF_REQ,
6716 l2cap_build_conf_req(chan, buf),
6717 buf);
6718 chan->num_conf_req++;
6719 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006720 }
6721
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006722 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006723 }
6724
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006725 mutex_unlock(&conn->chan_lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006726
Linus Torvalds1da177e2005-04-16 15:20:36 -07006727 return 0;
6728}
6729
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006730int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006731{
6732 struct l2cap_conn *conn = hcon->l2cap_data;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006733 struct l2cap_hdr *hdr;
6734 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006735
Andrei Emeltchenko1d13a252012-10-15 11:58:41 +03006736 /* For AMP controller do not create l2cap conn */
6737 if (!conn && hcon->hdev->dev_type != HCI_BREDR)
6738 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006739
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02006740 if (!conn)
Claudio Takahasibaf43252013-04-11 13:55:50 -03006741 conn = l2cap_conn_add(hcon);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02006742
6743 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006744 goto drop;
6745
6746 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
6747
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006748 switch (flags) {
6749 case ACL_START:
6750 case ACL_START_NO_FLUSH:
6751 case ACL_COMPLETE:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006752 if (conn->rx_len) {
6753 BT_ERR("Unexpected start frame (len %d)", skb->len);
6754 kfree_skb(conn->rx_skb);
6755 conn->rx_skb = NULL;
6756 conn->rx_len = 0;
6757 l2cap_conn_unreliable(conn, ECOMM);
6758 }
6759
Andrei Emeltchenkoaae7fe22010-09-15 14:28:43 +03006760 /* Start fragment always begin with Basic L2CAP header */
6761 if (skb->len < L2CAP_HDR_SIZE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006762 BT_ERR("Frame is too short (len %d)", skb->len);
6763 l2cap_conn_unreliable(conn, ECOMM);
6764 goto drop;
6765 }
6766
6767 hdr = (struct l2cap_hdr *) skb->data;
6768 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
6769
6770 if (len == skb->len) {
6771 /* Complete frame received */
6772 l2cap_recv_frame(conn, skb);
6773 return 0;
6774 }
6775
6776 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
6777
6778 if (skb->len > len) {
6779 BT_ERR("Frame is too long (len %d, expected len %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01006780 skb->len, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006781 l2cap_conn_unreliable(conn, ECOMM);
6782 goto drop;
6783 }
6784
6785 /* Allocate skb for the complete frame (with header) */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03006786 conn->rx_skb = bt_skb_alloc(len, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03006787 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006788 goto drop;
6789
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03006790 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01006791 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006792 conn->rx_len = len - skb->len;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006793 break;
6794
6795 case ACL_CONT:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006796 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
6797
6798 if (!conn->rx_len) {
6799 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
6800 l2cap_conn_unreliable(conn, ECOMM);
6801 goto drop;
6802 }
6803
6804 if (skb->len > conn->rx_len) {
6805 BT_ERR("Fragment is too long (len %d, expected %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01006806 skb->len, conn->rx_len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006807 kfree_skb(conn->rx_skb);
6808 conn->rx_skb = NULL;
6809 conn->rx_len = 0;
6810 l2cap_conn_unreliable(conn, ECOMM);
6811 goto drop;
6812 }
6813
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03006814 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01006815 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006816 conn->rx_len -= skb->len;
6817
6818 if (!conn->rx_len) {
Johan Hedbergc4e5baf2013-10-10 13:33:37 +02006819 /* Complete frame received. l2cap_recv_frame
6820 * takes ownership of the skb so set the global
6821 * rx_skb pointer to NULL first.
6822 */
6823 struct sk_buff *rx_skb = conn->rx_skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006824 conn->rx_skb = NULL;
Johan Hedbergc4e5baf2013-10-10 13:33:37 +02006825 l2cap_recv_frame(conn, rx_skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006826 }
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006827 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006828 }
6829
6830drop:
6831 kfree_skb(skb);
6832 return 0;
6833}
6834
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006835static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006836{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006837 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006838
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02006839 read_lock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006840
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006841 list_for_each_entry(c, &chan_list, global_l) {
6842 struct sock *sk = c->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006843
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +03006844 seq_printf(f, "%pMR %pMR %d %d 0x%4.4x 0x%4.4x %d %d %d %d\n",
6845 &bt_sk(sk)->src, &bt_sk(sk)->dst,
6846 c->state, __le16_to_cpu(c->psm),
6847 c->scid, c->dcid, c->imtu, c->omtu,
6848 c->sec_level, c->mode);
Andrei Emeltchenko61e1b4b2012-01-19 11:19:50 +02006849 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006850
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02006851 read_unlock(&chan_list_lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08006852
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006853 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006854}
6855
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006856static int l2cap_debugfs_open(struct inode *inode, struct file *file)
6857{
6858 return single_open(file, l2cap_debugfs_show, inode->i_private);
6859}
6860
6861static const struct file_operations l2cap_debugfs_fops = {
6862 .open = l2cap_debugfs_open,
6863 .read = seq_read,
6864 .llseek = seq_lseek,
6865 .release = single_release,
6866};
6867
6868static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006869
Gustavo F. Padovan64274512011-02-07 20:08:52 -02006870int __init l2cap_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006871{
6872 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08006873
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02006874 err = l2cap_init_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006875 if (err < 0)
6876 return err;
6877
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006878 if (bt_debugfs) {
Gustavo Padovan2d792812012-10-06 10:07:01 +01006879 l2cap_debugfs = debugfs_create_file("l2cap", 0444, bt_debugfs,
6880 NULL, &l2cap_debugfs_fops);
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006881 if (!l2cap_debugfs)
6882 BT_ERR("Failed to create L2CAP debug file");
6883 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006884
Linus Torvalds1da177e2005-04-16 15:20:36 -07006885 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006886}
6887
Gustavo F. Padovan64274512011-02-07 20:08:52 -02006888void l2cap_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006889{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006890 debugfs_remove(l2cap_debugfs);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02006891 l2cap_cleanup_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006892}
6893
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03006894module_param(disable_ertm, bool, 0644);
6895MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode");