blob: 062e28e4722b701ec3a8d80d002fc862fda8ef3f [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 Holtmann547d1032013-10-12 08:18:19 -070046static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN | L2CAP_FEAT_UCD;
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,
Marcel Holtmann6f59b902013-10-13 05:24:01 -07001384 &conn->hcon->src, &conn->hcon->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
Marcel Holtmann6f59b902013-10-13 05:24:01 -07001402 bacpy(&bt_sk(chan->sk)->src, &conn->hcon->src);
Marcel Holtmann98e0f7e2013-10-13 02:23:40 -07001403 bacpy(&bt_sk(chan->sk)->dst, &conn->hcon->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
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001668 conn->feat_mask = 0;
1669
Marcel Holtmann848566b2013-10-01 22:59:22 -07001670 if (hcon->type == ACL_LINK)
1671 conn->hs_enabled = test_bit(HCI_HS_ENABLED,
1672 &hcon->hdev->dev_flags);
1673
Linus Torvalds1da177e2005-04-16 15:20:36 -07001674 spin_lock_init(&conn->lock);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001675 mutex_init(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001676
1677 INIT_LIST_HEAD(&conn->chan_l);
David Herrmann2c8e1412013-04-06 20:28:45 +02001678 INIT_LIST_HEAD(&conn->users);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001679
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001680 if (hcon->type == LE_LINK)
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001681 INIT_DELAYED_WORK(&conn->security_timer, security_timeout);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001682 else
Gustavo F. Padovan030013d2011-12-20 10:57:28 -02001683 INIT_DELAYED_WORK(&conn->info_timer, l2cap_info_timeout);
Dave Young45054dc2009-10-18 20:28:30 +00001684
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001685 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01001686
Linus Torvalds1da177e2005-04-16 15:20:36 -07001687 return conn;
1688}
1689
David Herrmann9c903e32013-04-06 20:28:44 +02001690static void l2cap_conn_free(struct kref *ref)
1691{
1692 struct l2cap_conn *conn = container_of(ref, struct l2cap_conn, ref);
1693
1694 hci_conn_put(conn->hcon);
1695 kfree(conn);
1696}
1697
1698void l2cap_conn_get(struct l2cap_conn *conn)
1699{
1700 kref_get(&conn->ref);
1701}
1702EXPORT_SYMBOL(l2cap_conn_get);
1703
1704void l2cap_conn_put(struct l2cap_conn *conn)
1705{
1706 kref_put(&conn->ref, l2cap_conn_free);
1707}
1708EXPORT_SYMBOL(l2cap_conn_put);
1709
Linus Torvalds1da177e2005-04-16 15:20:36 -07001710/* ---- Socket interface ---- */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001711
Ido Yarivc2287682012-04-20 15:46:07 -03001712/* Find socket with psm and source / destination bdaddr.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001713 * Returns closest match.
1714 */
Ido Yarivc2287682012-04-20 15:46:07 -03001715static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
1716 bdaddr_t *src,
1717 bdaddr_t *dst)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001718{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001719 struct l2cap_chan *c, *c1 = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001720
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001721 read_lock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001722
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001723 list_for_each_entry(c, &chan_list, global_l) {
1724 struct sock *sk = c->sk;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001725
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001726 if (state && c->state != state)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001727 continue;
1728
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001729 if (c->psm == psm) {
Ido Yarivc2287682012-04-20 15:46:07 -03001730 int src_match, dst_match;
1731 int src_any, dst_any;
1732
Linus Torvalds1da177e2005-04-16 15:20:36 -07001733 /* Exact match. */
Ido Yarivc2287682012-04-20 15:46:07 -03001734 src_match = !bacmp(&bt_sk(sk)->src, src);
1735 dst_match = !bacmp(&bt_sk(sk)->dst, dst);
1736 if (src_match && dst_match) {
Johannes Berga7567b22011-06-01 08:29:54 +02001737 read_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001738 return c;
1739 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001740
1741 /* Closest match */
Ido Yarivc2287682012-04-20 15:46:07 -03001742 src_any = !bacmp(&bt_sk(sk)->src, BDADDR_ANY);
1743 dst_any = !bacmp(&bt_sk(sk)->dst, BDADDR_ANY);
1744 if ((src_match && dst_any) || (src_any && dst_match) ||
1745 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001746 c1 = c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001747 }
1748 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001749
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001750 read_unlock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001751
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001752 return c1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001753}
1754
Andre Guedes8e9f9892012-04-24 21:02:55 -03001755int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
1756 bdaddr_t *dst, u8 dst_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001757{
Gustavo F. Padovan5d41ce12011-04-08 15:40:02 -03001758 struct sock *sk = chan->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001759 struct l2cap_conn *conn;
1760 struct hci_conn *hcon;
1761 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001762 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +02001763 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001764
Marcel Holtmann4637f7c2013-10-13 05:56:37 -07001765 BT_DBG("%pMR -> %pMR (type %u) psm 0x%2.2x", &bt_sk(sk)->src, dst,
Syam Sidhardhanab195162012-07-27 23:51:22 +05301766 dst_type, __le16_to_cpu(psm));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001767
Marcel Holtmann4637f7c2013-10-13 05:56:37 -07001768 hdev = hci_get_route(dst, &bt_sk(sk)->src);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001769 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001770 return -EHOSTUNREACH;
1771
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001772 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001773
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001774 l2cap_chan_lock(chan);
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001775
1776 /* PSM must be odd and lsb of upper byte must be 0 */
1777 if ((__le16_to_cpu(psm) & 0x0101) != 0x0001 && !cid &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01001778 chan->chan_type != L2CAP_CHAN_RAW) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001779 err = -EINVAL;
1780 goto done;
1781 }
1782
1783 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && !(psm || cid)) {
1784 err = -EINVAL;
1785 goto done;
1786 }
1787
1788 switch (chan->mode) {
1789 case L2CAP_MODE_BASIC:
1790 break;
1791 case L2CAP_MODE_ERTM:
1792 case L2CAP_MODE_STREAMING:
1793 if (!disable_ertm)
1794 break;
1795 /* fall through */
1796 default:
1797 err = -ENOTSUPP;
1798 goto done;
1799 }
1800
Gustavo Padovan0797e012012-05-27 22:27:54 -03001801 switch (chan->state) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001802 case BT_CONNECT:
1803 case BT_CONNECT2:
1804 case BT_CONFIG:
1805 /* Already connecting */
1806 err = 0;
1807 goto done;
1808
1809 case BT_CONNECTED:
1810 /* Already connected */
1811 err = -EISCONN;
1812 goto done;
1813
1814 case BT_OPEN:
1815 case BT_BOUND:
1816 /* Can connect */
1817 break;
1818
1819 default:
1820 err = -EBADFD;
1821 goto done;
1822 }
1823
1824 /* Set destination address and psm */
Gustavo Padovan0797e012012-05-27 22:27:54 -03001825 lock_sock(sk);
Gustavo F. Padovan9219b2a2012-01-02 20:08:04 -02001826 bacpy(&bt_sk(sk)->dst, dst);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001827 release_sock(sk);
1828
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001829 chan->psm = psm;
1830 chan->dcid = cid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001831
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001832 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001833
Johan Hedbergf224ca52013-04-29 19:35:36 +03001834 if (bdaddr_type_is_le(dst_type))
Andre Guedes8e9f9892012-04-24 21:02:55 -03001835 hcon = hci_connect(hdev, LE_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001836 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001837 else
Andre Guedes8e9f9892012-04-24 21:02:55 -03001838 hcon = hci_connect(hdev, ACL_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001839 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001840
Ville Tervo30e76272011-02-22 16:10:53 -03001841 if (IS_ERR(hcon)) {
1842 err = PTR_ERR(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001843 goto done;
Ville Tervo30e76272011-02-22 16:10:53 -03001844 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001845
Claudio Takahasibaf43252013-04-11 13:55:50 -03001846 conn = l2cap_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001847 if (!conn) {
David Herrmann76a68ba2013-04-06 20:28:37 +02001848 hci_conn_drop(hcon);
Ville Tervo30e76272011-02-22 16:10:53 -03001849 err = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001850 goto done;
1851 }
1852
Johan Hedberg141d5702013-04-29 19:35:37 +03001853 if (cid && __l2cap_get_chan_by_dcid(conn, cid)) {
1854 hci_conn_drop(hcon);
1855 err = -EBUSY;
1856 goto done;
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001857 }
1858
Linus Torvalds1da177e2005-04-16 15:20:36 -07001859 /* Update source addr of the socket */
Marcel Holtmann4637f7c2013-10-13 05:56:37 -07001860 lock_sock(sk);
1861 bacpy(&bt_sk(sk)->src, &hcon->src);
1862 release_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001863
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001864 l2cap_chan_unlock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001865 l2cap_chan_add(conn, chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001866 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001867
Johan Hedberg5ee98912013-04-29 19:35:43 +03001868 /* l2cap_chan_add takes its own ref so we can drop this one */
1869 hci_conn_drop(hcon);
1870
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001871 l2cap_state_change(chan, BT_CONNECT);
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001872 __set_chan_timer(chan, sk->sk_sndtimeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001873
1874 if (hcon->state == BT_CONNECTED) {
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001875 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001876 __clear_chan_timer(chan);
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001877 if (l2cap_chan_check_security(chan))
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001878 l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001879 } else
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001880 l2cap_do_start(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001881 }
1882
Ville Tervo30e76272011-02-22 16:10:53 -03001883 err = 0;
1884
Linus Torvalds1da177e2005-04-16 15:20:36 -07001885done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001886 l2cap_chan_unlock(chan);
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001887 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001888 hci_dev_put(hdev);
1889 return err;
1890}
1891
Gustavo F. Padovandcba0db2011-02-04 03:08:36 -02001892int __l2cap_wait_ack(struct sock *sk)
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001893{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001894 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001895 DECLARE_WAITQUEUE(wait, current);
1896 int err = 0;
1897 int timeo = HZ/5;
1898
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001899 add_wait_queue(sk_sleep(sk), &wait);
Peter Hurleya71a0cf2011-07-25 18:36:26 -04001900 set_current_state(TASK_INTERRUPTIBLE);
1901 while (chan->unacked_frames > 0 && chan->conn) {
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001902 if (!timeo)
1903 timeo = HZ/5;
1904
1905 if (signal_pending(current)) {
1906 err = sock_intr_errno(timeo);
1907 break;
1908 }
1909
1910 release_sock(sk);
1911 timeo = schedule_timeout(timeo);
1912 lock_sock(sk);
Peter Hurleya71a0cf2011-07-25 18:36:26 -04001913 set_current_state(TASK_INTERRUPTIBLE);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001914
1915 err = sock_error(sk);
1916 if (err)
1917 break;
1918 }
1919 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001920 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001921 return err;
1922}
1923
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001924static void l2cap_monitor_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001925{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001926 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001927 monitor_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001928
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03001929 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001930
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001931 l2cap_chan_lock(chan);
1932
Mat Martineau80909e02012-05-17 20:53:50 -07001933 if (!chan->conn) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001934 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001935 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001936 return;
1937 }
1938
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001939 l2cap_tx(chan, NULL, NULL, L2CAP_EV_MONITOR_TO);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001940
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001941 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001942 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001943}
1944
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001945static void l2cap_retrans_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001946{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001947 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001948 retrans_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001949
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03001950 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001951
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001952 l2cap_chan_lock(chan);
1953
Mat Martineau80909e02012-05-17 20:53:50 -07001954 if (!chan->conn) {
1955 l2cap_chan_unlock(chan);
1956 l2cap_chan_put(chan);
1957 return;
1958 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001959
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001960 l2cap_tx(chan, NULL, NULL, L2CAP_EV_RETRANS_TO);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001961 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001962 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001963}
1964
Gustavo Padovand6603662012-05-21 13:58:22 -03001965static void l2cap_streaming_send(struct l2cap_chan *chan,
1966 struct sk_buff_head *skbs)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001967{
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001968 struct sk_buff *skb;
Mat Martineau37339372012-05-17 20:53:33 -07001969 struct l2cap_ctrl *control;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001970
Mat Martineau37339372012-05-17 20:53:33 -07001971 BT_DBG("chan %p, skbs %p", chan, skbs);
1972
Mat Martineaub99e13a2012-10-23 15:24:19 -07001973 if (__chan_is_moving(chan))
1974 return;
1975
Mat Martineau37339372012-05-17 20:53:33 -07001976 skb_queue_splice_tail_init(skbs, &chan->tx_q);
1977
1978 while (!skb_queue_empty(&chan->tx_q)) {
1979
1980 skb = skb_dequeue(&chan->tx_q);
1981
1982 bt_cb(skb)->control.retries = 1;
1983 control = &bt_cb(skb)->control;
1984
1985 control->reqseq = 0;
1986 control->txseq = chan->next_tx_seq;
1987
1988 __pack_control(chan, control, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001989
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001990 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau37339372012-05-17 20:53:33 -07001991 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
1992 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001993 }
1994
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001995 l2cap_do_send(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001996
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001997 BT_DBG("Sent txseq %u", control->txseq);
Mat Martineau37339372012-05-17 20:53:33 -07001998
Andrei Emeltchenko836be932011-10-17 12:19:57 +03001999 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau37339372012-05-17 20:53:33 -07002000 chan->frames_sent++;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002001 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002002}
2003
Szymon Janc67c9e842011-07-28 16:24:33 +02002004static int l2cap_ertm_send(struct l2cap_chan *chan)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002005{
2006 struct sk_buff *skb, *tx_skb;
Mat Martineau18a48e72012-05-17 20:53:34 -07002007 struct l2cap_ctrl *control;
2008 int sent = 0;
2009
2010 BT_DBG("chan %p", chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002011
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03002012 if (chan->state != BT_CONNECTED)
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03002013 return -ENOTCONN;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002014
Mat Martineau94122bb2012-05-02 09:42:02 -07002015 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2016 return 0;
2017
Mat Martineaub99e13a2012-10-23 15:24:19 -07002018 if (__chan_is_moving(chan))
2019 return 0;
2020
Mat Martineau18a48e72012-05-17 20:53:34 -07002021 while (chan->tx_send_head &&
2022 chan->unacked_frames < chan->remote_tx_win &&
2023 chan->tx_state == L2CAP_TX_STATE_XMIT) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002024
Mat Martineau18a48e72012-05-17 20:53:34 -07002025 skb = chan->tx_send_head;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002026
Mat Martineau18a48e72012-05-17 20:53:34 -07002027 bt_cb(skb)->control.retries = 1;
2028 control = &bt_cb(skb)->control;
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03002029
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03002030 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
Mat Martineau18a48e72012-05-17 20:53:34 -07002031 control->final = 1;
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03002032
Mat Martineau18a48e72012-05-17 20:53:34 -07002033 control->reqseq = chan->buffer_seq;
2034 chan->last_acked_seq = chan->buffer_seq;
2035 control->txseq = chan->next_tx_seq;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002036
Mat Martineau18a48e72012-05-17 20:53:34 -07002037 __pack_control(chan, control, skb);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002038
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002039 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau18a48e72012-05-17 20:53:34 -07002040 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
2041 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002042 }
2043
Mat Martineau18a48e72012-05-17 20:53:34 -07002044 /* Clone after data has been modified. Data is assumed to be
2045 read-only (for locking purposes) on cloned sk_buffs.
2046 */
2047 tx_skb = skb_clone(skb, GFP_KERNEL);
2048
2049 if (!tx_skb)
2050 break;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03002051
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03002052 __set_retrans_timer(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002053
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002054 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau18a48e72012-05-17 20:53:34 -07002055 chan->unacked_frames++;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03002056 chan->frames_sent++;
Mat Martineau18a48e72012-05-17 20:53:34 -07002057 sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002058
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03002059 if (skb_queue_is_last(&chan->tx_q, skb))
2060 chan->tx_send_head = NULL;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002061 else
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03002062 chan->tx_send_head = skb_queue_next(&chan->tx_q, skb);
Mat Martineau18a48e72012-05-17 20:53:34 -07002063
2064 l2cap_do_send(chan, tx_skb);
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002065 BT_DBG("Sent txseq %u", control->txseq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002066 }
2067
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002068 BT_DBG("Sent %d, %u unacked, %u in ERTM queue", sent,
2069 chan->unacked_frames, skb_queue_len(&chan->tx_q));
Mat Martineau18a48e72012-05-17 20:53:34 -07002070
2071 return sent;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03002072}
2073
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002074static void l2cap_ertm_resend(struct l2cap_chan *chan)
2075{
2076 struct l2cap_ctrl control;
2077 struct sk_buff *skb;
2078 struct sk_buff *tx_skb;
2079 u16 seq;
2080
2081 BT_DBG("chan %p", chan);
2082
2083 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2084 return;
2085
Mat Martineaub99e13a2012-10-23 15:24:19 -07002086 if (__chan_is_moving(chan))
2087 return;
2088
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002089 while (chan->retrans_list.head != L2CAP_SEQ_LIST_CLEAR) {
2090 seq = l2cap_seq_list_pop(&chan->retrans_list);
2091
2092 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, seq);
2093 if (!skb) {
2094 BT_DBG("Error: Can't retransmit seq %d, frame missing",
Gustavo Padovan2d792812012-10-06 10:07:01 +01002095 seq);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002096 continue;
2097 }
2098
2099 bt_cb(skb)->control.retries++;
2100 control = bt_cb(skb)->control;
2101
2102 if (chan->max_tx != 0 &&
2103 bt_cb(skb)->control.retries > chan->max_tx) {
2104 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02002105 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002106 l2cap_seq_list_clear(&chan->retrans_list);
2107 break;
2108 }
2109
2110 control.reqseq = chan->buffer_seq;
2111 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
2112 control.final = 1;
2113 else
2114 control.final = 0;
2115
2116 if (skb_cloned(skb)) {
2117 /* Cloned sk_buffs are read-only, so we need a
2118 * writeable copy
2119 */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002120 tx_skb = skb_copy(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002121 } else {
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002122 tx_skb = skb_clone(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002123 }
2124
2125 if (!tx_skb) {
2126 l2cap_seq_list_clear(&chan->retrans_list);
2127 break;
2128 }
2129
2130 /* Update skb contents */
2131 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
2132 put_unaligned_le32(__pack_extended_control(&control),
2133 tx_skb->data + L2CAP_HDR_SIZE);
2134 } else {
2135 put_unaligned_le16(__pack_enhanced_control(&control),
2136 tx_skb->data + L2CAP_HDR_SIZE);
2137 }
2138
2139 if (chan->fcs == L2CAP_FCS_CRC16) {
2140 u16 fcs = crc16(0, (u8 *) tx_skb->data, tx_skb->len);
2141 put_unaligned_le16(fcs, skb_put(tx_skb,
2142 L2CAP_FCS_SIZE));
2143 }
2144
2145 l2cap_do_send(chan, tx_skb);
2146
2147 BT_DBG("Resent txseq %d", control.txseq);
2148
2149 chan->last_acked_seq = chan->buffer_seq;
2150 }
2151}
2152
Mat Martineauf80842a2012-05-17 20:53:46 -07002153static void l2cap_retransmit(struct l2cap_chan *chan,
2154 struct l2cap_ctrl *control)
2155{
2156 BT_DBG("chan %p, control %p", chan, control);
2157
2158 l2cap_seq_list_append(&chan->retrans_list, control->reqseq);
2159 l2cap_ertm_resend(chan);
2160}
2161
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002162static void l2cap_retransmit_all(struct l2cap_chan *chan,
2163 struct l2cap_ctrl *control)
2164{
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002165 struct sk_buff *skb;
2166
2167 BT_DBG("chan %p, control %p", chan, control);
2168
2169 if (control->poll)
2170 set_bit(CONN_SEND_FBIT, &chan->conn_state);
2171
2172 l2cap_seq_list_clear(&chan->retrans_list);
2173
2174 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2175 return;
2176
2177 if (chan->unacked_frames) {
2178 skb_queue_walk(&chan->tx_q, skb) {
2179 if (bt_cb(skb)->control.txseq == control->reqseq ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01002180 skb == chan->tx_send_head)
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002181 break;
2182 }
2183
2184 skb_queue_walk_from(&chan->tx_q, skb) {
2185 if (skb == chan->tx_send_head)
2186 break;
2187
2188 l2cap_seq_list_append(&chan->retrans_list,
2189 bt_cb(skb)->control.txseq);
2190 }
2191
2192 l2cap_ertm_resend(chan);
2193 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002194}
2195
Szymon Jancb17e73b2012-01-11 10:59:47 +01002196static void l2cap_send_ack(struct l2cap_chan *chan)
2197{
Mat Martineau0a0aba42012-05-17 20:53:39 -07002198 struct l2cap_ctrl control;
2199 u16 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
2200 chan->last_acked_seq);
2201 int threshold;
2202
2203 BT_DBG("chan %p last_acked_seq %d buffer_seq %d",
2204 chan, chan->last_acked_seq, chan->buffer_seq);
2205
2206 memset(&control, 0, sizeof(control));
2207 control.sframe = 1;
2208
2209 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
2210 chan->rx_state == L2CAP_RX_STATE_RECV) {
2211 __clear_ack_timer(chan);
2212 control.super = L2CAP_SUPER_RNR;
2213 control.reqseq = chan->buffer_seq;
2214 l2cap_send_sframe(chan, &control);
2215 } else {
2216 if (!test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) {
2217 l2cap_ertm_send(chan);
2218 /* If any i-frames were sent, they included an ack */
2219 if (chan->buffer_seq == chan->last_acked_seq)
2220 frames_to_ack = 0;
2221 }
2222
Mat Martineauc20f8e32012-07-10 05:47:07 -07002223 /* Ack now if the window is 3/4ths full.
Mat Martineau0a0aba42012-05-17 20:53:39 -07002224 * Calculate without mul or div
2225 */
Mat Martineauc20f8e32012-07-10 05:47:07 -07002226 threshold = chan->ack_win;
Mat Martineau0a0aba42012-05-17 20:53:39 -07002227 threshold += threshold << 1;
2228 threshold >>= 2;
2229
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002230 BT_DBG("frames_to_ack %u, threshold %d", frames_to_ack,
Mat Martineau0a0aba42012-05-17 20:53:39 -07002231 threshold);
2232
2233 if (frames_to_ack >= threshold) {
2234 __clear_ack_timer(chan);
2235 control.super = L2CAP_SUPER_RR;
2236 control.reqseq = chan->buffer_seq;
2237 l2cap_send_sframe(chan, &control);
2238 frames_to_ack = 0;
2239 }
2240
2241 if (frames_to_ack)
2242 __set_ack_timer(chan);
2243 }
Szymon Jancb17e73b2012-01-11 10:59:47 +01002244}
2245
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002246static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
2247 struct msghdr *msg, int len,
2248 int count, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002249{
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002250 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002251 struct sk_buff **frag;
Gustavo Padovan90338942012-04-06 20:15:47 -03002252 int sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002253
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03002254 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002255 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002256
2257 sent += count;
2258 len -= count;
2259
2260 /* Continuation fragments (no L2CAP header) */
2261 frag = &skb_shinfo(skb)->frag_list;
2262 while (len) {
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002263 struct sk_buff *tmp;
2264
Linus Torvalds1da177e2005-04-16 15:20:36 -07002265 count = min_t(unsigned int, conn->mtu, len);
2266
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002267 tmp = chan->ops->alloc_skb(chan, count,
2268 msg->msg_flags & MSG_DONTWAIT);
2269 if (IS_ERR(tmp))
2270 return PTR_ERR(tmp);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002271
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002272 *frag = tmp;
2273
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002274 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
2275 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002276
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002277 (*frag)->priority = skb->priority;
2278
Linus Torvalds1da177e2005-04-16 15:20:36 -07002279 sent += count;
2280 len -= count;
2281
Gustavo Padovan2d0ed3d2012-05-11 13:16:12 -03002282 skb->len += (*frag)->len;
2283 skb->data_len += (*frag)->len;
2284
Linus Torvalds1da177e2005-04-16 15:20:36 -07002285 frag = &(*frag)->next;
2286 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002287
2288 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002289}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002290
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002291static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002292 struct msghdr *msg, size_t len,
2293 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002294{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002295 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002296 struct sk_buff *skb;
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002297 int err, count, hlen = L2CAP_HDR_SIZE + L2CAP_PSMLEN_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002298 struct l2cap_hdr *lh;
2299
Marcel Holtmann43b1b8d2013-10-12 06:01:26 -07002300 BT_DBG("chan %p psm 0x%2.2x len %zu priority %u", chan,
2301 __le16_to_cpu(chan->psm), len, priority);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002302
2303 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002304
2305 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002306 msg->msg_flags & MSG_DONTWAIT);
2307 if (IS_ERR(skb))
2308 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002309
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002310 skb->priority = priority;
2311
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002312 /* Create L2CAP header */
2313 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002314 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenkodaf6a78c2012-05-03 10:55:52 +03002315 lh->len = cpu_to_le16(len + L2CAP_PSMLEN_SIZE);
Marcel Holtmann43b1b8d2013-10-12 06:01:26 -07002316 put_unaligned(chan->psm, (__le16 *) skb_put(skb, L2CAP_PSMLEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002317
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002318 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002319 if (unlikely(err < 0)) {
2320 kfree_skb(skb);
2321 return ERR_PTR(err);
2322 }
2323 return skb;
2324}
2325
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002326static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002327 struct msghdr *msg, size_t len,
2328 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002329{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002330 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002331 struct sk_buff *skb;
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002332 int err, count;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002333 struct l2cap_hdr *lh;
2334
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002335 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002336
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002337 count = min_t(unsigned int, (conn->mtu - L2CAP_HDR_SIZE), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002338
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002339 skb = chan->ops->alloc_skb(chan, count + L2CAP_HDR_SIZE,
Gustavo Padovan90338942012-04-06 20:15:47 -03002340 msg->msg_flags & MSG_DONTWAIT);
2341 if (IS_ERR(skb))
2342 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002343
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002344 skb->priority = priority;
2345
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002346 /* Create L2CAP header */
2347 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002348 lh->cid = cpu_to_le16(chan->dcid);
Gustavo Padovan6ff9b5e2012-05-02 11:56:17 -03002349 lh->len = cpu_to_le16(len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002350
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002351 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002352 if (unlikely(err < 0)) {
2353 kfree_skb(skb);
2354 return ERR_PTR(err);
2355 }
2356 return skb;
2357}
2358
Luiz Augusto von Dentzab0ff762011-09-12 20:00:50 +03002359static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002360 struct msghdr *msg, size_t len,
2361 u16 sdulen)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002362{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002363 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002364 struct sk_buff *skb;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002365 int err, count, hlen;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002366 struct l2cap_hdr *lh;
2367
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002368 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002369
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03002370 if (!conn)
2371 return ERR_PTR(-ENOTCONN);
2372
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002373 hlen = __ertm_hdr_size(chan);
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002374
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002375 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002376 hlen += L2CAP_SDULEN_SIZE;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002377
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002378 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002379 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002380
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002381 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002382
2383 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002384 msg->msg_flags & MSG_DONTWAIT);
2385 if (IS_ERR(skb))
2386 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002387
2388 /* Create L2CAP header */
2389 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002390 lh->cid = cpu_to_le16(chan->dcid);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002391 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002392
Mat Martineau18a48e72012-05-17 20:53:34 -07002393 /* Control header is populated later */
2394 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
2395 put_unaligned_le32(0, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
2396 else
2397 put_unaligned_le16(0, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002398
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002399 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002400 put_unaligned_le16(sdulen, skb_put(skb, L2CAP_SDULEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002401
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002402 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002403 if (unlikely(err < 0)) {
2404 kfree_skb(skb);
2405 return ERR_PTR(err);
2406 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002407
Mat Martineau18a48e72012-05-17 20:53:34 -07002408 bt_cb(skb)->control.fcs = chan->fcs;
Mat Martineau3ce35142012-04-25 16:36:14 -07002409 bt_cb(skb)->control.retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002410 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002411}
2412
Mat Martineau94122bb2012-05-02 09:42:02 -07002413static int l2cap_segment_sdu(struct l2cap_chan *chan,
2414 struct sk_buff_head *seg_queue,
2415 struct msghdr *msg, size_t len)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002416{
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002417 struct sk_buff *skb;
Mat Martineau94122bb2012-05-02 09:42:02 -07002418 u16 sdu_len;
2419 size_t pdu_len;
Mat Martineau94122bb2012-05-02 09:42:02 -07002420 u8 sar;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002421
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002422 BT_DBG("chan %p, msg %p, len %zu", chan, msg, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002423
Mat Martineau94122bb2012-05-02 09:42:02 -07002424 /* It is critical that ERTM PDUs fit in a single HCI fragment,
2425 * so fragmented skbs are not used. The HCI layer's handling
2426 * of fragmented skbs is not compatible with ERTM's queueing.
2427 */
2428
2429 /* PDU size is derived from the HCI MTU */
2430 pdu_len = chan->conn->mtu;
2431
Mat Martineaua5495742012-10-23 15:24:21 -07002432 /* Constrain PDU size for BR/EDR connections */
2433 if (!chan->hs_hcon)
2434 pdu_len = min_t(size_t, pdu_len, L2CAP_BREDR_MAX_PAYLOAD);
Mat Martineau94122bb2012-05-02 09:42:02 -07002435
2436 /* Adjust for largest possible L2CAP overhead. */
Gustavo Padovan35d401d2012-05-25 18:57:05 -03002437 if (chan->fcs)
2438 pdu_len -= L2CAP_FCS_SIZE;
2439
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002440 pdu_len -= __ertm_hdr_size(chan);
Mat Martineau94122bb2012-05-02 09:42:02 -07002441
2442 /* Remote device may have requested smaller PDUs */
2443 pdu_len = min_t(size_t, pdu_len, chan->remote_mps);
2444
2445 if (len <= pdu_len) {
2446 sar = L2CAP_SAR_UNSEGMENTED;
2447 sdu_len = 0;
2448 pdu_len = len;
2449 } else {
2450 sar = L2CAP_SAR_START;
2451 sdu_len = len;
2452 pdu_len -= L2CAP_SDULEN_SIZE;
2453 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002454
2455 while (len > 0) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002456 skb = l2cap_create_iframe_pdu(chan, msg, pdu_len, sdu_len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002457
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002458 if (IS_ERR(skb)) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002459 __skb_queue_purge(seg_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002460 return PTR_ERR(skb);
2461 }
2462
Mat Martineau94122bb2012-05-02 09:42:02 -07002463 bt_cb(skb)->control.sar = sar;
2464 __skb_queue_tail(seg_queue, skb);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002465
Mat Martineau94122bb2012-05-02 09:42:02 -07002466 len -= pdu_len;
2467 if (sdu_len) {
2468 sdu_len = 0;
2469 pdu_len += L2CAP_SDULEN_SIZE;
2470 }
2471
2472 if (len <= pdu_len) {
2473 sar = L2CAP_SAR_END;
2474 pdu_len = len;
2475 } else {
2476 sar = L2CAP_SAR_CONTINUE;
2477 }
2478 }
2479
Gustavo Padovanf0f62792012-05-29 13:29:17 -03002480 return 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002481}
2482
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002483int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01002484 u32 priority)
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002485{
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002486 struct sk_buff *skb;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002487 int err;
Mat Martineau94122bb2012-05-02 09:42:02 -07002488 struct sk_buff_head seg_queue;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002489
2490 /* Connectionless channel */
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002491 if (chan->chan_type == L2CAP_CHAN_CONN_LESS) {
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002492 skb = l2cap_create_connless_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002493 if (IS_ERR(skb))
2494 return PTR_ERR(skb);
2495
2496 l2cap_do_send(chan, skb);
2497 return len;
2498 }
2499
2500 switch (chan->mode) {
2501 case L2CAP_MODE_BASIC:
2502 /* Check outgoing MTU */
2503 if (len > chan->omtu)
2504 return -EMSGSIZE;
2505
2506 /* Create a basic PDU */
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002507 skb = l2cap_create_basic_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002508 if (IS_ERR(skb))
2509 return PTR_ERR(skb);
2510
2511 l2cap_do_send(chan, skb);
2512 err = len;
2513 break;
2514
2515 case L2CAP_MODE_ERTM:
2516 case L2CAP_MODE_STREAMING:
Mat Martineau94122bb2012-05-02 09:42:02 -07002517 /* Check outgoing MTU */
2518 if (len > chan->omtu) {
2519 err = -EMSGSIZE;
2520 break;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002521 }
2522
Mat Martineau94122bb2012-05-02 09:42:02 -07002523 __skb_queue_head_init(&seg_queue);
2524
2525 /* Do segmentation before calling in to the state machine,
2526 * since it's possible to block while waiting for memory
2527 * allocation.
2528 */
2529 err = l2cap_segment_sdu(chan, &seg_queue, msg, len);
2530
2531 /* The channel could have been closed while segmenting,
2532 * check that it is still connected.
2533 */
2534 if (chan->state != BT_CONNECTED) {
2535 __skb_queue_purge(&seg_queue);
2536 err = -ENOTCONN;
2537 }
2538
2539 if (err)
2540 break;
2541
Mat Martineau37339372012-05-17 20:53:33 -07002542 if (chan->mode == L2CAP_MODE_ERTM)
Gustavo Padovand6603662012-05-21 13:58:22 -03002543 l2cap_tx(chan, NULL, &seg_queue, L2CAP_EV_DATA_REQUEST);
Mat Martineau37339372012-05-17 20:53:33 -07002544 else
Gustavo Padovand6603662012-05-21 13:58:22 -03002545 l2cap_streaming_send(chan, &seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002546
Gustavo Padovand6603662012-05-21 13:58:22 -03002547 err = len;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002548
Mat Martineau94122bb2012-05-02 09:42:02 -07002549 /* If the skbs were not queued for sending, they'll still be in
2550 * seg_queue and need to be purged.
2551 */
2552 __skb_queue_purge(&seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002553 break;
2554
2555 default:
2556 BT_DBG("bad state %1.1x", chan->mode);
2557 err = -EBADFD;
2558 }
2559
2560 return err;
2561}
2562
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002563static void l2cap_send_srej(struct l2cap_chan *chan, u16 txseq)
2564{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002565 struct l2cap_ctrl control;
2566 u16 seq;
2567
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002568 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002569
2570 memset(&control, 0, sizeof(control));
2571 control.sframe = 1;
2572 control.super = L2CAP_SUPER_SREJ;
2573
2574 for (seq = chan->expected_tx_seq; seq != txseq;
2575 seq = __next_seq(chan, seq)) {
2576 if (!l2cap_ertm_seq_in_queue(&chan->srej_q, seq)) {
2577 control.reqseq = seq;
2578 l2cap_send_sframe(chan, &control);
2579 l2cap_seq_list_append(&chan->srej_list, seq);
2580 }
2581 }
2582
2583 chan->expected_tx_seq = __next_seq(chan, txseq);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002584}
2585
2586static void l2cap_send_srej_tail(struct l2cap_chan *chan)
2587{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002588 struct l2cap_ctrl control;
2589
2590 BT_DBG("chan %p", chan);
2591
2592 if (chan->srej_list.tail == L2CAP_SEQ_LIST_CLEAR)
2593 return;
2594
2595 memset(&control, 0, sizeof(control));
2596 control.sframe = 1;
2597 control.super = L2CAP_SUPER_SREJ;
2598 control.reqseq = chan->srej_list.tail;
2599 l2cap_send_sframe(chan, &control);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002600}
2601
2602static void l2cap_send_srej_list(struct l2cap_chan *chan, u16 txseq)
2603{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002604 struct l2cap_ctrl control;
2605 u16 initial_head;
2606 u16 seq;
2607
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002608 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002609
2610 memset(&control, 0, sizeof(control));
2611 control.sframe = 1;
2612 control.super = L2CAP_SUPER_SREJ;
2613
2614 /* Capture initial list head to allow only one pass through the list. */
2615 initial_head = chan->srej_list.head;
2616
2617 do {
2618 seq = l2cap_seq_list_pop(&chan->srej_list);
2619 if (seq == txseq || seq == L2CAP_SEQ_LIST_CLEAR)
2620 break;
2621
2622 control.reqseq = seq;
2623 l2cap_send_sframe(chan, &control);
2624 l2cap_seq_list_append(&chan->srej_list, seq);
2625 } while (chan->srej_list.head != initial_head);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002626}
2627
Mat Martineau608bcc62012-05-17 20:53:32 -07002628static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq)
2629{
2630 struct sk_buff *acked_skb;
2631 u16 ackseq;
2632
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002633 BT_DBG("chan %p, reqseq %u", chan, reqseq);
Mat Martineau608bcc62012-05-17 20:53:32 -07002634
2635 if (chan->unacked_frames == 0 || reqseq == chan->expected_ack_seq)
2636 return;
2637
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002638 BT_DBG("expected_ack_seq %u, unacked_frames %u",
Mat Martineau608bcc62012-05-17 20:53:32 -07002639 chan->expected_ack_seq, chan->unacked_frames);
2640
2641 for (ackseq = chan->expected_ack_seq; ackseq != reqseq;
2642 ackseq = __next_seq(chan, ackseq)) {
2643
2644 acked_skb = l2cap_ertm_seq_in_queue(&chan->tx_q, ackseq);
2645 if (acked_skb) {
2646 skb_unlink(acked_skb, &chan->tx_q);
2647 kfree_skb(acked_skb);
2648 chan->unacked_frames--;
2649 }
2650 }
2651
2652 chan->expected_ack_seq = reqseq;
2653
2654 if (chan->unacked_frames == 0)
2655 __clear_retrans_timer(chan);
2656
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002657 BT_DBG("unacked_frames %u", chan->unacked_frames);
Mat Martineau608bcc62012-05-17 20:53:32 -07002658}
2659
2660static void l2cap_abort_rx_srej_sent(struct l2cap_chan *chan)
2661{
2662 BT_DBG("chan %p", chan);
2663
2664 chan->expected_tx_seq = chan->buffer_seq;
2665 l2cap_seq_list_clear(&chan->srej_list);
2666 skb_queue_purge(&chan->srej_q);
2667 chan->rx_state = L2CAP_RX_STATE_RECV;
2668}
2669
Gustavo Padovand6603662012-05-21 13:58:22 -03002670static void l2cap_tx_state_xmit(struct l2cap_chan *chan,
2671 struct l2cap_ctrl *control,
2672 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002673{
Mat Martineau608bcc62012-05-17 20:53:32 -07002674 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2675 event);
2676
2677 switch (event) {
2678 case L2CAP_EV_DATA_REQUEST:
2679 if (chan->tx_send_head == NULL)
2680 chan->tx_send_head = skb_peek(skbs);
2681
2682 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2683 l2cap_ertm_send(chan);
2684 break;
2685 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2686 BT_DBG("Enter LOCAL_BUSY");
2687 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2688
2689 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2690 /* The SREJ_SENT state must be aborted if we are to
2691 * enter the LOCAL_BUSY state.
2692 */
2693 l2cap_abort_rx_srej_sent(chan);
2694 }
2695
2696 l2cap_send_ack(chan);
2697
2698 break;
2699 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2700 BT_DBG("Exit LOCAL_BUSY");
2701 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2702
2703 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2704 struct l2cap_ctrl local_control;
2705
2706 memset(&local_control, 0, sizeof(local_control));
2707 local_control.sframe = 1;
2708 local_control.super = L2CAP_SUPER_RR;
2709 local_control.poll = 1;
2710 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002711 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002712
2713 chan->retry_count = 1;
2714 __set_monitor_timer(chan);
2715 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2716 }
2717 break;
2718 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2719 l2cap_process_reqseq(chan, control->reqseq);
2720 break;
2721 case L2CAP_EV_EXPLICIT_POLL:
2722 l2cap_send_rr_or_rnr(chan, 1);
2723 chan->retry_count = 1;
2724 __set_monitor_timer(chan);
2725 __clear_ack_timer(chan);
2726 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2727 break;
2728 case L2CAP_EV_RETRANS_TO:
2729 l2cap_send_rr_or_rnr(chan, 1);
2730 chan->retry_count = 1;
2731 __set_monitor_timer(chan);
2732 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2733 break;
2734 case L2CAP_EV_RECV_FBIT:
2735 /* Nothing to process */
2736 break;
2737 default:
2738 break;
2739 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002740}
2741
Gustavo Padovand6603662012-05-21 13:58:22 -03002742static void l2cap_tx_state_wait_f(struct l2cap_chan *chan,
2743 struct l2cap_ctrl *control,
2744 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002745{
Mat Martineau608bcc62012-05-17 20:53:32 -07002746 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2747 event);
2748
2749 switch (event) {
2750 case L2CAP_EV_DATA_REQUEST:
2751 if (chan->tx_send_head == NULL)
2752 chan->tx_send_head = skb_peek(skbs);
2753 /* Queue data, but don't send. */
2754 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2755 break;
2756 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2757 BT_DBG("Enter LOCAL_BUSY");
2758 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2759
2760 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2761 /* The SREJ_SENT state must be aborted if we are to
2762 * enter the LOCAL_BUSY state.
2763 */
2764 l2cap_abort_rx_srej_sent(chan);
2765 }
2766
2767 l2cap_send_ack(chan);
2768
2769 break;
2770 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2771 BT_DBG("Exit LOCAL_BUSY");
2772 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2773
2774 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2775 struct l2cap_ctrl local_control;
2776 memset(&local_control, 0, sizeof(local_control));
2777 local_control.sframe = 1;
2778 local_control.super = L2CAP_SUPER_RR;
2779 local_control.poll = 1;
2780 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002781 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002782
2783 chan->retry_count = 1;
2784 __set_monitor_timer(chan);
2785 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2786 }
2787 break;
2788 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2789 l2cap_process_reqseq(chan, control->reqseq);
2790
2791 /* Fall through */
2792
2793 case L2CAP_EV_RECV_FBIT:
2794 if (control && control->final) {
2795 __clear_monitor_timer(chan);
2796 if (chan->unacked_frames > 0)
2797 __set_retrans_timer(chan);
2798 chan->retry_count = 0;
2799 chan->tx_state = L2CAP_TX_STATE_XMIT;
2800 BT_DBG("recv fbit tx_state 0x2.2%x", chan->tx_state);
2801 }
2802 break;
2803 case L2CAP_EV_EXPLICIT_POLL:
2804 /* Ignore */
2805 break;
2806 case L2CAP_EV_MONITOR_TO:
2807 if (chan->max_tx == 0 || chan->retry_count < chan->max_tx) {
2808 l2cap_send_rr_or_rnr(chan, 1);
2809 __set_monitor_timer(chan);
2810 chan->retry_count++;
2811 } else {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02002812 l2cap_send_disconn_req(chan, ECONNABORTED);
Mat Martineau608bcc62012-05-17 20:53:32 -07002813 }
2814 break;
2815 default:
2816 break;
2817 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002818}
2819
Gustavo Padovand6603662012-05-21 13:58:22 -03002820static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
2821 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002822{
Mat Martineau608bcc62012-05-17 20:53:32 -07002823 BT_DBG("chan %p, control %p, skbs %p, event %d, state %d",
2824 chan, control, skbs, event, chan->tx_state);
2825
2826 switch (chan->tx_state) {
2827 case L2CAP_TX_STATE_XMIT:
Gustavo Padovand6603662012-05-21 13:58:22 -03002828 l2cap_tx_state_xmit(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002829 break;
2830 case L2CAP_TX_STATE_WAIT_F:
Gustavo Padovand6603662012-05-21 13:58:22 -03002831 l2cap_tx_state_wait_f(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002832 break;
2833 default:
2834 /* Ignore event */
2835 break;
2836 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002837}
2838
Mat Martineau4b51dae92012-05-17 20:53:37 -07002839static void l2cap_pass_to_tx(struct l2cap_chan *chan,
2840 struct l2cap_ctrl *control)
2841{
2842 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002843 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_REQSEQ_AND_FBIT);
Mat Martineau4b51dae92012-05-17 20:53:37 -07002844}
2845
Mat Martineauf80842a2012-05-17 20:53:46 -07002846static void l2cap_pass_to_tx_fbit(struct l2cap_chan *chan,
2847 struct l2cap_ctrl *control)
2848{
2849 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002850 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_FBIT);
Mat Martineauf80842a2012-05-17 20:53:46 -07002851}
2852
Linus Torvalds1da177e2005-04-16 15:20:36 -07002853/* Copy frame to all raw sockets on that connection */
2854static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2855{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002856 struct sk_buff *nskb;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002857 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002858
2859 BT_DBG("conn %p", conn);
2860
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002861 mutex_lock(&conn->chan_lock);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002862
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002863 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002864 struct sock *sk = chan->sk;
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002865 if (chan->chan_type != L2CAP_CHAN_RAW)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002866 continue;
2867
2868 /* Don't send frame to the socket it came from */
2869 if (skb->sk == sk)
2870 continue;
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002871 nskb = skb_clone(skb, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002872 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002873 continue;
2874
Gustavo Padovan80b98022012-05-27 22:27:51 -03002875 if (chan->ops->recv(chan, nskb))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002876 kfree_skb(nskb);
2877 }
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002878
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002879 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002880}
2881
2882/* ---- L2CAP signalling commands ---- */
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002883static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code,
2884 u8 ident, u16 dlen, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002885{
2886 struct sk_buff *skb, **frag;
2887 struct l2cap_cmd_hdr *cmd;
2888 struct l2cap_hdr *lh;
2889 int len, count;
2890
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002891 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %u",
2892 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002893
Anderson Lizardo300b9622013-06-02 16:30:40 -04002894 if (conn->mtu < L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE)
2895 return NULL;
2896
Linus Torvalds1da177e2005-04-16 15:20:36 -07002897 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2898 count = min_t(unsigned int, conn->mtu, len);
2899
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002900 skb = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002901 if (!skb)
2902 return NULL;
2903
2904 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002905 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002906
2907 if (conn->hcon->type == LE_LINK)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002908 lh->cid = __constant_cpu_to_le16(L2CAP_CID_LE_SIGNALING);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002909 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002910 lh->cid = __constant_cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002911
2912 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2913 cmd->code = code;
2914 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002915 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002916
2917 if (dlen) {
2918 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2919 memcpy(skb_put(skb, count), data, count);
2920 data += count;
2921 }
2922
2923 len -= skb->len;
2924
2925 /* Continuation fragments (no L2CAP header) */
2926 frag = &skb_shinfo(skb)->frag_list;
2927 while (len) {
2928 count = min_t(unsigned int, conn->mtu, len);
2929
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002930 *frag = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002931 if (!*frag)
2932 goto fail;
2933
2934 memcpy(skb_put(*frag, count), data, count);
2935
2936 len -= count;
2937 data += count;
2938
2939 frag = &(*frag)->next;
2940 }
2941
2942 return skb;
2943
2944fail:
2945 kfree_skb(skb);
2946 return NULL;
2947}
2948
Gustavo Padovan2d792812012-10-06 10:07:01 +01002949static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen,
2950 unsigned long *val)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002951{
2952 struct l2cap_conf_opt *opt = *ptr;
2953 int len;
2954
2955 len = L2CAP_CONF_OPT_SIZE + opt->len;
2956 *ptr += len;
2957
2958 *type = opt->type;
2959 *olen = opt->len;
2960
2961 switch (opt->len) {
2962 case 1:
2963 *val = *((u8 *) opt->val);
2964 break;
2965
2966 case 2:
steven miaobfaaeb32010-10-16 18:29:47 -04002967 *val = get_unaligned_le16(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002968 break;
2969
2970 case 4:
steven miaobfaaeb32010-10-16 18:29:47 -04002971 *val = get_unaligned_le32(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002972 break;
2973
2974 default:
2975 *val = (unsigned long) opt->val;
2976 break;
2977 }
2978
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002979 BT_DBG("type 0x%2.2x len %u val 0x%lx", *type, opt->len, *val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002980 return len;
2981}
2982
Linus Torvalds1da177e2005-04-16 15:20:36 -07002983static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2984{
2985 struct l2cap_conf_opt *opt = *ptr;
2986
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002987 BT_DBG("type 0x%2.2x len %u val 0x%lx", type, len, val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002988
2989 opt->type = type;
2990 opt->len = len;
2991
2992 switch (len) {
2993 case 1:
2994 *((u8 *) opt->val) = val;
2995 break;
2996
2997 case 2:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002998 put_unaligned_le16(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002999 break;
3000
3001 case 4:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02003002 put_unaligned_le32(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003003 break;
3004
3005 default:
3006 memcpy(opt->val, (void *) val, len);
3007 break;
3008 }
3009
3010 *ptr += L2CAP_CONF_OPT_SIZE + len;
3011}
3012
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003013static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan)
3014{
3015 struct l2cap_conf_efs efs;
3016
Szymon Janc1ec918c2011-11-16 09:32:21 +01003017 switch (chan->mode) {
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003018 case L2CAP_MODE_ERTM:
3019 efs.id = chan->local_id;
3020 efs.stype = chan->local_stype;
3021 efs.msdu = cpu_to_le16(chan->local_msdu);
3022 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003023 efs.acc_lat = __constant_cpu_to_le32(L2CAP_DEFAULT_ACC_LAT);
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03003024 efs.flush_to = __constant_cpu_to_le32(L2CAP_EFS_DEFAULT_FLUSH_TO);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003025 break;
3026
3027 case L2CAP_MODE_STREAMING:
3028 efs.id = 1;
3029 efs.stype = L2CAP_SERV_BESTEFFORT;
3030 efs.msdu = cpu_to_le16(chan->local_msdu);
3031 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
3032 efs.acc_lat = 0;
3033 efs.flush_to = 0;
3034 break;
3035
3036 default:
3037 return;
3038 }
3039
3040 l2cap_add_conf_opt(ptr, L2CAP_CONF_EFS, sizeof(efs),
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03003041 (unsigned long) &efs);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003042}
3043
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003044static void l2cap_ack_timeout(struct work_struct *work)
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003045{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003046 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau03625202012-05-17 20:53:51 -07003047 ack_timer.work);
3048 u16 frames_to_ack;
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003049
Gustavo F. Padovan2fb9b3d2011-12-22 16:56:05 -02003050 BT_DBG("chan %p", chan);
3051
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003052 l2cap_chan_lock(chan);
3053
Mat Martineau03625202012-05-17 20:53:51 -07003054 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
3055 chan->last_acked_seq);
3056
3057 if (frames_to_ack)
3058 l2cap_send_rr_or_rnr(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003059
3060 l2cap_chan_unlock(chan);
Szymon Janc09bfb2e2012-01-11 10:59:49 +01003061 l2cap_chan_put(chan);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003062}
3063
Andrei Emeltchenko466f8002012-05-29 13:59:01 +03003064int l2cap_ertm_init(struct l2cap_chan *chan)
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003065{
Mat Martineau3c588192012-04-11 10:48:42 -07003066 int err;
3067
Mat Martineau105bdf92012-04-27 16:50:48 -07003068 chan->next_tx_seq = 0;
3069 chan->expected_tx_seq = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03003070 chan->expected_ack_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03003071 chan->unacked_frames = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03003072 chan->buffer_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03003073 chan->frames_sent = 0;
Mat Martineau105bdf92012-04-27 16:50:48 -07003074 chan->last_acked_seq = 0;
3075 chan->sdu = NULL;
3076 chan->sdu_last_frag = NULL;
3077 chan->sdu_len = 0;
3078
Mat Martineaud34c34f2012-05-14 14:49:27 -07003079 skb_queue_head_init(&chan->tx_q);
3080
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003081 chan->local_amp_id = AMP_ID_BREDR;
3082 chan->move_id = AMP_ID_BREDR;
Mat Martineau08333282012-10-23 15:24:06 -07003083 chan->move_state = L2CAP_MOVE_STABLE;
3084 chan->move_role = L2CAP_MOVE_ROLE_NONE;
3085
Mat Martineau105bdf92012-04-27 16:50:48 -07003086 if (chan->mode != L2CAP_MODE_ERTM)
3087 return 0;
3088
3089 chan->rx_state = L2CAP_RX_STATE_RECV;
3090 chan->tx_state = L2CAP_TX_STATE_XMIT;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003091
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003092 INIT_DELAYED_WORK(&chan->retrans_timer, l2cap_retrans_timeout);
3093 INIT_DELAYED_WORK(&chan->monitor_timer, l2cap_monitor_timeout);
3094 INIT_DELAYED_WORK(&chan->ack_timer, l2cap_ack_timeout);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003095
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -03003096 skb_queue_head_init(&chan->srej_q);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003097
Mat Martineau3c588192012-04-11 10:48:42 -07003098 err = l2cap_seq_list_init(&chan->srej_list, chan->tx_win);
3099 if (err < 0)
3100 return err;
3101
Mat Martineau9dc9aff2012-05-17 16:20:14 -07003102 err = l2cap_seq_list_init(&chan->retrans_list, chan->remote_tx_win);
3103 if (err < 0)
3104 l2cap_seq_list_free(&chan->srej_list);
3105
3106 return err;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003107}
3108
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003109static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
3110{
3111 switch (mode) {
3112 case L2CAP_MODE_STREAMING:
3113 case L2CAP_MODE_ERTM:
3114 if (l2cap_mode_supported(mode, remote_feat_mask))
3115 return mode;
3116 /* fall through */
3117 default:
3118 return L2CAP_MODE_BASIC;
3119 }
3120}
3121
Marcel Holtmann848566b2013-10-01 22:59:22 -07003122static inline bool __l2cap_ews_supported(struct l2cap_conn *conn)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003123{
Marcel Holtmann848566b2013-10-01 22:59:22 -07003124 return conn->hs_enabled && conn->feat_mask & L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003125}
3126
Marcel Holtmann848566b2013-10-01 22:59:22 -07003127static inline bool __l2cap_efs_supported(struct l2cap_conn *conn)
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003128{
Marcel Holtmann848566b2013-10-01 22:59:22 -07003129 return conn->hs_enabled && conn->feat_mask & L2CAP_FEAT_EXT_FLOW;
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003130}
3131
Mat Martineau36c86c82012-10-23 15:24:20 -07003132static void __l2cap_set_ertm_timeouts(struct l2cap_chan *chan,
3133 struct l2cap_conf_rfc *rfc)
3134{
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003135 if (chan->local_amp_id != AMP_ID_BREDR && chan->hs_hcon) {
Mat Martineau36c86c82012-10-23 15:24:20 -07003136 u64 ertm_to = chan->hs_hcon->hdev->amp_be_flush_to;
3137
3138 /* Class 1 devices have must have ERTM timeouts
3139 * exceeding the Link Supervision Timeout. The
3140 * default Link Supervision Timeout for AMP
3141 * controllers is 10 seconds.
3142 *
3143 * Class 1 devices use 0xffffffff for their
3144 * best-effort flush timeout, so the clamping logic
3145 * will result in a timeout that meets the above
3146 * requirement. ERTM timeouts are 16-bit values, so
3147 * the maximum timeout is 65.535 seconds.
3148 */
3149
3150 /* Convert timeout to milliseconds and round */
3151 ertm_to = DIV_ROUND_UP_ULL(ertm_to, 1000);
3152
3153 /* This is the recommended formula for class 2 devices
3154 * that start ERTM timers when packets are sent to the
3155 * controller.
3156 */
3157 ertm_to = 3 * ertm_to + 500;
3158
3159 if (ertm_to > 0xffff)
3160 ertm_to = 0xffff;
3161
3162 rfc->retrans_timeout = cpu_to_le16((u16) ertm_to);
3163 rfc->monitor_timeout = rfc->retrans_timeout;
3164 } else {
3165 rfc->retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
3166 rfc->monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
3167 }
3168}
3169
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003170static inline void l2cap_txwin_setup(struct l2cap_chan *chan)
3171{
3172 if (chan->tx_win > L2CAP_DEFAULT_TX_WINDOW &&
Marcel Holtmann848566b2013-10-01 22:59:22 -07003173 __l2cap_ews_supported(chan->conn)) {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003174 /* use extended control field */
3175 set_bit(FLAG_EXT_CTRL, &chan->flags);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003176 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
3177 } else {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003178 chan->tx_win = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003179 L2CAP_DEFAULT_TX_WINDOW);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003180 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
3181 }
Mat Martineauc20f8e32012-07-10 05:47:07 -07003182 chan->ack_win = chan->tx_win;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003183}
3184
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003185static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003186{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003187 struct l2cap_conf_req *req = data;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003188 struct l2cap_conf_rfc rfc = { .mode = chan->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07003189 void *ptr = req->data;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003190 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003191
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03003192 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003193
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003194 if (chan->num_conf_req || chan->num_conf_rsp)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003195 goto done;
3196
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003197 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003198 case L2CAP_MODE_STREAMING:
3199 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003200 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state))
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003201 break;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003202
Marcel Holtmann848566b2013-10-01 22:59:22 -07003203 if (__l2cap_efs_supported(chan->conn))
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003204 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3205
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03003206 /* fall through */
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003207 default:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003208 chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003209 break;
3210 }
3211
3212done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003213 if (chan->imtu != L2CAP_DEFAULT_MTU)
3214 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovan7990681c2011-01-24 16:01:43 -02003215
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003216 switch (chan->mode) {
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003217 case L2CAP_MODE_BASIC:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003218 if (!(chan->conn->feat_mask & L2CAP_FEAT_ERTM) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003219 !(chan->conn->feat_mask & L2CAP_FEAT_STREAMING))
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003220 break;
3221
Gustavo F. Padovan62547752010-06-08 20:05:31 -03003222 rfc.mode = L2CAP_MODE_BASIC;
3223 rfc.txwin_size = 0;
3224 rfc.max_transmit = 0;
3225 rfc.retrans_timeout = 0;
3226 rfc.monitor_timeout = 0;
3227 rfc.max_pdu_size = 0;
3228
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003229 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003230 (unsigned long) &rfc);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003231 break;
3232
3233 case L2CAP_MODE_ERTM:
3234 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003235 rfc.max_transmit = chan->max_tx;
Mat Martineau36c86c82012-10-23 15:24:20 -07003236
3237 __l2cap_set_ertm_timeouts(chan, &rfc);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003238
3239 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003240 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3241 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003242 rfc.max_pdu_size = cpu_to_le16(size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003243
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003244 l2cap_txwin_setup(chan);
3245
3246 rfc.txwin_size = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003247 L2CAP_DEFAULT_TX_WINDOW);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003248
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003249 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003250 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003251
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003252 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3253 l2cap_add_opt_efs(&ptr, chan);
3254
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003255 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3256 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003257 chan->tx_win);
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003258
3259 if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
3260 if (chan->fcs == L2CAP_FCS_NONE ||
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003261 test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003262 chan->fcs = L2CAP_FCS_NONE;
3263 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
3264 chan->fcs);
3265 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003266 break;
3267
3268 case L2CAP_MODE_STREAMING:
Mat Martineau273759e2012-05-17 20:53:53 -07003269 l2cap_txwin_setup(chan);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003270 rfc.mode = L2CAP_MODE_STREAMING;
3271 rfc.txwin_size = 0;
3272 rfc.max_transmit = 0;
3273 rfc.retrans_timeout = 0;
3274 rfc.monitor_timeout = 0;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003275
3276 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003277 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3278 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003279 rfc.max_pdu_size = cpu_to_le16(size);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003280
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003281 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003282 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003283
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003284 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3285 l2cap_add_opt_efs(&ptr, chan);
3286
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003287 if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
3288 if (chan->fcs == L2CAP_FCS_NONE ||
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003289 test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003290 chan->fcs = L2CAP_FCS_NONE;
3291 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
3292 chan->fcs);
3293 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003294 break;
3295 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003296
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003297 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003298 req->flags = __constant_cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003299
3300 return ptr - data;
3301}
3302
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003303static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003304{
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003305 struct l2cap_conf_rsp *rsp = data;
3306 void *ptr = rsp->data;
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003307 void *req = chan->conf_req;
3308 int len = chan->conf_len;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003309 int type, hint, olen;
3310 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003311 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003312 struct l2cap_conf_efs efs;
3313 u8 remote_efs = 0;
Marcel Holtmann861d6882007-10-20 13:37:06 +02003314 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003315 u16 result = L2CAP_CONF_SUCCESS;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003316 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003317
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003318 BT_DBG("chan %p", chan);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01003319
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003320 while (len >= L2CAP_CONF_OPT_SIZE) {
3321 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003322
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03003323 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003324 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003325
3326 switch (type) {
3327 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02003328 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003329 break;
3330
3331 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003332 chan->flush_to = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003333 break;
3334
3335 case L2CAP_CONF_QOS:
3336 break;
3337
Marcel Holtmann6464f352007-10-20 13:39:51 +02003338 case L2CAP_CONF_RFC:
3339 if (olen == sizeof(rfc))
3340 memcpy(&rfc, (void *) val, olen);
3341 break;
3342
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003343 case L2CAP_CONF_FCS:
3344 if (val == L2CAP_FCS_NONE)
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003345 set_bit(CONF_RECV_NO_FCS, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003346 break;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003347
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003348 case L2CAP_CONF_EFS:
3349 remote_efs = 1;
3350 if (olen == sizeof(efs))
3351 memcpy(&efs, (void *) val, olen);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003352 break;
3353
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003354 case L2CAP_CONF_EWS:
Marcel Holtmann848566b2013-10-01 22:59:22 -07003355 if (!chan->conn->hs_enabled)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003356 return -ECONNREFUSED;
3357
3358 set_bit(FLAG_EXT_CTRL, &chan->flags);
3359 set_bit(CONF_EWS_RECV, &chan->conf_state);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003360 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003361 chan->remote_tx_win = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003362 break;
3363
3364 default:
3365 if (hint)
3366 break;
3367
3368 result = L2CAP_CONF_UNKNOWN;
3369 *((u8 *) ptr++) = type;
3370 break;
3371 }
3372 }
3373
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003374 if (chan->num_conf_rsp || chan->num_conf_req > 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003375 goto done;
3376
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003377 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003378 case L2CAP_MODE_STREAMING:
3379 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003380 if (!test_bit(CONF_STATE2_DEVICE, &chan->conf_state)) {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003381 chan->mode = l2cap_select_mode(rfc.mode,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003382 chan->conn->feat_mask);
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003383 break;
3384 }
3385
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003386 if (remote_efs) {
Marcel Holtmann848566b2013-10-01 22:59:22 -07003387 if (__l2cap_efs_supported(chan->conn))
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003388 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3389 else
3390 return -ECONNREFUSED;
3391 }
3392
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003393 if (chan->mode != rfc.mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003394 return -ECONNREFUSED;
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03003395
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003396 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003397 }
3398
3399done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003400 if (chan->mode != rfc.mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003401 result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003402 rfc.mode = chan->mode;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003403
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003404 if (chan->num_conf_rsp == 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003405 return -ECONNREFUSED;
3406
Gustavo Padovan2d792812012-10-06 10:07:01 +01003407 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3408 (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003409 }
3410
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003411 if (result == L2CAP_CONF_SUCCESS) {
3412 /* Configure output options and let the other side know
3413 * which ones we don't like. */
3414
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003415 if (mtu < L2CAP_DEFAULT_MIN_MTU)
3416 result = L2CAP_CONF_UNACCEPT;
3417 else {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003418 chan->omtu = mtu;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003419 set_bit(CONF_MTU_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003420 }
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003421 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003422
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003423 if (remote_efs) {
3424 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003425 efs.stype != L2CAP_SERV_NOTRAFIC &&
3426 efs.stype != chan->local_stype) {
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003427
3428 result = L2CAP_CONF_UNACCEPT;
3429
3430 if (chan->num_conf_req >= 1)
3431 return -ECONNREFUSED;
3432
3433 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003434 sizeof(efs),
3435 (unsigned long) &efs);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003436 } else {
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003437 /* Send PENDING Conf Rsp */
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003438 result = L2CAP_CONF_PENDING;
3439 set_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003440 }
3441 }
3442
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003443 switch (rfc.mode) {
3444 case L2CAP_MODE_BASIC:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003445 chan->fcs = L2CAP_FCS_NONE;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003446 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003447 break;
3448
3449 case L2CAP_MODE_ERTM:
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003450 if (!test_bit(CONF_EWS_RECV, &chan->conf_state))
3451 chan->remote_tx_win = rfc.txwin_size;
3452 else
3453 rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW;
3454
Gustavo F. Padovan2c03a7a2011-03-25 20:15:28 -03003455 chan->remote_max_tx = rfc.max_transmit;
Mat Martineau86b1b262010-08-05 15:54:22 -07003456
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003457 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003458 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3459 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003460 rfc.max_pdu_size = cpu_to_le16(size);
3461 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003462
Mat Martineau36c86c82012-10-23 15:24:20 -07003463 __l2cap_set_ertm_timeouts(chan, &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003464
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003465 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003466
3467 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003468 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003469
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003470 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3471 chan->remote_id = efs.id;
3472 chan->remote_stype = efs.stype;
3473 chan->remote_msdu = le16_to_cpu(efs.msdu);
3474 chan->remote_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003475 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003476 chan->remote_acc_lat =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003477 le32_to_cpu(efs.acc_lat);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003478 chan->remote_sdu_itime =
3479 le32_to_cpu(efs.sdu_itime);
3480 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003481 sizeof(efs),
3482 (unsigned long) &efs);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003483 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003484 break;
3485
3486 case L2CAP_MODE_STREAMING:
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003487 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003488 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3489 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003490 rfc.max_pdu_size = cpu_to_le16(size);
3491 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003492
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003493 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003494
Gustavo Padovan2d792812012-10-06 10:07:01 +01003495 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3496 (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003497
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003498 break;
3499
3500 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02003501 result = L2CAP_CONF_UNACCEPT;
3502
3503 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003504 rfc.mode = chan->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003505 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003506
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003507 if (result == L2CAP_CONF_SUCCESS)
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003508 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003509 }
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003510 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003511 rsp->result = cpu_to_le16(result);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003512 rsp->flags = __constant_cpu_to_le16(0);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003513
3514 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003515}
3516
Gustavo Padovan2d792812012-10-06 10:07:01 +01003517static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len,
3518 void *data, u16 *result)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003519{
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003520 struct l2cap_conf_req *req = data;
3521 void *ptr = req->data;
3522 int type, olen;
3523 unsigned long val;
Mat Martineau36e999a2011-12-08 17:23:21 -08003524 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003525 struct l2cap_conf_efs efs;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003526
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003527 BT_DBG("chan %p, rsp %p, len %d, req %p", chan, rsp, len, data);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003528
3529 while (len >= L2CAP_CONF_OPT_SIZE) {
3530 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3531
3532 switch (type) {
3533 case L2CAP_CONF_MTU:
3534 if (val < L2CAP_DEFAULT_MIN_MTU) {
3535 *result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003536 chan->imtu = L2CAP_DEFAULT_MIN_MTU;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003537 } else
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003538 chan->imtu = val;
3539 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003540 break;
3541
3542 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003543 chan->flush_to = val;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003544 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003545 2, chan->flush_to);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003546 break;
3547
3548 case L2CAP_CONF_RFC:
3549 if (olen == sizeof(rfc))
3550 memcpy(&rfc, (void *)val, olen);
3551
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003552 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003553 rfc.mode != chan->mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003554 return -ECONNREFUSED;
3555
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003556 chan->fcs = 0;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003557
3558 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003559 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003560 break;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003561
3562 case L2CAP_CONF_EWS:
Mat Martineauc20f8e32012-07-10 05:47:07 -07003563 chan->ack_win = min_t(u16, val, chan->ack_win);
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003564 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Mat Martineauc20f8e32012-07-10 05:47:07 -07003565 chan->tx_win);
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003566 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003567
3568 case L2CAP_CONF_EFS:
3569 if (olen == sizeof(efs))
3570 memcpy(&efs, (void *)val, olen);
3571
3572 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003573 efs.stype != L2CAP_SERV_NOTRAFIC &&
3574 efs.stype != chan->local_stype)
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003575 return -ECONNREFUSED;
3576
Gustavo Padovan2d792812012-10-06 10:07:01 +01003577 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs),
3578 (unsigned long) &efs);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003579 break;
Andrei Emeltchenkocbabee72012-11-29 17:46:07 +02003580
3581 case L2CAP_CONF_FCS:
3582 if (*result == L2CAP_CONF_PENDING)
3583 if (val == L2CAP_FCS_NONE)
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003584 set_bit(CONF_RECV_NO_FCS,
Andrei Emeltchenkocbabee72012-11-29 17:46:07 +02003585 &chan->conf_state);
3586 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003587 }
3588 }
3589
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003590 if (chan->mode == L2CAP_MODE_BASIC && chan->mode != rfc.mode)
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003591 return -ECONNREFUSED;
3592
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003593 chan->mode = rfc.mode;
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003594
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003595 if (*result == L2CAP_CONF_SUCCESS || *result == L2CAP_CONF_PENDING) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003596 switch (rfc.mode) {
3597 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003598 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3599 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
3600 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003601 if (!test_bit(FLAG_EXT_CTRL, &chan->flags))
3602 chan->ack_win = min_t(u16, chan->ack_win,
3603 rfc.txwin_size);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003604
3605 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3606 chan->local_msdu = le16_to_cpu(efs.msdu);
3607 chan->local_sdu_itime =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003608 le32_to_cpu(efs.sdu_itime);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003609 chan->local_acc_lat = le32_to_cpu(efs.acc_lat);
3610 chan->local_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003611 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003612 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003613 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003614
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003615 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003616 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003617 }
3618 }
3619
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003620 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003621 req->flags = __constant_cpu_to_le16(0);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003622
3623 return ptr - data;
3624}
3625
Gustavo Padovan2d792812012-10-06 10:07:01 +01003626static int l2cap_build_conf_rsp(struct l2cap_chan *chan, void *data,
3627 u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003628{
3629 struct l2cap_conf_rsp *rsp = data;
3630 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003631
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003632 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003633
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003634 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003635 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003636 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003637
3638 return ptr - data;
3639}
3640
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003641void __l2cap_connect_rsp_defer(struct l2cap_chan *chan)
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003642{
3643 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003644 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003645 u8 buf[128];
Andrei Emeltchenko439f34a2012-10-31 15:46:28 +02003646 u8 rsp_code;
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003647
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003648 rsp.scid = cpu_to_le16(chan->dcid);
3649 rsp.dcid = cpu_to_le16(chan->scid);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003650 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
3651 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Andrei Emeltchenko439f34a2012-10-31 15:46:28 +02003652
3653 if (chan->hs_hcon)
3654 rsp_code = L2CAP_CREATE_CHAN_RSP;
3655 else
3656 rsp_code = L2CAP_CONN_RSP;
3657
3658 BT_DBG("chan %p rsp_code %u", chan, rsp_code);
3659
3660 l2cap_send_cmd(conn, chan->ident, rsp_code, sizeof(rsp), &rsp);
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003661
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003662 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003663 return;
3664
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003665 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003666 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003667 chan->num_conf_req++;
3668}
3669
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003670static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003671{
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003672 int type, olen;
3673 unsigned long val;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003674 /* Use sane default values in case a misbehaving remote device
3675 * did not send an RFC or extended window size option.
3676 */
3677 u16 txwin_ext = chan->ack_win;
3678 struct l2cap_conf_rfc rfc = {
3679 .mode = chan->mode,
3680 .retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO),
3681 .monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO),
3682 .max_pdu_size = cpu_to_le16(chan->imtu),
3683 .txwin_size = min_t(u16, chan->ack_win, L2CAP_DEFAULT_TX_WINDOW),
3684 };
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003685
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003686 BT_DBG("chan %p, rsp %p, len %d", chan, rsp, len);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003687
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003688 if ((chan->mode != L2CAP_MODE_ERTM) && (chan->mode != L2CAP_MODE_STREAMING))
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003689 return;
3690
3691 while (len >= L2CAP_CONF_OPT_SIZE) {
3692 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3693
Mat Martineauc20f8e32012-07-10 05:47:07 -07003694 switch (type) {
3695 case L2CAP_CONF_RFC:
3696 if (olen == sizeof(rfc))
3697 memcpy(&rfc, (void *)val, olen);
Szymon Janc8f321f82012-06-08 11:33:33 +02003698 break;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003699 case L2CAP_CONF_EWS:
3700 txwin_ext = val;
3701 break;
3702 }
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003703 }
3704
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003705 switch (rfc.mode) {
3706 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003707 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3708 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003709 chan->mps = le16_to_cpu(rfc.max_pdu_size);
3710 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3711 chan->ack_win = min_t(u16, chan->ack_win, txwin_ext);
3712 else
3713 chan->ack_win = min_t(u16, chan->ack_win,
3714 rfc.txwin_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003715 break;
3716 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003717 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003718 }
3719}
3720
Gustavo Padovan2d792812012-10-06 10:07:01 +01003721static inline int l2cap_command_rej(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003722 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3723 u8 *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003724{
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003725 struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003726
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003727 if (cmd_len < sizeof(*rej))
3728 return -EPROTO;
3729
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003730 if (rej->reason != L2CAP_REJ_NOT_UNDERSTOOD)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003731 return 0;
3732
3733 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003734 cmd->ident == conn->info_ident) {
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02003735 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01003736
3737 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003738 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003739
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003740 l2cap_conn_start(conn);
3741 }
3742
3743 return 0;
3744}
3745
Mat Martineau17009152012-10-23 15:24:07 -07003746static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
3747 struct l2cap_cmd_hdr *cmd,
3748 u8 *data, u8 rsp_code, u8 amp_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003749{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003750 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
3751 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003752 struct l2cap_chan *chan = NULL, *pchan;
Nathan Holsteind793fe82010-10-15 11:54:02 -04003753 struct sock *parent, *sk = NULL;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003754 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003755
3756 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003757 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003758
Andrei Emeltchenko097db762012-03-09 14:16:17 +02003759 BT_DBG("psm 0x%2.2x scid 0x%4.4x", __le16_to_cpu(psm), scid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003760
3761 /* Check if we have socket listening on psm */
Marcel Holtmann6f59b902013-10-13 05:24:01 -07003762 pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, &conn->hcon->src,
Marcel Holtmann98e0f7e2013-10-13 02:23:40 -07003763 &conn->hcon->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003764 if (!pchan) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003765 result = L2CAP_CR_BAD_PSM;
3766 goto sendresp;
3767 }
3768
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003769 parent = pchan->sk;
3770
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003771 mutex_lock(&conn->chan_lock);
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003772 lock_sock(parent);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00003773
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003774 /* Check if the ACL is secure enough (if not SDP) */
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +03003775 if (psm != __constant_cpu_to_le16(L2CAP_PSM_SDP) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003776 !hci_conn_check_link_mode(conn->hcon)) {
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003777 conn->disc_reason = HCI_ERROR_AUTH_FAILURE;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003778 result = L2CAP_CR_SEC_BLOCK;
3779 goto response;
3780 }
3781
Linus Torvalds1da177e2005-04-16 15:20:36 -07003782 result = L2CAP_CR_NO_MEM;
3783
Gustavo Padovan2dfa1002012-05-27 22:27:58 -03003784 /* Check if we already have channel with that dcid */
3785 if (__l2cap_get_chan_by_dcid(conn, scid))
3786 goto response;
3787
Gustavo Padovan80b98022012-05-27 22:27:51 -03003788 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003789 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003790 goto response;
3791
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003792 sk = chan->sk;
3793
Syam Sidhardhan330b6c12013-08-06 01:59:12 +09003794 /* For certain devices (ex: HID mouse), support for authentication,
3795 * pairing and bonding is optional. For such devices, inorder to avoid
3796 * the ACL alive for too long after L2CAP disconnection, reset the ACL
3797 * disc_timeout back to HCI_DISCONN_TIMEOUT during L2CAP connect.
3798 */
3799 conn->hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
3800
Marcel Holtmann6f59b902013-10-13 05:24:01 -07003801 bacpy(&bt_sk(sk)->src, &conn->hcon->src);
Marcel Holtmann98e0f7e2013-10-13 02:23:40 -07003802 bacpy(&bt_sk(sk)->dst, &conn->hcon->dst);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003803 chan->psm = psm;
3804 chan->dcid = scid;
Mat Martineau17009152012-10-23 15:24:07 -07003805 chan->local_amp_id = amp_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003806
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003807 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003808
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003809 dcid = chan->scid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003810
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03003811 __set_chan_timer(chan, sk->sk_sndtimeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003812
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003813 chan->ident = cmd->ident;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003814
Marcel Holtmann984947d2009-02-06 23:35:19 +01003815 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02003816 if (l2cap_chan_check_security(chan)) {
Gustavo Padovanc5daa682012-05-16 12:17:10 -03003817 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003818 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003819 result = L2CAP_CR_PEND;
3820 status = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08003821 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003822 } else {
Mat Martineau17009152012-10-23 15:24:07 -07003823 /* Force pending result for AMP controllers.
3824 * The connection will succeed after the
3825 * physical link is up.
3826 */
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003827 if (amp_id == AMP_ID_BREDR) {
Mat Martineau17009152012-10-23 15:24:07 -07003828 __l2cap_state_change(chan, BT_CONFIG);
3829 result = L2CAP_CR_SUCCESS;
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003830 } else {
3831 __l2cap_state_change(chan, BT_CONNECT2);
3832 result = L2CAP_CR_PEND;
Mat Martineau17009152012-10-23 15:24:07 -07003833 }
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003834 status = L2CAP_CS_NO_INFO;
3835 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003836 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003837 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003838 result = L2CAP_CR_PEND;
3839 status = L2CAP_CS_AUTHEN_PEND;
3840 }
3841 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003842 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003843 result = L2CAP_CR_PEND;
3844 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003845 }
3846
Linus Torvalds1da177e2005-04-16 15:20:36 -07003847response:
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003848 release_sock(parent);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003849 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003850
3851sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003852 rsp.scid = cpu_to_le16(scid);
3853 rsp.dcid = cpu_to_le16(dcid);
3854 rsp.result = cpu_to_le16(result);
3855 rsp.status = cpu_to_le16(status);
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003856 l2cap_send_cmd(conn, cmd->ident, rsp_code, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003857
3858 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
3859 struct l2cap_info_req info;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003860 info.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003861
3862 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
3863 conn->info_ident = l2cap_get_ident(conn);
3864
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08003865 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003866
Gustavo Padovan2d792812012-10-06 10:07:01 +01003867 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
3868 sizeof(info), &info);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003869 }
3870
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003871 if (chan && !test_bit(CONF_REQ_SENT, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003872 result == L2CAP_CR_SUCCESS) {
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003873 u8 buf[128];
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003874 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003875 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003876 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003877 chan->num_conf_req++;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003878 }
Mat Martineau17009152012-10-23 15:24:07 -07003879
3880 return chan;
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003881}
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003882
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003883static int l2cap_connect_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003884 struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003885{
Jaganath Kanakkassery7b064ed2013-01-10 10:28:35 +05303886 struct hci_dev *hdev = conn->hcon->hdev;
3887 struct hci_conn *hcon = conn->hcon;
3888
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003889 if (cmd_len < sizeof(struct l2cap_conn_req))
3890 return -EPROTO;
3891
Jaganath Kanakkassery7b064ed2013-01-10 10:28:35 +05303892 hci_dev_lock(hdev);
3893 if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
3894 !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &hcon->flags))
3895 mgmt_device_connected(hdev, &hcon->dst, hcon->type,
3896 hcon->dst_type, 0, NULL, 0,
3897 hcon->dev_class);
3898 hci_dev_unlock(hdev);
3899
Gustavo Padovan300229f2012-10-12 19:40:40 +08003900 l2cap_connect(conn, cmd, data, L2CAP_CONN_RSP, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003901 return 0;
3902}
3903
Mat Martineau5909cf32012-10-23 15:24:08 -07003904static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003905 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3906 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003907{
3908 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
3909 u16 scid, dcid, result, status;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003910 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003911 u8 req[128];
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003912 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003913
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003914 if (cmd_len < sizeof(*rsp))
3915 return -EPROTO;
3916
Linus Torvalds1da177e2005-04-16 15:20:36 -07003917 scid = __le16_to_cpu(rsp->scid);
3918 dcid = __le16_to_cpu(rsp->dcid);
3919 result = __le16_to_cpu(rsp->result);
3920 status = __le16_to_cpu(rsp->status);
3921
Andrei Emeltchenko1b009c92012-02-21 12:54:54 +02003922 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 +01003923 dcid, scid, result, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003924
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003925 mutex_lock(&conn->chan_lock);
3926
Linus Torvalds1da177e2005-04-16 15:20:36 -07003927 if (scid) {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003928 chan = __l2cap_get_chan_by_scid(conn, scid);
3929 if (!chan) {
Johan Hedberg21870b52013-09-16 13:05:14 +03003930 err = -EBADSLT;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003931 goto unlock;
3932 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003933 } else {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003934 chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
3935 if (!chan) {
Johan Hedberg21870b52013-09-16 13:05:14 +03003936 err = -EBADSLT;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003937 goto unlock;
3938 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003939 }
3940
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003941 err = 0;
3942
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003943 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003944
Linus Torvalds1da177e2005-04-16 15:20:36 -07003945 switch (result) {
3946 case L2CAP_CR_SUCCESS:
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03003947 l2cap_state_change(chan, BT_CONFIG);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003948 chan->ident = 0;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003949 chan->dcid = dcid;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003950 clear_bit(CONF_CONNECT_PEND, &chan->conf_state);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003951
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003952 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003953 break;
3954
Linus Torvalds1da177e2005-04-16 15:20:36 -07003955 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003956 l2cap_build_conf_req(chan, req), req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003957 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003958 break;
3959
3960 case L2CAP_CR_PEND:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003961 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003962 break;
3963
3964 default:
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003965 l2cap_chan_del(chan, ECONNREFUSED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003966 break;
3967 }
3968
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003969 l2cap_chan_unlock(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003970
3971unlock:
3972 mutex_unlock(&conn->chan_lock);
3973
3974 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003975}
3976
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003977static inline void set_default_fcs(struct l2cap_chan *chan)
Mat Martineau8c462b62010-08-24 15:35:42 -07003978{
3979 /* FCS is enabled only in ERTM or streaming mode, if one or both
3980 * sides request it.
3981 */
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003982 if (chan->mode != L2CAP_MODE_ERTM && chan->mode != L2CAP_MODE_STREAMING)
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003983 chan->fcs = L2CAP_FCS_NONE;
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003984 else if (!test_bit(CONF_RECV_NO_FCS, &chan->conf_state))
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003985 chan->fcs = L2CAP_FCS_CRC16;
Mat Martineau8c462b62010-08-24 15:35:42 -07003986}
3987
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03003988static void l2cap_send_efs_conf_rsp(struct l2cap_chan *chan, void *data,
3989 u8 ident, u16 flags)
3990{
3991 struct l2cap_conn *conn = chan->conn;
3992
3993 BT_DBG("conn %p chan %p ident %d flags 0x%4.4x", conn, chan, ident,
3994 flags);
3995
3996 clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
3997 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
3998
3999 l2cap_send_cmd(conn, ident, L2CAP_CONF_RSP,
4000 l2cap_build_conf_rsp(chan, data,
4001 L2CAP_CONF_SUCCESS, flags), data);
4002}
4003
Gustavo Padovan2d792812012-10-06 10:07:01 +01004004static inline int l2cap_config_req(struct l2cap_conn *conn,
4005 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4006 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004007{
4008 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
4009 u16 dcid, flags;
4010 u8 rsp[64];
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004011 struct l2cap_chan *chan;
Mat Martineau3c588192012-04-11 10:48:42 -07004012 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004013
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004014 if (cmd_len < sizeof(*req))
4015 return -EPROTO;
4016
Linus Torvalds1da177e2005-04-16 15:20:36 -07004017 dcid = __le16_to_cpu(req->dcid);
4018 flags = __le16_to_cpu(req->flags);
4019
4020 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
4021
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03004022 chan = l2cap_get_chan_by_scid(conn, dcid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004023 if (!chan)
Johan Hedberg21870b52013-09-16 13:05:14 +03004024 return -EBADSLT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004025
David S. Miller033b1142011-07-21 13:38:42 -07004026 if (chan->state != BT_CONFIG && chan->state != BT_CONNECT2) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03004027 struct l2cap_cmd_rej_cid rej;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03004028
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004029 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_INVALID_CID);
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03004030 rej.scid = cpu_to_le16(chan->scid);
4031 rej.dcid = cpu_to_le16(chan->dcid);
4032
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03004033 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004034 sizeof(rej), &rej);
Marcel Holtmann354f60a2006-11-18 22:15:20 +01004035 goto unlock;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03004036 }
Marcel Holtmann354f60a2006-11-18 22:15:20 +01004037
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004038 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07004039 len = cmd_len - sizeof(*req);
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004040 if (chan->conf_len + len > sizeof(chan->conf_req)) {
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004041 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004042 l2cap_build_conf_rsp(chan, rsp,
4043 L2CAP_CONF_REJECT, flags), rsp);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004044 goto unlock;
4045 }
4046
4047 /* Store config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004048 memcpy(chan->conf_req + chan->conf_len, req->data, len);
4049 chan->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004050
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03004051 if (flags & L2CAP_CONF_FLAG_CONTINUATION) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004052 /* Incomplete config. Send empty response. */
4053 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004054 l2cap_build_conf_rsp(chan, rsp,
4055 L2CAP_CONF_SUCCESS, flags), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004056 goto unlock;
4057 }
4058
4059 /* Complete config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004060 len = l2cap_parse_conf_req(chan, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004061 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004062 l2cap_send_disconn_req(chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004063 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004064 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004065
Mat Martineau1500109b2012-10-23 15:24:15 -07004066 chan->ident = cmd->ident;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004067 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004068 chan->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004069
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004070 /* Reset config buffer. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004071 chan->conf_len = 0;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004072
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004073 if (!test_bit(CONF_OUTPUT_DONE, &chan->conf_state))
Marcel Holtmann876d9482007-10-20 13:35:42 +02004074 goto unlock;
4075
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004076 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004077 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004078
Mat Martineau105bdf92012-04-27 16:50:48 -07004079 if (chan->mode == L2CAP_MODE_ERTM ||
4080 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07004081 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03004082
Mat Martineau3c588192012-04-11 10:48:42 -07004083 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004084 l2cap_send_disconn_req(chan, -err);
Mat Martineau3c588192012-04-11 10:48:42 -07004085 else
4086 l2cap_chan_ready(chan);
4087
Marcel Holtmann876d9482007-10-20 13:35:42 +02004088 goto unlock;
4089 }
4090
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004091 if (!test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004092 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004093 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004094 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004095 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004096 }
4097
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004098 /* Got Conf Rsp PENDING from remote side and asume we sent
4099 Conf Rsp PENDING in the code above */
4100 if (test_bit(CONF_REM_CONF_PEND, &chan->conf_state) &&
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03004101 test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004102
4103 /* check compatibility */
4104
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004105 /* Send rsp for BR/EDR channel */
Andrei Emeltchenkof351bc72012-10-31 15:46:35 +02004106 if (!chan->hs_hcon)
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004107 l2cap_send_efs_conf_rsp(chan, rsp, cmd->ident, flags);
4108 else
4109 chan->ident = cmd->ident;
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004110 }
4111
Linus Torvalds1da177e2005-04-16 15:20:36 -07004112unlock:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004113 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07004114 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004115}
4116
Gustavo Padovan2d792812012-10-06 10:07:01 +01004117static inline int l2cap_config_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004118 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4119 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004120{
4121 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
4122 u16 scid, flags, result;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004123 struct l2cap_chan *chan;
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004124 int len = cmd_len - sizeof(*rsp);
Mat Martineau3c588192012-04-11 10:48:42 -07004125 int err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004126
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004127 if (cmd_len < sizeof(*rsp))
4128 return -EPROTO;
4129
Linus Torvalds1da177e2005-04-16 15:20:36 -07004130 scid = __le16_to_cpu(rsp->scid);
4131 flags = __le16_to_cpu(rsp->flags);
4132 result = __le16_to_cpu(rsp->result);
4133
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02004134 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x len %d", scid, flags,
4135 result, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004136
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03004137 chan = l2cap_get_chan_by_scid(conn, scid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004138 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004139 return 0;
4140
4141 switch (result) {
4142 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004143 l2cap_conf_rfc_get(chan, rsp->data, len);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004144 clear_bit(CONF_REM_CONF_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004145 break;
4146
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004147 case L2CAP_CONF_PENDING:
4148 set_bit(CONF_REM_CONF_PEND, &chan->conf_state);
4149
4150 if (test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
4151 char buf[64];
4152
4153 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004154 buf, &result);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004155 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004156 l2cap_send_disconn_req(chan, ECONNRESET);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004157 goto done;
4158 }
4159
Andrei Emeltchenkof351bc72012-10-31 15:46:35 +02004160 if (!chan->hs_hcon) {
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004161 l2cap_send_efs_conf_rsp(chan, buf, cmd->ident,
4162 0);
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +02004163 } else {
4164 if (l2cap_check_efs(chan)) {
4165 amp_create_logical_link(chan);
4166 chan->ident = cmd->ident;
4167 }
4168 }
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004169 }
4170 goto done;
4171
Linus Torvalds1da177e2005-04-16 15:20:36 -07004172 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004173 if (chan->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004174 char req[64];
4175
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02004176 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004177 l2cap_send_disconn_req(chan, ECONNRESET);
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02004178 goto done;
4179 }
4180
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004181 /* throw out any old stored conf requests */
4182 result = L2CAP_CONF_SUCCESS;
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03004183 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004184 req, &result);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004185 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004186 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004187 goto done;
4188 }
4189
4190 l2cap_send_cmd(conn, l2cap_get_ident(conn),
Gustavo Padovan2d792812012-10-06 10:07:01 +01004191 L2CAP_CONF_REQ, len, req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004192 chan->num_conf_req++;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004193 if (result != L2CAP_CONF_SUCCESS)
4194 goto done;
4195 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004196 }
4197
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09004198 default:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004199 l2cap_chan_set_err(chan, ECONNRESET);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02004200
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08004201 __set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004202 l2cap_send_disconn_req(chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004203 goto done;
4204 }
4205
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03004206 if (flags & L2CAP_CONF_FLAG_CONTINUATION)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004207 goto done;
4208
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004209 set_bit(CONF_INPUT_DONE, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004210
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004211 if (test_bit(CONF_OUTPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004212 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004213
Mat Martineau105bdf92012-04-27 16:50:48 -07004214 if (chan->mode == L2CAP_MODE_ERTM ||
4215 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07004216 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03004217
Mat Martineau3c588192012-04-11 10:48:42 -07004218 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004219 l2cap_send_disconn_req(chan, -err);
Mat Martineau3c588192012-04-11 10:48:42 -07004220 else
4221 l2cap_chan_ready(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004222 }
4223
4224done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004225 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07004226 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004227}
4228
Gustavo Padovan2d792812012-10-06 10:07:01 +01004229static inline int l2cap_disconnect_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004230 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4231 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004232{
4233 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
4234 struct l2cap_disconn_rsp rsp;
4235 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004236 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004237 struct sock *sk;
4238
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004239 if (cmd_len != sizeof(*req))
4240 return -EPROTO;
4241
Linus Torvalds1da177e2005-04-16 15:20:36 -07004242 scid = __le16_to_cpu(req->scid);
4243 dcid = __le16_to_cpu(req->dcid);
4244
4245 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
4246
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004247 mutex_lock(&conn->chan_lock);
4248
4249 chan = __l2cap_get_chan_by_scid(conn, dcid);
4250 if (!chan) {
4251 mutex_unlock(&conn->chan_lock);
Johan Hedbergc4ea2492013-09-16 13:05:15 +03004252 return -EBADSLT;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004253 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004254
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004255 l2cap_chan_lock(chan);
4256
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004257 sk = chan->sk;
4258
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03004259 rsp.dcid = cpu_to_le16(chan->scid);
4260 rsp.scid = cpu_to_le16(chan->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004261 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
4262
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004263 lock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004264 sk->sk_shutdown = SHUTDOWN_MASK;
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004265 release_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004266
Mat Martineau61d6ef32012-04-27 16:50:50 -07004267 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004268 l2cap_chan_del(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004269
4270 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004271
Gustavo Padovan80b98022012-05-27 22:27:51 -03004272 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004273 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004274
4275 mutex_unlock(&conn->chan_lock);
4276
Linus Torvalds1da177e2005-04-16 15:20:36 -07004277 return 0;
4278}
4279
Gustavo Padovan2d792812012-10-06 10:07:01 +01004280static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004281 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4282 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004283{
4284 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
4285 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004286 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004287
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004288 if (cmd_len != sizeof(*rsp))
4289 return -EPROTO;
4290
Linus Torvalds1da177e2005-04-16 15:20:36 -07004291 scid = __le16_to_cpu(rsp->scid);
4292 dcid = __le16_to_cpu(rsp->dcid);
4293
4294 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
4295
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004296 mutex_lock(&conn->chan_lock);
4297
4298 chan = __l2cap_get_chan_by_scid(conn, scid);
4299 if (!chan) {
4300 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004301 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004302 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004303
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004304 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004305
Mat Martineau61d6ef32012-04-27 16:50:50 -07004306 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004307 l2cap_chan_del(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004308
4309 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004310
Gustavo Padovan80b98022012-05-27 22:27:51 -03004311 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004312 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004313
4314 mutex_unlock(&conn->chan_lock);
4315
Linus Torvalds1da177e2005-04-16 15:20:36 -07004316 return 0;
4317}
4318
Gustavo Padovan2d792812012-10-06 10:07:01 +01004319static inline int l2cap_information_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004320 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4321 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004322{
4323 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004324 u16 type;
4325
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004326 if (cmd_len != sizeof(*req))
4327 return -EPROTO;
4328
Linus Torvalds1da177e2005-04-16 15:20:36 -07004329 type = __le16_to_cpu(req->type);
4330
4331 BT_DBG("type 0x%4.4x", type);
4332
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004333 if (type == L2CAP_IT_FEAT_MASK) {
4334 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07004335 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004336 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004337 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
4338 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03004339 if (!disable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004340 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
Gustavo Padovan2d792812012-10-06 10:07:01 +01004341 | L2CAP_FEAT_FCS;
Marcel Holtmann848566b2013-10-01 22:59:22 -07004342 if (conn->hs_enabled)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03004343 feat_mask |= L2CAP_FEAT_EXT_FLOW
Gustavo Padovan2d792812012-10-06 10:07:01 +01004344 | L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03004345
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03004346 put_unaligned_le32(feat_mask, rsp->data);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004347 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4348 buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004349 } else if (type == L2CAP_IT_FIXED_CHAN) {
4350 u8 buf[12];
4351 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Mat Martineau50a147c2011-11-02 16:18:34 -07004352
Marcel Holtmann848566b2013-10-01 22:59:22 -07004353 if (conn->hs_enabled)
Mat Martineau50a147c2011-11-02 16:18:34 -07004354 l2cap_fixed_chan[0] |= L2CAP_FC_A2MP;
4355 else
4356 l2cap_fixed_chan[0] &= ~L2CAP_FC_A2MP;
4357
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004358 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
4359 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Andrei Emeltchenkoc6337ea2011-10-20 17:02:44 +03004360 memcpy(rsp->data, l2cap_fixed_chan, sizeof(l2cap_fixed_chan));
Gustavo Padovan2d792812012-10-06 10:07:01 +01004361 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4362 buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004363 } else {
4364 struct l2cap_info_rsp rsp;
4365 rsp.type = cpu_to_le16(type);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004366 rsp.result = __constant_cpu_to_le16(L2CAP_IR_NOTSUPP);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004367 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(rsp),
4368 &rsp);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004369 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004370
4371 return 0;
4372}
4373
Gustavo Padovan2d792812012-10-06 10:07:01 +01004374static inline int l2cap_information_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004375 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4376 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004377{
4378 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
4379 u16 type, result;
4380
Jaganath Kanakkassery3f6fa3d2013-06-21 19:55:11 +05304381 if (cmd_len < sizeof(*rsp))
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004382 return -EPROTO;
4383
Linus Torvalds1da177e2005-04-16 15:20:36 -07004384 type = __le16_to_cpu(rsp->type);
4385 result = __le16_to_cpu(rsp->result);
4386
4387 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
4388
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004389 /* L2CAP Info req/rsp are unbound to channels, add extra checks */
4390 if (cmd->ident != conn->info_ident ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01004391 conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004392 return 0;
4393
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02004394 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004395
Ville Tervoadb08ed2010-08-04 09:43:33 +03004396 if (result != L2CAP_IR_SUCCESS) {
4397 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4398 conn->info_ident = 0;
4399
4400 l2cap_conn_start(conn);
4401
4402 return 0;
4403 }
4404
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004405 switch (type) {
4406 case L2CAP_IT_FEAT_MASK:
Harvey Harrison83985312008-05-02 16:25:46 -07004407 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004408
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07004409 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004410 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004411 req.type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004412
4413 conn->info_ident = l2cap_get_ident(conn);
4414
4415 l2cap_send_cmd(conn, conn->info_ident,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004416 L2CAP_INFO_REQ, sizeof(req), &req);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004417 } else {
4418 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4419 conn->info_ident = 0;
4420
4421 l2cap_conn_start(conn);
4422 }
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004423 break;
4424
4425 case L2CAP_IT_FIXED_CHAN:
4426 conn->fixed_chan_mask = rsp->data[0];
Marcel Holtmann984947d2009-02-06 23:35:19 +01004427 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004428 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004429
4430 l2cap_conn_start(conn);
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004431 break;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004432 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004433
Linus Torvalds1da177e2005-04-16 15:20:36 -07004434 return 0;
4435}
4436
Mat Martineau17009152012-10-23 15:24:07 -07004437static int l2cap_create_channel_req(struct l2cap_conn *conn,
4438 struct l2cap_cmd_hdr *cmd,
4439 u16 cmd_len, void *data)
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004440{
4441 struct l2cap_create_chan_req *req = data;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004442 struct l2cap_create_chan_rsp rsp;
Mat Martineau17009152012-10-23 15:24:07 -07004443 struct l2cap_chan *chan;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004444 struct hci_dev *hdev;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004445 u16 psm, scid;
4446
4447 if (cmd_len != sizeof(*req))
4448 return -EPROTO;
4449
Marcel Holtmann848566b2013-10-01 22:59:22 -07004450 if (!conn->hs_enabled)
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004451 return -EINVAL;
4452
4453 psm = le16_to_cpu(req->psm);
4454 scid = le16_to_cpu(req->scid);
4455
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004456 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 -07004457
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004458 /* For controller id 0 make BR/EDR connection */
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004459 if (req->amp_id == AMP_ID_BREDR) {
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004460 l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4461 req->amp_id);
4462 return 0;
4463 }
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004464
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004465 /* Validate AMP controller id */
4466 hdev = hci_dev_get(req->amp_id);
4467 if (!hdev)
4468 goto error;
Mat Martineau17009152012-10-23 15:24:07 -07004469
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004470 if (hdev->dev_type != HCI_AMP || !test_bit(HCI_UP, &hdev->flags)) {
Mat Martineau17009152012-10-23 15:24:07 -07004471 hci_dev_put(hdev);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004472 goto error;
Mat Martineau17009152012-10-23 15:24:07 -07004473 }
4474
4475 chan = l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4476 req->amp_id);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004477 if (chan) {
4478 struct amp_mgr *mgr = conn->hcon->amp_mgr;
4479 struct hci_conn *hs_hcon;
4480
Marcel Holtmann98e0f7e2013-10-13 02:23:40 -07004481 hs_hcon = hci_conn_hash_lookup_ba(hdev, AMP_LINK,
4482 &conn->hcon->dst);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004483 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) &&
Marcel Holtmann6f59b902013-10-13 05:24:01 -07004925 bacmp(&conn->hcon->src, &conn->hcon->dst) > 0) {
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004926 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
Marcel Holtmann6f59b902013-10-13 05:24:01 -07006440 chan = l2cap_global_chan_by_psm(0, psm, &conn->hcon->src,
Marcel Holtmann98e0f7e2013-10-13 02:23:40 -07006441 &conn->hcon->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006442 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006443 goto drop;
6444
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02006445 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006446
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006447 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006448 goto drop;
6449
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03006450 if (chan->imtu < skb->len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006451 goto drop;
6452
Gustavo Padovan80b98022012-05-27 22:27:51 -03006453 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03006454 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006455
6456drop:
6457 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006458}
6459
Marcel Holtmann72f78352013-04-23 00:59:00 -07006460static void l2cap_att_channel(struct l2cap_conn *conn,
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03006461 struct sk_buff *skb)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006462{
Marcel Holtmannb99707d2013-10-03 02:54:11 -07006463 struct hci_conn *hcon = conn->hcon;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006464 struct l2cap_chan *chan;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006465
Marcel Holtmannb99707d2013-10-03 02:54:11 -07006466 if (hcon->type != LE_LINK)
6467 goto drop;
6468
Johan Hedbergaf1c0132013-04-29 19:35:42 +03006469 chan = l2cap_global_chan_by_scid(BT_CONNECTED, L2CAP_CID_ATT,
Marcel Holtmann6f59b902013-10-13 05:24:01 -07006470 &conn->hcon->src, &conn->hcon->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006471 if (!chan)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006472 goto drop;
6473
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02006474 BT_DBG("chan %p, len %d", chan, skb->len);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006475
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03006476 if (chan->imtu < skb->len)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006477 goto drop;
6478
Gustavo Padovan80b98022012-05-27 22:27:51 -03006479 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03006480 return;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006481
6482drop:
6483 kfree_skb(skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006484}
6485
Linus Torvalds1da177e2005-04-16 15:20:36 -07006486static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
6487{
6488 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07006489 u16 cid, len;
6490 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006491
6492 skb_pull(skb, L2CAP_HDR_SIZE);
6493 cid = __le16_to_cpu(lh->cid);
6494 len = __le16_to_cpu(lh->len);
6495
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006496 if (len != skb->len) {
6497 kfree_skb(skb);
6498 return;
6499 }
6500
Linus Torvalds1da177e2005-04-16 15:20:36 -07006501 BT_DBG("len %d, cid 0x%4.4x", len, cid);
6502
6503 switch (cid) {
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03006504 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006505 l2cap_sig_channel(conn, skb);
6506 break;
6507
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03006508 case L2CAP_CID_CONN_LESS:
Andrei Emeltchenko097db762012-03-09 14:16:17 +02006509 psm = get_unaligned((__le16 *) skb->data);
Andrei Emeltchenko0181a702012-05-29 10:04:05 +03006510 skb_pull(skb, L2CAP_PSMLEN_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006511 l2cap_conless_channel(conn, psm, skb);
6512 break;
6513
Johan Hedberg073d1cf2013-04-29 19:35:35 +03006514 case L2CAP_CID_ATT:
Marcel Holtmann72f78352013-04-23 00:59:00 -07006515 l2cap_att_channel(conn, skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006516 break;
6517
Marcel Holtmanna2877622013-10-02 23:46:54 -07006518 case L2CAP_CID_LE_SIGNALING:
6519 l2cap_le_sig_channel(conn, skb);
6520 break;
6521
Anderson Brigliab501d6a2011-06-07 18:46:31 -03006522 case L2CAP_CID_SMP:
6523 if (smp_sig_channel(conn, skb))
6524 l2cap_conn_del(conn->hcon, EACCES);
6525 break;
6526
Linus Torvalds1da177e2005-04-16 15:20:36 -07006527 default:
6528 l2cap_data_channel(conn, cid, skb);
6529 break;
6530 }
6531}
6532
6533/* ---- L2CAP interface with lower layer (HCI) ---- */
6534
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006535int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006536{
6537 int exact = 0, lm1 = 0, lm2 = 0;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006538 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006539
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03006540 BT_DBG("hdev %s, bdaddr %pMR", hdev->name, bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006541
6542 /* Find listening sockets and check their link_mode */
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006543 read_lock(&chan_list_lock);
6544 list_for_each_entry(c, &chan_list, global_l) {
6545 struct sock *sk = c->sk;
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006546
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006547 if (c->state != BT_LISTEN)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006548 continue;
6549
6550 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006551 lm1 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03006552 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006553 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006554 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006555 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
6556 lm2 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03006557 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006558 lm2 |= HCI_LM_MASTER;
6559 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006560 }
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006561 read_unlock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006562
6563 return exact ? lm1 : lm2;
6564}
6565
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03006566void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006567{
Marcel Holtmann01394182006-07-03 10:02:46 +02006568 struct l2cap_conn *conn;
6569
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03006570 BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006571
Linus Torvalds1da177e2005-04-16 15:20:36 -07006572 if (!status) {
Claudio Takahasibaf43252013-04-11 13:55:50 -03006573 conn = l2cap_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006574 if (conn)
6575 l2cap_conn_ready(conn);
Andrei Emeltchenkoba6fc312012-10-31 15:46:26 +02006576 } else {
Joe Perchese1750722011-06-29 18:18:29 -07006577 l2cap_conn_del(hcon, bt_to_errno(status));
Andrei Emeltchenkoba6fc312012-10-31 15:46:26 +02006578 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006579}
6580
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006581int l2cap_disconn_ind(struct hci_conn *hcon)
Marcel Holtmann2950f212009-02-12 14:02:50 +01006582{
6583 struct l2cap_conn *conn = hcon->l2cap_data;
6584
6585 BT_DBG("hcon %p", hcon);
6586
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006587 if (!conn)
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02006588 return HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01006589 return conn->disc_reason;
6590}
6591
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03006592void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006593{
6594 BT_DBG("hcon %p reason %d", hcon, reason);
6595
Joe Perchese1750722011-06-29 18:18:29 -07006596 l2cap_conn_del(hcon, bt_to_errno(reason));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006597}
6598
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006599static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006600{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03006601 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED)
Marcel Holtmann255c7602009-02-04 21:07:19 +01006602 return;
6603
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006604 if (encrypt == 0x00) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006605 if (chan->sec_level == BT_SECURITY_MEDIUM) {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006606 __set_chan_timer(chan, L2CAP_ENC_TIMEOUT);
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006607 } else if (chan->sec_level == BT_SECURITY_HIGH)
Gustavo F. Padovan0f852722011-05-04 19:42:50 -03006608 l2cap_chan_close(chan, ECONNREFUSED);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006609 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006610 if (chan->sec_level == BT_SECURITY_MEDIUM)
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03006611 __clear_chan_timer(chan);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006612 }
6613}
6614
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006615int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006616{
Marcel Holtmann40be4922008-07-14 20:13:50 +02006617 struct l2cap_conn *conn = hcon->l2cap_data;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006618 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006619
Marcel Holtmann01394182006-07-03 10:02:46 +02006620 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006621 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02006622
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03006623 BT_DBG("conn %p status 0x%2.2x encrypt %u", conn, status, encrypt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006624
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03006625 if (hcon->type == LE_LINK) {
Hemant Gupta35d4adcc2012-04-18 14:46:26 +05306626 if (!status && encrypt)
6627 smp_distribute_keys(conn, 0);
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02006628 cancel_delayed_work(&conn->security_timer);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03006629 }
6630
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006631 mutex_lock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006632
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006633 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006634 l2cap_chan_lock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006635
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03006636 BT_DBG("chan %p scid 0x%4.4x state %s", chan, chan->scid,
6637 state_to_string(chan->state));
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006638
Andrei Emeltchenko78eb2f92012-07-19 17:03:47 +03006639 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
6640 l2cap_chan_unlock(chan);
6641 continue;
6642 }
6643
Johan Hedberg073d1cf2013-04-29 19:35:35 +03006644 if (chan->scid == L2CAP_CID_ATT) {
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006645 if (!status && encrypt) {
6646 chan->sec_level = hcon->sec_level;
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02006647 l2cap_chan_ready(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006648 }
6649
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006650 l2cap_chan_unlock(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006651 continue;
6652 }
6653
Andrei Emeltchenko96eff462012-11-15 18:14:53 +02006654 if (!__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006655 l2cap_chan_unlock(chan);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01006656 continue;
6657 }
6658
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006659 if (!status && (chan->state == BT_CONNECTED ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01006660 chan->state == BT_CONFIG)) {
Gustavo Padovana7d77232012-05-13 03:20:07 -03006661 struct sock *sk = chan->sk;
6662
Gustavo Padovanc5daa682012-05-16 12:17:10 -03006663 clear_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags);
Gustavo Padovana7d77232012-05-13 03:20:07 -03006664 sk->sk_state_change(sk);
6665
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006666 l2cap_check_encryption(chan, encrypt);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006667 l2cap_chan_unlock(chan);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02006668 continue;
6669 }
6670
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006671 if (chan->state == BT_CONNECT) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006672 if (!status) {
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03006673 l2cap_start_connection(chan);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006674 } else {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006675 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006676 }
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006677 } else if (chan->state == BT_CONNECT2) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006678 struct sock *sk = chan->sk;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006679 struct l2cap_conn_rsp rsp;
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006680 __u16 res, stat;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006681
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006682 lock_sock(sk);
6683
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006684 if (!status) {
Gustavo Padovanc5daa682012-05-16 12:17:10 -03006685 if (test_bit(BT_SK_DEFER_SETUP,
6686 &bt_sk(sk)->flags)) {
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006687 res = L2CAP_CR_PEND;
6688 stat = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08006689 chan->ops->defer(chan);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006690 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02006691 __l2cap_state_change(chan, BT_CONFIG);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006692 res = L2CAP_CR_SUCCESS;
6693 stat = L2CAP_CS_NO_INFO;
6694 }
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006695 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02006696 __l2cap_state_change(chan, BT_DISCONN);
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006697 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006698 res = L2CAP_CR_SEC_BLOCK;
6699 stat = L2CAP_CS_NO_INFO;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006700 }
6701
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006702 release_sock(sk);
6703
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03006704 rsp.scid = cpu_to_le16(chan->dcid);
6705 rsp.dcid = cpu_to_le16(chan->scid);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006706 rsp.result = cpu_to_le16(res);
6707 rsp.status = cpu_to_le16(stat);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03006708 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01006709 sizeof(rsp), &rsp);
Mat Martineau2d369352012-05-23 14:59:30 -07006710
6711 if (!test_bit(CONF_REQ_SENT, &chan->conf_state) &&
6712 res == L2CAP_CR_SUCCESS) {
6713 char buf[128];
6714 set_bit(CONF_REQ_SENT, &chan->conf_state);
6715 l2cap_send_cmd(conn, l2cap_get_ident(conn),
6716 L2CAP_CONF_REQ,
6717 l2cap_build_conf_req(chan, buf),
6718 buf);
6719 chan->num_conf_req++;
6720 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006721 }
6722
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006723 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006724 }
6725
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006726 mutex_unlock(&conn->chan_lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006727
Linus Torvalds1da177e2005-04-16 15:20:36 -07006728 return 0;
6729}
6730
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006731int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006732{
6733 struct l2cap_conn *conn = hcon->l2cap_data;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006734 struct l2cap_hdr *hdr;
6735 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006736
Andrei Emeltchenko1d13a252012-10-15 11:58:41 +03006737 /* For AMP controller do not create l2cap conn */
6738 if (!conn && hcon->hdev->dev_type != HCI_BREDR)
6739 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006740
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02006741 if (!conn)
Claudio Takahasibaf43252013-04-11 13:55:50 -03006742 conn = l2cap_conn_add(hcon);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02006743
6744 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006745 goto drop;
6746
6747 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
6748
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006749 switch (flags) {
6750 case ACL_START:
6751 case ACL_START_NO_FLUSH:
6752 case ACL_COMPLETE:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006753 if (conn->rx_len) {
6754 BT_ERR("Unexpected start frame (len %d)", skb->len);
6755 kfree_skb(conn->rx_skb);
6756 conn->rx_skb = NULL;
6757 conn->rx_len = 0;
6758 l2cap_conn_unreliable(conn, ECOMM);
6759 }
6760
Andrei Emeltchenkoaae7fe22010-09-15 14:28:43 +03006761 /* Start fragment always begin with Basic L2CAP header */
6762 if (skb->len < L2CAP_HDR_SIZE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006763 BT_ERR("Frame is too short (len %d)", skb->len);
6764 l2cap_conn_unreliable(conn, ECOMM);
6765 goto drop;
6766 }
6767
6768 hdr = (struct l2cap_hdr *) skb->data;
6769 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
6770
6771 if (len == skb->len) {
6772 /* Complete frame received */
6773 l2cap_recv_frame(conn, skb);
6774 return 0;
6775 }
6776
6777 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
6778
6779 if (skb->len > len) {
6780 BT_ERR("Frame is too long (len %d, expected len %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01006781 skb->len, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006782 l2cap_conn_unreliable(conn, ECOMM);
6783 goto drop;
6784 }
6785
6786 /* Allocate skb for the complete frame (with header) */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03006787 conn->rx_skb = bt_skb_alloc(len, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03006788 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006789 goto drop;
6790
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03006791 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01006792 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006793 conn->rx_len = len - skb->len;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006794 break;
6795
6796 case ACL_CONT:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006797 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
6798
6799 if (!conn->rx_len) {
6800 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
6801 l2cap_conn_unreliable(conn, ECOMM);
6802 goto drop;
6803 }
6804
6805 if (skb->len > conn->rx_len) {
6806 BT_ERR("Fragment is too long (len %d, expected %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01006807 skb->len, conn->rx_len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006808 kfree_skb(conn->rx_skb);
6809 conn->rx_skb = NULL;
6810 conn->rx_len = 0;
6811 l2cap_conn_unreliable(conn, ECOMM);
6812 goto drop;
6813 }
6814
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03006815 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01006816 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006817 conn->rx_len -= skb->len;
6818
6819 if (!conn->rx_len) {
Johan Hedbergc4e5baf2013-10-10 13:33:37 +02006820 /* Complete frame received. l2cap_recv_frame
6821 * takes ownership of the skb so set the global
6822 * rx_skb pointer to NULL first.
6823 */
6824 struct sk_buff *rx_skb = conn->rx_skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006825 conn->rx_skb = NULL;
Johan Hedbergc4e5baf2013-10-10 13:33:37 +02006826 l2cap_recv_frame(conn, rx_skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006827 }
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006828 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006829 }
6830
6831drop:
6832 kfree_skb(skb);
6833 return 0;
6834}
6835
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006836static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006837{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006838 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006839
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02006840 read_lock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006841
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006842 list_for_each_entry(c, &chan_list, global_l) {
6843 struct sock *sk = c->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006844
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +03006845 seq_printf(f, "%pMR %pMR %d %d 0x%4.4x 0x%4.4x %d %d %d %d\n",
6846 &bt_sk(sk)->src, &bt_sk(sk)->dst,
6847 c->state, __le16_to_cpu(c->psm),
6848 c->scid, c->dcid, c->imtu, c->omtu,
6849 c->sec_level, c->mode);
Andrei Emeltchenko61e1b4b2012-01-19 11:19:50 +02006850 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006851
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02006852 read_unlock(&chan_list_lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08006853
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006854 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006855}
6856
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006857static int l2cap_debugfs_open(struct inode *inode, struct file *file)
6858{
6859 return single_open(file, l2cap_debugfs_show, inode->i_private);
6860}
6861
6862static const struct file_operations l2cap_debugfs_fops = {
6863 .open = l2cap_debugfs_open,
6864 .read = seq_read,
6865 .llseek = seq_lseek,
6866 .release = single_release,
6867};
6868
6869static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006870
Gustavo F. Padovan64274512011-02-07 20:08:52 -02006871int __init l2cap_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006872{
6873 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08006874
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02006875 err = l2cap_init_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006876 if (err < 0)
6877 return err;
6878
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006879 if (bt_debugfs) {
Gustavo Padovan2d792812012-10-06 10:07:01 +01006880 l2cap_debugfs = debugfs_create_file("l2cap", 0444, bt_debugfs,
6881 NULL, &l2cap_debugfs_fops);
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006882 if (!l2cap_debugfs)
6883 BT_ERR("Failed to create L2CAP debug file");
6884 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006885
Linus Torvalds1da177e2005-04-16 15:20:36 -07006886 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006887}
6888
Gustavo F. Padovan64274512011-02-07 20:08:52 -02006889void l2cap_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006890{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006891 debugfs_remove(l2cap_debugfs);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02006892 l2cap_cleanup_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006893}
6894
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03006895module_param(disable_ertm, bool, 0644);
6896MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode");