blob: 3ed9a2bf3d7c22f7ef800b5c9a5709c1fe6e3518 [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 bdaddr_t *src = &bt_sk(sk)->src;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001760 struct l2cap_conn *conn;
1761 struct hci_conn *hcon;
1762 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001763 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +02001764 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001765
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001766 BT_DBG("%pMR -> %pMR (type %u) psm 0x%2.2x", src, dst,
Syam Sidhardhanab195162012-07-27 23:51:22 +05301767 dst_type, __le16_to_cpu(psm));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001768
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001769 hdev = hci_get_route(dst, src);
1770 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001771 return -EHOSTUNREACH;
1772
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001773 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001774
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001775 l2cap_chan_lock(chan);
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001776
1777 /* PSM must be odd and lsb of upper byte must be 0 */
1778 if ((__le16_to_cpu(psm) & 0x0101) != 0x0001 && !cid &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01001779 chan->chan_type != L2CAP_CHAN_RAW) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001780 err = -EINVAL;
1781 goto done;
1782 }
1783
1784 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && !(psm || cid)) {
1785 err = -EINVAL;
1786 goto done;
1787 }
1788
1789 switch (chan->mode) {
1790 case L2CAP_MODE_BASIC:
1791 break;
1792 case L2CAP_MODE_ERTM:
1793 case L2CAP_MODE_STREAMING:
1794 if (!disable_ertm)
1795 break;
1796 /* fall through */
1797 default:
1798 err = -ENOTSUPP;
1799 goto done;
1800 }
1801
Gustavo Padovan0797e012012-05-27 22:27:54 -03001802 switch (chan->state) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001803 case BT_CONNECT:
1804 case BT_CONNECT2:
1805 case BT_CONFIG:
1806 /* Already connecting */
1807 err = 0;
1808 goto done;
1809
1810 case BT_CONNECTED:
1811 /* Already connected */
1812 err = -EISCONN;
1813 goto done;
1814
1815 case BT_OPEN:
1816 case BT_BOUND:
1817 /* Can connect */
1818 break;
1819
1820 default:
1821 err = -EBADFD;
1822 goto done;
1823 }
1824
1825 /* Set destination address and psm */
Gustavo Padovan0797e012012-05-27 22:27:54 -03001826 lock_sock(sk);
Gustavo F. Padovan9219b2a2012-01-02 20:08:04 -02001827 bacpy(&bt_sk(sk)->dst, dst);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001828 release_sock(sk);
1829
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001830 chan->psm = psm;
1831 chan->dcid = cid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001832
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001833 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001834
Johan Hedbergf224ca52013-04-29 19:35:36 +03001835 if (bdaddr_type_is_le(dst_type))
Andre Guedes8e9f9892012-04-24 21:02:55 -03001836 hcon = hci_connect(hdev, LE_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001837 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001838 else
Andre Guedes8e9f9892012-04-24 21:02:55 -03001839 hcon = hci_connect(hdev, ACL_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001840 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001841
Ville Tervo30e76272011-02-22 16:10:53 -03001842 if (IS_ERR(hcon)) {
1843 err = PTR_ERR(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001844 goto done;
Ville Tervo30e76272011-02-22 16:10:53 -03001845 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001846
Claudio Takahasibaf43252013-04-11 13:55:50 -03001847 conn = l2cap_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001848 if (!conn) {
David Herrmann76a68ba2013-04-06 20:28:37 +02001849 hci_conn_drop(hcon);
Ville Tervo30e76272011-02-22 16:10:53 -03001850 err = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001851 goto done;
1852 }
1853
Johan Hedberg141d5702013-04-29 19:35:37 +03001854 if (cid && __l2cap_get_chan_by_dcid(conn, cid)) {
1855 hci_conn_drop(hcon);
1856 err = -EBUSY;
1857 goto done;
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001858 }
1859
Linus Torvalds1da177e2005-04-16 15:20:36 -07001860 /* Update source addr of the socket */
Marcel Holtmann98e0f7e2013-10-13 02:23:40 -07001861 bacpy(src, &hdev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001862
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001863 l2cap_chan_unlock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001864 l2cap_chan_add(conn, chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001865 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001866
Johan Hedberg5ee98912013-04-29 19:35:43 +03001867 /* l2cap_chan_add takes its own ref so we can drop this one */
1868 hci_conn_drop(hcon);
1869
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001870 l2cap_state_change(chan, BT_CONNECT);
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001871 __set_chan_timer(chan, sk->sk_sndtimeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001872
1873 if (hcon->state == BT_CONNECTED) {
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001874 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001875 __clear_chan_timer(chan);
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001876 if (l2cap_chan_check_security(chan))
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001877 l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001878 } else
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001879 l2cap_do_start(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001880 }
1881
Ville Tervo30e76272011-02-22 16:10:53 -03001882 err = 0;
1883
Linus Torvalds1da177e2005-04-16 15:20:36 -07001884done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001885 l2cap_chan_unlock(chan);
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001886 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001887 hci_dev_put(hdev);
1888 return err;
1889}
1890
Gustavo F. Padovandcba0db2011-02-04 03:08:36 -02001891int __l2cap_wait_ack(struct sock *sk)
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001892{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001893 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001894 DECLARE_WAITQUEUE(wait, current);
1895 int err = 0;
1896 int timeo = HZ/5;
1897
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001898 add_wait_queue(sk_sleep(sk), &wait);
Peter Hurleya71a0cf2011-07-25 18:36:26 -04001899 set_current_state(TASK_INTERRUPTIBLE);
1900 while (chan->unacked_frames > 0 && chan->conn) {
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001901 if (!timeo)
1902 timeo = HZ/5;
1903
1904 if (signal_pending(current)) {
1905 err = sock_intr_errno(timeo);
1906 break;
1907 }
1908
1909 release_sock(sk);
1910 timeo = schedule_timeout(timeo);
1911 lock_sock(sk);
Peter Hurleya71a0cf2011-07-25 18:36:26 -04001912 set_current_state(TASK_INTERRUPTIBLE);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001913
1914 err = sock_error(sk);
1915 if (err)
1916 break;
1917 }
1918 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001919 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001920 return err;
1921}
1922
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001923static void l2cap_monitor_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001924{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001925 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001926 monitor_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001927
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03001928 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001929
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001930 l2cap_chan_lock(chan);
1931
Mat Martineau80909e02012-05-17 20:53:50 -07001932 if (!chan->conn) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001933 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001934 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001935 return;
1936 }
1937
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001938 l2cap_tx(chan, NULL, NULL, L2CAP_EV_MONITOR_TO);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001939
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001940 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001941 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001942}
1943
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001944static void l2cap_retrans_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001945{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001946 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001947 retrans_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001948
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03001949 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001950
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001951 l2cap_chan_lock(chan);
1952
Mat Martineau80909e02012-05-17 20:53:50 -07001953 if (!chan->conn) {
1954 l2cap_chan_unlock(chan);
1955 l2cap_chan_put(chan);
1956 return;
1957 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001958
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001959 l2cap_tx(chan, NULL, NULL, L2CAP_EV_RETRANS_TO);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001960 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001961 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001962}
1963
Gustavo Padovand6603662012-05-21 13:58:22 -03001964static void l2cap_streaming_send(struct l2cap_chan *chan,
1965 struct sk_buff_head *skbs)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001966{
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001967 struct sk_buff *skb;
Mat Martineau37339372012-05-17 20:53:33 -07001968 struct l2cap_ctrl *control;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001969
Mat Martineau37339372012-05-17 20:53:33 -07001970 BT_DBG("chan %p, skbs %p", chan, skbs);
1971
Mat Martineaub99e13a2012-10-23 15:24:19 -07001972 if (__chan_is_moving(chan))
1973 return;
1974
Mat Martineau37339372012-05-17 20:53:33 -07001975 skb_queue_splice_tail_init(skbs, &chan->tx_q);
1976
1977 while (!skb_queue_empty(&chan->tx_q)) {
1978
1979 skb = skb_dequeue(&chan->tx_q);
1980
1981 bt_cb(skb)->control.retries = 1;
1982 control = &bt_cb(skb)->control;
1983
1984 control->reqseq = 0;
1985 control->txseq = chan->next_tx_seq;
1986
1987 __pack_control(chan, control, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001988
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001989 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau37339372012-05-17 20:53:33 -07001990 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
1991 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001992 }
1993
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001994 l2cap_do_send(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001995
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001996 BT_DBG("Sent txseq %u", control->txseq);
Mat Martineau37339372012-05-17 20:53:33 -07001997
Andrei Emeltchenko836be932011-10-17 12:19:57 +03001998 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau37339372012-05-17 20:53:33 -07001999 chan->frames_sent++;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002000 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002001}
2002
Szymon Janc67c9e842011-07-28 16:24:33 +02002003static int l2cap_ertm_send(struct l2cap_chan *chan)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002004{
2005 struct sk_buff *skb, *tx_skb;
Mat Martineau18a48e72012-05-17 20:53:34 -07002006 struct l2cap_ctrl *control;
2007 int sent = 0;
2008
2009 BT_DBG("chan %p", chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002010
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03002011 if (chan->state != BT_CONNECTED)
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03002012 return -ENOTCONN;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002013
Mat Martineau94122bb2012-05-02 09:42:02 -07002014 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2015 return 0;
2016
Mat Martineaub99e13a2012-10-23 15:24:19 -07002017 if (__chan_is_moving(chan))
2018 return 0;
2019
Mat Martineau18a48e72012-05-17 20:53:34 -07002020 while (chan->tx_send_head &&
2021 chan->unacked_frames < chan->remote_tx_win &&
2022 chan->tx_state == L2CAP_TX_STATE_XMIT) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002023
Mat Martineau18a48e72012-05-17 20:53:34 -07002024 skb = chan->tx_send_head;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002025
Mat Martineau18a48e72012-05-17 20:53:34 -07002026 bt_cb(skb)->control.retries = 1;
2027 control = &bt_cb(skb)->control;
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03002028
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03002029 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
Mat Martineau18a48e72012-05-17 20:53:34 -07002030 control->final = 1;
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03002031
Mat Martineau18a48e72012-05-17 20:53:34 -07002032 control->reqseq = chan->buffer_seq;
2033 chan->last_acked_seq = chan->buffer_seq;
2034 control->txseq = chan->next_tx_seq;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002035
Mat Martineau18a48e72012-05-17 20:53:34 -07002036 __pack_control(chan, control, skb);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002037
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002038 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau18a48e72012-05-17 20:53:34 -07002039 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
2040 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002041 }
2042
Mat Martineau18a48e72012-05-17 20:53:34 -07002043 /* Clone after data has been modified. Data is assumed to be
2044 read-only (for locking purposes) on cloned sk_buffs.
2045 */
2046 tx_skb = skb_clone(skb, GFP_KERNEL);
2047
2048 if (!tx_skb)
2049 break;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03002050
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03002051 __set_retrans_timer(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002052
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002053 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau18a48e72012-05-17 20:53:34 -07002054 chan->unacked_frames++;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03002055 chan->frames_sent++;
Mat Martineau18a48e72012-05-17 20:53:34 -07002056 sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002057
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03002058 if (skb_queue_is_last(&chan->tx_q, skb))
2059 chan->tx_send_head = NULL;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002060 else
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03002061 chan->tx_send_head = skb_queue_next(&chan->tx_q, skb);
Mat Martineau18a48e72012-05-17 20:53:34 -07002062
2063 l2cap_do_send(chan, tx_skb);
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002064 BT_DBG("Sent txseq %u", control->txseq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002065 }
2066
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002067 BT_DBG("Sent %d, %u unacked, %u in ERTM queue", sent,
2068 chan->unacked_frames, skb_queue_len(&chan->tx_q));
Mat Martineau18a48e72012-05-17 20:53:34 -07002069
2070 return sent;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03002071}
2072
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002073static void l2cap_ertm_resend(struct l2cap_chan *chan)
2074{
2075 struct l2cap_ctrl control;
2076 struct sk_buff *skb;
2077 struct sk_buff *tx_skb;
2078 u16 seq;
2079
2080 BT_DBG("chan %p", chan);
2081
2082 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2083 return;
2084
Mat Martineaub99e13a2012-10-23 15:24:19 -07002085 if (__chan_is_moving(chan))
2086 return;
2087
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002088 while (chan->retrans_list.head != L2CAP_SEQ_LIST_CLEAR) {
2089 seq = l2cap_seq_list_pop(&chan->retrans_list);
2090
2091 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, seq);
2092 if (!skb) {
2093 BT_DBG("Error: Can't retransmit seq %d, frame missing",
Gustavo Padovan2d792812012-10-06 10:07:01 +01002094 seq);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002095 continue;
2096 }
2097
2098 bt_cb(skb)->control.retries++;
2099 control = bt_cb(skb)->control;
2100
2101 if (chan->max_tx != 0 &&
2102 bt_cb(skb)->control.retries > chan->max_tx) {
2103 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02002104 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002105 l2cap_seq_list_clear(&chan->retrans_list);
2106 break;
2107 }
2108
2109 control.reqseq = chan->buffer_seq;
2110 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
2111 control.final = 1;
2112 else
2113 control.final = 0;
2114
2115 if (skb_cloned(skb)) {
2116 /* Cloned sk_buffs are read-only, so we need a
2117 * writeable copy
2118 */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002119 tx_skb = skb_copy(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002120 } else {
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002121 tx_skb = skb_clone(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002122 }
2123
2124 if (!tx_skb) {
2125 l2cap_seq_list_clear(&chan->retrans_list);
2126 break;
2127 }
2128
2129 /* Update skb contents */
2130 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
2131 put_unaligned_le32(__pack_extended_control(&control),
2132 tx_skb->data + L2CAP_HDR_SIZE);
2133 } else {
2134 put_unaligned_le16(__pack_enhanced_control(&control),
2135 tx_skb->data + L2CAP_HDR_SIZE);
2136 }
2137
2138 if (chan->fcs == L2CAP_FCS_CRC16) {
2139 u16 fcs = crc16(0, (u8 *) tx_skb->data, tx_skb->len);
2140 put_unaligned_le16(fcs, skb_put(tx_skb,
2141 L2CAP_FCS_SIZE));
2142 }
2143
2144 l2cap_do_send(chan, tx_skb);
2145
2146 BT_DBG("Resent txseq %d", control.txseq);
2147
2148 chan->last_acked_seq = chan->buffer_seq;
2149 }
2150}
2151
Mat Martineauf80842a2012-05-17 20:53:46 -07002152static void l2cap_retransmit(struct l2cap_chan *chan,
2153 struct l2cap_ctrl *control)
2154{
2155 BT_DBG("chan %p, control %p", chan, control);
2156
2157 l2cap_seq_list_append(&chan->retrans_list, control->reqseq);
2158 l2cap_ertm_resend(chan);
2159}
2160
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002161static void l2cap_retransmit_all(struct l2cap_chan *chan,
2162 struct l2cap_ctrl *control)
2163{
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002164 struct sk_buff *skb;
2165
2166 BT_DBG("chan %p, control %p", chan, control);
2167
2168 if (control->poll)
2169 set_bit(CONN_SEND_FBIT, &chan->conn_state);
2170
2171 l2cap_seq_list_clear(&chan->retrans_list);
2172
2173 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2174 return;
2175
2176 if (chan->unacked_frames) {
2177 skb_queue_walk(&chan->tx_q, skb) {
2178 if (bt_cb(skb)->control.txseq == control->reqseq ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01002179 skb == chan->tx_send_head)
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002180 break;
2181 }
2182
2183 skb_queue_walk_from(&chan->tx_q, skb) {
2184 if (skb == chan->tx_send_head)
2185 break;
2186
2187 l2cap_seq_list_append(&chan->retrans_list,
2188 bt_cb(skb)->control.txseq);
2189 }
2190
2191 l2cap_ertm_resend(chan);
2192 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002193}
2194
Szymon Jancb17e73b2012-01-11 10:59:47 +01002195static void l2cap_send_ack(struct l2cap_chan *chan)
2196{
Mat Martineau0a0aba42012-05-17 20:53:39 -07002197 struct l2cap_ctrl control;
2198 u16 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
2199 chan->last_acked_seq);
2200 int threshold;
2201
2202 BT_DBG("chan %p last_acked_seq %d buffer_seq %d",
2203 chan, chan->last_acked_seq, chan->buffer_seq);
2204
2205 memset(&control, 0, sizeof(control));
2206 control.sframe = 1;
2207
2208 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
2209 chan->rx_state == L2CAP_RX_STATE_RECV) {
2210 __clear_ack_timer(chan);
2211 control.super = L2CAP_SUPER_RNR;
2212 control.reqseq = chan->buffer_seq;
2213 l2cap_send_sframe(chan, &control);
2214 } else {
2215 if (!test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) {
2216 l2cap_ertm_send(chan);
2217 /* If any i-frames were sent, they included an ack */
2218 if (chan->buffer_seq == chan->last_acked_seq)
2219 frames_to_ack = 0;
2220 }
2221
Mat Martineauc20f8e32012-07-10 05:47:07 -07002222 /* Ack now if the window is 3/4ths full.
Mat Martineau0a0aba42012-05-17 20:53:39 -07002223 * Calculate without mul or div
2224 */
Mat Martineauc20f8e32012-07-10 05:47:07 -07002225 threshold = chan->ack_win;
Mat Martineau0a0aba42012-05-17 20:53:39 -07002226 threshold += threshold << 1;
2227 threshold >>= 2;
2228
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002229 BT_DBG("frames_to_ack %u, threshold %d", frames_to_ack,
Mat Martineau0a0aba42012-05-17 20:53:39 -07002230 threshold);
2231
2232 if (frames_to_ack >= threshold) {
2233 __clear_ack_timer(chan);
2234 control.super = L2CAP_SUPER_RR;
2235 control.reqseq = chan->buffer_seq;
2236 l2cap_send_sframe(chan, &control);
2237 frames_to_ack = 0;
2238 }
2239
2240 if (frames_to_ack)
2241 __set_ack_timer(chan);
2242 }
Szymon Jancb17e73b2012-01-11 10:59:47 +01002243}
2244
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002245static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
2246 struct msghdr *msg, int len,
2247 int count, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002248{
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002249 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002250 struct sk_buff **frag;
Gustavo Padovan90338942012-04-06 20:15:47 -03002251 int sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002252
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03002253 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002254 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002255
2256 sent += count;
2257 len -= count;
2258
2259 /* Continuation fragments (no L2CAP header) */
2260 frag = &skb_shinfo(skb)->frag_list;
2261 while (len) {
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002262 struct sk_buff *tmp;
2263
Linus Torvalds1da177e2005-04-16 15:20:36 -07002264 count = min_t(unsigned int, conn->mtu, len);
2265
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002266 tmp = chan->ops->alloc_skb(chan, count,
2267 msg->msg_flags & MSG_DONTWAIT);
2268 if (IS_ERR(tmp))
2269 return PTR_ERR(tmp);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002270
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002271 *frag = tmp;
2272
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002273 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
2274 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002275
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002276 (*frag)->priority = skb->priority;
2277
Linus Torvalds1da177e2005-04-16 15:20:36 -07002278 sent += count;
2279 len -= count;
2280
Gustavo Padovan2d0ed3d2012-05-11 13:16:12 -03002281 skb->len += (*frag)->len;
2282 skb->data_len += (*frag)->len;
2283
Linus Torvalds1da177e2005-04-16 15:20:36 -07002284 frag = &(*frag)->next;
2285 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002286
2287 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002288}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002289
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002290static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002291 struct msghdr *msg, size_t len,
2292 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002293{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002294 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002295 struct sk_buff *skb;
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002296 int err, count, hlen = L2CAP_HDR_SIZE + L2CAP_PSMLEN_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002297 struct l2cap_hdr *lh;
2298
Marcel Holtmann43b1b8d2013-10-12 06:01:26 -07002299 BT_DBG("chan %p psm 0x%2.2x len %zu priority %u", chan,
2300 __le16_to_cpu(chan->psm), len, priority);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002301
2302 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002303
2304 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002305 msg->msg_flags & MSG_DONTWAIT);
2306 if (IS_ERR(skb))
2307 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002308
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002309 skb->priority = priority;
2310
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002311 /* Create L2CAP header */
2312 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002313 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenkodaf6a78c2012-05-03 10:55:52 +03002314 lh->len = cpu_to_le16(len + L2CAP_PSMLEN_SIZE);
Marcel Holtmann43b1b8d2013-10-12 06:01:26 -07002315 put_unaligned(chan->psm, (__le16 *) skb_put(skb, L2CAP_PSMLEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002316
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002317 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002318 if (unlikely(err < 0)) {
2319 kfree_skb(skb);
2320 return ERR_PTR(err);
2321 }
2322 return skb;
2323}
2324
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002325static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002326 struct msghdr *msg, size_t len,
2327 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002328{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002329 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002330 struct sk_buff *skb;
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002331 int err, count;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002332 struct l2cap_hdr *lh;
2333
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002334 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002335
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002336 count = min_t(unsigned int, (conn->mtu - L2CAP_HDR_SIZE), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002337
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002338 skb = chan->ops->alloc_skb(chan, count + L2CAP_HDR_SIZE,
Gustavo Padovan90338942012-04-06 20:15:47 -03002339 msg->msg_flags & MSG_DONTWAIT);
2340 if (IS_ERR(skb))
2341 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002342
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002343 skb->priority = priority;
2344
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002345 /* Create L2CAP header */
2346 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002347 lh->cid = cpu_to_le16(chan->dcid);
Gustavo Padovan6ff9b5e2012-05-02 11:56:17 -03002348 lh->len = cpu_to_le16(len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002349
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002350 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002351 if (unlikely(err < 0)) {
2352 kfree_skb(skb);
2353 return ERR_PTR(err);
2354 }
2355 return skb;
2356}
2357
Luiz Augusto von Dentzab0ff762011-09-12 20:00:50 +03002358static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002359 struct msghdr *msg, size_t len,
2360 u16 sdulen)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002361{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002362 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002363 struct sk_buff *skb;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002364 int err, count, hlen;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002365 struct l2cap_hdr *lh;
2366
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002367 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002368
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03002369 if (!conn)
2370 return ERR_PTR(-ENOTCONN);
2371
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002372 hlen = __ertm_hdr_size(chan);
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002373
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002374 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002375 hlen += L2CAP_SDULEN_SIZE;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002376
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002377 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002378 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002379
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002380 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002381
2382 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002383 msg->msg_flags & MSG_DONTWAIT);
2384 if (IS_ERR(skb))
2385 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002386
2387 /* Create L2CAP header */
2388 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002389 lh->cid = cpu_to_le16(chan->dcid);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002390 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002391
Mat Martineau18a48e72012-05-17 20:53:34 -07002392 /* Control header is populated later */
2393 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
2394 put_unaligned_le32(0, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
2395 else
2396 put_unaligned_le16(0, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002397
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002398 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002399 put_unaligned_le16(sdulen, skb_put(skb, L2CAP_SDULEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002400
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002401 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002402 if (unlikely(err < 0)) {
2403 kfree_skb(skb);
2404 return ERR_PTR(err);
2405 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002406
Mat Martineau18a48e72012-05-17 20:53:34 -07002407 bt_cb(skb)->control.fcs = chan->fcs;
Mat Martineau3ce35142012-04-25 16:36:14 -07002408 bt_cb(skb)->control.retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002409 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002410}
2411
Mat Martineau94122bb2012-05-02 09:42:02 -07002412static int l2cap_segment_sdu(struct l2cap_chan *chan,
2413 struct sk_buff_head *seg_queue,
2414 struct msghdr *msg, size_t len)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002415{
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002416 struct sk_buff *skb;
Mat Martineau94122bb2012-05-02 09:42:02 -07002417 u16 sdu_len;
2418 size_t pdu_len;
Mat Martineau94122bb2012-05-02 09:42:02 -07002419 u8 sar;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002420
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002421 BT_DBG("chan %p, msg %p, len %zu", chan, msg, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002422
Mat Martineau94122bb2012-05-02 09:42:02 -07002423 /* It is critical that ERTM PDUs fit in a single HCI fragment,
2424 * so fragmented skbs are not used. The HCI layer's handling
2425 * of fragmented skbs is not compatible with ERTM's queueing.
2426 */
2427
2428 /* PDU size is derived from the HCI MTU */
2429 pdu_len = chan->conn->mtu;
2430
Mat Martineaua5495742012-10-23 15:24:21 -07002431 /* Constrain PDU size for BR/EDR connections */
2432 if (!chan->hs_hcon)
2433 pdu_len = min_t(size_t, pdu_len, L2CAP_BREDR_MAX_PAYLOAD);
Mat Martineau94122bb2012-05-02 09:42:02 -07002434
2435 /* Adjust for largest possible L2CAP overhead. */
Gustavo Padovan35d401d2012-05-25 18:57:05 -03002436 if (chan->fcs)
2437 pdu_len -= L2CAP_FCS_SIZE;
2438
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002439 pdu_len -= __ertm_hdr_size(chan);
Mat Martineau94122bb2012-05-02 09:42:02 -07002440
2441 /* Remote device may have requested smaller PDUs */
2442 pdu_len = min_t(size_t, pdu_len, chan->remote_mps);
2443
2444 if (len <= pdu_len) {
2445 sar = L2CAP_SAR_UNSEGMENTED;
2446 sdu_len = 0;
2447 pdu_len = len;
2448 } else {
2449 sar = L2CAP_SAR_START;
2450 sdu_len = len;
2451 pdu_len -= L2CAP_SDULEN_SIZE;
2452 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002453
2454 while (len > 0) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002455 skb = l2cap_create_iframe_pdu(chan, msg, pdu_len, sdu_len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002456
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002457 if (IS_ERR(skb)) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002458 __skb_queue_purge(seg_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002459 return PTR_ERR(skb);
2460 }
2461
Mat Martineau94122bb2012-05-02 09:42:02 -07002462 bt_cb(skb)->control.sar = sar;
2463 __skb_queue_tail(seg_queue, skb);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002464
Mat Martineau94122bb2012-05-02 09:42:02 -07002465 len -= pdu_len;
2466 if (sdu_len) {
2467 sdu_len = 0;
2468 pdu_len += L2CAP_SDULEN_SIZE;
2469 }
2470
2471 if (len <= pdu_len) {
2472 sar = L2CAP_SAR_END;
2473 pdu_len = len;
2474 } else {
2475 sar = L2CAP_SAR_CONTINUE;
2476 }
2477 }
2478
Gustavo Padovanf0f62792012-05-29 13:29:17 -03002479 return 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002480}
2481
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002482int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01002483 u32 priority)
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002484{
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002485 struct sk_buff *skb;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002486 int err;
Mat Martineau94122bb2012-05-02 09:42:02 -07002487 struct sk_buff_head seg_queue;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002488
2489 /* Connectionless channel */
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002490 if (chan->chan_type == L2CAP_CHAN_CONN_LESS) {
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002491 skb = l2cap_create_connless_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002492 if (IS_ERR(skb))
2493 return PTR_ERR(skb);
2494
2495 l2cap_do_send(chan, skb);
2496 return len;
2497 }
2498
2499 switch (chan->mode) {
2500 case L2CAP_MODE_BASIC:
2501 /* Check outgoing MTU */
2502 if (len > chan->omtu)
2503 return -EMSGSIZE;
2504
2505 /* Create a basic PDU */
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002506 skb = l2cap_create_basic_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002507 if (IS_ERR(skb))
2508 return PTR_ERR(skb);
2509
2510 l2cap_do_send(chan, skb);
2511 err = len;
2512 break;
2513
2514 case L2CAP_MODE_ERTM:
2515 case L2CAP_MODE_STREAMING:
Mat Martineau94122bb2012-05-02 09:42:02 -07002516 /* Check outgoing MTU */
2517 if (len > chan->omtu) {
2518 err = -EMSGSIZE;
2519 break;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002520 }
2521
Mat Martineau94122bb2012-05-02 09:42:02 -07002522 __skb_queue_head_init(&seg_queue);
2523
2524 /* Do segmentation before calling in to the state machine,
2525 * since it's possible to block while waiting for memory
2526 * allocation.
2527 */
2528 err = l2cap_segment_sdu(chan, &seg_queue, msg, len);
2529
2530 /* The channel could have been closed while segmenting,
2531 * check that it is still connected.
2532 */
2533 if (chan->state != BT_CONNECTED) {
2534 __skb_queue_purge(&seg_queue);
2535 err = -ENOTCONN;
2536 }
2537
2538 if (err)
2539 break;
2540
Mat Martineau37339372012-05-17 20:53:33 -07002541 if (chan->mode == L2CAP_MODE_ERTM)
Gustavo Padovand6603662012-05-21 13:58:22 -03002542 l2cap_tx(chan, NULL, &seg_queue, L2CAP_EV_DATA_REQUEST);
Mat Martineau37339372012-05-17 20:53:33 -07002543 else
Gustavo Padovand6603662012-05-21 13:58:22 -03002544 l2cap_streaming_send(chan, &seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002545
Gustavo Padovand6603662012-05-21 13:58:22 -03002546 err = len;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002547
Mat Martineau94122bb2012-05-02 09:42:02 -07002548 /* If the skbs were not queued for sending, they'll still be in
2549 * seg_queue and need to be purged.
2550 */
2551 __skb_queue_purge(&seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002552 break;
2553
2554 default:
2555 BT_DBG("bad state %1.1x", chan->mode);
2556 err = -EBADFD;
2557 }
2558
2559 return err;
2560}
2561
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002562static void l2cap_send_srej(struct l2cap_chan *chan, u16 txseq)
2563{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002564 struct l2cap_ctrl control;
2565 u16 seq;
2566
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002567 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002568
2569 memset(&control, 0, sizeof(control));
2570 control.sframe = 1;
2571 control.super = L2CAP_SUPER_SREJ;
2572
2573 for (seq = chan->expected_tx_seq; seq != txseq;
2574 seq = __next_seq(chan, seq)) {
2575 if (!l2cap_ertm_seq_in_queue(&chan->srej_q, seq)) {
2576 control.reqseq = seq;
2577 l2cap_send_sframe(chan, &control);
2578 l2cap_seq_list_append(&chan->srej_list, seq);
2579 }
2580 }
2581
2582 chan->expected_tx_seq = __next_seq(chan, txseq);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002583}
2584
2585static void l2cap_send_srej_tail(struct l2cap_chan *chan)
2586{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002587 struct l2cap_ctrl control;
2588
2589 BT_DBG("chan %p", chan);
2590
2591 if (chan->srej_list.tail == L2CAP_SEQ_LIST_CLEAR)
2592 return;
2593
2594 memset(&control, 0, sizeof(control));
2595 control.sframe = 1;
2596 control.super = L2CAP_SUPER_SREJ;
2597 control.reqseq = chan->srej_list.tail;
2598 l2cap_send_sframe(chan, &control);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002599}
2600
2601static void l2cap_send_srej_list(struct l2cap_chan *chan, u16 txseq)
2602{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002603 struct l2cap_ctrl control;
2604 u16 initial_head;
2605 u16 seq;
2606
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002607 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002608
2609 memset(&control, 0, sizeof(control));
2610 control.sframe = 1;
2611 control.super = L2CAP_SUPER_SREJ;
2612
2613 /* Capture initial list head to allow only one pass through the list. */
2614 initial_head = chan->srej_list.head;
2615
2616 do {
2617 seq = l2cap_seq_list_pop(&chan->srej_list);
2618 if (seq == txseq || seq == L2CAP_SEQ_LIST_CLEAR)
2619 break;
2620
2621 control.reqseq = seq;
2622 l2cap_send_sframe(chan, &control);
2623 l2cap_seq_list_append(&chan->srej_list, seq);
2624 } while (chan->srej_list.head != initial_head);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002625}
2626
Mat Martineau608bcc62012-05-17 20:53:32 -07002627static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq)
2628{
2629 struct sk_buff *acked_skb;
2630 u16 ackseq;
2631
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002632 BT_DBG("chan %p, reqseq %u", chan, reqseq);
Mat Martineau608bcc62012-05-17 20:53:32 -07002633
2634 if (chan->unacked_frames == 0 || reqseq == chan->expected_ack_seq)
2635 return;
2636
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002637 BT_DBG("expected_ack_seq %u, unacked_frames %u",
Mat Martineau608bcc62012-05-17 20:53:32 -07002638 chan->expected_ack_seq, chan->unacked_frames);
2639
2640 for (ackseq = chan->expected_ack_seq; ackseq != reqseq;
2641 ackseq = __next_seq(chan, ackseq)) {
2642
2643 acked_skb = l2cap_ertm_seq_in_queue(&chan->tx_q, ackseq);
2644 if (acked_skb) {
2645 skb_unlink(acked_skb, &chan->tx_q);
2646 kfree_skb(acked_skb);
2647 chan->unacked_frames--;
2648 }
2649 }
2650
2651 chan->expected_ack_seq = reqseq;
2652
2653 if (chan->unacked_frames == 0)
2654 __clear_retrans_timer(chan);
2655
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002656 BT_DBG("unacked_frames %u", chan->unacked_frames);
Mat Martineau608bcc62012-05-17 20:53:32 -07002657}
2658
2659static void l2cap_abort_rx_srej_sent(struct l2cap_chan *chan)
2660{
2661 BT_DBG("chan %p", chan);
2662
2663 chan->expected_tx_seq = chan->buffer_seq;
2664 l2cap_seq_list_clear(&chan->srej_list);
2665 skb_queue_purge(&chan->srej_q);
2666 chan->rx_state = L2CAP_RX_STATE_RECV;
2667}
2668
Gustavo Padovand6603662012-05-21 13:58:22 -03002669static void l2cap_tx_state_xmit(struct l2cap_chan *chan,
2670 struct l2cap_ctrl *control,
2671 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002672{
Mat Martineau608bcc62012-05-17 20:53:32 -07002673 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2674 event);
2675
2676 switch (event) {
2677 case L2CAP_EV_DATA_REQUEST:
2678 if (chan->tx_send_head == NULL)
2679 chan->tx_send_head = skb_peek(skbs);
2680
2681 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2682 l2cap_ertm_send(chan);
2683 break;
2684 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2685 BT_DBG("Enter LOCAL_BUSY");
2686 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2687
2688 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2689 /* The SREJ_SENT state must be aborted if we are to
2690 * enter the LOCAL_BUSY state.
2691 */
2692 l2cap_abort_rx_srej_sent(chan);
2693 }
2694
2695 l2cap_send_ack(chan);
2696
2697 break;
2698 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2699 BT_DBG("Exit LOCAL_BUSY");
2700 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2701
2702 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2703 struct l2cap_ctrl local_control;
2704
2705 memset(&local_control, 0, sizeof(local_control));
2706 local_control.sframe = 1;
2707 local_control.super = L2CAP_SUPER_RR;
2708 local_control.poll = 1;
2709 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002710 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002711
2712 chan->retry_count = 1;
2713 __set_monitor_timer(chan);
2714 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2715 }
2716 break;
2717 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2718 l2cap_process_reqseq(chan, control->reqseq);
2719 break;
2720 case L2CAP_EV_EXPLICIT_POLL:
2721 l2cap_send_rr_or_rnr(chan, 1);
2722 chan->retry_count = 1;
2723 __set_monitor_timer(chan);
2724 __clear_ack_timer(chan);
2725 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2726 break;
2727 case L2CAP_EV_RETRANS_TO:
2728 l2cap_send_rr_or_rnr(chan, 1);
2729 chan->retry_count = 1;
2730 __set_monitor_timer(chan);
2731 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2732 break;
2733 case L2CAP_EV_RECV_FBIT:
2734 /* Nothing to process */
2735 break;
2736 default:
2737 break;
2738 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002739}
2740
Gustavo Padovand6603662012-05-21 13:58:22 -03002741static void l2cap_tx_state_wait_f(struct l2cap_chan *chan,
2742 struct l2cap_ctrl *control,
2743 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002744{
Mat Martineau608bcc62012-05-17 20:53:32 -07002745 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2746 event);
2747
2748 switch (event) {
2749 case L2CAP_EV_DATA_REQUEST:
2750 if (chan->tx_send_head == NULL)
2751 chan->tx_send_head = skb_peek(skbs);
2752 /* Queue data, but don't send. */
2753 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2754 break;
2755 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2756 BT_DBG("Enter LOCAL_BUSY");
2757 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2758
2759 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2760 /* The SREJ_SENT state must be aborted if we are to
2761 * enter the LOCAL_BUSY state.
2762 */
2763 l2cap_abort_rx_srej_sent(chan);
2764 }
2765
2766 l2cap_send_ack(chan);
2767
2768 break;
2769 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2770 BT_DBG("Exit LOCAL_BUSY");
2771 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2772
2773 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2774 struct l2cap_ctrl local_control;
2775 memset(&local_control, 0, sizeof(local_control));
2776 local_control.sframe = 1;
2777 local_control.super = L2CAP_SUPER_RR;
2778 local_control.poll = 1;
2779 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002780 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002781
2782 chan->retry_count = 1;
2783 __set_monitor_timer(chan);
2784 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2785 }
2786 break;
2787 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2788 l2cap_process_reqseq(chan, control->reqseq);
2789
2790 /* Fall through */
2791
2792 case L2CAP_EV_RECV_FBIT:
2793 if (control && control->final) {
2794 __clear_monitor_timer(chan);
2795 if (chan->unacked_frames > 0)
2796 __set_retrans_timer(chan);
2797 chan->retry_count = 0;
2798 chan->tx_state = L2CAP_TX_STATE_XMIT;
2799 BT_DBG("recv fbit tx_state 0x2.2%x", chan->tx_state);
2800 }
2801 break;
2802 case L2CAP_EV_EXPLICIT_POLL:
2803 /* Ignore */
2804 break;
2805 case L2CAP_EV_MONITOR_TO:
2806 if (chan->max_tx == 0 || chan->retry_count < chan->max_tx) {
2807 l2cap_send_rr_or_rnr(chan, 1);
2808 __set_monitor_timer(chan);
2809 chan->retry_count++;
2810 } else {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02002811 l2cap_send_disconn_req(chan, ECONNABORTED);
Mat Martineau608bcc62012-05-17 20:53:32 -07002812 }
2813 break;
2814 default:
2815 break;
2816 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002817}
2818
Gustavo Padovand6603662012-05-21 13:58:22 -03002819static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
2820 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002821{
Mat Martineau608bcc62012-05-17 20:53:32 -07002822 BT_DBG("chan %p, control %p, skbs %p, event %d, state %d",
2823 chan, control, skbs, event, chan->tx_state);
2824
2825 switch (chan->tx_state) {
2826 case L2CAP_TX_STATE_XMIT:
Gustavo Padovand6603662012-05-21 13:58:22 -03002827 l2cap_tx_state_xmit(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002828 break;
2829 case L2CAP_TX_STATE_WAIT_F:
Gustavo Padovand6603662012-05-21 13:58:22 -03002830 l2cap_tx_state_wait_f(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002831 break;
2832 default:
2833 /* Ignore event */
2834 break;
2835 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002836}
2837
Mat Martineau4b51dae92012-05-17 20:53:37 -07002838static void l2cap_pass_to_tx(struct l2cap_chan *chan,
2839 struct l2cap_ctrl *control)
2840{
2841 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002842 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_REQSEQ_AND_FBIT);
Mat Martineau4b51dae92012-05-17 20:53:37 -07002843}
2844
Mat Martineauf80842a2012-05-17 20:53:46 -07002845static void l2cap_pass_to_tx_fbit(struct l2cap_chan *chan,
2846 struct l2cap_ctrl *control)
2847{
2848 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002849 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_FBIT);
Mat Martineauf80842a2012-05-17 20:53:46 -07002850}
2851
Linus Torvalds1da177e2005-04-16 15:20:36 -07002852/* Copy frame to all raw sockets on that connection */
2853static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2854{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002855 struct sk_buff *nskb;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002856 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002857
2858 BT_DBG("conn %p", conn);
2859
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002860 mutex_lock(&conn->chan_lock);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002861
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002862 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002863 struct sock *sk = chan->sk;
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002864 if (chan->chan_type != L2CAP_CHAN_RAW)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002865 continue;
2866
2867 /* Don't send frame to the socket it came from */
2868 if (skb->sk == sk)
2869 continue;
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002870 nskb = skb_clone(skb, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002871 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002872 continue;
2873
Gustavo Padovan80b98022012-05-27 22:27:51 -03002874 if (chan->ops->recv(chan, nskb))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002875 kfree_skb(nskb);
2876 }
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002877
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002878 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002879}
2880
2881/* ---- L2CAP signalling commands ---- */
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002882static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code,
2883 u8 ident, u16 dlen, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002884{
2885 struct sk_buff *skb, **frag;
2886 struct l2cap_cmd_hdr *cmd;
2887 struct l2cap_hdr *lh;
2888 int len, count;
2889
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002890 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %u",
2891 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002892
Anderson Lizardo300b9622013-06-02 16:30:40 -04002893 if (conn->mtu < L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE)
2894 return NULL;
2895
Linus Torvalds1da177e2005-04-16 15:20:36 -07002896 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2897 count = min_t(unsigned int, conn->mtu, len);
2898
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002899 skb = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002900 if (!skb)
2901 return NULL;
2902
2903 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002904 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002905
2906 if (conn->hcon->type == LE_LINK)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002907 lh->cid = __constant_cpu_to_le16(L2CAP_CID_LE_SIGNALING);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002908 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002909 lh->cid = __constant_cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002910
2911 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2912 cmd->code = code;
2913 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002914 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002915
2916 if (dlen) {
2917 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2918 memcpy(skb_put(skb, count), data, count);
2919 data += count;
2920 }
2921
2922 len -= skb->len;
2923
2924 /* Continuation fragments (no L2CAP header) */
2925 frag = &skb_shinfo(skb)->frag_list;
2926 while (len) {
2927 count = min_t(unsigned int, conn->mtu, len);
2928
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002929 *frag = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002930 if (!*frag)
2931 goto fail;
2932
2933 memcpy(skb_put(*frag, count), data, count);
2934
2935 len -= count;
2936 data += count;
2937
2938 frag = &(*frag)->next;
2939 }
2940
2941 return skb;
2942
2943fail:
2944 kfree_skb(skb);
2945 return NULL;
2946}
2947
Gustavo Padovan2d792812012-10-06 10:07:01 +01002948static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen,
2949 unsigned long *val)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002950{
2951 struct l2cap_conf_opt *opt = *ptr;
2952 int len;
2953
2954 len = L2CAP_CONF_OPT_SIZE + opt->len;
2955 *ptr += len;
2956
2957 *type = opt->type;
2958 *olen = opt->len;
2959
2960 switch (opt->len) {
2961 case 1:
2962 *val = *((u8 *) opt->val);
2963 break;
2964
2965 case 2:
steven miaobfaaeb32010-10-16 18:29:47 -04002966 *val = get_unaligned_le16(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002967 break;
2968
2969 case 4:
steven miaobfaaeb32010-10-16 18:29:47 -04002970 *val = get_unaligned_le32(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002971 break;
2972
2973 default:
2974 *val = (unsigned long) opt->val;
2975 break;
2976 }
2977
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002978 BT_DBG("type 0x%2.2x len %u val 0x%lx", *type, opt->len, *val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002979 return len;
2980}
2981
Linus Torvalds1da177e2005-04-16 15:20:36 -07002982static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2983{
2984 struct l2cap_conf_opt *opt = *ptr;
2985
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002986 BT_DBG("type 0x%2.2x len %u val 0x%lx", type, len, val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002987
2988 opt->type = type;
2989 opt->len = len;
2990
2991 switch (len) {
2992 case 1:
2993 *((u8 *) opt->val) = val;
2994 break;
2995
2996 case 2:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002997 put_unaligned_le16(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002998 break;
2999
3000 case 4:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02003001 put_unaligned_le32(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003002 break;
3003
3004 default:
3005 memcpy(opt->val, (void *) val, len);
3006 break;
3007 }
3008
3009 *ptr += L2CAP_CONF_OPT_SIZE + len;
3010}
3011
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003012static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan)
3013{
3014 struct l2cap_conf_efs efs;
3015
Szymon Janc1ec918c2011-11-16 09:32:21 +01003016 switch (chan->mode) {
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003017 case L2CAP_MODE_ERTM:
3018 efs.id = chan->local_id;
3019 efs.stype = chan->local_stype;
3020 efs.msdu = cpu_to_le16(chan->local_msdu);
3021 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003022 efs.acc_lat = __constant_cpu_to_le32(L2CAP_DEFAULT_ACC_LAT);
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03003023 efs.flush_to = __constant_cpu_to_le32(L2CAP_EFS_DEFAULT_FLUSH_TO);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003024 break;
3025
3026 case L2CAP_MODE_STREAMING:
3027 efs.id = 1;
3028 efs.stype = L2CAP_SERV_BESTEFFORT;
3029 efs.msdu = cpu_to_le16(chan->local_msdu);
3030 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
3031 efs.acc_lat = 0;
3032 efs.flush_to = 0;
3033 break;
3034
3035 default:
3036 return;
3037 }
3038
3039 l2cap_add_conf_opt(ptr, L2CAP_CONF_EFS, sizeof(efs),
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03003040 (unsigned long) &efs);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003041}
3042
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003043static void l2cap_ack_timeout(struct work_struct *work)
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003044{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003045 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau03625202012-05-17 20:53:51 -07003046 ack_timer.work);
3047 u16 frames_to_ack;
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003048
Gustavo F. Padovan2fb9b3d2011-12-22 16:56:05 -02003049 BT_DBG("chan %p", chan);
3050
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003051 l2cap_chan_lock(chan);
3052
Mat Martineau03625202012-05-17 20:53:51 -07003053 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
3054 chan->last_acked_seq);
3055
3056 if (frames_to_ack)
3057 l2cap_send_rr_or_rnr(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003058
3059 l2cap_chan_unlock(chan);
Szymon Janc09bfb2e2012-01-11 10:59:49 +01003060 l2cap_chan_put(chan);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003061}
3062
Andrei Emeltchenko466f8002012-05-29 13:59:01 +03003063int l2cap_ertm_init(struct l2cap_chan *chan)
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003064{
Mat Martineau3c588192012-04-11 10:48:42 -07003065 int err;
3066
Mat Martineau105bdf92012-04-27 16:50:48 -07003067 chan->next_tx_seq = 0;
3068 chan->expected_tx_seq = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03003069 chan->expected_ack_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03003070 chan->unacked_frames = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03003071 chan->buffer_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03003072 chan->frames_sent = 0;
Mat Martineau105bdf92012-04-27 16:50:48 -07003073 chan->last_acked_seq = 0;
3074 chan->sdu = NULL;
3075 chan->sdu_last_frag = NULL;
3076 chan->sdu_len = 0;
3077
Mat Martineaud34c34f2012-05-14 14:49:27 -07003078 skb_queue_head_init(&chan->tx_q);
3079
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003080 chan->local_amp_id = AMP_ID_BREDR;
3081 chan->move_id = AMP_ID_BREDR;
Mat Martineau08333282012-10-23 15:24:06 -07003082 chan->move_state = L2CAP_MOVE_STABLE;
3083 chan->move_role = L2CAP_MOVE_ROLE_NONE;
3084
Mat Martineau105bdf92012-04-27 16:50:48 -07003085 if (chan->mode != L2CAP_MODE_ERTM)
3086 return 0;
3087
3088 chan->rx_state = L2CAP_RX_STATE_RECV;
3089 chan->tx_state = L2CAP_TX_STATE_XMIT;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003090
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003091 INIT_DELAYED_WORK(&chan->retrans_timer, l2cap_retrans_timeout);
3092 INIT_DELAYED_WORK(&chan->monitor_timer, l2cap_monitor_timeout);
3093 INIT_DELAYED_WORK(&chan->ack_timer, l2cap_ack_timeout);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003094
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -03003095 skb_queue_head_init(&chan->srej_q);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003096
Mat Martineau3c588192012-04-11 10:48:42 -07003097 err = l2cap_seq_list_init(&chan->srej_list, chan->tx_win);
3098 if (err < 0)
3099 return err;
3100
Mat Martineau9dc9aff2012-05-17 16:20:14 -07003101 err = l2cap_seq_list_init(&chan->retrans_list, chan->remote_tx_win);
3102 if (err < 0)
3103 l2cap_seq_list_free(&chan->srej_list);
3104
3105 return err;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003106}
3107
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003108static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
3109{
3110 switch (mode) {
3111 case L2CAP_MODE_STREAMING:
3112 case L2CAP_MODE_ERTM:
3113 if (l2cap_mode_supported(mode, remote_feat_mask))
3114 return mode;
3115 /* fall through */
3116 default:
3117 return L2CAP_MODE_BASIC;
3118 }
3119}
3120
Marcel Holtmann848566b2013-10-01 22:59:22 -07003121static inline bool __l2cap_ews_supported(struct l2cap_conn *conn)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003122{
Marcel Holtmann848566b2013-10-01 22:59:22 -07003123 return conn->hs_enabled && conn->feat_mask & L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003124}
3125
Marcel Holtmann848566b2013-10-01 22:59:22 -07003126static inline bool __l2cap_efs_supported(struct l2cap_conn *conn)
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003127{
Marcel Holtmann848566b2013-10-01 22:59:22 -07003128 return conn->hs_enabled && conn->feat_mask & L2CAP_FEAT_EXT_FLOW;
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003129}
3130
Mat Martineau36c86c82012-10-23 15:24:20 -07003131static void __l2cap_set_ertm_timeouts(struct l2cap_chan *chan,
3132 struct l2cap_conf_rfc *rfc)
3133{
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003134 if (chan->local_amp_id != AMP_ID_BREDR && chan->hs_hcon) {
Mat Martineau36c86c82012-10-23 15:24:20 -07003135 u64 ertm_to = chan->hs_hcon->hdev->amp_be_flush_to;
3136
3137 /* Class 1 devices have must have ERTM timeouts
3138 * exceeding the Link Supervision Timeout. The
3139 * default Link Supervision Timeout for AMP
3140 * controllers is 10 seconds.
3141 *
3142 * Class 1 devices use 0xffffffff for their
3143 * best-effort flush timeout, so the clamping logic
3144 * will result in a timeout that meets the above
3145 * requirement. ERTM timeouts are 16-bit values, so
3146 * the maximum timeout is 65.535 seconds.
3147 */
3148
3149 /* Convert timeout to milliseconds and round */
3150 ertm_to = DIV_ROUND_UP_ULL(ertm_to, 1000);
3151
3152 /* This is the recommended formula for class 2 devices
3153 * that start ERTM timers when packets are sent to the
3154 * controller.
3155 */
3156 ertm_to = 3 * ertm_to + 500;
3157
3158 if (ertm_to > 0xffff)
3159 ertm_to = 0xffff;
3160
3161 rfc->retrans_timeout = cpu_to_le16((u16) ertm_to);
3162 rfc->monitor_timeout = rfc->retrans_timeout;
3163 } else {
3164 rfc->retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
3165 rfc->monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
3166 }
3167}
3168
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003169static inline void l2cap_txwin_setup(struct l2cap_chan *chan)
3170{
3171 if (chan->tx_win > L2CAP_DEFAULT_TX_WINDOW &&
Marcel Holtmann848566b2013-10-01 22:59:22 -07003172 __l2cap_ews_supported(chan->conn)) {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003173 /* use extended control field */
3174 set_bit(FLAG_EXT_CTRL, &chan->flags);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003175 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
3176 } else {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003177 chan->tx_win = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003178 L2CAP_DEFAULT_TX_WINDOW);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003179 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
3180 }
Mat Martineauc20f8e32012-07-10 05:47:07 -07003181 chan->ack_win = chan->tx_win;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003182}
3183
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003184static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003185{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003186 struct l2cap_conf_req *req = data;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003187 struct l2cap_conf_rfc rfc = { .mode = chan->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07003188 void *ptr = req->data;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003189 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003190
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03003191 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003192
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003193 if (chan->num_conf_req || chan->num_conf_rsp)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003194 goto done;
3195
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003196 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003197 case L2CAP_MODE_STREAMING:
3198 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003199 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state))
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003200 break;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003201
Marcel Holtmann848566b2013-10-01 22:59:22 -07003202 if (__l2cap_efs_supported(chan->conn))
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003203 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3204
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03003205 /* fall through */
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003206 default:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003207 chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003208 break;
3209 }
3210
3211done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003212 if (chan->imtu != L2CAP_DEFAULT_MTU)
3213 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovan7990681c2011-01-24 16:01:43 -02003214
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003215 switch (chan->mode) {
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003216 case L2CAP_MODE_BASIC:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003217 if (!(chan->conn->feat_mask & L2CAP_FEAT_ERTM) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003218 !(chan->conn->feat_mask & L2CAP_FEAT_STREAMING))
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003219 break;
3220
Gustavo F. Padovan62547752010-06-08 20:05:31 -03003221 rfc.mode = L2CAP_MODE_BASIC;
3222 rfc.txwin_size = 0;
3223 rfc.max_transmit = 0;
3224 rfc.retrans_timeout = 0;
3225 rfc.monitor_timeout = 0;
3226 rfc.max_pdu_size = 0;
3227
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003228 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003229 (unsigned long) &rfc);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003230 break;
3231
3232 case L2CAP_MODE_ERTM:
3233 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003234 rfc.max_transmit = chan->max_tx;
Mat Martineau36c86c82012-10-23 15:24:20 -07003235
3236 __l2cap_set_ertm_timeouts(chan, &rfc);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003237
3238 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003239 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3240 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003241 rfc.max_pdu_size = cpu_to_le16(size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003242
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003243 l2cap_txwin_setup(chan);
3244
3245 rfc.txwin_size = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003246 L2CAP_DEFAULT_TX_WINDOW);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003247
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003248 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003249 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003250
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003251 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3252 l2cap_add_opt_efs(&ptr, chan);
3253
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003254 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3255 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003256 chan->tx_win);
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003257
3258 if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
3259 if (chan->fcs == L2CAP_FCS_NONE ||
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003260 test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003261 chan->fcs = L2CAP_FCS_NONE;
3262 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
3263 chan->fcs);
3264 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003265 break;
3266
3267 case L2CAP_MODE_STREAMING:
Mat Martineau273759e2012-05-17 20:53:53 -07003268 l2cap_txwin_setup(chan);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003269 rfc.mode = L2CAP_MODE_STREAMING;
3270 rfc.txwin_size = 0;
3271 rfc.max_transmit = 0;
3272 rfc.retrans_timeout = 0;
3273 rfc.monitor_timeout = 0;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003274
3275 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003276 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3277 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003278 rfc.max_pdu_size = cpu_to_le16(size);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003279
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003280 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003281 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003282
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003283 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3284 l2cap_add_opt_efs(&ptr, chan);
3285
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003286 if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
3287 if (chan->fcs == L2CAP_FCS_NONE ||
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003288 test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003289 chan->fcs = L2CAP_FCS_NONE;
3290 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
3291 chan->fcs);
3292 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003293 break;
3294 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003295
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003296 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003297 req->flags = __constant_cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003298
3299 return ptr - data;
3300}
3301
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003302static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003303{
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003304 struct l2cap_conf_rsp *rsp = data;
3305 void *ptr = rsp->data;
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003306 void *req = chan->conf_req;
3307 int len = chan->conf_len;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003308 int type, hint, olen;
3309 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003310 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003311 struct l2cap_conf_efs efs;
3312 u8 remote_efs = 0;
Marcel Holtmann861d6882007-10-20 13:37:06 +02003313 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003314 u16 result = L2CAP_CONF_SUCCESS;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003315 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003316
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003317 BT_DBG("chan %p", chan);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01003318
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003319 while (len >= L2CAP_CONF_OPT_SIZE) {
3320 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003321
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03003322 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003323 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003324
3325 switch (type) {
3326 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02003327 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003328 break;
3329
3330 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003331 chan->flush_to = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003332 break;
3333
3334 case L2CAP_CONF_QOS:
3335 break;
3336
Marcel Holtmann6464f352007-10-20 13:39:51 +02003337 case L2CAP_CONF_RFC:
3338 if (olen == sizeof(rfc))
3339 memcpy(&rfc, (void *) val, olen);
3340 break;
3341
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003342 case L2CAP_CONF_FCS:
3343 if (val == L2CAP_FCS_NONE)
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003344 set_bit(CONF_RECV_NO_FCS, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003345 break;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003346
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003347 case L2CAP_CONF_EFS:
3348 remote_efs = 1;
3349 if (olen == sizeof(efs))
3350 memcpy(&efs, (void *) val, olen);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003351 break;
3352
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003353 case L2CAP_CONF_EWS:
Marcel Holtmann848566b2013-10-01 22:59:22 -07003354 if (!chan->conn->hs_enabled)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003355 return -ECONNREFUSED;
3356
3357 set_bit(FLAG_EXT_CTRL, &chan->flags);
3358 set_bit(CONF_EWS_RECV, &chan->conf_state);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003359 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003360 chan->remote_tx_win = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003361 break;
3362
3363 default:
3364 if (hint)
3365 break;
3366
3367 result = L2CAP_CONF_UNKNOWN;
3368 *((u8 *) ptr++) = type;
3369 break;
3370 }
3371 }
3372
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003373 if (chan->num_conf_rsp || chan->num_conf_req > 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003374 goto done;
3375
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003376 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003377 case L2CAP_MODE_STREAMING:
3378 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003379 if (!test_bit(CONF_STATE2_DEVICE, &chan->conf_state)) {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003380 chan->mode = l2cap_select_mode(rfc.mode,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003381 chan->conn->feat_mask);
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003382 break;
3383 }
3384
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003385 if (remote_efs) {
Marcel Holtmann848566b2013-10-01 22:59:22 -07003386 if (__l2cap_efs_supported(chan->conn))
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003387 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3388 else
3389 return -ECONNREFUSED;
3390 }
3391
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003392 if (chan->mode != rfc.mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003393 return -ECONNREFUSED;
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03003394
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003395 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003396 }
3397
3398done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003399 if (chan->mode != rfc.mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003400 result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003401 rfc.mode = chan->mode;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003402
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003403 if (chan->num_conf_rsp == 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003404 return -ECONNREFUSED;
3405
Gustavo Padovan2d792812012-10-06 10:07:01 +01003406 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3407 (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003408 }
3409
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003410 if (result == L2CAP_CONF_SUCCESS) {
3411 /* Configure output options and let the other side know
3412 * which ones we don't like. */
3413
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003414 if (mtu < L2CAP_DEFAULT_MIN_MTU)
3415 result = L2CAP_CONF_UNACCEPT;
3416 else {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003417 chan->omtu = mtu;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003418 set_bit(CONF_MTU_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003419 }
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003420 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003421
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003422 if (remote_efs) {
3423 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003424 efs.stype != L2CAP_SERV_NOTRAFIC &&
3425 efs.stype != chan->local_stype) {
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003426
3427 result = L2CAP_CONF_UNACCEPT;
3428
3429 if (chan->num_conf_req >= 1)
3430 return -ECONNREFUSED;
3431
3432 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003433 sizeof(efs),
3434 (unsigned long) &efs);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003435 } else {
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003436 /* Send PENDING Conf Rsp */
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003437 result = L2CAP_CONF_PENDING;
3438 set_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003439 }
3440 }
3441
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003442 switch (rfc.mode) {
3443 case L2CAP_MODE_BASIC:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003444 chan->fcs = L2CAP_FCS_NONE;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003445 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003446 break;
3447
3448 case L2CAP_MODE_ERTM:
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003449 if (!test_bit(CONF_EWS_RECV, &chan->conf_state))
3450 chan->remote_tx_win = rfc.txwin_size;
3451 else
3452 rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW;
3453
Gustavo F. Padovan2c03a7a2011-03-25 20:15:28 -03003454 chan->remote_max_tx = rfc.max_transmit;
Mat Martineau86b1b262010-08-05 15:54:22 -07003455
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003456 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003457 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3458 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003459 rfc.max_pdu_size = cpu_to_le16(size);
3460 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003461
Mat Martineau36c86c82012-10-23 15:24:20 -07003462 __l2cap_set_ertm_timeouts(chan, &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003463
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003464 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003465
3466 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003467 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003468
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003469 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3470 chan->remote_id = efs.id;
3471 chan->remote_stype = efs.stype;
3472 chan->remote_msdu = le16_to_cpu(efs.msdu);
3473 chan->remote_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003474 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003475 chan->remote_acc_lat =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003476 le32_to_cpu(efs.acc_lat);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003477 chan->remote_sdu_itime =
3478 le32_to_cpu(efs.sdu_itime);
3479 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003480 sizeof(efs),
3481 (unsigned long) &efs);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003482 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003483 break;
3484
3485 case L2CAP_MODE_STREAMING:
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003486 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003487 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3488 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003489 rfc.max_pdu_size = cpu_to_le16(size);
3490 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003491
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003492 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003493
Gustavo Padovan2d792812012-10-06 10:07:01 +01003494 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3495 (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003496
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003497 break;
3498
3499 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02003500 result = L2CAP_CONF_UNACCEPT;
3501
3502 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003503 rfc.mode = chan->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003504 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003505
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003506 if (result == L2CAP_CONF_SUCCESS)
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003507 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003508 }
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003509 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003510 rsp->result = cpu_to_le16(result);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003511 rsp->flags = __constant_cpu_to_le16(0);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003512
3513 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003514}
3515
Gustavo Padovan2d792812012-10-06 10:07:01 +01003516static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len,
3517 void *data, u16 *result)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003518{
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003519 struct l2cap_conf_req *req = data;
3520 void *ptr = req->data;
3521 int type, olen;
3522 unsigned long val;
Mat Martineau36e999a2011-12-08 17:23:21 -08003523 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003524 struct l2cap_conf_efs efs;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003525
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003526 BT_DBG("chan %p, rsp %p, len %d, req %p", chan, rsp, len, data);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003527
3528 while (len >= L2CAP_CONF_OPT_SIZE) {
3529 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3530
3531 switch (type) {
3532 case L2CAP_CONF_MTU:
3533 if (val < L2CAP_DEFAULT_MIN_MTU) {
3534 *result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003535 chan->imtu = L2CAP_DEFAULT_MIN_MTU;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003536 } else
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003537 chan->imtu = val;
3538 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003539 break;
3540
3541 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003542 chan->flush_to = val;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003543 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003544 2, chan->flush_to);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003545 break;
3546
3547 case L2CAP_CONF_RFC:
3548 if (olen == sizeof(rfc))
3549 memcpy(&rfc, (void *)val, olen);
3550
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003551 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003552 rfc.mode != chan->mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003553 return -ECONNREFUSED;
3554
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003555 chan->fcs = 0;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003556
3557 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003558 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003559 break;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003560
3561 case L2CAP_CONF_EWS:
Mat Martineauc20f8e32012-07-10 05:47:07 -07003562 chan->ack_win = min_t(u16, val, chan->ack_win);
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003563 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Mat Martineauc20f8e32012-07-10 05:47:07 -07003564 chan->tx_win);
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003565 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003566
3567 case L2CAP_CONF_EFS:
3568 if (olen == sizeof(efs))
3569 memcpy(&efs, (void *)val, olen);
3570
3571 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003572 efs.stype != L2CAP_SERV_NOTRAFIC &&
3573 efs.stype != chan->local_stype)
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003574 return -ECONNREFUSED;
3575
Gustavo Padovan2d792812012-10-06 10:07:01 +01003576 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs),
3577 (unsigned long) &efs);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003578 break;
Andrei Emeltchenkocbabee72012-11-29 17:46:07 +02003579
3580 case L2CAP_CONF_FCS:
3581 if (*result == L2CAP_CONF_PENDING)
3582 if (val == L2CAP_FCS_NONE)
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003583 set_bit(CONF_RECV_NO_FCS,
Andrei Emeltchenkocbabee72012-11-29 17:46:07 +02003584 &chan->conf_state);
3585 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003586 }
3587 }
3588
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003589 if (chan->mode == L2CAP_MODE_BASIC && chan->mode != rfc.mode)
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003590 return -ECONNREFUSED;
3591
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003592 chan->mode = rfc.mode;
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003593
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003594 if (*result == L2CAP_CONF_SUCCESS || *result == L2CAP_CONF_PENDING) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003595 switch (rfc.mode) {
3596 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003597 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3598 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
3599 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003600 if (!test_bit(FLAG_EXT_CTRL, &chan->flags))
3601 chan->ack_win = min_t(u16, chan->ack_win,
3602 rfc.txwin_size);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003603
3604 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3605 chan->local_msdu = le16_to_cpu(efs.msdu);
3606 chan->local_sdu_itime =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003607 le32_to_cpu(efs.sdu_itime);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003608 chan->local_acc_lat = le32_to_cpu(efs.acc_lat);
3609 chan->local_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003610 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003611 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003612 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003613
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003614 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003615 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003616 }
3617 }
3618
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003619 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003620 req->flags = __constant_cpu_to_le16(0);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003621
3622 return ptr - data;
3623}
3624
Gustavo Padovan2d792812012-10-06 10:07:01 +01003625static int l2cap_build_conf_rsp(struct l2cap_chan *chan, void *data,
3626 u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003627{
3628 struct l2cap_conf_rsp *rsp = data;
3629 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003630
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003631 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003632
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003633 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003634 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003635 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003636
3637 return ptr - data;
3638}
3639
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003640void __l2cap_connect_rsp_defer(struct l2cap_chan *chan)
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003641{
3642 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003643 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003644 u8 buf[128];
Andrei Emeltchenko439f34a2012-10-31 15:46:28 +02003645 u8 rsp_code;
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003646
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003647 rsp.scid = cpu_to_le16(chan->dcid);
3648 rsp.dcid = cpu_to_le16(chan->scid);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003649 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
3650 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Andrei Emeltchenko439f34a2012-10-31 15:46:28 +02003651
3652 if (chan->hs_hcon)
3653 rsp_code = L2CAP_CREATE_CHAN_RSP;
3654 else
3655 rsp_code = L2CAP_CONN_RSP;
3656
3657 BT_DBG("chan %p rsp_code %u", chan, rsp_code);
3658
3659 l2cap_send_cmd(conn, chan->ident, rsp_code, sizeof(rsp), &rsp);
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003660
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003661 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003662 return;
3663
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003664 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003665 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003666 chan->num_conf_req++;
3667}
3668
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003669static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003670{
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003671 int type, olen;
3672 unsigned long val;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003673 /* Use sane default values in case a misbehaving remote device
3674 * did not send an RFC or extended window size option.
3675 */
3676 u16 txwin_ext = chan->ack_win;
3677 struct l2cap_conf_rfc rfc = {
3678 .mode = chan->mode,
3679 .retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO),
3680 .monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO),
3681 .max_pdu_size = cpu_to_le16(chan->imtu),
3682 .txwin_size = min_t(u16, chan->ack_win, L2CAP_DEFAULT_TX_WINDOW),
3683 };
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003684
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003685 BT_DBG("chan %p, rsp %p, len %d", chan, rsp, len);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003686
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003687 if ((chan->mode != L2CAP_MODE_ERTM) && (chan->mode != L2CAP_MODE_STREAMING))
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003688 return;
3689
3690 while (len >= L2CAP_CONF_OPT_SIZE) {
3691 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3692
Mat Martineauc20f8e32012-07-10 05:47:07 -07003693 switch (type) {
3694 case L2CAP_CONF_RFC:
3695 if (olen == sizeof(rfc))
3696 memcpy(&rfc, (void *)val, olen);
Szymon Janc8f321f82012-06-08 11:33:33 +02003697 break;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003698 case L2CAP_CONF_EWS:
3699 txwin_ext = val;
3700 break;
3701 }
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003702 }
3703
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003704 switch (rfc.mode) {
3705 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003706 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3707 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003708 chan->mps = le16_to_cpu(rfc.max_pdu_size);
3709 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3710 chan->ack_win = min_t(u16, chan->ack_win, txwin_ext);
3711 else
3712 chan->ack_win = min_t(u16, chan->ack_win,
3713 rfc.txwin_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003714 break;
3715 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003716 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003717 }
3718}
3719
Gustavo Padovan2d792812012-10-06 10:07:01 +01003720static inline int l2cap_command_rej(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003721 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3722 u8 *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003723{
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003724 struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003725
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003726 if (cmd_len < sizeof(*rej))
3727 return -EPROTO;
3728
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003729 if (rej->reason != L2CAP_REJ_NOT_UNDERSTOOD)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003730 return 0;
3731
3732 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003733 cmd->ident == conn->info_ident) {
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02003734 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01003735
3736 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003737 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003738
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003739 l2cap_conn_start(conn);
3740 }
3741
3742 return 0;
3743}
3744
Mat Martineau17009152012-10-23 15:24:07 -07003745static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
3746 struct l2cap_cmd_hdr *cmd,
3747 u8 *data, u8 rsp_code, u8 amp_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003748{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003749 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
3750 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003751 struct l2cap_chan *chan = NULL, *pchan;
Nathan Holsteind793fe82010-10-15 11:54:02 -04003752 struct sock *parent, *sk = NULL;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003753 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003754
3755 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003756 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003757
Andrei Emeltchenko097db762012-03-09 14:16:17 +02003758 BT_DBG("psm 0x%2.2x scid 0x%4.4x", __le16_to_cpu(psm), scid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003759
3760 /* Check if we have socket listening on psm */
Marcel Holtmann6f59b902013-10-13 05:24:01 -07003761 pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, &conn->hcon->src,
Marcel Holtmann98e0f7e2013-10-13 02:23:40 -07003762 &conn->hcon->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003763 if (!pchan) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003764 result = L2CAP_CR_BAD_PSM;
3765 goto sendresp;
3766 }
3767
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003768 parent = pchan->sk;
3769
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003770 mutex_lock(&conn->chan_lock);
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003771 lock_sock(parent);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00003772
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003773 /* Check if the ACL is secure enough (if not SDP) */
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +03003774 if (psm != __constant_cpu_to_le16(L2CAP_PSM_SDP) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003775 !hci_conn_check_link_mode(conn->hcon)) {
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003776 conn->disc_reason = HCI_ERROR_AUTH_FAILURE;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003777 result = L2CAP_CR_SEC_BLOCK;
3778 goto response;
3779 }
3780
Linus Torvalds1da177e2005-04-16 15:20:36 -07003781 result = L2CAP_CR_NO_MEM;
3782
Gustavo Padovan2dfa1002012-05-27 22:27:58 -03003783 /* Check if we already have channel with that dcid */
3784 if (__l2cap_get_chan_by_dcid(conn, scid))
3785 goto response;
3786
Gustavo Padovan80b98022012-05-27 22:27:51 -03003787 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003788 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003789 goto response;
3790
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003791 sk = chan->sk;
3792
Syam Sidhardhan330b6c12013-08-06 01:59:12 +09003793 /* For certain devices (ex: HID mouse), support for authentication,
3794 * pairing and bonding is optional. For such devices, inorder to avoid
3795 * the ACL alive for too long after L2CAP disconnection, reset the ACL
3796 * disc_timeout back to HCI_DISCONN_TIMEOUT during L2CAP connect.
3797 */
3798 conn->hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
3799
Marcel Holtmann6f59b902013-10-13 05:24:01 -07003800 bacpy(&bt_sk(sk)->src, &conn->hcon->src);
Marcel Holtmann98e0f7e2013-10-13 02:23:40 -07003801 bacpy(&bt_sk(sk)->dst, &conn->hcon->dst);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003802 chan->psm = psm;
3803 chan->dcid = scid;
Mat Martineau17009152012-10-23 15:24:07 -07003804 chan->local_amp_id = amp_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003805
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003806 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003807
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003808 dcid = chan->scid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003809
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03003810 __set_chan_timer(chan, sk->sk_sndtimeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003811
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003812 chan->ident = cmd->ident;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003813
Marcel Holtmann984947d2009-02-06 23:35:19 +01003814 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02003815 if (l2cap_chan_check_security(chan)) {
Gustavo Padovanc5daa682012-05-16 12:17:10 -03003816 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003817 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003818 result = L2CAP_CR_PEND;
3819 status = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08003820 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003821 } else {
Mat Martineau17009152012-10-23 15:24:07 -07003822 /* Force pending result for AMP controllers.
3823 * The connection will succeed after the
3824 * physical link is up.
3825 */
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003826 if (amp_id == AMP_ID_BREDR) {
Mat Martineau17009152012-10-23 15:24:07 -07003827 __l2cap_state_change(chan, BT_CONFIG);
3828 result = L2CAP_CR_SUCCESS;
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003829 } else {
3830 __l2cap_state_change(chan, BT_CONNECT2);
3831 result = L2CAP_CR_PEND;
Mat Martineau17009152012-10-23 15:24:07 -07003832 }
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003833 status = L2CAP_CS_NO_INFO;
3834 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003835 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003836 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003837 result = L2CAP_CR_PEND;
3838 status = L2CAP_CS_AUTHEN_PEND;
3839 }
3840 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003841 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003842 result = L2CAP_CR_PEND;
3843 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003844 }
3845
Linus Torvalds1da177e2005-04-16 15:20:36 -07003846response:
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003847 release_sock(parent);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003848 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003849
3850sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003851 rsp.scid = cpu_to_le16(scid);
3852 rsp.dcid = cpu_to_le16(dcid);
3853 rsp.result = cpu_to_le16(result);
3854 rsp.status = cpu_to_le16(status);
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003855 l2cap_send_cmd(conn, cmd->ident, rsp_code, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003856
3857 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
3858 struct l2cap_info_req info;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003859 info.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003860
3861 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
3862 conn->info_ident = l2cap_get_ident(conn);
3863
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08003864 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003865
Gustavo Padovan2d792812012-10-06 10:07:01 +01003866 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
3867 sizeof(info), &info);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003868 }
3869
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003870 if (chan && !test_bit(CONF_REQ_SENT, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003871 result == L2CAP_CR_SUCCESS) {
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003872 u8 buf[128];
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003873 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003874 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003875 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003876 chan->num_conf_req++;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003877 }
Mat Martineau17009152012-10-23 15:24:07 -07003878
3879 return chan;
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003880}
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003881
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003882static int l2cap_connect_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003883 struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003884{
Jaganath Kanakkassery7b064ed2013-01-10 10:28:35 +05303885 struct hci_dev *hdev = conn->hcon->hdev;
3886 struct hci_conn *hcon = conn->hcon;
3887
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003888 if (cmd_len < sizeof(struct l2cap_conn_req))
3889 return -EPROTO;
3890
Jaganath Kanakkassery7b064ed2013-01-10 10:28:35 +05303891 hci_dev_lock(hdev);
3892 if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
3893 !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &hcon->flags))
3894 mgmt_device_connected(hdev, &hcon->dst, hcon->type,
3895 hcon->dst_type, 0, NULL, 0,
3896 hcon->dev_class);
3897 hci_dev_unlock(hdev);
3898
Gustavo Padovan300229f2012-10-12 19:40:40 +08003899 l2cap_connect(conn, cmd, data, L2CAP_CONN_RSP, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003900 return 0;
3901}
3902
Mat Martineau5909cf32012-10-23 15:24:08 -07003903static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003904 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3905 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003906{
3907 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
3908 u16 scid, dcid, result, status;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003909 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003910 u8 req[128];
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003911 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003912
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003913 if (cmd_len < sizeof(*rsp))
3914 return -EPROTO;
3915
Linus Torvalds1da177e2005-04-16 15:20:36 -07003916 scid = __le16_to_cpu(rsp->scid);
3917 dcid = __le16_to_cpu(rsp->dcid);
3918 result = __le16_to_cpu(rsp->result);
3919 status = __le16_to_cpu(rsp->status);
3920
Andrei Emeltchenko1b009c92012-02-21 12:54:54 +02003921 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 +01003922 dcid, scid, result, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003923
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003924 mutex_lock(&conn->chan_lock);
3925
Linus Torvalds1da177e2005-04-16 15:20:36 -07003926 if (scid) {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003927 chan = __l2cap_get_chan_by_scid(conn, scid);
3928 if (!chan) {
Johan Hedberg21870b52013-09-16 13:05:14 +03003929 err = -EBADSLT;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003930 goto unlock;
3931 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003932 } else {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003933 chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
3934 if (!chan) {
Johan Hedberg21870b52013-09-16 13:05:14 +03003935 err = -EBADSLT;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003936 goto unlock;
3937 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003938 }
3939
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003940 err = 0;
3941
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003942 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003943
Linus Torvalds1da177e2005-04-16 15:20:36 -07003944 switch (result) {
3945 case L2CAP_CR_SUCCESS:
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03003946 l2cap_state_change(chan, BT_CONFIG);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003947 chan->ident = 0;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003948 chan->dcid = dcid;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003949 clear_bit(CONF_CONNECT_PEND, &chan->conf_state);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003950
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003951 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003952 break;
3953
Linus Torvalds1da177e2005-04-16 15:20:36 -07003954 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003955 l2cap_build_conf_req(chan, req), req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003956 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003957 break;
3958
3959 case L2CAP_CR_PEND:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003960 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003961 break;
3962
3963 default:
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003964 l2cap_chan_del(chan, ECONNREFUSED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003965 break;
3966 }
3967
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003968 l2cap_chan_unlock(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003969
3970unlock:
3971 mutex_unlock(&conn->chan_lock);
3972
3973 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003974}
3975
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003976static inline void set_default_fcs(struct l2cap_chan *chan)
Mat Martineau8c462b62010-08-24 15:35:42 -07003977{
3978 /* FCS is enabled only in ERTM or streaming mode, if one or both
3979 * sides request it.
3980 */
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003981 if (chan->mode != L2CAP_MODE_ERTM && chan->mode != L2CAP_MODE_STREAMING)
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003982 chan->fcs = L2CAP_FCS_NONE;
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003983 else if (!test_bit(CONF_RECV_NO_FCS, &chan->conf_state))
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003984 chan->fcs = L2CAP_FCS_CRC16;
Mat Martineau8c462b62010-08-24 15:35:42 -07003985}
3986
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03003987static void l2cap_send_efs_conf_rsp(struct l2cap_chan *chan, void *data,
3988 u8 ident, u16 flags)
3989{
3990 struct l2cap_conn *conn = chan->conn;
3991
3992 BT_DBG("conn %p chan %p ident %d flags 0x%4.4x", conn, chan, ident,
3993 flags);
3994
3995 clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
3996 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
3997
3998 l2cap_send_cmd(conn, ident, L2CAP_CONF_RSP,
3999 l2cap_build_conf_rsp(chan, data,
4000 L2CAP_CONF_SUCCESS, flags), data);
4001}
4002
Gustavo Padovan2d792812012-10-06 10:07:01 +01004003static inline int l2cap_config_req(struct l2cap_conn *conn,
4004 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4005 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004006{
4007 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
4008 u16 dcid, flags;
4009 u8 rsp[64];
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004010 struct l2cap_chan *chan;
Mat Martineau3c588192012-04-11 10:48:42 -07004011 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004012
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004013 if (cmd_len < sizeof(*req))
4014 return -EPROTO;
4015
Linus Torvalds1da177e2005-04-16 15:20:36 -07004016 dcid = __le16_to_cpu(req->dcid);
4017 flags = __le16_to_cpu(req->flags);
4018
4019 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
4020
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03004021 chan = l2cap_get_chan_by_scid(conn, dcid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004022 if (!chan)
Johan Hedberg21870b52013-09-16 13:05:14 +03004023 return -EBADSLT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004024
David S. Miller033b1142011-07-21 13:38:42 -07004025 if (chan->state != BT_CONFIG && chan->state != BT_CONNECT2) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03004026 struct l2cap_cmd_rej_cid rej;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03004027
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004028 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_INVALID_CID);
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03004029 rej.scid = cpu_to_le16(chan->scid);
4030 rej.dcid = cpu_to_le16(chan->dcid);
4031
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03004032 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004033 sizeof(rej), &rej);
Marcel Holtmann354f60a2006-11-18 22:15:20 +01004034 goto unlock;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03004035 }
Marcel Holtmann354f60a2006-11-18 22:15:20 +01004036
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004037 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07004038 len = cmd_len - sizeof(*req);
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004039 if (chan->conf_len + len > sizeof(chan->conf_req)) {
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004040 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004041 l2cap_build_conf_rsp(chan, rsp,
4042 L2CAP_CONF_REJECT, flags), rsp);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004043 goto unlock;
4044 }
4045
4046 /* Store config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004047 memcpy(chan->conf_req + chan->conf_len, req->data, len);
4048 chan->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004049
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03004050 if (flags & L2CAP_CONF_FLAG_CONTINUATION) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004051 /* Incomplete config. Send empty response. */
4052 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004053 l2cap_build_conf_rsp(chan, rsp,
4054 L2CAP_CONF_SUCCESS, flags), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004055 goto unlock;
4056 }
4057
4058 /* Complete config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004059 len = l2cap_parse_conf_req(chan, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004060 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004061 l2cap_send_disconn_req(chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004062 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004063 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004064
Mat Martineau1500109b2012-10-23 15:24:15 -07004065 chan->ident = cmd->ident;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004066 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004067 chan->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004068
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004069 /* Reset config buffer. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004070 chan->conf_len = 0;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004071
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004072 if (!test_bit(CONF_OUTPUT_DONE, &chan->conf_state))
Marcel Holtmann876d9482007-10-20 13:35:42 +02004073 goto unlock;
4074
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004075 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004076 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004077
Mat Martineau105bdf92012-04-27 16:50:48 -07004078 if (chan->mode == L2CAP_MODE_ERTM ||
4079 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07004080 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03004081
Mat Martineau3c588192012-04-11 10:48:42 -07004082 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004083 l2cap_send_disconn_req(chan, -err);
Mat Martineau3c588192012-04-11 10:48:42 -07004084 else
4085 l2cap_chan_ready(chan);
4086
Marcel Holtmann876d9482007-10-20 13:35:42 +02004087 goto unlock;
4088 }
4089
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004090 if (!test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004091 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004092 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004093 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004094 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004095 }
4096
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004097 /* Got Conf Rsp PENDING from remote side and asume we sent
4098 Conf Rsp PENDING in the code above */
4099 if (test_bit(CONF_REM_CONF_PEND, &chan->conf_state) &&
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03004100 test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004101
4102 /* check compatibility */
4103
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004104 /* Send rsp for BR/EDR channel */
Andrei Emeltchenkof351bc72012-10-31 15:46:35 +02004105 if (!chan->hs_hcon)
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004106 l2cap_send_efs_conf_rsp(chan, rsp, cmd->ident, flags);
4107 else
4108 chan->ident = cmd->ident;
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004109 }
4110
Linus Torvalds1da177e2005-04-16 15:20:36 -07004111unlock:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004112 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07004113 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004114}
4115
Gustavo Padovan2d792812012-10-06 10:07:01 +01004116static inline int l2cap_config_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004117 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4118 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004119{
4120 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
4121 u16 scid, flags, result;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004122 struct l2cap_chan *chan;
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004123 int len = cmd_len - sizeof(*rsp);
Mat Martineau3c588192012-04-11 10:48:42 -07004124 int err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004125
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004126 if (cmd_len < sizeof(*rsp))
4127 return -EPROTO;
4128
Linus Torvalds1da177e2005-04-16 15:20:36 -07004129 scid = __le16_to_cpu(rsp->scid);
4130 flags = __le16_to_cpu(rsp->flags);
4131 result = __le16_to_cpu(rsp->result);
4132
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02004133 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x len %d", scid, flags,
4134 result, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004135
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03004136 chan = l2cap_get_chan_by_scid(conn, scid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004137 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004138 return 0;
4139
4140 switch (result) {
4141 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004142 l2cap_conf_rfc_get(chan, rsp->data, len);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004143 clear_bit(CONF_REM_CONF_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004144 break;
4145
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004146 case L2CAP_CONF_PENDING:
4147 set_bit(CONF_REM_CONF_PEND, &chan->conf_state);
4148
4149 if (test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
4150 char buf[64];
4151
4152 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004153 buf, &result);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004154 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004155 l2cap_send_disconn_req(chan, ECONNRESET);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004156 goto done;
4157 }
4158
Andrei Emeltchenkof351bc72012-10-31 15:46:35 +02004159 if (!chan->hs_hcon) {
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004160 l2cap_send_efs_conf_rsp(chan, buf, cmd->ident,
4161 0);
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +02004162 } else {
4163 if (l2cap_check_efs(chan)) {
4164 amp_create_logical_link(chan);
4165 chan->ident = cmd->ident;
4166 }
4167 }
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004168 }
4169 goto done;
4170
Linus Torvalds1da177e2005-04-16 15:20:36 -07004171 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004172 if (chan->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004173 char req[64];
4174
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02004175 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004176 l2cap_send_disconn_req(chan, ECONNRESET);
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02004177 goto done;
4178 }
4179
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004180 /* throw out any old stored conf requests */
4181 result = L2CAP_CONF_SUCCESS;
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03004182 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004183 req, &result);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004184 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004185 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004186 goto done;
4187 }
4188
4189 l2cap_send_cmd(conn, l2cap_get_ident(conn),
Gustavo Padovan2d792812012-10-06 10:07:01 +01004190 L2CAP_CONF_REQ, len, req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004191 chan->num_conf_req++;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004192 if (result != L2CAP_CONF_SUCCESS)
4193 goto done;
4194 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004195 }
4196
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09004197 default:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004198 l2cap_chan_set_err(chan, ECONNRESET);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02004199
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08004200 __set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004201 l2cap_send_disconn_req(chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004202 goto done;
4203 }
4204
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03004205 if (flags & L2CAP_CONF_FLAG_CONTINUATION)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004206 goto done;
4207
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004208 set_bit(CONF_INPUT_DONE, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004209
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004210 if (test_bit(CONF_OUTPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004211 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004212
Mat Martineau105bdf92012-04-27 16:50:48 -07004213 if (chan->mode == L2CAP_MODE_ERTM ||
4214 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07004215 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03004216
Mat Martineau3c588192012-04-11 10:48:42 -07004217 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004218 l2cap_send_disconn_req(chan, -err);
Mat Martineau3c588192012-04-11 10:48:42 -07004219 else
4220 l2cap_chan_ready(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004221 }
4222
4223done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004224 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07004225 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004226}
4227
Gustavo Padovan2d792812012-10-06 10:07:01 +01004228static inline int l2cap_disconnect_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004229 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4230 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004231{
4232 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
4233 struct l2cap_disconn_rsp rsp;
4234 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004235 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004236 struct sock *sk;
4237
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004238 if (cmd_len != sizeof(*req))
4239 return -EPROTO;
4240
Linus Torvalds1da177e2005-04-16 15:20:36 -07004241 scid = __le16_to_cpu(req->scid);
4242 dcid = __le16_to_cpu(req->dcid);
4243
4244 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
4245
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004246 mutex_lock(&conn->chan_lock);
4247
4248 chan = __l2cap_get_chan_by_scid(conn, dcid);
4249 if (!chan) {
4250 mutex_unlock(&conn->chan_lock);
Johan Hedbergc4ea2492013-09-16 13:05:15 +03004251 return -EBADSLT;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004252 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004253
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004254 l2cap_chan_lock(chan);
4255
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004256 sk = chan->sk;
4257
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03004258 rsp.dcid = cpu_to_le16(chan->scid);
4259 rsp.scid = cpu_to_le16(chan->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004260 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
4261
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004262 lock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004263 sk->sk_shutdown = SHUTDOWN_MASK;
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004264 release_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004265
Mat Martineau61d6ef32012-04-27 16:50:50 -07004266 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004267 l2cap_chan_del(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004268
4269 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004270
Gustavo Padovan80b98022012-05-27 22:27:51 -03004271 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004272 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004273
4274 mutex_unlock(&conn->chan_lock);
4275
Linus Torvalds1da177e2005-04-16 15:20:36 -07004276 return 0;
4277}
4278
Gustavo Padovan2d792812012-10-06 10:07:01 +01004279static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004280 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4281 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004282{
4283 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
4284 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004285 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004286
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004287 if (cmd_len != sizeof(*rsp))
4288 return -EPROTO;
4289
Linus Torvalds1da177e2005-04-16 15:20:36 -07004290 scid = __le16_to_cpu(rsp->scid);
4291 dcid = __le16_to_cpu(rsp->dcid);
4292
4293 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
4294
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004295 mutex_lock(&conn->chan_lock);
4296
4297 chan = __l2cap_get_chan_by_scid(conn, scid);
4298 if (!chan) {
4299 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004300 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004301 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004302
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004303 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004304
Mat Martineau61d6ef32012-04-27 16:50:50 -07004305 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004306 l2cap_chan_del(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004307
4308 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004309
Gustavo Padovan80b98022012-05-27 22:27:51 -03004310 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004311 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004312
4313 mutex_unlock(&conn->chan_lock);
4314
Linus Torvalds1da177e2005-04-16 15:20:36 -07004315 return 0;
4316}
4317
Gustavo Padovan2d792812012-10-06 10:07:01 +01004318static inline int l2cap_information_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004319 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4320 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004321{
4322 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004323 u16 type;
4324
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004325 if (cmd_len != sizeof(*req))
4326 return -EPROTO;
4327
Linus Torvalds1da177e2005-04-16 15:20:36 -07004328 type = __le16_to_cpu(req->type);
4329
4330 BT_DBG("type 0x%4.4x", type);
4331
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004332 if (type == L2CAP_IT_FEAT_MASK) {
4333 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07004334 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004335 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004336 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
4337 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03004338 if (!disable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004339 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
Gustavo Padovan2d792812012-10-06 10:07:01 +01004340 | L2CAP_FEAT_FCS;
Marcel Holtmann848566b2013-10-01 22:59:22 -07004341 if (conn->hs_enabled)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03004342 feat_mask |= L2CAP_FEAT_EXT_FLOW
Gustavo Padovan2d792812012-10-06 10:07:01 +01004343 | L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03004344
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03004345 put_unaligned_le32(feat_mask, rsp->data);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004346 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4347 buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004348 } else if (type == L2CAP_IT_FIXED_CHAN) {
4349 u8 buf[12];
4350 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Mat Martineau50a147c2011-11-02 16:18:34 -07004351
Marcel Holtmann848566b2013-10-01 22:59:22 -07004352 if (conn->hs_enabled)
Mat Martineau50a147c2011-11-02 16:18:34 -07004353 l2cap_fixed_chan[0] |= L2CAP_FC_A2MP;
4354 else
4355 l2cap_fixed_chan[0] &= ~L2CAP_FC_A2MP;
4356
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004357 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
4358 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Andrei Emeltchenkoc6337ea2011-10-20 17:02:44 +03004359 memcpy(rsp->data, l2cap_fixed_chan, sizeof(l2cap_fixed_chan));
Gustavo Padovan2d792812012-10-06 10:07:01 +01004360 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4361 buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004362 } else {
4363 struct l2cap_info_rsp rsp;
4364 rsp.type = cpu_to_le16(type);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004365 rsp.result = __constant_cpu_to_le16(L2CAP_IR_NOTSUPP);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004366 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(rsp),
4367 &rsp);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004368 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004369
4370 return 0;
4371}
4372
Gustavo Padovan2d792812012-10-06 10:07:01 +01004373static inline int l2cap_information_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004374 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4375 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004376{
4377 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
4378 u16 type, result;
4379
Jaganath Kanakkassery3f6fa3d2013-06-21 19:55:11 +05304380 if (cmd_len < sizeof(*rsp))
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004381 return -EPROTO;
4382
Linus Torvalds1da177e2005-04-16 15:20:36 -07004383 type = __le16_to_cpu(rsp->type);
4384 result = __le16_to_cpu(rsp->result);
4385
4386 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
4387
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004388 /* L2CAP Info req/rsp are unbound to channels, add extra checks */
4389 if (cmd->ident != conn->info_ident ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01004390 conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004391 return 0;
4392
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02004393 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004394
Ville Tervoadb08ed2010-08-04 09:43:33 +03004395 if (result != L2CAP_IR_SUCCESS) {
4396 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4397 conn->info_ident = 0;
4398
4399 l2cap_conn_start(conn);
4400
4401 return 0;
4402 }
4403
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004404 switch (type) {
4405 case L2CAP_IT_FEAT_MASK:
Harvey Harrison83985312008-05-02 16:25:46 -07004406 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004407
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07004408 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004409 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004410 req.type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004411
4412 conn->info_ident = l2cap_get_ident(conn);
4413
4414 l2cap_send_cmd(conn, conn->info_ident,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004415 L2CAP_INFO_REQ, sizeof(req), &req);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004416 } else {
4417 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4418 conn->info_ident = 0;
4419
4420 l2cap_conn_start(conn);
4421 }
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004422 break;
4423
4424 case L2CAP_IT_FIXED_CHAN:
4425 conn->fixed_chan_mask = rsp->data[0];
Marcel Holtmann984947d2009-02-06 23:35:19 +01004426 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004427 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004428
4429 l2cap_conn_start(conn);
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004430 break;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004431 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004432
Linus Torvalds1da177e2005-04-16 15:20:36 -07004433 return 0;
4434}
4435
Mat Martineau17009152012-10-23 15:24:07 -07004436static int l2cap_create_channel_req(struct l2cap_conn *conn,
4437 struct l2cap_cmd_hdr *cmd,
4438 u16 cmd_len, void *data)
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004439{
4440 struct l2cap_create_chan_req *req = data;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004441 struct l2cap_create_chan_rsp rsp;
Mat Martineau17009152012-10-23 15:24:07 -07004442 struct l2cap_chan *chan;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004443 struct hci_dev *hdev;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004444 u16 psm, scid;
4445
4446 if (cmd_len != sizeof(*req))
4447 return -EPROTO;
4448
Marcel Holtmann848566b2013-10-01 22:59:22 -07004449 if (!conn->hs_enabled)
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004450 return -EINVAL;
4451
4452 psm = le16_to_cpu(req->psm);
4453 scid = le16_to_cpu(req->scid);
4454
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004455 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 -07004456
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004457 /* For controller id 0 make BR/EDR connection */
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004458 if (req->amp_id == AMP_ID_BREDR) {
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004459 l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4460 req->amp_id);
4461 return 0;
4462 }
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004463
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004464 /* Validate AMP controller id */
4465 hdev = hci_dev_get(req->amp_id);
4466 if (!hdev)
4467 goto error;
Mat Martineau17009152012-10-23 15:24:07 -07004468
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004469 if (hdev->dev_type != HCI_AMP || !test_bit(HCI_UP, &hdev->flags)) {
Mat Martineau17009152012-10-23 15:24:07 -07004470 hci_dev_put(hdev);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004471 goto error;
Mat Martineau17009152012-10-23 15:24:07 -07004472 }
4473
4474 chan = l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4475 req->amp_id);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004476 if (chan) {
4477 struct amp_mgr *mgr = conn->hcon->amp_mgr;
4478 struct hci_conn *hs_hcon;
4479
Marcel Holtmann98e0f7e2013-10-13 02:23:40 -07004480 hs_hcon = hci_conn_hash_lookup_ba(hdev, AMP_LINK,
4481 &conn->hcon->dst);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004482 if (!hs_hcon) {
4483 hci_dev_put(hdev);
Johan Hedberg21870b52013-09-16 13:05:14 +03004484 return -EBADSLT;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004485 }
4486
4487 BT_DBG("mgr %p bredr_chan %p hs_hcon %p", mgr, chan, hs_hcon);
4488
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004489 mgr->bredr_chan = chan;
4490 chan->hs_hcon = hs_hcon;
Andrei Emeltchenkofd45bf42012-11-20 17:16:22 +02004491 chan->fcs = L2CAP_FCS_NONE;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004492 conn->mtu = hdev->block_mtu;
4493 }
4494
4495 hci_dev_put(hdev);
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004496
4497 return 0;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004498
4499error:
4500 rsp.dcid = 0;
4501 rsp.scid = cpu_to_le16(scid);
4502 rsp.result = __constant_cpu_to_le16(L2CAP_CR_BAD_AMP);
4503 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
4504
4505 l2cap_send_cmd(conn, cmd->ident, L2CAP_CREATE_CHAN_RSP,
4506 sizeof(rsp), &rsp);
4507
Johan Hedbergdc280802013-09-16 13:05:13 +03004508 return 0;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004509}
4510
Mat Martineau8eb200b2012-10-23 15:24:17 -07004511static void l2cap_send_move_chan_req(struct l2cap_chan *chan, u8 dest_amp_id)
4512{
4513 struct l2cap_move_chan_req req;
4514 u8 ident;
4515
4516 BT_DBG("chan %p, dest_amp_id %d", chan, dest_amp_id);
4517
4518 ident = l2cap_get_ident(chan->conn);
4519 chan->ident = ident;
4520
4521 req.icid = cpu_to_le16(chan->scid);
4522 req.dest_amp_id = dest_amp_id;
4523
4524 l2cap_send_cmd(chan->conn, ident, L2CAP_MOVE_CHAN_REQ, sizeof(req),
4525 &req);
4526
4527 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4528}
4529
Mat Martineau1500109b2012-10-23 15:24:15 -07004530static void l2cap_send_move_chan_rsp(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004531{
4532 struct l2cap_move_chan_rsp rsp;
4533
Mat Martineau1500109b2012-10-23 15:24:15 -07004534 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004535
Mat Martineau1500109b2012-10-23 15:24:15 -07004536 rsp.icid = cpu_to_le16(chan->dcid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004537 rsp.result = cpu_to_le16(result);
4538
Mat Martineau1500109b2012-10-23 15:24:15 -07004539 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_RSP,
4540 sizeof(rsp), &rsp);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004541}
4542
Mat Martineau5b155ef2012-10-23 15:24:14 -07004543static void l2cap_send_move_chan_cfm(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004544{
4545 struct l2cap_move_chan_cfm cfm;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004546
Mat Martineau5b155ef2012-10-23 15:24:14 -07004547 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004548
Mat Martineau5b155ef2012-10-23 15:24:14 -07004549 chan->ident = l2cap_get_ident(chan->conn);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004550
Mat Martineau5b155ef2012-10-23 15:24:14 -07004551 cfm.icid = cpu_to_le16(chan->scid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004552 cfm.result = cpu_to_le16(result);
4553
Mat Martineau5b155ef2012-10-23 15:24:14 -07004554 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_CFM,
4555 sizeof(cfm), &cfm);
4556
4557 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4558}
4559
4560static void l2cap_send_move_chan_cfm_icid(struct l2cap_conn *conn, u16 icid)
4561{
4562 struct l2cap_move_chan_cfm cfm;
4563
4564 BT_DBG("conn %p, icid 0x%4.4x", conn, icid);
4565
4566 cfm.icid = cpu_to_le16(icid);
4567 cfm.result = __constant_cpu_to_le16(L2CAP_MC_UNCONFIRMED);
4568
4569 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_MOVE_CHAN_CFM,
4570 sizeof(cfm), &cfm);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004571}
4572
4573static void l2cap_send_move_chan_cfm_rsp(struct l2cap_conn *conn, u8 ident,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004574 u16 icid)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004575{
4576 struct l2cap_move_chan_cfm_rsp rsp;
4577
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004578 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004579
4580 rsp.icid = cpu_to_le16(icid);
4581 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM_RSP, sizeof(rsp), &rsp);
4582}
4583
Mat Martineau5f3847a2012-10-23 15:24:12 -07004584static void __release_logical_link(struct l2cap_chan *chan)
4585{
4586 chan->hs_hchan = NULL;
4587 chan->hs_hcon = NULL;
4588
4589 /* Placeholder - release the logical link */
4590}
4591
Mat Martineau1500109b2012-10-23 15:24:15 -07004592static void l2cap_logical_fail(struct l2cap_chan *chan)
4593{
4594 /* Logical link setup failed */
4595 if (chan->state != BT_CONNECTED) {
4596 /* Create channel failure, disconnect */
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004597 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineau1500109b2012-10-23 15:24:15 -07004598 return;
4599 }
4600
4601 switch (chan->move_role) {
4602 case L2CAP_MOVE_ROLE_RESPONDER:
4603 l2cap_move_done(chan);
4604 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_SUPP);
4605 break;
4606 case L2CAP_MOVE_ROLE_INITIATOR:
4607 if (chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_COMP ||
4608 chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_CFM) {
4609 /* Remote has only sent pending or
4610 * success responses, clean up
4611 */
4612 l2cap_move_done(chan);
4613 }
4614
4615 /* Other amp move states imply that the move
4616 * has already aborted
4617 */
4618 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4619 break;
4620 }
4621}
4622
4623static void l2cap_logical_finish_create(struct l2cap_chan *chan,
4624 struct hci_chan *hchan)
4625{
4626 struct l2cap_conf_rsp rsp;
Mat Martineau1500109b2012-10-23 15:24:15 -07004627
Andrei Emeltchenko336178a2012-10-31 15:46:27 +02004628 chan->hs_hchan = hchan;
Mat Martineau1500109b2012-10-23 15:24:15 -07004629 chan->hs_hcon->l2cap_data = chan->conn;
4630
Andrei Emeltchenko35ba9562012-10-25 15:20:43 +03004631 l2cap_send_efs_conf_rsp(chan, &rsp, chan->ident, 0);
Mat Martineau1500109b2012-10-23 15:24:15 -07004632
4633 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Andrei Emeltchenkofe79c6f2012-10-25 15:20:42 +03004634 int err;
Mat Martineau1500109b2012-10-23 15:24:15 -07004635
4636 set_default_fcs(chan);
4637
4638 err = l2cap_ertm_init(chan);
4639 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004640 l2cap_send_disconn_req(chan, -err);
Mat Martineau1500109b2012-10-23 15:24:15 -07004641 else
4642 l2cap_chan_ready(chan);
4643 }
4644}
4645
4646static void l2cap_logical_finish_move(struct l2cap_chan *chan,
4647 struct hci_chan *hchan)
4648{
4649 chan->hs_hcon = hchan->conn;
4650 chan->hs_hcon->l2cap_data = chan->conn;
4651
4652 BT_DBG("move_state %d", chan->move_state);
4653
4654 switch (chan->move_state) {
4655 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
4656 /* Move confirm will be sent after a success
4657 * response is received
4658 */
4659 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4660 break;
4661 case L2CAP_MOVE_WAIT_LOGICAL_CFM:
4662 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4663 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4664 } else if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
4665 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
4666 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4667 } else if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
4668 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4669 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
4670 }
4671 break;
4672 default:
4673 /* Move was not in expected state, free the channel */
4674 __release_logical_link(chan);
4675
4676 chan->move_state = L2CAP_MOVE_STABLE;
4677 }
4678}
4679
4680/* Call with chan locked */
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03004681void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan,
4682 u8 status)
Mat Martineau5b155ef2012-10-23 15:24:14 -07004683{
Mat Martineau1500109b2012-10-23 15:24:15 -07004684 BT_DBG("chan %p, hchan %p, status %d", chan, hchan, status);
4685
4686 if (status) {
4687 l2cap_logical_fail(chan);
4688 __release_logical_link(chan);
4689 return;
4690 }
4691
4692 if (chan->state != BT_CONNECTED) {
4693 /* Ignore logical link if channel is on BR/EDR */
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004694 if (chan->local_amp_id != AMP_ID_BREDR)
Mat Martineau1500109b2012-10-23 15:24:15 -07004695 l2cap_logical_finish_create(chan, hchan);
4696 } else {
4697 l2cap_logical_finish_move(chan, hchan);
4698 }
Mat Martineau5b155ef2012-10-23 15:24:14 -07004699}
4700
Mat Martineau3f7a56c2012-10-23 15:24:23 -07004701void l2cap_move_start(struct l2cap_chan *chan)
4702{
4703 BT_DBG("chan %p", chan);
4704
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004705 if (chan->local_amp_id == AMP_ID_BREDR) {
Mat Martineau3f7a56c2012-10-23 15:24:23 -07004706 if (chan->chan_policy != BT_CHANNEL_POLICY_AMP_PREFERRED)
4707 return;
4708 chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
4709 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
4710 /* Placeholder - start physical link setup */
4711 } else {
4712 chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
4713 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4714 chan->move_id = 0;
4715 l2cap_move_setup(chan);
4716 l2cap_send_move_chan_req(chan, 0);
4717 }
4718}
4719
Mat Martineau8eb200b2012-10-23 15:24:17 -07004720static void l2cap_do_create(struct l2cap_chan *chan, int result,
4721 u8 local_amp_id, u8 remote_amp_id)
4722{
Andrei Emeltchenko62748ca2012-11-20 17:16:19 +02004723 BT_DBG("chan %p state %s %u -> %u", chan, state_to_string(chan->state),
4724 local_amp_id, remote_amp_id);
4725
Andrei Emeltchenko12d6cc62012-11-14 17:39:31 +02004726 chan->fcs = L2CAP_FCS_NONE;
4727
Andrei Emeltchenko62748ca2012-11-20 17:16:19 +02004728 /* Outgoing channel on AMP */
4729 if (chan->state == BT_CONNECT) {
4730 if (result == L2CAP_CR_SUCCESS) {
4731 chan->local_amp_id = local_amp_id;
4732 l2cap_send_create_chan_req(chan, remote_amp_id);
4733 } else {
4734 /* Revert to BR/EDR connect */
4735 l2cap_send_conn_req(chan);
4736 }
4737
4738 return;
4739 }
4740
4741 /* Incoming channel on AMP */
4742 if (__l2cap_no_conn_pending(chan)) {
Mat Martineau8eb200b2012-10-23 15:24:17 -07004743 struct l2cap_conn_rsp rsp;
4744 char buf[128];
4745 rsp.scid = cpu_to_le16(chan->dcid);
4746 rsp.dcid = cpu_to_le16(chan->scid);
4747
Mat Martineau8eb200b2012-10-23 15:24:17 -07004748 if (result == L2CAP_CR_SUCCESS) {
4749 /* Send successful response */
Andrei Emeltchenko62cd50e2012-11-14 17:39:32 +02004750 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
4751 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004752 } else {
4753 /* Send negative response */
Andrei Emeltchenko62cd50e2012-11-14 17:39:32 +02004754 rsp.result = __constant_cpu_to_le16(L2CAP_CR_NO_MEM);
4755 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004756 }
4757
4758 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_RSP,
4759 sizeof(rsp), &rsp);
4760
4761 if (result == L2CAP_CR_SUCCESS) {
4762 __l2cap_state_change(chan, BT_CONFIG);
4763 set_bit(CONF_REQ_SENT, &chan->conf_state);
4764 l2cap_send_cmd(chan->conn, l2cap_get_ident(chan->conn),
4765 L2CAP_CONF_REQ,
4766 l2cap_build_conf_req(chan, buf), buf);
4767 chan->num_conf_req++;
4768 }
Mat Martineau8eb200b2012-10-23 15:24:17 -07004769 }
4770}
4771
4772static void l2cap_do_move_initiate(struct l2cap_chan *chan, u8 local_amp_id,
4773 u8 remote_amp_id)
4774{
4775 l2cap_move_setup(chan);
4776 chan->move_id = local_amp_id;
4777 chan->move_state = L2CAP_MOVE_WAIT_RSP;
4778
4779 l2cap_send_move_chan_req(chan, remote_amp_id);
4780}
4781
4782static void l2cap_do_move_respond(struct l2cap_chan *chan, int result)
4783{
4784 struct hci_chan *hchan = NULL;
4785
4786 /* Placeholder - get hci_chan for logical link */
4787
4788 if (hchan) {
4789 if (hchan->state == BT_CONNECTED) {
4790 /* Logical link is ready to go */
4791 chan->hs_hcon = hchan->conn;
4792 chan->hs_hcon->l2cap_data = chan->conn;
4793 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4794 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
4795
4796 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
4797 } else {
4798 /* Wait for logical link to be ready */
4799 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4800 }
4801 } else {
4802 /* Logical link not available */
4803 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_ALLOWED);
4804 }
4805}
4806
4807static void l2cap_do_move_cancel(struct l2cap_chan *chan, int result)
4808{
4809 if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
4810 u8 rsp_result;
4811 if (result == -EINVAL)
4812 rsp_result = L2CAP_MR_BAD_ID;
4813 else
4814 rsp_result = L2CAP_MR_NOT_ALLOWED;
4815
4816 l2cap_send_move_chan_rsp(chan, rsp_result);
4817 }
4818
4819 chan->move_role = L2CAP_MOVE_ROLE_NONE;
4820 chan->move_state = L2CAP_MOVE_STABLE;
4821
4822 /* Restart data transmission */
4823 l2cap_ertm_send(chan);
4824}
4825
Andrei Emeltchenkoa514b172012-11-14 17:39:30 +02004826/* Invoke with locked chan */
4827void __l2cap_physical_cfm(struct l2cap_chan *chan, int result)
Mat Martineau8eb200b2012-10-23 15:24:17 -07004828{
Andrei Emeltchenko770bfef2012-10-31 15:46:29 +02004829 u8 local_amp_id = chan->local_amp_id;
Andrei Emeltchenkofffadc02012-11-01 15:37:03 +02004830 u8 remote_amp_id = chan->remote_amp_id;
Andrei Emeltchenko770bfef2012-10-31 15:46:29 +02004831
Mat Martineau8eb200b2012-10-23 15:24:17 -07004832 BT_DBG("chan %p, result %d, local_amp_id %d, remote_amp_id %d",
4833 chan, result, local_amp_id, remote_amp_id);
4834
Mat Martineau8eb200b2012-10-23 15:24:17 -07004835 if (chan->state == BT_DISCONN || chan->state == BT_CLOSED) {
4836 l2cap_chan_unlock(chan);
4837 return;
4838 }
4839
4840 if (chan->state != BT_CONNECTED) {
4841 l2cap_do_create(chan, result, local_amp_id, remote_amp_id);
4842 } else if (result != L2CAP_MR_SUCCESS) {
4843 l2cap_do_move_cancel(chan, result);
4844 } else {
4845 switch (chan->move_role) {
4846 case L2CAP_MOVE_ROLE_INITIATOR:
4847 l2cap_do_move_initiate(chan, local_amp_id,
4848 remote_amp_id);
4849 break;
4850 case L2CAP_MOVE_ROLE_RESPONDER:
4851 l2cap_do_move_respond(chan, result);
4852 break;
4853 default:
4854 l2cap_do_move_cancel(chan, result);
4855 break;
4856 }
4857 }
Mat Martineau8eb200b2012-10-23 15:24:17 -07004858}
4859
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004860static inline int l2cap_move_channel_req(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004861 struct l2cap_cmd_hdr *cmd,
4862 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004863{
4864 struct l2cap_move_chan_req *req = data;
Mat Martineau1500109b2012-10-23 15:24:15 -07004865 struct l2cap_move_chan_rsp rsp;
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004866 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004867 u16 icid = 0;
4868 u16 result = L2CAP_MR_NOT_ALLOWED;
4869
4870 if (cmd_len != sizeof(*req))
4871 return -EPROTO;
4872
4873 icid = le16_to_cpu(req->icid);
4874
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004875 BT_DBG("icid 0x%4.4x, dest_amp_id %d", icid, req->dest_amp_id);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004876
Marcel Holtmann848566b2013-10-01 22:59:22 -07004877 if (!conn->hs_enabled)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004878 return -EINVAL;
4879
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004880 chan = l2cap_get_chan_by_dcid(conn, icid);
4881 if (!chan) {
Mat Martineau1500109b2012-10-23 15:24:15 -07004882 rsp.icid = cpu_to_le16(icid);
4883 rsp.result = __constant_cpu_to_le16(L2CAP_MR_NOT_ALLOWED);
4884 l2cap_send_cmd(conn, cmd->ident, L2CAP_MOVE_CHAN_RSP,
4885 sizeof(rsp), &rsp);
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004886 return 0;
4887 }
4888
Mat Martineau1500109b2012-10-23 15:24:15 -07004889 chan->ident = cmd->ident;
4890
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004891 if (chan->scid < L2CAP_CID_DYN_START ||
4892 chan->chan_policy == BT_CHANNEL_POLICY_BREDR_ONLY ||
4893 (chan->mode != L2CAP_MODE_ERTM &&
4894 chan->mode != L2CAP_MODE_STREAMING)) {
4895 result = L2CAP_MR_NOT_ALLOWED;
4896 goto send_move_response;
4897 }
4898
4899 if (chan->local_amp_id == req->dest_amp_id) {
4900 result = L2CAP_MR_SAME_ID;
4901 goto send_move_response;
4902 }
4903
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004904 if (req->dest_amp_id != AMP_ID_BREDR) {
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004905 struct hci_dev *hdev;
4906 hdev = hci_dev_get(req->dest_amp_id);
4907 if (!hdev || hdev->dev_type != HCI_AMP ||
4908 !test_bit(HCI_UP, &hdev->flags)) {
4909 if (hdev)
4910 hci_dev_put(hdev);
4911
4912 result = L2CAP_MR_BAD_ID;
4913 goto send_move_response;
4914 }
4915 hci_dev_put(hdev);
4916 }
4917
4918 /* Detect a move collision. Only send a collision response
4919 * if this side has "lost", otherwise proceed with the move.
4920 * The winner has the larger bd_addr.
4921 */
4922 if ((__chan_is_moving(chan) ||
4923 chan->move_role != L2CAP_MOVE_ROLE_NONE) &&
Marcel Holtmann6f59b902013-10-13 05:24:01 -07004924 bacmp(&conn->hcon->src, &conn->hcon->dst) > 0) {
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004925 result = L2CAP_MR_COLLISION;
4926 goto send_move_response;
4927 }
4928
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004929 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
4930 l2cap_move_setup(chan);
4931 chan->move_id = req->dest_amp_id;
4932 icid = chan->dcid;
4933
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004934 if (req->dest_amp_id == AMP_ID_BREDR) {
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004935 /* Moving to BR/EDR */
4936 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4937 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4938 result = L2CAP_MR_PEND;
4939 } else {
4940 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4941 result = L2CAP_MR_SUCCESS;
4942 }
4943 } else {
4944 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
4945 /* Placeholder - uncomment when amp functions are available */
4946 /*amp_accept_physical(chan, req->dest_amp_id);*/
4947 result = L2CAP_MR_PEND;
4948 }
4949
4950send_move_response:
Mat Martineau1500109b2012-10-23 15:24:15 -07004951 l2cap_send_move_chan_rsp(chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004952
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004953 l2cap_chan_unlock(chan);
4954
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004955 return 0;
4956}
4957
Mat Martineau5b155ef2012-10-23 15:24:14 -07004958static void l2cap_move_continue(struct l2cap_conn *conn, u16 icid, u16 result)
4959{
4960 struct l2cap_chan *chan;
4961 struct hci_chan *hchan = NULL;
4962
4963 chan = l2cap_get_chan_by_scid(conn, icid);
4964 if (!chan) {
4965 l2cap_send_move_chan_cfm_icid(conn, icid);
4966 return;
4967 }
4968
4969 __clear_chan_timer(chan);
4970 if (result == L2CAP_MR_PEND)
4971 __set_chan_timer(chan, L2CAP_MOVE_ERTX_TIMEOUT);
4972
4973 switch (chan->move_state) {
4974 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
4975 /* Move confirm will be sent when logical link
4976 * is complete.
4977 */
4978 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4979 break;
4980 case L2CAP_MOVE_WAIT_RSP_SUCCESS:
4981 if (result == L2CAP_MR_PEND) {
4982 break;
4983 } else if (test_bit(CONN_LOCAL_BUSY,
4984 &chan->conn_state)) {
4985 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4986 } else {
4987 /* Logical link is up or moving to BR/EDR,
4988 * proceed with move
4989 */
4990 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
4991 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4992 }
4993 break;
4994 case L2CAP_MOVE_WAIT_RSP:
4995 /* Moving to AMP */
4996 if (result == L2CAP_MR_SUCCESS) {
4997 /* Remote is ready, send confirm immediately
4998 * after logical link is ready
4999 */
5000 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
5001 } else {
5002 /* Both logical link and move success
5003 * are required to confirm
5004 */
5005 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_COMP;
5006 }
5007
5008 /* Placeholder - get hci_chan for logical link */
5009 if (!hchan) {
5010 /* Logical link not available */
5011 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
5012 break;
5013 }
5014
5015 /* If the logical link is not yet connected, do not
5016 * send confirmation.
5017 */
5018 if (hchan->state != BT_CONNECTED)
5019 break;
5020
5021 /* Logical link is already ready to go */
5022
5023 chan->hs_hcon = hchan->conn;
5024 chan->hs_hcon->l2cap_data = chan->conn;
5025
5026 if (result == L2CAP_MR_SUCCESS) {
5027 /* Can confirm now */
5028 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
5029 } else {
5030 /* Now only need move success
5031 * to confirm
5032 */
5033 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
5034 }
5035
5036 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
5037 break;
5038 default:
5039 /* Any other amp move state means the move failed. */
5040 chan->move_id = chan->local_amp_id;
5041 l2cap_move_done(chan);
5042 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
5043 }
5044
5045 l2cap_chan_unlock(chan);
5046}
5047
5048static void l2cap_move_fail(struct l2cap_conn *conn, u8 ident, u16 icid,
5049 u16 result)
5050{
5051 struct l2cap_chan *chan;
5052
5053 chan = l2cap_get_chan_by_ident(conn, ident);
5054 if (!chan) {
5055 /* Could not locate channel, icid is best guess */
5056 l2cap_send_move_chan_cfm_icid(conn, icid);
5057 return;
5058 }
5059
5060 __clear_chan_timer(chan);
5061
5062 if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
5063 if (result == L2CAP_MR_COLLISION) {
5064 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
5065 } else {
5066 /* Cleanup - cancel move */
5067 chan->move_id = chan->local_amp_id;
5068 l2cap_move_done(chan);
5069 }
5070 }
5071
5072 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
5073
5074 l2cap_chan_unlock(chan);
5075}
5076
5077static int l2cap_move_channel_rsp(struct l2cap_conn *conn,
5078 struct l2cap_cmd_hdr *cmd,
5079 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005080{
5081 struct l2cap_move_chan_rsp *rsp = data;
5082 u16 icid, result;
5083
5084 if (cmd_len != sizeof(*rsp))
5085 return -EPROTO;
5086
5087 icid = le16_to_cpu(rsp->icid);
5088 result = le16_to_cpu(rsp->result);
5089
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005090 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005091
Mat Martineau5b155ef2012-10-23 15:24:14 -07005092 if (result == L2CAP_MR_SUCCESS || result == L2CAP_MR_PEND)
5093 l2cap_move_continue(conn, icid, result);
5094 else
5095 l2cap_move_fail(conn, cmd->ident, icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005096
5097 return 0;
5098}
5099
Mat Martineau5f3847a2012-10-23 15:24:12 -07005100static int l2cap_move_channel_confirm(struct l2cap_conn *conn,
5101 struct l2cap_cmd_hdr *cmd,
5102 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005103{
5104 struct l2cap_move_chan_cfm *cfm = data;
Mat Martineau5f3847a2012-10-23 15:24:12 -07005105 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005106 u16 icid, result;
5107
5108 if (cmd_len != sizeof(*cfm))
5109 return -EPROTO;
5110
5111 icid = le16_to_cpu(cfm->icid);
5112 result = le16_to_cpu(cfm->result);
5113
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005114 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005115
Mat Martineau5f3847a2012-10-23 15:24:12 -07005116 chan = l2cap_get_chan_by_dcid(conn, icid);
5117 if (!chan) {
5118 /* Spec requires a response even if the icid was not found */
5119 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
5120 return 0;
5121 }
5122
5123 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM) {
5124 if (result == L2CAP_MC_CONFIRMED) {
5125 chan->local_amp_id = chan->move_id;
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07005126 if (chan->local_amp_id == AMP_ID_BREDR)
Mat Martineau5f3847a2012-10-23 15:24:12 -07005127 __release_logical_link(chan);
5128 } else {
5129 chan->move_id = chan->local_amp_id;
5130 }
5131
5132 l2cap_move_done(chan);
5133 }
5134
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005135 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
5136
Mat Martineau5f3847a2012-10-23 15:24:12 -07005137 l2cap_chan_unlock(chan);
5138
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005139 return 0;
5140}
5141
5142static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005143 struct l2cap_cmd_hdr *cmd,
5144 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005145{
5146 struct l2cap_move_chan_cfm_rsp *rsp = data;
Mat Martineau3fd71a02012-10-23 15:24:16 -07005147 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005148 u16 icid;
5149
5150 if (cmd_len != sizeof(*rsp))
5151 return -EPROTO;
5152
5153 icid = le16_to_cpu(rsp->icid);
5154
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005155 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005156
Mat Martineau3fd71a02012-10-23 15:24:16 -07005157 chan = l2cap_get_chan_by_scid(conn, icid);
5158 if (!chan)
5159 return 0;
5160
5161 __clear_chan_timer(chan);
5162
5163 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM_RSP) {
5164 chan->local_amp_id = chan->move_id;
5165
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07005166 if (chan->local_amp_id == AMP_ID_BREDR && chan->hs_hchan)
Mat Martineau3fd71a02012-10-23 15:24:16 -07005167 __release_logical_link(chan);
5168
5169 l2cap_move_done(chan);
5170 }
5171
5172 l2cap_chan_unlock(chan);
5173
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005174 return 0;
5175}
5176
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03005177static inline int l2cap_check_conn_param(u16 min, u16 max, u16 latency,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005178 u16 to_multiplier)
Claudio Takahaside731152011-02-11 19:28:55 -02005179{
5180 u16 max_latency;
5181
5182 if (min > max || min < 6 || max > 3200)
5183 return -EINVAL;
5184
5185 if (to_multiplier < 10 || to_multiplier > 3200)
5186 return -EINVAL;
5187
5188 if (max >= to_multiplier * 8)
5189 return -EINVAL;
5190
5191 max_latency = (to_multiplier * 8 / max) - 1;
5192 if (latency > 499 || latency > max_latency)
5193 return -EINVAL;
5194
5195 return 0;
5196}
5197
5198static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005199 struct l2cap_cmd_hdr *cmd,
5200 u8 *data)
Claudio Takahaside731152011-02-11 19:28:55 -02005201{
5202 struct hci_conn *hcon = conn->hcon;
5203 struct l2cap_conn_param_update_req *req;
5204 struct l2cap_conn_param_update_rsp rsp;
5205 u16 min, max, latency, to_multiplier, cmd_len;
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005206 int err;
Claudio Takahaside731152011-02-11 19:28:55 -02005207
5208 if (!(hcon->link_mode & HCI_LM_MASTER))
5209 return -EINVAL;
5210
5211 cmd_len = __le16_to_cpu(cmd->len);
5212 if (cmd_len != sizeof(struct l2cap_conn_param_update_req))
5213 return -EPROTO;
5214
5215 req = (struct l2cap_conn_param_update_req *) data;
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03005216 min = __le16_to_cpu(req->min);
5217 max = __le16_to_cpu(req->max);
Claudio Takahaside731152011-02-11 19:28:55 -02005218 latency = __le16_to_cpu(req->latency);
5219 to_multiplier = __le16_to_cpu(req->to_multiplier);
5220
5221 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 +01005222 min, max, latency, to_multiplier);
Claudio Takahaside731152011-02-11 19:28:55 -02005223
5224 memset(&rsp, 0, sizeof(rsp));
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005225
5226 err = l2cap_check_conn_param(min, max, latency, to_multiplier);
5227 if (err)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005228 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
Claudio Takahaside731152011-02-11 19:28:55 -02005229 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005230 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED);
Claudio Takahaside731152011-02-11 19:28:55 -02005231
5232 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005233 sizeof(rsp), &rsp);
Claudio Takahaside731152011-02-11 19:28:55 -02005234
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005235 if (!err)
5236 hci_le_conn_update(hcon, min, max, latency, to_multiplier);
5237
Claudio Takahaside731152011-02-11 19:28:55 -02005238 return 0;
5239}
5240
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005241static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005242 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5243 u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005244{
5245 int err = 0;
5246
5247 switch (cmd->code) {
5248 case L2CAP_COMMAND_REJ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005249 l2cap_command_rej(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005250 break;
5251
5252 case L2CAP_CONN_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005253 err = l2cap_connect_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005254 break;
5255
5256 case L2CAP_CONN_RSP:
Mat Martineauf5a25982012-10-11 17:48:21 +03005257 case L2CAP_CREATE_CHAN_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005258 l2cap_connect_create_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005259 break;
5260
5261 case L2CAP_CONF_REQ:
5262 err = l2cap_config_req(conn, cmd, cmd_len, data);
5263 break;
5264
5265 case L2CAP_CONF_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005266 l2cap_config_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005267 break;
5268
5269 case L2CAP_DISCONN_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005270 err = l2cap_disconnect_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005271 break;
5272
5273 case L2CAP_DISCONN_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005274 l2cap_disconnect_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005275 break;
5276
5277 case L2CAP_ECHO_REQ:
5278 l2cap_send_cmd(conn, cmd->ident, L2CAP_ECHO_RSP, cmd_len, data);
5279 break;
5280
5281 case L2CAP_ECHO_RSP:
5282 break;
5283
5284 case L2CAP_INFO_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005285 err = l2cap_information_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005286 break;
5287
5288 case L2CAP_INFO_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005289 l2cap_information_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005290 break;
5291
Mat Martineauf94ff6f2011-11-02 16:18:32 -07005292 case L2CAP_CREATE_CHAN_REQ:
5293 err = l2cap_create_channel_req(conn, cmd, cmd_len, data);
5294 break;
5295
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005296 case L2CAP_MOVE_CHAN_REQ:
5297 err = l2cap_move_channel_req(conn, cmd, cmd_len, data);
5298 break;
5299
5300 case L2CAP_MOVE_CHAN_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005301 l2cap_move_channel_rsp(conn, cmd, cmd_len, data);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005302 break;
5303
5304 case L2CAP_MOVE_CHAN_CFM:
5305 err = l2cap_move_channel_confirm(conn, cmd, cmd_len, data);
5306 break;
5307
5308 case L2CAP_MOVE_CHAN_CFM_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005309 l2cap_move_channel_confirm_rsp(conn, cmd, cmd_len, data);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005310 break;
5311
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005312 default:
5313 BT_ERR("Unknown BR/EDR signaling command 0x%2.2x", cmd->code);
5314 err = -EINVAL;
5315 break;
5316 }
5317
5318 return err;
5319}
5320
5321static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005322 struct l2cap_cmd_hdr *cmd, u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005323{
5324 switch (cmd->code) {
5325 case L2CAP_COMMAND_REJ:
5326 return 0;
5327
5328 case L2CAP_CONN_PARAM_UPDATE_REQ:
Claudio Takahaside731152011-02-11 19:28:55 -02005329 return l2cap_conn_param_update_req(conn, cmd, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005330
5331 case L2CAP_CONN_PARAM_UPDATE_RSP:
5332 return 0;
5333
5334 default:
5335 BT_ERR("Unknown LE signaling command 0x%2.2x", cmd->code);
5336 return -EINVAL;
5337 }
5338}
5339
Johan Hedberg7c2005d2013-09-16 13:05:16 +03005340static __le16 l2cap_err_to_reason(int err)
5341{
5342 switch (err) {
5343 case -EBADSLT:
5344 return __constant_cpu_to_le16(L2CAP_REJ_INVALID_CID);
5345 case -EMSGSIZE:
5346 return __constant_cpu_to_le16(L2CAP_REJ_MTU_EXCEEDED);
5347 case -EINVAL:
5348 case -EPROTO:
5349 default:
5350 return __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
5351 }
5352}
5353
Johan Hedbergc5623552013-04-29 19:35:33 +03005354static inline void l2cap_le_sig_channel(struct l2cap_conn *conn,
5355 struct sk_buff *skb)
5356{
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005357 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005358 struct l2cap_cmd_hdr *cmd;
5359 u16 len;
Johan Hedbergc5623552013-04-29 19:35:33 +03005360 int err;
5361
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005362 if (hcon->type != LE_LINK)
Marcel Holtmann3b166292013-10-02 08:28:21 -07005363 goto drop;
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005364
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005365 if (skb->len < L2CAP_CMD_HDR_SIZE)
5366 goto drop;
Johan Hedbergc5623552013-04-29 19:35:33 +03005367
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005368 cmd = (void *) skb->data;
5369 skb_pull(skb, L2CAP_CMD_HDR_SIZE);
Johan Hedbergc5623552013-04-29 19:35:33 +03005370
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005371 len = le16_to_cpu(cmd->len);
Johan Hedbergc5623552013-04-29 19:35:33 +03005372
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005373 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd->code, len, cmd->ident);
Johan Hedbergc5623552013-04-29 19:35:33 +03005374
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005375 if (len != skb->len || !cmd->ident) {
5376 BT_DBG("corrupted command");
5377 goto drop;
5378 }
Johan Hedbergc5623552013-04-29 19:35:33 +03005379
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005380 err = l2cap_le_sig_cmd(conn, cmd, skb->data);
5381 if (err) {
5382 struct l2cap_cmd_rej_unk rej;
Johan Hedbergc5623552013-04-29 19:35:33 +03005383
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005384 BT_ERR("Wrong link type (%d)", err);
Johan Hedbergc5623552013-04-29 19:35:33 +03005385
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005386 rej.reason = l2cap_err_to_reason(err);
5387 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
5388 sizeof(rej), &rej);
Johan Hedbergc5623552013-04-29 19:35:33 +03005389 }
5390
Marcel Holtmann3b166292013-10-02 08:28:21 -07005391drop:
Johan Hedbergc5623552013-04-29 19:35:33 +03005392 kfree_skb(skb);
5393}
5394
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005395static inline void l2cap_sig_channel(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005396 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005397{
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005398 struct hci_conn *hcon = conn->hcon;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005399 u8 *data = skb->data;
5400 int len = skb->len;
5401 struct l2cap_cmd_hdr cmd;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005402 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005403
5404 l2cap_raw_recv(conn, skb);
5405
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005406 if (hcon->type != ACL_LINK)
Marcel Holtmann3b166292013-10-02 08:28:21 -07005407 goto drop;
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005408
Linus Torvalds1da177e2005-04-16 15:20:36 -07005409 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07005410 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005411 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
5412 data += L2CAP_CMD_HDR_SIZE;
5413 len -= L2CAP_CMD_HDR_SIZE;
5414
Al Viro88219a02007-07-29 00:17:25 -07005415 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005416
Gustavo Padovan2d792812012-10-06 10:07:01 +01005417 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len,
5418 cmd.ident);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005419
Al Viro88219a02007-07-29 00:17:25 -07005420 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005421 BT_DBG("corrupted command");
5422 break;
5423 }
5424
Johan Hedbergc5623552013-04-29 19:35:33 +03005425 err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005426 if (err) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03005427 struct l2cap_cmd_rej_unk rej;
Gustavo F. Padovan2c6d1a22011-03-23 14:38:32 -03005428
5429 BT_ERR("Wrong link type (%d)", err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005430
Johan Hedberg7c2005d2013-09-16 13:05:16 +03005431 rej.reason = l2cap_err_to_reason(err);
Gustavo Padovan2d792812012-10-06 10:07:01 +01005432 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ,
5433 sizeof(rej), &rej);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005434 }
5435
Al Viro88219a02007-07-29 00:17:25 -07005436 data += cmd_len;
5437 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005438 }
5439
Marcel Holtmann3b166292013-10-02 08:28:21 -07005440drop:
Linus Torvalds1da177e2005-04-16 15:20:36 -07005441 kfree_skb(skb);
5442}
5443
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005444static int l2cap_check_fcs(struct l2cap_chan *chan, struct sk_buff *skb)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005445{
5446 u16 our_fcs, rcv_fcs;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03005447 int hdr_size;
5448
5449 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
5450 hdr_size = L2CAP_EXT_HDR_SIZE;
5451 else
5452 hdr_size = L2CAP_ENH_HDR_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005453
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005454 if (chan->fcs == L2CAP_FCS_CRC16) {
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005455 skb_trim(skb, skb->len - L2CAP_FCS_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005456 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
5457 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
5458
5459 if (our_fcs != rcv_fcs)
João Paulo Rechi Vita7a560e52010-06-22 13:56:27 -03005460 return -EBADMSG;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005461 }
5462 return 0;
5463}
5464
Mat Martineau6ea00482012-05-17 20:53:52 -07005465static void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan)
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005466{
Mat Martineaue31f7632012-05-17 20:53:41 -07005467 struct l2cap_ctrl control;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005468
Mat Martineaue31f7632012-05-17 20:53:41 -07005469 BT_DBG("chan %p", chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005470
Mat Martineaue31f7632012-05-17 20:53:41 -07005471 memset(&control, 0, sizeof(control));
5472 control.sframe = 1;
5473 control.final = 1;
5474 control.reqseq = chan->buffer_seq;
5475 set_bit(CONN_SEND_FBIT, &chan->conn_state);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005476
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03005477 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
Mat Martineaue31f7632012-05-17 20:53:41 -07005478 control.super = L2CAP_SUPER_RNR;
5479 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005480 }
5481
Mat Martineaue31f7632012-05-17 20:53:41 -07005482 if (test_and_clear_bit(CONN_REMOTE_BUSY, &chan->conn_state) &&
5483 chan->unacked_frames > 0)
5484 __set_retrans_timer(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005485
Mat Martineaue31f7632012-05-17 20:53:41 -07005486 /* Send pending iframes */
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03005487 l2cap_ertm_send(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005488
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03005489 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
Mat Martineaue31f7632012-05-17 20:53:41 -07005490 test_bit(CONN_SEND_FBIT, &chan->conn_state)) {
5491 /* F-bit wasn't sent in an s-frame or i-frame yet, so
5492 * send it now.
5493 */
5494 control.super = L2CAP_SUPER_RR;
5495 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005496 }
5497}
5498
Gustavo Padovan2d792812012-10-06 10:07:01 +01005499static void append_skb_frag(struct sk_buff *skb, struct sk_buff *new_frag,
5500 struct sk_buff **last_frag)
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005501{
Mat Martineau84084a32011-07-22 14:54:00 -07005502 /* skb->len reflects data in skb as well as all fragments
5503 * skb->data_len reflects only data in fragments
5504 */
5505 if (!skb_has_frag_list(skb))
5506 skb_shinfo(skb)->frag_list = new_frag;
5507
5508 new_frag->next = NULL;
5509
5510 (*last_frag)->next = new_frag;
5511 *last_frag = new_frag;
5512
5513 skb->len += new_frag->len;
5514 skb->data_len += new_frag->len;
5515 skb->truesize += new_frag->truesize;
5516}
5517
Mat Martineau4b51dae92012-05-17 20:53:37 -07005518static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb,
5519 struct l2cap_ctrl *control)
Mat Martineau84084a32011-07-22 14:54:00 -07005520{
5521 int err = -EINVAL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005522
Mat Martineau4b51dae92012-05-17 20:53:37 -07005523 switch (control->sar) {
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005524 case L2CAP_SAR_UNSEGMENTED:
Mat Martineau84084a32011-07-22 14:54:00 -07005525 if (chan->sdu)
5526 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005527
Gustavo Padovan80b98022012-05-27 22:27:51 -03005528 err = chan->ops->recv(chan, skb);
Mat Martineau84084a32011-07-22 14:54:00 -07005529 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005530
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005531 case L2CAP_SAR_START:
Mat Martineau84084a32011-07-22 14:54:00 -07005532 if (chan->sdu)
5533 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005534
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005535 chan->sdu_len = get_unaligned_le16(skb->data);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005536 skb_pull(skb, L2CAP_SDULEN_SIZE);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005537
Mat Martineau84084a32011-07-22 14:54:00 -07005538 if (chan->sdu_len > chan->imtu) {
5539 err = -EMSGSIZE;
5540 break;
5541 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005542
Mat Martineau84084a32011-07-22 14:54:00 -07005543 if (skb->len >= chan->sdu_len)
5544 break;
5545
5546 chan->sdu = skb;
5547 chan->sdu_last_frag = skb;
5548
5549 skb = NULL;
5550 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005551 break;
5552
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005553 case L2CAP_SAR_CONTINUE:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005554 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07005555 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005556
Mat Martineau84084a32011-07-22 14:54:00 -07005557 append_skb_frag(chan->sdu, skb,
5558 &chan->sdu_last_frag);
5559 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005560
Mat Martineau84084a32011-07-22 14:54:00 -07005561 if (chan->sdu->len >= chan->sdu_len)
5562 break;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03005563
Mat Martineau84084a32011-07-22 14:54:00 -07005564 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005565 break;
5566
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005567 case L2CAP_SAR_END:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005568 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07005569 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005570
Mat Martineau84084a32011-07-22 14:54:00 -07005571 append_skb_frag(chan->sdu, skb,
5572 &chan->sdu_last_frag);
5573 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005574
Mat Martineau84084a32011-07-22 14:54:00 -07005575 if (chan->sdu->len != chan->sdu_len)
5576 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005577
Gustavo Padovan80b98022012-05-27 22:27:51 -03005578 err = chan->ops->recv(chan, chan->sdu);
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03005579
Mat Martineau84084a32011-07-22 14:54:00 -07005580 if (!err) {
5581 /* Reassembly complete */
5582 chan->sdu = NULL;
5583 chan->sdu_last_frag = NULL;
5584 chan->sdu_len = 0;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03005585 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005586 break;
5587 }
5588
Mat Martineau84084a32011-07-22 14:54:00 -07005589 if (err) {
5590 kfree_skb(skb);
5591 kfree_skb(chan->sdu);
5592 chan->sdu = NULL;
5593 chan->sdu_last_frag = NULL;
5594 chan->sdu_len = 0;
5595 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005596
Mat Martineau84084a32011-07-22 14:54:00 -07005597 return err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005598}
5599
Mat Martineau32b32732012-10-23 15:24:11 -07005600static int l2cap_resegment(struct l2cap_chan *chan)
5601{
5602 /* Placeholder */
5603 return 0;
5604}
5605
Mat Martineaue3281402011-07-07 09:39:02 -07005606void l2cap_chan_busy(struct l2cap_chan *chan, int busy)
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03005607{
Mat Martineau61aa4f52012-05-17 20:53:40 -07005608 u8 event;
5609
5610 if (chan->mode != L2CAP_MODE_ERTM)
5611 return;
5612
5613 event = busy ? L2CAP_EV_LOCAL_BUSY_DETECTED : L2CAP_EV_LOCAL_BUSY_CLEAR;
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03005614 l2cap_tx(chan, NULL, NULL, event);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03005615}
5616
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005617static int l2cap_rx_queued_iframes(struct l2cap_chan *chan)
5618{
Mat Martineau63838722012-05-17 20:53:45 -07005619 int err = 0;
5620 /* Pass sequential frames to l2cap_reassemble_sdu()
5621 * until a gap is encountered.
5622 */
5623
5624 BT_DBG("chan %p", chan);
5625
5626 while (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5627 struct sk_buff *skb;
5628 BT_DBG("Searching for skb with txseq %d (queue len %d)",
5629 chan->buffer_seq, skb_queue_len(&chan->srej_q));
5630
5631 skb = l2cap_ertm_seq_in_queue(&chan->srej_q, chan->buffer_seq);
5632
5633 if (!skb)
5634 break;
5635
5636 skb_unlink(skb, &chan->srej_q);
5637 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
5638 err = l2cap_reassemble_sdu(chan, skb, &bt_cb(skb)->control);
5639 if (err)
5640 break;
5641 }
5642
5643 if (skb_queue_empty(&chan->srej_q)) {
5644 chan->rx_state = L2CAP_RX_STATE_RECV;
5645 l2cap_send_ack(chan);
5646 }
5647
5648 return err;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005649}
5650
5651static void l2cap_handle_srej(struct l2cap_chan *chan,
5652 struct l2cap_ctrl *control)
5653{
Mat Martineauf80842a2012-05-17 20:53:46 -07005654 struct sk_buff *skb;
5655
5656 BT_DBG("chan %p, control %p", chan, control);
5657
5658 if (control->reqseq == chan->next_tx_seq) {
5659 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005660 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineauf80842a2012-05-17 20:53:46 -07005661 return;
5662 }
5663
5664 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
5665
5666 if (skb == NULL) {
5667 BT_DBG("Seq %d not available for retransmission",
5668 control->reqseq);
5669 return;
5670 }
5671
5672 if (chan->max_tx != 0 && bt_cb(skb)->control.retries >= chan->max_tx) {
5673 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005674 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineauf80842a2012-05-17 20:53:46 -07005675 return;
5676 }
5677
5678 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5679
5680 if (control->poll) {
5681 l2cap_pass_to_tx(chan, control);
5682
5683 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5684 l2cap_retransmit(chan, control);
5685 l2cap_ertm_send(chan);
5686
5687 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
5688 set_bit(CONN_SREJ_ACT, &chan->conn_state);
5689 chan->srej_save_reqseq = control->reqseq;
5690 }
5691 } else {
5692 l2cap_pass_to_tx_fbit(chan, control);
5693
5694 if (control->final) {
5695 if (chan->srej_save_reqseq != control->reqseq ||
5696 !test_and_clear_bit(CONN_SREJ_ACT,
5697 &chan->conn_state))
5698 l2cap_retransmit(chan, control);
5699 } else {
5700 l2cap_retransmit(chan, control);
5701 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
5702 set_bit(CONN_SREJ_ACT, &chan->conn_state);
5703 chan->srej_save_reqseq = control->reqseq;
5704 }
5705 }
5706 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005707}
5708
5709static void l2cap_handle_rej(struct l2cap_chan *chan,
5710 struct l2cap_ctrl *control)
5711{
Mat Martineaufcd289d2012-05-17 20:53:47 -07005712 struct sk_buff *skb;
5713
5714 BT_DBG("chan %p, control %p", chan, control);
5715
5716 if (control->reqseq == chan->next_tx_seq) {
5717 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005718 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaufcd289d2012-05-17 20:53:47 -07005719 return;
5720 }
5721
5722 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
5723
5724 if (chan->max_tx && skb &&
5725 bt_cb(skb)->control.retries >= chan->max_tx) {
5726 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005727 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaufcd289d2012-05-17 20:53:47 -07005728 return;
5729 }
5730
5731 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5732
5733 l2cap_pass_to_tx(chan, control);
5734
5735 if (control->final) {
5736 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state))
5737 l2cap_retransmit_all(chan, control);
5738 } else {
5739 l2cap_retransmit_all(chan, control);
5740 l2cap_ertm_send(chan);
5741 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F)
5742 set_bit(CONN_REJ_ACT, &chan->conn_state);
5743 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005744}
5745
Mat Martineau4b51dae92012-05-17 20:53:37 -07005746static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq)
5747{
5748 BT_DBG("chan %p, txseq %d", chan, txseq);
5749
5750 BT_DBG("last_acked_seq %d, expected_tx_seq %d", chan->last_acked_seq,
5751 chan->expected_tx_seq);
5752
5753 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
5754 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
Gustavo Padovan2d792812012-10-06 10:07:01 +01005755 chan->tx_win) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07005756 /* See notes below regarding "double poll" and
5757 * invalid packets.
5758 */
5759 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
5760 BT_DBG("Invalid/Ignore - after SREJ");
5761 return L2CAP_TXSEQ_INVALID_IGNORE;
5762 } else {
5763 BT_DBG("Invalid - in window after SREJ sent");
5764 return L2CAP_TXSEQ_INVALID;
5765 }
5766 }
5767
5768 if (chan->srej_list.head == txseq) {
5769 BT_DBG("Expected SREJ");
5770 return L2CAP_TXSEQ_EXPECTED_SREJ;
5771 }
5772
5773 if (l2cap_ertm_seq_in_queue(&chan->srej_q, txseq)) {
5774 BT_DBG("Duplicate SREJ - txseq already stored");
5775 return L2CAP_TXSEQ_DUPLICATE_SREJ;
5776 }
5777
5778 if (l2cap_seq_list_contains(&chan->srej_list, txseq)) {
5779 BT_DBG("Unexpected SREJ - not requested");
5780 return L2CAP_TXSEQ_UNEXPECTED_SREJ;
5781 }
5782 }
5783
5784 if (chan->expected_tx_seq == txseq) {
5785 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
5786 chan->tx_win) {
5787 BT_DBG("Invalid - txseq outside tx window");
5788 return L2CAP_TXSEQ_INVALID;
5789 } else {
5790 BT_DBG("Expected");
5791 return L2CAP_TXSEQ_EXPECTED;
5792 }
5793 }
5794
5795 if (__seq_offset(chan, txseq, chan->last_acked_seq) <
Gustavo Padovan2d792812012-10-06 10:07:01 +01005796 __seq_offset(chan, chan->expected_tx_seq, chan->last_acked_seq)) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07005797 BT_DBG("Duplicate - expected_tx_seq later than txseq");
5798 return L2CAP_TXSEQ_DUPLICATE;
5799 }
5800
5801 if (__seq_offset(chan, txseq, chan->last_acked_seq) >= chan->tx_win) {
5802 /* A source of invalid packets is a "double poll" condition,
5803 * where delays cause us to send multiple poll packets. If
5804 * the remote stack receives and processes both polls,
5805 * sequence numbers can wrap around in such a way that a
5806 * resent frame has a sequence number that looks like new data
5807 * with a sequence gap. This would trigger an erroneous SREJ
5808 * request.
5809 *
5810 * Fortunately, this is impossible with a tx window that's
5811 * less than half of the maximum sequence number, which allows
5812 * invalid frames to be safely ignored.
5813 *
5814 * With tx window sizes greater than half of the tx window
5815 * maximum, the frame is invalid and cannot be ignored. This
5816 * causes a disconnect.
5817 */
5818
5819 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
5820 BT_DBG("Invalid/Ignore - txseq outside tx window");
5821 return L2CAP_TXSEQ_INVALID_IGNORE;
5822 } else {
5823 BT_DBG("Invalid - txseq outside tx window");
5824 return L2CAP_TXSEQ_INVALID;
5825 }
5826 } else {
5827 BT_DBG("Unexpected - txseq indicates missing frames");
5828 return L2CAP_TXSEQ_UNEXPECTED;
5829 }
5830}
5831
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005832static int l2cap_rx_state_recv(struct l2cap_chan *chan,
5833 struct l2cap_ctrl *control,
5834 struct sk_buff *skb, u8 event)
5835{
5836 int err = 0;
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005837 bool skb_in_use = false;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005838
5839 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
5840 event);
5841
5842 switch (event) {
5843 case L2CAP_EV_RECV_IFRAME:
5844 switch (l2cap_classify_txseq(chan, control->txseq)) {
5845 case L2CAP_TXSEQ_EXPECTED:
5846 l2cap_pass_to_tx(chan, control);
5847
5848 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5849 BT_DBG("Busy, discarding expected seq %d",
5850 control->txseq);
5851 break;
5852 }
5853
5854 chan->expected_tx_seq = __next_seq(chan,
5855 control->txseq);
5856
5857 chan->buffer_seq = chan->expected_tx_seq;
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005858 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005859
5860 err = l2cap_reassemble_sdu(chan, skb, control);
5861 if (err)
5862 break;
5863
5864 if (control->final) {
5865 if (!test_and_clear_bit(CONN_REJ_ACT,
5866 &chan->conn_state)) {
5867 control->final = 0;
5868 l2cap_retransmit_all(chan, control);
5869 l2cap_ertm_send(chan);
5870 }
5871 }
5872
5873 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
5874 l2cap_send_ack(chan);
5875 break;
5876 case L2CAP_TXSEQ_UNEXPECTED:
5877 l2cap_pass_to_tx(chan, control);
5878
5879 /* Can't issue SREJ frames in the local busy state.
5880 * Drop this frame, it will be seen as missing
5881 * when local busy is exited.
5882 */
5883 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5884 BT_DBG("Busy, discarding unexpected seq %d",
5885 control->txseq);
5886 break;
5887 }
5888
5889 /* There was a gap in the sequence, so an SREJ
5890 * must be sent for each missing frame. The
5891 * current frame is stored for later use.
5892 */
5893 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005894 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005895 BT_DBG("Queued %p (queue len %d)", skb,
5896 skb_queue_len(&chan->srej_q));
5897
5898 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
5899 l2cap_seq_list_clear(&chan->srej_list);
5900 l2cap_send_srej(chan, control->txseq);
5901
5902 chan->rx_state = L2CAP_RX_STATE_SREJ_SENT;
5903 break;
5904 case L2CAP_TXSEQ_DUPLICATE:
5905 l2cap_pass_to_tx(chan, control);
5906 break;
5907 case L2CAP_TXSEQ_INVALID_IGNORE:
5908 break;
5909 case L2CAP_TXSEQ_INVALID:
5910 default:
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005911 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005912 break;
5913 }
5914 break;
5915 case L2CAP_EV_RECV_RR:
5916 l2cap_pass_to_tx(chan, control);
5917 if (control->final) {
5918 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5919
Mat Martineaue6a3ee62012-10-23 15:24:22 -07005920 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state) &&
5921 !__chan_is_moving(chan)) {
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005922 control->final = 0;
5923 l2cap_retransmit_all(chan, control);
5924 }
5925
5926 l2cap_ertm_send(chan);
5927 } else if (control->poll) {
5928 l2cap_send_i_or_rr_or_rnr(chan);
5929 } else {
5930 if (test_and_clear_bit(CONN_REMOTE_BUSY,
5931 &chan->conn_state) &&
5932 chan->unacked_frames)
5933 __set_retrans_timer(chan);
5934
5935 l2cap_ertm_send(chan);
5936 }
5937 break;
5938 case L2CAP_EV_RECV_RNR:
5939 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5940 l2cap_pass_to_tx(chan, control);
5941 if (control && control->poll) {
5942 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5943 l2cap_send_rr_or_rnr(chan, 0);
5944 }
5945 __clear_retrans_timer(chan);
5946 l2cap_seq_list_clear(&chan->retrans_list);
5947 break;
5948 case L2CAP_EV_RECV_REJ:
5949 l2cap_handle_rej(chan, control);
5950 break;
5951 case L2CAP_EV_RECV_SREJ:
5952 l2cap_handle_srej(chan, control);
5953 break;
5954 default:
5955 break;
5956 }
5957
5958 if (skb && !skb_in_use) {
5959 BT_DBG("Freeing %p", skb);
5960 kfree_skb(skb);
5961 }
5962
5963 return err;
5964}
5965
5966static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan,
5967 struct l2cap_ctrl *control,
5968 struct sk_buff *skb, u8 event)
5969{
5970 int err = 0;
5971 u16 txseq = control->txseq;
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005972 bool skb_in_use = false;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005973
5974 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
5975 event);
5976
5977 switch (event) {
5978 case L2CAP_EV_RECV_IFRAME:
5979 switch (l2cap_classify_txseq(chan, txseq)) {
5980 case L2CAP_TXSEQ_EXPECTED:
5981 /* Keep frame for reassembly later */
5982 l2cap_pass_to_tx(chan, control);
5983 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005984 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005985 BT_DBG("Queued %p (queue len %d)", skb,
5986 skb_queue_len(&chan->srej_q));
5987
5988 chan->expected_tx_seq = __next_seq(chan, txseq);
5989 break;
5990 case L2CAP_TXSEQ_EXPECTED_SREJ:
5991 l2cap_seq_list_pop(&chan->srej_list);
5992
5993 l2cap_pass_to_tx(chan, control);
5994 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005995 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005996 BT_DBG("Queued %p (queue len %d)", skb,
5997 skb_queue_len(&chan->srej_q));
5998
5999 err = l2cap_rx_queued_iframes(chan);
6000 if (err)
6001 break;
6002
6003 break;
6004 case L2CAP_TXSEQ_UNEXPECTED:
6005 /* Got a frame that can't be reassembled yet.
6006 * Save it for later, and send SREJs to cover
6007 * the missing frames.
6008 */
6009 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006010 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006011 BT_DBG("Queued %p (queue len %d)", skb,
6012 skb_queue_len(&chan->srej_q));
6013
6014 l2cap_pass_to_tx(chan, control);
6015 l2cap_send_srej(chan, control->txseq);
6016 break;
6017 case L2CAP_TXSEQ_UNEXPECTED_SREJ:
6018 /* This frame was requested with an SREJ, but
6019 * some expected retransmitted frames are
6020 * missing. Request retransmission of missing
6021 * SREJ'd frames.
6022 */
6023 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006024 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006025 BT_DBG("Queued %p (queue len %d)", skb,
6026 skb_queue_len(&chan->srej_q));
6027
6028 l2cap_pass_to_tx(chan, control);
6029 l2cap_send_srej_list(chan, control->txseq);
6030 break;
6031 case L2CAP_TXSEQ_DUPLICATE_SREJ:
6032 /* We've already queued this frame. Drop this copy. */
6033 l2cap_pass_to_tx(chan, control);
6034 break;
6035 case L2CAP_TXSEQ_DUPLICATE:
6036 /* Expecting a later sequence number, so this frame
6037 * was already received. Ignore it completely.
6038 */
6039 break;
6040 case L2CAP_TXSEQ_INVALID_IGNORE:
6041 break;
6042 case L2CAP_TXSEQ_INVALID:
6043 default:
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006044 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006045 break;
6046 }
6047 break;
6048 case L2CAP_EV_RECV_RR:
6049 l2cap_pass_to_tx(chan, control);
6050 if (control->final) {
6051 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6052
6053 if (!test_and_clear_bit(CONN_REJ_ACT,
6054 &chan->conn_state)) {
6055 control->final = 0;
6056 l2cap_retransmit_all(chan, control);
6057 }
6058
6059 l2cap_ertm_send(chan);
6060 } else if (control->poll) {
6061 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6062 &chan->conn_state) &&
6063 chan->unacked_frames) {
6064 __set_retrans_timer(chan);
6065 }
6066
6067 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6068 l2cap_send_srej_tail(chan);
6069 } else {
6070 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6071 &chan->conn_state) &&
6072 chan->unacked_frames)
6073 __set_retrans_timer(chan);
6074
6075 l2cap_send_ack(chan);
6076 }
6077 break;
6078 case L2CAP_EV_RECV_RNR:
6079 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6080 l2cap_pass_to_tx(chan, control);
6081 if (control->poll) {
6082 l2cap_send_srej_tail(chan);
6083 } else {
6084 struct l2cap_ctrl rr_control;
6085 memset(&rr_control, 0, sizeof(rr_control));
6086 rr_control.sframe = 1;
6087 rr_control.super = L2CAP_SUPER_RR;
6088 rr_control.reqseq = chan->buffer_seq;
6089 l2cap_send_sframe(chan, &rr_control);
6090 }
6091
6092 break;
6093 case L2CAP_EV_RECV_REJ:
6094 l2cap_handle_rej(chan, control);
6095 break;
6096 case L2CAP_EV_RECV_SREJ:
6097 l2cap_handle_srej(chan, control);
6098 break;
6099 }
6100
6101 if (skb && !skb_in_use) {
6102 BT_DBG("Freeing %p", skb);
6103 kfree_skb(skb);
6104 }
6105
6106 return err;
6107}
6108
Mat Martineau32b32732012-10-23 15:24:11 -07006109static int l2cap_finish_move(struct l2cap_chan *chan)
6110{
6111 BT_DBG("chan %p", chan);
6112
6113 chan->rx_state = L2CAP_RX_STATE_RECV;
6114
6115 if (chan->hs_hcon)
6116 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
6117 else
6118 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
6119
6120 return l2cap_resegment(chan);
6121}
6122
6123static int l2cap_rx_state_wait_p(struct l2cap_chan *chan,
6124 struct l2cap_ctrl *control,
6125 struct sk_buff *skb, u8 event)
6126{
6127 int err;
6128
6129 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
6130 event);
6131
6132 if (!control->poll)
6133 return -EPROTO;
6134
6135 l2cap_process_reqseq(chan, control->reqseq);
6136
6137 if (!skb_queue_empty(&chan->tx_q))
6138 chan->tx_send_head = skb_peek(&chan->tx_q);
6139 else
6140 chan->tx_send_head = NULL;
6141
6142 /* Rewind next_tx_seq to the point expected
6143 * by the receiver.
6144 */
6145 chan->next_tx_seq = control->reqseq;
6146 chan->unacked_frames = 0;
6147
6148 err = l2cap_finish_move(chan);
6149 if (err)
6150 return err;
6151
6152 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6153 l2cap_send_i_or_rr_or_rnr(chan);
6154
6155 if (event == L2CAP_EV_RECV_IFRAME)
6156 return -EPROTO;
6157
6158 return l2cap_rx_state_recv(chan, control, NULL, event);
6159}
6160
6161static int l2cap_rx_state_wait_f(struct l2cap_chan *chan,
6162 struct l2cap_ctrl *control,
6163 struct sk_buff *skb, u8 event)
6164{
6165 int err;
6166
6167 if (!control->final)
6168 return -EPROTO;
6169
6170 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6171
6172 chan->rx_state = L2CAP_RX_STATE_RECV;
6173 l2cap_process_reqseq(chan, control->reqseq);
6174
6175 if (!skb_queue_empty(&chan->tx_q))
6176 chan->tx_send_head = skb_peek(&chan->tx_q);
6177 else
6178 chan->tx_send_head = NULL;
6179
6180 /* Rewind next_tx_seq to the point expected
6181 * by the receiver.
6182 */
6183 chan->next_tx_seq = control->reqseq;
6184 chan->unacked_frames = 0;
6185
6186 if (chan->hs_hcon)
6187 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
6188 else
6189 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
6190
6191 err = l2cap_resegment(chan);
6192
6193 if (!err)
6194 err = l2cap_rx_state_recv(chan, control, skb, event);
6195
6196 return err;
6197}
6198
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006199static bool __valid_reqseq(struct l2cap_chan *chan, u16 reqseq)
6200{
6201 /* Make sure reqseq is for a packet that has been sent but not acked */
6202 u16 unacked;
6203
6204 unacked = __seq_offset(chan, chan->next_tx_seq, chan->expected_ack_seq);
6205 return __seq_offset(chan, chan->next_tx_seq, reqseq) <= unacked;
6206}
6207
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006208static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
6209 struct sk_buff *skb, u8 event)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006210{
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006211 int err = 0;
6212
6213 BT_DBG("chan %p, control %p, skb %p, event %d, state %d", chan,
6214 control, skb, event, chan->rx_state);
6215
6216 if (__valid_reqseq(chan, control->reqseq)) {
6217 switch (chan->rx_state) {
6218 case L2CAP_RX_STATE_RECV:
6219 err = l2cap_rx_state_recv(chan, control, skb, event);
6220 break;
6221 case L2CAP_RX_STATE_SREJ_SENT:
6222 err = l2cap_rx_state_srej_sent(chan, control, skb,
6223 event);
6224 break;
Mat Martineau32b32732012-10-23 15:24:11 -07006225 case L2CAP_RX_STATE_WAIT_P:
6226 err = l2cap_rx_state_wait_p(chan, control, skb, event);
6227 break;
6228 case L2CAP_RX_STATE_WAIT_F:
6229 err = l2cap_rx_state_wait_f(chan, control, skb, event);
6230 break;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006231 default:
6232 /* shut it down */
6233 break;
6234 }
6235 } else {
6236 BT_DBG("Invalid reqseq %d (next_tx_seq %d, expected_ack_seq %d",
6237 control->reqseq, chan->next_tx_seq,
6238 chan->expected_ack_seq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006239 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006240 }
6241
6242 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006243}
6244
6245static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
6246 struct sk_buff *skb)
6247{
Mat Martineau4b51dae92012-05-17 20:53:37 -07006248 int err = 0;
6249
6250 BT_DBG("chan %p, control %p, skb %p, state %d", chan, control, skb,
6251 chan->rx_state);
6252
6253 if (l2cap_classify_txseq(chan, control->txseq) ==
6254 L2CAP_TXSEQ_EXPECTED) {
6255 l2cap_pass_to_tx(chan, control);
6256
6257 BT_DBG("buffer_seq %d->%d", chan->buffer_seq,
6258 __next_seq(chan, chan->buffer_seq));
6259
6260 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
6261
6262 l2cap_reassemble_sdu(chan, skb, control);
6263 } else {
6264 if (chan->sdu) {
6265 kfree_skb(chan->sdu);
6266 chan->sdu = NULL;
6267 }
6268 chan->sdu_last_frag = NULL;
6269 chan->sdu_len = 0;
6270
6271 if (skb) {
6272 BT_DBG("Freeing %p", skb);
6273 kfree_skb(skb);
6274 }
6275 }
6276
6277 chan->last_acked_seq = control->txseq;
6278 chan->expected_tx_seq = __next_seq(chan, control->txseq);
6279
6280 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006281}
6282
6283static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
6284{
6285 struct l2cap_ctrl *control = &bt_cb(skb)->control;
6286 u16 len;
6287 u8 event;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006288
Mat Martineaub76bbd62012-04-11 10:48:43 -07006289 __unpack_control(chan, skb);
6290
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006291 len = skb->len;
6292
6293 /*
6294 * We can just drop the corrupted I-frame here.
6295 * Receiver will miss it and start proper recovery
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006296 * procedures and ask for retransmission.
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006297 */
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006298 if (l2cap_check_fcs(chan, skb))
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006299 goto drop;
6300
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006301 if (!control->sframe && control->sar == L2CAP_SAR_START)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03006302 len -= L2CAP_SDULEN_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006303
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006304 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03006305 len -= L2CAP_FCS_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006306
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006307 if (len > chan->mps) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006308 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006309 goto drop;
6310 }
6311
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006312 if (!control->sframe) {
6313 int err;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006314
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006315 BT_DBG("iframe sar %d, reqseq %d, final %d, txseq %d",
6316 control->sar, control->reqseq, control->final,
6317 control->txseq);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03006318
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006319 /* Validate F-bit - F=0 always valid, F=1 only
6320 * valid in TX WAIT_F
6321 */
6322 if (control->final && chan->tx_state != L2CAP_TX_STATE_WAIT_F)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006323 goto drop;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006324
6325 if (chan->mode != L2CAP_MODE_STREAMING) {
6326 event = L2CAP_EV_RECV_IFRAME;
6327 err = l2cap_rx(chan, control, skb, event);
6328 } else {
6329 err = l2cap_stream_rx(chan, control, skb);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006330 }
6331
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006332 if (err)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006333 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006334 } else {
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006335 const u8 rx_func_to_event[4] = {
6336 L2CAP_EV_RECV_RR, L2CAP_EV_RECV_REJ,
6337 L2CAP_EV_RECV_RNR, L2CAP_EV_RECV_SREJ
6338 };
6339
6340 /* Only I-frames are expected in streaming mode */
6341 if (chan->mode == L2CAP_MODE_STREAMING)
6342 goto drop;
6343
6344 BT_DBG("sframe reqseq %d, final %d, poll %d, super %d",
6345 control->reqseq, control->final, control->poll,
6346 control->super);
6347
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006348 if (len != 0) {
Andrei Emeltchenko1bb166e2012-11-20 17:16:21 +02006349 BT_ERR("Trailing bytes: %d in sframe", len);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006350 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006351 goto drop;
6352 }
6353
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006354 /* Validate F and P bits */
6355 if (control->final && (control->poll ||
6356 chan->tx_state != L2CAP_TX_STATE_WAIT_F))
6357 goto drop;
6358
6359 event = rx_func_to_event[control->super];
6360 if (l2cap_rx(chan, control, skb, event))
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006361 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006362 }
6363
6364 return 0;
6365
6366drop:
6367 kfree_skb(skb);
6368 return 0;
6369}
6370
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006371static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid,
6372 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006373{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006374 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006375
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03006376 chan = l2cap_get_chan_by_scid(conn, cid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006377 if (!chan) {
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006378 if (cid == L2CAP_CID_A2MP) {
6379 chan = a2mp_channel_create(conn, skb);
6380 if (!chan) {
6381 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006382 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006383 }
6384
6385 l2cap_chan_lock(chan);
6386 } else {
6387 BT_DBG("unknown cid 0x%4.4x", cid);
6388 /* Drop packet and return */
6389 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006390 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006391 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006392 }
6393
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03006394 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006395
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006396 if (chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006397 goto drop;
6398
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006399 switch (chan->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006400 case L2CAP_MODE_BASIC:
6401 /* If socket recv buffers overflows we drop data here
6402 * which is *bad* because L2CAP has to be reliable.
6403 * But we don't have any other choice. L2CAP doesn't
6404 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006405
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006406 if (chan->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006407 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006408
Gustavo Padovan80b98022012-05-27 22:27:51 -03006409 if (!chan->ops->recv(chan, skb))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006410 goto done;
6411 break;
6412
6413 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03006414 case L2CAP_MODE_STREAMING:
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006415 l2cap_data_rcv(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03006416 goto done;
6417
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006418 default:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006419 BT_DBG("chan %p: bad mode 0x%2.2x", chan, chan->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006420 break;
6421 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006422
6423drop:
6424 kfree_skb(skb);
6425
6426done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006427 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006428}
6429
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03006430static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm,
6431 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006432{
Marcel Holtmannae4fd2d2013-10-03 00:03:39 -07006433 struct hci_conn *hcon = conn->hcon;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006434 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006435
Marcel Holtmannae4fd2d2013-10-03 00:03:39 -07006436 if (hcon->type != ACL_LINK)
6437 goto drop;
6438
Marcel Holtmann6f59b902013-10-13 05:24:01 -07006439 chan = l2cap_global_chan_by_psm(0, psm, &conn->hcon->src,
Marcel Holtmann98e0f7e2013-10-13 02:23:40 -07006440 &conn->hcon->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006441 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006442 goto drop;
6443
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02006444 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006445
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006446 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006447 goto drop;
6448
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03006449 if (chan->imtu < skb->len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006450 goto drop;
6451
Gustavo Padovan80b98022012-05-27 22:27:51 -03006452 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03006453 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006454
6455drop:
6456 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006457}
6458
Marcel Holtmann72f78352013-04-23 00:59:00 -07006459static void l2cap_att_channel(struct l2cap_conn *conn,
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03006460 struct sk_buff *skb)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006461{
Marcel Holtmannb99707d2013-10-03 02:54:11 -07006462 struct hci_conn *hcon = conn->hcon;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006463 struct l2cap_chan *chan;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006464
Marcel Holtmannb99707d2013-10-03 02:54:11 -07006465 if (hcon->type != LE_LINK)
6466 goto drop;
6467
Johan Hedbergaf1c0132013-04-29 19:35:42 +03006468 chan = l2cap_global_chan_by_scid(BT_CONNECTED, L2CAP_CID_ATT,
Marcel Holtmann6f59b902013-10-13 05:24:01 -07006469 &conn->hcon->src, &conn->hcon->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006470 if (!chan)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006471 goto drop;
6472
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02006473 BT_DBG("chan %p, len %d", chan, skb->len);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006474
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03006475 if (chan->imtu < skb->len)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006476 goto drop;
6477
Gustavo Padovan80b98022012-05-27 22:27:51 -03006478 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03006479 return;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006480
6481drop:
6482 kfree_skb(skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006483}
6484
Linus Torvalds1da177e2005-04-16 15:20:36 -07006485static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
6486{
6487 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07006488 u16 cid, len;
6489 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006490
6491 skb_pull(skb, L2CAP_HDR_SIZE);
6492 cid = __le16_to_cpu(lh->cid);
6493 len = __le16_to_cpu(lh->len);
6494
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006495 if (len != skb->len) {
6496 kfree_skb(skb);
6497 return;
6498 }
6499
Linus Torvalds1da177e2005-04-16 15:20:36 -07006500 BT_DBG("len %d, cid 0x%4.4x", len, cid);
6501
6502 switch (cid) {
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03006503 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006504 l2cap_sig_channel(conn, skb);
6505 break;
6506
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03006507 case L2CAP_CID_CONN_LESS:
Andrei Emeltchenko097db762012-03-09 14:16:17 +02006508 psm = get_unaligned((__le16 *) skb->data);
Andrei Emeltchenko0181a702012-05-29 10:04:05 +03006509 skb_pull(skb, L2CAP_PSMLEN_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006510 l2cap_conless_channel(conn, psm, skb);
6511 break;
6512
Johan Hedberg073d1cf2013-04-29 19:35:35 +03006513 case L2CAP_CID_ATT:
Marcel Holtmann72f78352013-04-23 00:59:00 -07006514 l2cap_att_channel(conn, skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006515 break;
6516
Marcel Holtmanna2877622013-10-02 23:46:54 -07006517 case L2CAP_CID_LE_SIGNALING:
6518 l2cap_le_sig_channel(conn, skb);
6519 break;
6520
Anderson Brigliab501d6a2011-06-07 18:46:31 -03006521 case L2CAP_CID_SMP:
6522 if (smp_sig_channel(conn, skb))
6523 l2cap_conn_del(conn->hcon, EACCES);
6524 break;
6525
Linus Torvalds1da177e2005-04-16 15:20:36 -07006526 default:
6527 l2cap_data_channel(conn, cid, skb);
6528 break;
6529 }
6530}
6531
6532/* ---- L2CAP interface with lower layer (HCI) ---- */
6533
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006534int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006535{
6536 int exact = 0, lm1 = 0, lm2 = 0;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006537 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006538
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03006539 BT_DBG("hdev %s, bdaddr %pMR", hdev->name, bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006540
6541 /* Find listening sockets and check their link_mode */
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006542 read_lock(&chan_list_lock);
6543 list_for_each_entry(c, &chan_list, global_l) {
6544 struct sock *sk = c->sk;
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006545
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006546 if (c->state != BT_LISTEN)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006547 continue;
6548
6549 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006550 lm1 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03006551 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006552 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006553 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006554 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
6555 lm2 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03006556 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006557 lm2 |= HCI_LM_MASTER;
6558 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006559 }
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006560 read_unlock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006561
6562 return exact ? lm1 : lm2;
6563}
6564
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03006565void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006566{
Marcel Holtmann01394182006-07-03 10:02:46 +02006567 struct l2cap_conn *conn;
6568
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03006569 BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006570
Linus Torvalds1da177e2005-04-16 15:20:36 -07006571 if (!status) {
Claudio Takahasibaf43252013-04-11 13:55:50 -03006572 conn = l2cap_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006573 if (conn)
6574 l2cap_conn_ready(conn);
Andrei Emeltchenkoba6fc312012-10-31 15:46:26 +02006575 } else {
Joe Perchese1750722011-06-29 18:18:29 -07006576 l2cap_conn_del(hcon, bt_to_errno(status));
Andrei Emeltchenkoba6fc312012-10-31 15:46:26 +02006577 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006578}
6579
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006580int l2cap_disconn_ind(struct hci_conn *hcon)
Marcel Holtmann2950f212009-02-12 14:02:50 +01006581{
6582 struct l2cap_conn *conn = hcon->l2cap_data;
6583
6584 BT_DBG("hcon %p", hcon);
6585
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006586 if (!conn)
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02006587 return HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01006588 return conn->disc_reason;
6589}
6590
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03006591void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006592{
6593 BT_DBG("hcon %p reason %d", hcon, reason);
6594
Joe Perchese1750722011-06-29 18:18:29 -07006595 l2cap_conn_del(hcon, bt_to_errno(reason));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006596}
6597
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006598static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006599{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03006600 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED)
Marcel Holtmann255c7602009-02-04 21:07:19 +01006601 return;
6602
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006603 if (encrypt == 0x00) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006604 if (chan->sec_level == BT_SECURITY_MEDIUM) {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006605 __set_chan_timer(chan, L2CAP_ENC_TIMEOUT);
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006606 } else if (chan->sec_level == BT_SECURITY_HIGH)
Gustavo F. Padovan0f852722011-05-04 19:42:50 -03006607 l2cap_chan_close(chan, ECONNREFUSED);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006608 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006609 if (chan->sec_level == BT_SECURITY_MEDIUM)
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03006610 __clear_chan_timer(chan);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006611 }
6612}
6613
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006614int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006615{
Marcel Holtmann40be4922008-07-14 20:13:50 +02006616 struct l2cap_conn *conn = hcon->l2cap_data;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006617 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006618
Marcel Holtmann01394182006-07-03 10:02:46 +02006619 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006620 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02006621
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03006622 BT_DBG("conn %p status 0x%2.2x encrypt %u", conn, status, encrypt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006623
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03006624 if (hcon->type == LE_LINK) {
Hemant Gupta35d4adcc2012-04-18 14:46:26 +05306625 if (!status && encrypt)
6626 smp_distribute_keys(conn, 0);
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02006627 cancel_delayed_work(&conn->security_timer);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03006628 }
6629
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006630 mutex_lock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006631
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006632 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006633 l2cap_chan_lock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006634
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03006635 BT_DBG("chan %p scid 0x%4.4x state %s", chan, chan->scid,
6636 state_to_string(chan->state));
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006637
Andrei Emeltchenko78eb2f92012-07-19 17:03:47 +03006638 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
6639 l2cap_chan_unlock(chan);
6640 continue;
6641 }
6642
Johan Hedberg073d1cf2013-04-29 19:35:35 +03006643 if (chan->scid == L2CAP_CID_ATT) {
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006644 if (!status && encrypt) {
6645 chan->sec_level = hcon->sec_level;
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02006646 l2cap_chan_ready(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006647 }
6648
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006649 l2cap_chan_unlock(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006650 continue;
6651 }
6652
Andrei Emeltchenko96eff462012-11-15 18:14:53 +02006653 if (!__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006654 l2cap_chan_unlock(chan);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01006655 continue;
6656 }
6657
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006658 if (!status && (chan->state == BT_CONNECTED ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01006659 chan->state == BT_CONFIG)) {
Gustavo Padovana7d77232012-05-13 03:20:07 -03006660 struct sock *sk = chan->sk;
6661
Gustavo Padovanc5daa682012-05-16 12:17:10 -03006662 clear_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags);
Gustavo Padovana7d77232012-05-13 03:20:07 -03006663 sk->sk_state_change(sk);
6664
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006665 l2cap_check_encryption(chan, encrypt);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006666 l2cap_chan_unlock(chan);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02006667 continue;
6668 }
6669
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006670 if (chan->state == BT_CONNECT) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006671 if (!status) {
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03006672 l2cap_start_connection(chan);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006673 } else {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006674 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006675 }
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006676 } else if (chan->state == BT_CONNECT2) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006677 struct sock *sk = chan->sk;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006678 struct l2cap_conn_rsp rsp;
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006679 __u16 res, stat;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006680
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006681 lock_sock(sk);
6682
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006683 if (!status) {
Gustavo Padovanc5daa682012-05-16 12:17:10 -03006684 if (test_bit(BT_SK_DEFER_SETUP,
6685 &bt_sk(sk)->flags)) {
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006686 res = L2CAP_CR_PEND;
6687 stat = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08006688 chan->ops->defer(chan);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006689 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02006690 __l2cap_state_change(chan, BT_CONFIG);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006691 res = L2CAP_CR_SUCCESS;
6692 stat = L2CAP_CS_NO_INFO;
6693 }
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006694 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02006695 __l2cap_state_change(chan, BT_DISCONN);
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006696 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006697 res = L2CAP_CR_SEC_BLOCK;
6698 stat = L2CAP_CS_NO_INFO;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006699 }
6700
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006701 release_sock(sk);
6702
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03006703 rsp.scid = cpu_to_le16(chan->dcid);
6704 rsp.dcid = cpu_to_le16(chan->scid);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006705 rsp.result = cpu_to_le16(res);
6706 rsp.status = cpu_to_le16(stat);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03006707 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01006708 sizeof(rsp), &rsp);
Mat Martineau2d369352012-05-23 14:59:30 -07006709
6710 if (!test_bit(CONF_REQ_SENT, &chan->conf_state) &&
6711 res == L2CAP_CR_SUCCESS) {
6712 char buf[128];
6713 set_bit(CONF_REQ_SENT, &chan->conf_state);
6714 l2cap_send_cmd(conn, l2cap_get_ident(conn),
6715 L2CAP_CONF_REQ,
6716 l2cap_build_conf_req(chan, buf),
6717 buf);
6718 chan->num_conf_req++;
6719 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006720 }
6721
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006722 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006723 }
6724
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006725 mutex_unlock(&conn->chan_lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006726
Linus Torvalds1da177e2005-04-16 15:20:36 -07006727 return 0;
6728}
6729
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006730int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006731{
6732 struct l2cap_conn *conn = hcon->l2cap_data;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006733 struct l2cap_hdr *hdr;
6734 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006735
Andrei Emeltchenko1d13a252012-10-15 11:58:41 +03006736 /* For AMP controller do not create l2cap conn */
6737 if (!conn && hcon->hdev->dev_type != HCI_BREDR)
6738 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006739
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02006740 if (!conn)
Claudio Takahasibaf43252013-04-11 13:55:50 -03006741 conn = l2cap_conn_add(hcon);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02006742
6743 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006744 goto drop;
6745
6746 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
6747
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006748 switch (flags) {
6749 case ACL_START:
6750 case ACL_START_NO_FLUSH:
6751 case ACL_COMPLETE:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006752 if (conn->rx_len) {
6753 BT_ERR("Unexpected start frame (len %d)", skb->len);
6754 kfree_skb(conn->rx_skb);
6755 conn->rx_skb = NULL;
6756 conn->rx_len = 0;
6757 l2cap_conn_unreliable(conn, ECOMM);
6758 }
6759
Andrei Emeltchenkoaae7fe22010-09-15 14:28:43 +03006760 /* Start fragment always begin with Basic L2CAP header */
6761 if (skb->len < L2CAP_HDR_SIZE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006762 BT_ERR("Frame is too short (len %d)", skb->len);
6763 l2cap_conn_unreliable(conn, ECOMM);
6764 goto drop;
6765 }
6766
6767 hdr = (struct l2cap_hdr *) skb->data;
6768 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
6769
6770 if (len == skb->len) {
6771 /* Complete frame received */
6772 l2cap_recv_frame(conn, skb);
6773 return 0;
6774 }
6775
6776 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
6777
6778 if (skb->len > len) {
6779 BT_ERR("Frame is too long (len %d, expected len %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01006780 skb->len, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006781 l2cap_conn_unreliable(conn, ECOMM);
6782 goto drop;
6783 }
6784
6785 /* Allocate skb for the complete frame (with header) */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03006786 conn->rx_skb = bt_skb_alloc(len, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03006787 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006788 goto drop;
6789
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03006790 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01006791 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006792 conn->rx_len = len - skb->len;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006793 break;
6794
6795 case ACL_CONT:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006796 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
6797
6798 if (!conn->rx_len) {
6799 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
6800 l2cap_conn_unreliable(conn, ECOMM);
6801 goto drop;
6802 }
6803
6804 if (skb->len > conn->rx_len) {
6805 BT_ERR("Fragment is too long (len %d, expected %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01006806 skb->len, conn->rx_len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006807 kfree_skb(conn->rx_skb);
6808 conn->rx_skb = NULL;
6809 conn->rx_len = 0;
6810 l2cap_conn_unreliable(conn, ECOMM);
6811 goto drop;
6812 }
6813
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03006814 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01006815 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006816 conn->rx_len -= skb->len;
6817
6818 if (!conn->rx_len) {
Johan Hedbergc4e5baf2013-10-10 13:33:37 +02006819 /* Complete frame received. l2cap_recv_frame
6820 * takes ownership of the skb so set the global
6821 * rx_skb pointer to NULL first.
6822 */
6823 struct sk_buff *rx_skb = conn->rx_skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006824 conn->rx_skb = NULL;
Johan Hedbergc4e5baf2013-10-10 13:33:37 +02006825 l2cap_recv_frame(conn, rx_skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006826 }
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006827 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006828 }
6829
6830drop:
6831 kfree_skb(skb);
6832 return 0;
6833}
6834
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006835static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006836{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006837 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006838
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02006839 read_lock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006840
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006841 list_for_each_entry(c, &chan_list, global_l) {
6842 struct sock *sk = c->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006843
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +03006844 seq_printf(f, "%pMR %pMR %d %d 0x%4.4x 0x%4.4x %d %d %d %d\n",
6845 &bt_sk(sk)->src, &bt_sk(sk)->dst,
6846 c->state, __le16_to_cpu(c->psm),
6847 c->scid, c->dcid, c->imtu, c->omtu,
6848 c->sec_level, c->mode);
Andrei Emeltchenko61e1b4b2012-01-19 11:19:50 +02006849 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006850
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02006851 read_unlock(&chan_list_lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08006852
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006853 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006854}
6855
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006856static int l2cap_debugfs_open(struct inode *inode, struct file *file)
6857{
6858 return single_open(file, l2cap_debugfs_show, inode->i_private);
6859}
6860
6861static const struct file_operations l2cap_debugfs_fops = {
6862 .open = l2cap_debugfs_open,
6863 .read = seq_read,
6864 .llseek = seq_lseek,
6865 .release = single_release,
6866};
6867
6868static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006869
Gustavo F. Padovan64274512011-02-07 20:08:52 -02006870int __init l2cap_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006871{
6872 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08006873
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02006874 err = l2cap_init_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006875 if (err < 0)
6876 return err;
6877
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006878 if (bt_debugfs) {
Gustavo Padovan2d792812012-10-06 10:07:01 +01006879 l2cap_debugfs = debugfs_create_file("l2cap", 0444, bt_debugfs,
6880 NULL, &l2cap_debugfs_fops);
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006881 if (!l2cap_debugfs)
6882 BT_ERR("Failed to create L2CAP debug file");
6883 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006884
Linus Torvalds1da177e2005-04-16 15:20:36 -07006885 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006886}
6887
Gustavo F. Padovan64274512011-02-07 20:08:52 -02006888void l2cap_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006889{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006890 debugfs_remove(l2cap_debugfs);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02006891 l2cap_cleanup_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006892}
6893
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03006894module_param(disable_ertm, bool, 0644);
6895MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode");