blob: 8a0d235215cd36ae97ea3d4ec9a4be09350db6fb [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. Padovan710f9b02011-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 Holtmann4f1654e2013-10-13 08:50:41 -070062static inline __u8 bdaddr_type(struct hci_conn *hcon, __u8 type)
63{
64 if (hcon->type == LE_LINK) {
65 if (type == ADDR_LE_DEV_PUBLIC)
66 return BDADDR_LE_PUBLIC;
67 else
68 return BDADDR_LE_RANDOM;
69 }
70
71 return BDADDR_BREDR;
72}
73
Marcel Holtmann01394182006-07-03 10:02:46 +020074/* ---- L2CAP channels ---- */
Gustavo F. Padovan71ba0e52011-05-17 14:34:52 -030075
Gustavo Padovan2d792812012-10-06 10:07:01 +010076static struct l2cap_chan *__l2cap_get_chan_by_dcid(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->dcid == 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
Gustavo Padovan2d792812012-10-06 10:07:01 +010088static struct l2cap_chan *__l2cap_get_chan_by_scid(struct l2cap_conn *conn,
89 u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +020090{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020091 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030092
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020093 list_for_each_entry(c, &conn->chan_l, list) {
94 if (c->scid == cid)
95 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +020096 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020097 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +020098}
99
100/* Find channel with given SCID.
Mat Martineauef191ad2012-05-02 09:42:00 -0700101 * Returns locked channel. */
Gustavo Padovan2d792812012-10-06 10:07:01 +0100102static struct l2cap_chan *l2cap_get_chan_by_scid(struct l2cap_conn *conn,
103 u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +0200104{
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300105 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300106
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200107 mutex_lock(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300108 c = __l2cap_get_chan_by_scid(conn, cid);
Mat Martineauef191ad2012-05-02 09:42:00 -0700109 if (c)
110 l2cap_chan_lock(c);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200111 mutex_unlock(&conn->chan_lock);
112
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300113 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +0200114}
115
Mat Martineaub1a130b2012-10-23 15:24:09 -0700116/* Find channel with given DCID.
117 * Returns locked channel.
118 */
119static struct l2cap_chan *l2cap_get_chan_by_dcid(struct l2cap_conn *conn,
120 u16 cid)
121{
122 struct l2cap_chan *c;
123
124 mutex_lock(&conn->chan_lock);
125 c = __l2cap_get_chan_by_dcid(conn, cid);
126 if (c)
127 l2cap_chan_lock(c);
128 mutex_unlock(&conn->chan_lock);
129
130 return c;
131}
132
Gustavo Padovan2d792812012-10-06 10:07:01 +0100133static struct l2cap_chan *__l2cap_get_chan_by_ident(struct l2cap_conn *conn,
134 u8 ident)
Marcel Holtmann01394182006-07-03 10:02:46 +0200135{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200136 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300137
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200138 list_for_each_entry(c, &conn->chan_l, list) {
139 if (c->ident == ident)
140 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +0200141 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200142 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200143}
144
Mat Martineau5b155ef2012-10-23 15:24:14 -0700145static struct l2cap_chan *l2cap_get_chan_by_ident(struct l2cap_conn *conn,
146 u8 ident)
147{
148 struct l2cap_chan *c;
149
150 mutex_lock(&conn->chan_lock);
151 c = __l2cap_get_chan_by_ident(conn, ident);
152 if (c)
153 l2cap_chan_lock(c);
154 mutex_unlock(&conn->chan_lock);
155
156 return c;
157}
158
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300159static struct l2cap_chan *__l2cap_global_chan_by_addr(__le16 psm, bdaddr_t *src)
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300160{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300161 struct l2cap_chan *c;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300162
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300163 list_for_each_entry(c, &chan_list, global_l) {
Marcel Holtmann7eafc592013-10-13 08:12:47 -0700164 if (c->sport == psm && !bacmp(&c->src, src))
Szymon Janc250938c2011-11-16 09:32:22 +0100165 return c;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300166 }
Szymon Janc250938c2011-11-16 09:32:22 +0100167 return NULL;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300168}
169
170int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm)
171{
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300172 int err;
173
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200174 write_lock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300175
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300176 if (psm && __l2cap_global_chan_by_addr(psm, src)) {
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300177 err = -EADDRINUSE;
178 goto done;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300179 }
180
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300181 if (psm) {
182 chan->psm = psm;
183 chan->sport = psm;
184 err = 0;
185 } else {
186 u16 p;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300187
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300188 err = -EINVAL;
189 for (p = 0x1001; p < 0x1100; p += 2)
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300190 if (!__l2cap_global_chan_by_addr(cpu_to_le16(p), src)) {
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300191 chan->psm = cpu_to_le16(p);
192 chan->sport = cpu_to_le16(p);
193 err = 0;
194 break;
195 }
196 }
197
198done:
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200199 write_unlock(&chan_list_lock);
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300200 return err;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300201}
202
203int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid)
204{
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200205 write_lock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300206
207 chan->scid = scid;
208
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200209 write_unlock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300210
211 return 0;
212}
213
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300214static u16 l2cap_alloc_cid(struct l2cap_conn *conn)
Marcel Holtmann01394182006-07-03 10:02:46 +0200215{
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300216 u16 cid = L2CAP_CID_DYN_START;
Marcel Holtmann01394182006-07-03 10:02:46 +0200217
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300218 for (; cid < L2CAP_CID_DYN_END; cid++) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300219 if (!__l2cap_get_chan_by_scid(conn, cid))
Marcel Holtmann01394182006-07-03 10:02:46 +0200220 return cid;
221 }
222
223 return 0;
224}
225
Gustavo Padovanf93fa272013-10-21 14:21:40 -0200226static void l2cap_state_change(struct l2cap_chan *chan, int state)
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300227{
Andrei Emeltchenko42d2d872012-02-17 11:40:57 +0200228 BT_DBG("chan %p %s -> %s", chan, state_to_string(chan->state),
Gustavo Padovan2d792812012-10-06 10:07:01 +0100229 state_to_string(state));
Gustavo F. Padovanbadaaa02011-11-23 20:11:46 -0200230
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300231 chan->state = state;
Gustavo Padovan53f52122013-10-15 19:24:45 -0300232 chan->ops->state_change(chan, state, 0);
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300233}
234
Gustavo Padovanf8e73012013-10-15 19:24:46 -0300235static inline void l2cap_state_change_and_error(struct l2cap_chan *chan,
236 int state, int err)
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +0200237{
Gustavo Padovanf8e73012013-10-15 19:24:46 -0300238 chan->state = state;
Gustavo Padovan53f52122013-10-15 19:24:45 -0300239 chan->ops->state_change(chan, chan->state, err);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +0200240}
241
242static inline void l2cap_chan_set_err(struct l2cap_chan *chan, int err)
243{
Gustavo Padovanf8e73012013-10-15 19:24:46 -0300244 chan->ops->state_change(chan, chan->state, err);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +0200245}
246
Mat Martineau4239d162012-05-17 20:53:49 -0700247static void __set_retrans_timer(struct l2cap_chan *chan)
248{
249 if (!delayed_work_pending(&chan->monitor_timer) &&
250 chan->retrans_timeout) {
251 l2cap_set_timer(chan, &chan->retrans_timer,
252 msecs_to_jiffies(chan->retrans_timeout));
253 }
254}
255
256static void __set_monitor_timer(struct l2cap_chan *chan)
257{
258 __clear_retrans_timer(chan);
259 if (chan->monitor_timeout) {
260 l2cap_set_timer(chan, &chan->monitor_timer,
261 msecs_to_jiffies(chan->monitor_timeout));
262 }
263}
264
Mat Martineau608bcc62012-05-17 20:53:32 -0700265static struct sk_buff *l2cap_ertm_seq_in_queue(struct sk_buff_head *head,
266 u16 seq)
267{
268 struct sk_buff *skb;
269
270 skb_queue_walk(head, skb) {
271 if (bt_cb(skb)->control.txseq == seq)
272 return skb;
273 }
274
275 return NULL;
276}
277
Mat Martineau3c588192012-04-11 10:48:42 -0700278/* ---- L2CAP sequence number lists ---- */
279
280/* For ERTM, ordered lists of sequence numbers must be tracked for
281 * SREJ requests that are received and for frames that are to be
282 * retransmitted. These seq_list functions implement a singly-linked
283 * list in an array, where membership in the list can also be checked
284 * in constant time. Items can also be added to the tail of the list
285 * and removed from the head in constant time, without further memory
286 * allocs or frees.
287 */
288
289static int l2cap_seq_list_init(struct l2cap_seq_list *seq_list, u16 size)
290{
291 size_t alloc_size, i;
292
293 /* Allocated size is a power of 2 to map sequence numbers
294 * (which may be up to 14 bits) in to a smaller array that is
295 * sized for the negotiated ERTM transmit windows.
296 */
297 alloc_size = roundup_pow_of_two(size);
298
299 seq_list->list = kmalloc(sizeof(u16) * alloc_size, GFP_KERNEL);
300 if (!seq_list->list)
301 return -ENOMEM;
302
303 seq_list->mask = alloc_size - 1;
304 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
305 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
306 for (i = 0; i < alloc_size; i++)
307 seq_list->list[i] = L2CAP_SEQ_LIST_CLEAR;
308
309 return 0;
310}
311
312static inline void l2cap_seq_list_free(struct l2cap_seq_list *seq_list)
313{
314 kfree(seq_list->list);
315}
316
317static inline bool l2cap_seq_list_contains(struct l2cap_seq_list *seq_list,
318 u16 seq)
319{
320 /* Constant-time check for list membership */
321 return seq_list->list[seq & seq_list->mask] != L2CAP_SEQ_LIST_CLEAR;
322}
323
324static u16 l2cap_seq_list_remove(struct l2cap_seq_list *seq_list, u16 seq)
325{
326 u16 mask = seq_list->mask;
327
328 if (seq_list->head == L2CAP_SEQ_LIST_CLEAR) {
329 /* In case someone tries to pop the head of an empty list */
330 return L2CAP_SEQ_LIST_CLEAR;
331 } else if (seq_list->head == seq) {
332 /* Head can be removed in constant time */
333 seq_list->head = seq_list->list[seq & mask];
334 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_CLEAR;
335
336 if (seq_list->head == L2CAP_SEQ_LIST_TAIL) {
337 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
338 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
339 }
340 } else {
341 /* Walk the list to find the sequence number */
342 u16 prev = seq_list->head;
343 while (seq_list->list[prev & mask] != seq) {
344 prev = seq_list->list[prev & mask];
345 if (prev == L2CAP_SEQ_LIST_TAIL)
346 return L2CAP_SEQ_LIST_CLEAR;
347 }
348
349 /* Unlink the number from the list and clear it */
350 seq_list->list[prev & mask] = seq_list->list[seq & mask];
351 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_CLEAR;
352 if (seq_list->tail == seq)
353 seq_list->tail = prev;
354 }
355 return seq;
356}
357
358static inline u16 l2cap_seq_list_pop(struct l2cap_seq_list *seq_list)
359{
360 /* Remove the head in constant time */
361 return l2cap_seq_list_remove(seq_list, seq_list->head);
362}
363
364static void l2cap_seq_list_clear(struct l2cap_seq_list *seq_list)
365{
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300366 u16 i;
Mat Martineau3c588192012-04-11 10:48:42 -0700367
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300368 if (seq_list->head == L2CAP_SEQ_LIST_CLEAR)
369 return;
370
371 for (i = 0; i <= seq_list->mask; i++)
372 seq_list->list[i] = L2CAP_SEQ_LIST_CLEAR;
373
374 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
375 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
Mat Martineau3c588192012-04-11 10:48:42 -0700376}
377
378static void l2cap_seq_list_append(struct l2cap_seq_list *seq_list, u16 seq)
379{
380 u16 mask = seq_list->mask;
381
382 /* All appends happen in constant time */
383
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300384 if (seq_list->list[seq & mask] != L2CAP_SEQ_LIST_CLEAR)
385 return;
Mat Martineau3c588192012-04-11 10:48:42 -0700386
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300387 if (seq_list->tail == L2CAP_SEQ_LIST_CLEAR)
388 seq_list->head = seq;
389 else
390 seq_list->list[seq_list->tail & mask] = seq;
391
392 seq_list->tail = seq;
393 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_TAIL;
Mat Martineau3c588192012-04-11 10:48:42 -0700394}
395
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300396static void l2cap_chan_timeout(struct work_struct *work)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300397{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300398 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100399 chan_timer.work);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200400 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300401 int reason;
402
Andrei Emeltchenkoe05dcc32012-02-17 11:40:56 +0200403 BT_DBG("chan %p state %s", chan, state_to_string(chan->state));
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300404
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200405 mutex_lock(&conn->chan_lock);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200406 l2cap_chan_lock(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300407
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300408 if (chan->state == BT_CONNECTED || chan->state == BT_CONFIG)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300409 reason = ECONNREFUSED;
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300410 else if (chan->state == BT_CONNECT &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100411 chan->sec_level != BT_SECURITY_SDP)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300412 reason = ECONNREFUSED;
413 else
414 reason = ETIMEDOUT;
415
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300416 l2cap_chan_close(chan, reason);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300417
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200418 l2cap_chan_unlock(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300419
Gustavo Padovan80b98022012-05-27 22:27:51 -0300420 chan->ops->close(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200421 mutex_unlock(&conn->chan_lock);
422
Ulisses Furquim371fd832011-12-21 20:02:36 -0200423 l2cap_chan_put(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300424}
425
Gustavo Padovaneef1d9b2012-03-25 13:59:16 -0300426struct l2cap_chan *l2cap_chan_create(void)
Marcel Holtmann01394182006-07-03 10:02:46 +0200427{
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300428 struct l2cap_chan *chan;
Marcel Holtmann01394182006-07-03 10:02:46 +0200429
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300430 chan = kzalloc(sizeof(*chan), GFP_ATOMIC);
431 if (!chan)
432 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200433
Andrei Emeltchenkoc03b3552012-02-21 12:54:56 +0200434 mutex_init(&chan->lock);
435
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200436 write_lock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300437 list_add(&chan->global_l, &chan_list);
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200438 write_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300439
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300440 INIT_DELAYED_WORK(&chan->chan_timer, l2cap_chan_timeout);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300441
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300442 chan->state = BT_OPEN;
443
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530444 kref_init(&chan->kref);
Gustavo F. Padovan71ba0e52011-05-17 14:34:52 -0300445
Mat Martineau28270112012-05-17 21:14:09 -0700446 /* This flag is cleared in l2cap_chan_ready() */
447 set_bit(CONF_NOT_COMPLETE, &chan->conf_state);
448
Gustavo Padovaneef1d9b2012-03-25 13:59:16 -0300449 BT_DBG("chan %p", chan);
Szymon Jancabc545b2011-11-03 16:05:44 +0100450
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300451 return chan;
Marcel Holtmann01394182006-07-03 10:02:46 +0200452}
453
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530454static void l2cap_chan_destroy(struct kref *kref)
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300455{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530456 struct l2cap_chan *chan = container_of(kref, struct l2cap_chan, kref);
457
Jaganath Kanakkassery4af66c62012-07-13 18:17:55 +0530458 BT_DBG("chan %p", chan);
459
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200460 write_lock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300461 list_del(&chan->global_l);
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200462 write_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300463
Jaganath Kanakkassery4af66c62012-07-13 18:17:55 +0530464 kfree(chan);
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300465}
466
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530467void l2cap_chan_hold(struct l2cap_chan *c)
468{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530469 BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->kref.refcount));
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530470
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530471 kref_get(&c->kref);
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530472}
473
474void l2cap_chan_put(struct l2cap_chan *c)
475{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530476 BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->kref.refcount));
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530477
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530478 kref_put(&c->kref, l2cap_chan_destroy);
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530479}
480
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +0300481void l2cap_chan_set_defaults(struct l2cap_chan *chan)
482{
483 chan->fcs = L2CAP_FCS_CRC16;
484 chan->max_tx = L2CAP_DEFAULT_MAX_TX;
485 chan->tx_win = L2CAP_DEFAULT_TX_WINDOW;
486 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
Mat Martineauc20f8e32012-07-10 05:47:07 -0700487 chan->ack_win = L2CAP_DEFAULT_TX_WINDOW;
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +0300488 chan->sec_level = BT_SECURITY_LOW;
489
490 set_bit(FLAG_FORCE_ACTIVE, &chan->flags);
491}
492
Johan Hedberg38319712013-05-17 12:49:23 +0300493void l2cap_le_flowctl_init(struct l2cap_chan *chan)
494{
495 chan->imtu = L2CAP_DEFAULT_MTU;
496 chan->omtu = L2CAP_LE_MIN_MTU;
497 chan->mode = L2CAP_MODE_LE_FLOWCTL;
Johan Hedberg0cd75f72013-05-17 13:09:05 +0300498 chan->tx_credits = 0;
499 chan->rx_credits = L2CAP_LE_MAX_CREDITS;
Johan Hedberg38319712013-05-17 12:49:23 +0300500}
501
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +0300502void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Marcel Holtmann01394182006-07-03 10:02:46 +0200503{
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300504 BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
Andrei Emeltchenko097db762012-03-09 14:16:17 +0200505 __le16_to_cpu(chan->psm), chan->dcid);
Marcel Holtmann01394182006-07-03 10:02:46 +0200506
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +0200507 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +0100508
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300509 chan->conn = conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200510
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200511 switch (chan->chan_type) {
512 case L2CAP_CHAN_CONN_ORIENTED:
Ville Tervob62f3282011-02-10 22:38:50 -0300513 if (conn->hcon->type == LE_LINK) {
514 /* LE connection */
Andre Guedes6fcb06a2012-05-31 17:01:33 -0300515 chan->omtu = L2CAP_DEFAULT_MTU;
Johan Hedberg9f22398c2013-04-29 19:35:38 +0300516 if (chan->dcid == L2CAP_CID_ATT)
517 chan->scid = L2CAP_CID_ATT;
518 else
519 chan->scid = l2cap_alloc_cid(conn);
Ville Tervob62f3282011-02-10 22:38:50 -0300520 } else {
521 /* Alloc CID for connection-oriented socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300522 chan->scid = l2cap_alloc_cid(conn);
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300523 chan->omtu = L2CAP_DEFAULT_MTU;
Ville Tervob62f3282011-02-10 22:38:50 -0300524 }
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200525 break;
526
527 case L2CAP_CHAN_CONN_LESS:
Marcel Holtmann01394182006-07-03 10:02:46 +0200528 /* Connectionless socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300529 chan->scid = L2CAP_CID_CONN_LESS;
530 chan->dcid = L2CAP_CID_CONN_LESS;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300531 chan->omtu = L2CAP_DEFAULT_MTU;
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200532 break;
533
Andrei Emeltchenko416fa752012-05-29 13:59:16 +0300534 case L2CAP_CHAN_CONN_FIX_A2MP:
535 chan->scid = L2CAP_CID_A2MP;
536 chan->dcid = L2CAP_CID_A2MP;
537 chan->omtu = L2CAP_A2MP_DEFAULT_MTU;
538 chan->imtu = L2CAP_A2MP_DEFAULT_MTU;
539 break;
540
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200541 default:
Marcel Holtmann01394182006-07-03 10:02:46 +0200542 /* Raw socket can send/recv signalling messages only */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300543 chan->scid = L2CAP_CID_SIGNALING;
544 chan->dcid = L2CAP_CID_SIGNALING;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300545 chan->omtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann01394182006-07-03 10:02:46 +0200546 }
547
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300548 chan->local_id = L2CAP_BESTEFFORT_ID;
549 chan->local_stype = L2CAP_SERV_BESTEFFORT;
550 chan->local_msdu = L2CAP_DEFAULT_MAX_SDU_SIZE;
551 chan->local_sdu_itime = L2CAP_DEFAULT_SDU_ITIME;
552 chan->local_acc_lat = L2CAP_DEFAULT_ACC_LAT;
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +0300553 chan->local_flush_to = L2CAP_EFS_DEFAULT_FLUSH_TO;
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300554
Ulisses Furquim371fd832011-12-21 20:02:36 -0200555 l2cap_chan_hold(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300556
Johan Hedberg5ee98912013-04-29 19:35:43 +0300557 hci_conn_hold(conn->hcon);
558
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200559 list_add(&chan->list, &conn->chan_l);
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200560}
561
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300562void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200563{
564 mutex_lock(&conn->chan_lock);
565 __l2cap_chan_add(conn, chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200566 mutex_unlock(&conn->chan_lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200567}
568
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300569void l2cap_chan_del(struct l2cap_chan *chan, int err)
Marcel Holtmann01394182006-07-03 10:02:46 +0200570{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300571 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200572
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300573 __clear_chan_timer(chan);
Marcel Holtmann01394182006-07-03 10:02:46 +0200574
Gustavo F. Padovan49208c92011-04-04 15:59:54 -0300575 BT_DBG("chan %p, conn %p, err %d", chan, conn, err);
Marcel Holtmann01394182006-07-03 10:02:46 +0200576
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900577 if (conn) {
Andrei Emeltchenko56f60982012-10-15 11:58:44 +0300578 struct amp_mgr *mgr = conn->hcon->amp_mgr;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300579 /* Delete from channel list */
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200580 list_del(&chan->list);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -0200581
Ulisses Furquim371fd832011-12-21 20:02:36 -0200582 l2cap_chan_put(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300583
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300584 chan->conn = NULL;
Andrei Emeltchenko3cabbfd2012-05-31 11:01:37 +0300585
586 if (chan->chan_type != L2CAP_CHAN_CONN_FIX_A2MP)
David Herrmann76a68ba2013-04-06 20:28:37 +0200587 hci_conn_drop(conn->hcon);
Andrei Emeltchenko56f60982012-10-15 11:58:44 +0300588
589 if (mgr && mgr->bredr_chan == chan)
590 mgr->bredr_chan = NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200591 }
592
Andrei Emeltchenko419e08c2012-10-31 15:46:34 +0200593 if (chan->hs_hchan) {
594 struct hci_chan *hs_hchan = chan->hs_hchan;
595
596 BT_DBG("chan %p disconnect hs_hchan %p", chan, hs_hchan);
597 amp_disconnect_logical_link(hs_hchan);
598 }
599
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100600 chan->ops->teardown(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200601
Mat Martineau28270112012-05-17 21:14:09 -0700602 if (test_bit(CONF_NOT_COMPLETE, &chan->conf_state))
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300603 return;
Gustavo F. Padovan2ead70b2011-04-01 15:13:36 -0300604
Gustavo Padovanee556f62012-05-18 20:22:38 -0300605 switch(chan->mode) {
606 case L2CAP_MODE_BASIC:
607 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300608
Johan Hedberg38319712013-05-17 12:49:23 +0300609 case L2CAP_MODE_LE_FLOWCTL:
610 break;
611
Gustavo Padovanee556f62012-05-18 20:22:38 -0300612 case L2CAP_MODE_ERTM:
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -0300613 __clear_retrans_timer(chan);
614 __clear_monitor_timer(chan);
615 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300616
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -0300617 skb_queue_purge(&chan->srej_q);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300618
Mat Martineau3c588192012-04-11 10:48:42 -0700619 l2cap_seq_list_free(&chan->srej_list);
620 l2cap_seq_list_free(&chan->retrans_list);
Gustavo Padovanee556f62012-05-18 20:22:38 -0300621
622 /* fall through */
623
624 case L2CAP_MODE_STREAMING:
625 skb_queue_purge(&chan->tx_q);
626 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300627 }
Gustavo Padovanee556f62012-05-18 20:22:38 -0300628
629 return;
Marcel Holtmann01394182006-07-03 10:02:46 +0200630}
631
Johan Hedberg27e2d4c2013-05-14 13:27:21 +0300632static void l2cap_chan_le_connect_reject(struct l2cap_chan *chan)
633{
634 struct l2cap_conn *conn = chan->conn;
635 struct l2cap_le_conn_rsp rsp;
636 u16 result;
637
638 if (test_bit(FLAG_DEFER_SETUP, &chan->flags))
639 result = L2CAP_CR_AUTHORIZATION;
640 else
641 result = L2CAP_CR_BAD_PSM;
642
643 l2cap_state_change(chan, BT_DISCONN);
644
645 rsp.dcid = cpu_to_le16(chan->scid);
646 rsp.mtu = cpu_to_le16(chan->imtu);
647 rsp.mps = __constant_cpu_to_le16(L2CAP_LE_DEFAULT_MPS);
Johan Hedberg0cd75f72013-05-17 13:09:05 +0300648 rsp.credits = cpu_to_le16(chan->rx_credits);
Johan Hedberg27e2d4c2013-05-14 13:27:21 +0300649 rsp.result = cpu_to_le16(result);
650
651 l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CONN_RSP, sizeof(rsp),
652 &rsp);
653}
654
Johan Hedberg791d60f2013-05-14 22:24:44 +0300655static void l2cap_chan_connect_reject(struct l2cap_chan *chan)
656{
657 struct l2cap_conn *conn = chan->conn;
658 struct l2cap_conn_rsp rsp;
659 u16 result;
660
661 if (test_bit(FLAG_DEFER_SETUP, &chan->flags))
662 result = L2CAP_CR_SEC_BLOCK;
663 else
664 result = L2CAP_CR_BAD_PSM;
665
666 l2cap_state_change(chan, BT_DISCONN);
667
668 rsp.scid = cpu_to_le16(chan->dcid);
669 rsp.dcid = cpu_to_le16(chan->scid);
670 rsp.result = cpu_to_le16(result);
671 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
672
673 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
674}
675
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300676void l2cap_chan_close(struct l2cap_chan *chan, int reason)
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300677{
678 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300679
Marcel Holtmann7eafc592013-10-13 08:12:47 -0700680 BT_DBG("chan %p state %s", chan, state_to_string(chan->state));
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300681
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300682 switch (chan->state) {
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300683 case BT_LISTEN:
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100684 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300685 break;
686
687 case BT_CONNECTED:
688 case BT_CONFIG:
Johan Hedbergcea04ce32013-05-14 22:46:01 +0300689 /* ATT uses L2CAP_CHAN_CONN_ORIENTED so we must also
690 * check for chan->psm.
691 */
692 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && chan->psm) {
Gustavo Padovan8d836d72013-10-15 19:24:47 -0300693 __set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +0200694 l2cap_send_disconn_req(chan, reason);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300695 } else
696 l2cap_chan_del(chan, reason);
697 break;
698
699 case BT_CONNECT2:
Johan Hedberg791d60f2013-05-14 22:24:44 +0300700 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED) {
701 if (conn->hcon->type == ACL_LINK)
702 l2cap_chan_connect_reject(chan);
Johan Hedberg27e2d4c2013-05-14 13:27:21 +0300703 else if (conn->hcon->type == LE_LINK)
704 l2cap_chan_le_connect_reject(chan);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300705 }
706
707 l2cap_chan_del(chan, reason);
708 break;
709
710 case BT_CONNECT:
711 case BT_DISCONN:
712 l2cap_chan_del(chan, reason);
713 break;
714
715 default:
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100716 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300717 break;
718 }
719}
720
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300721static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530722{
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700723 switch (chan->chan_type) {
724 case L2CAP_CHAN_RAW:
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300725 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530726 case BT_SECURITY_HIGH:
727 return HCI_AT_DEDICATED_BONDING_MITM;
728 case BT_SECURITY_MEDIUM:
729 return HCI_AT_DEDICATED_BONDING;
730 default:
731 return HCI_AT_NO_BONDING;
732 }
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700733 break;
Marcel Holtmann3124b842013-10-12 07:19:32 -0700734 case L2CAP_CHAN_CONN_LESS:
735 if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_3DSP)) {
736 if (chan->sec_level == BT_SECURITY_LOW)
737 chan->sec_level = BT_SECURITY_SDP;
738 }
739 if (chan->sec_level == BT_SECURITY_HIGH)
740 return HCI_AT_NO_BONDING_MITM;
741 else
742 return HCI_AT_NO_BONDING;
743 break;
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700744 case L2CAP_CHAN_CONN_ORIENTED:
745 if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_SDP)) {
746 if (chan->sec_level == BT_SECURITY_LOW)
747 chan->sec_level = BT_SECURITY_SDP;
Johan Hedberg8556edd32011-01-19 12:06:50 +0530748
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700749 if (chan->sec_level == BT_SECURITY_HIGH)
750 return HCI_AT_NO_BONDING_MITM;
751 else
752 return HCI_AT_NO_BONDING;
753 }
754 /* fall through */
755 default:
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300756 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530757 case BT_SECURITY_HIGH:
758 return HCI_AT_GENERAL_BONDING_MITM;
759 case BT_SECURITY_MEDIUM:
760 return HCI_AT_GENERAL_BONDING;
761 default:
762 return HCI_AT_NO_BONDING;
763 }
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700764 break;
Johan Hedberg8556edd32011-01-19 12:06:50 +0530765 }
766}
767
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200768/* Service level security */
Gustavo F. Padovand45fc422011-11-05 19:54:24 -0200769int l2cap_chan_check_security(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200770{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300771 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100772 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200773
Johan Hedberga17de2f2013-05-14 13:25:37 +0300774 if (conn->hcon->type == LE_LINK)
775 return smp_conn_security(conn->hcon, chan->sec_level);
776
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300777 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100778
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300779 return hci_conn_security(conn->hcon, chan->sec_level, auth_type);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200780}
781
Johannes Bergb5ad8b72011-06-01 08:54:45 +0200782static u8 l2cap_get_ident(struct l2cap_conn *conn)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200783{
784 u8 id;
785
786 /* Get next available identificator.
787 * 1 - 128 are used by kernel.
788 * 129 - 199 are reserved.
789 * 200 - 254 are used by utilities like l2ping, etc.
790 */
791
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200792 spin_lock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200793
794 if (++conn->tx_ident > 128)
795 conn->tx_ident = 1;
796
797 id = conn->tx_ident;
798
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200799 spin_unlock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200800
801 return id;
802}
803
Gustavo Padovan2d792812012-10-06 10:07:01 +0100804static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
805 void *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200806{
807 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200808 u8 flags;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200809
810 BT_DBG("code 0x%2.2x", code);
811
812 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300813 return;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200814
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200815 if (lmp_no_flush_capable(conn->hcon->hdev))
816 flags = ACL_START_NO_FLUSH;
817 else
818 flags = ACL_START;
819
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700820 bt_cb(skb)->force_active = BT_POWER_FORCE_ACTIVE_ON;
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +0200821 skb->priority = HCI_PRIO_MAX;
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700822
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200823 hci_send_acl(conn->hchan, skb, flags);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200824}
825
Mat Martineau02b0fbb2012-10-23 15:24:10 -0700826static bool __chan_is_moving(struct l2cap_chan *chan)
827{
828 return chan->move_state != L2CAP_MOVE_STABLE &&
829 chan->move_state != L2CAP_MOVE_WAIT_PREPARE;
830}
831
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200832static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb)
833{
834 struct hci_conn *hcon = chan->conn->hcon;
835 u16 flags;
836
837 BT_DBG("chan %p, skb %p len %d priority %u", chan, skb, skb->len,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100838 skb->priority);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200839
Mat Martineaud5f8a752012-10-23 15:24:18 -0700840 if (chan->hs_hcon && !__chan_is_moving(chan)) {
841 if (chan->hs_hchan)
842 hci_send_acl(chan->hs_hchan, skb, ACL_COMPLETE);
843 else
844 kfree_skb(skb);
845
846 return;
847 }
848
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200849 if (!test_bit(FLAG_FLUSHABLE, &chan->flags) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100850 lmp_no_flush_capable(hcon->hdev))
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200851 flags = ACL_START_NO_FLUSH;
852 else
853 flags = ACL_START;
854
855 bt_cb(skb)->force_active = test_bit(FLAG_FORCE_ACTIVE, &chan->flags);
856 hci_send_acl(chan->conn->hchan, skb, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700857}
858
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700859static void __unpack_enhanced_control(u16 enh, struct l2cap_ctrl *control)
860{
861 control->reqseq = (enh & L2CAP_CTRL_REQSEQ) >> L2CAP_CTRL_REQSEQ_SHIFT;
862 control->final = (enh & L2CAP_CTRL_FINAL) >> L2CAP_CTRL_FINAL_SHIFT;
863
864 if (enh & L2CAP_CTRL_FRAME_TYPE) {
865 /* S-Frame */
866 control->sframe = 1;
867 control->poll = (enh & L2CAP_CTRL_POLL) >> L2CAP_CTRL_POLL_SHIFT;
868 control->super = (enh & L2CAP_CTRL_SUPERVISE) >> L2CAP_CTRL_SUPER_SHIFT;
869
870 control->sar = 0;
871 control->txseq = 0;
872 } else {
873 /* I-Frame */
874 control->sframe = 0;
875 control->sar = (enh & L2CAP_CTRL_SAR) >> L2CAP_CTRL_SAR_SHIFT;
876 control->txseq = (enh & L2CAP_CTRL_TXSEQ) >> L2CAP_CTRL_TXSEQ_SHIFT;
877
878 control->poll = 0;
879 control->super = 0;
880 }
881}
882
883static void __unpack_extended_control(u32 ext, struct l2cap_ctrl *control)
884{
885 control->reqseq = (ext & L2CAP_EXT_CTRL_REQSEQ) >> L2CAP_EXT_CTRL_REQSEQ_SHIFT;
886 control->final = (ext & L2CAP_EXT_CTRL_FINAL) >> L2CAP_EXT_CTRL_FINAL_SHIFT;
887
888 if (ext & L2CAP_EXT_CTRL_FRAME_TYPE) {
889 /* S-Frame */
890 control->sframe = 1;
891 control->poll = (ext & L2CAP_EXT_CTRL_POLL) >> L2CAP_EXT_CTRL_POLL_SHIFT;
892 control->super = (ext & L2CAP_EXT_CTRL_SUPERVISE) >> L2CAP_EXT_CTRL_SUPER_SHIFT;
893
894 control->sar = 0;
895 control->txseq = 0;
896 } else {
897 /* I-Frame */
898 control->sframe = 0;
899 control->sar = (ext & L2CAP_EXT_CTRL_SAR) >> L2CAP_EXT_CTRL_SAR_SHIFT;
900 control->txseq = (ext & L2CAP_EXT_CTRL_TXSEQ) >> L2CAP_EXT_CTRL_TXSEQ_SHIFT;
901
902 control->poll = 0;
903 control->super = 0;
904 }
905}
906
907static inline void __unpack_control(struct l2cap_chan *chan,
908 struct sk_buff *skb)
909{
910 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
911 __unpack_extended_control(get_unaligned_le32(skb->data),
912 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700913 skb_pull(skb, L2CAP_EXT_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700914 } else {
915 __unpack_enhanced_control(get_unaligned_le16(skb->data),
916 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700917 skb_pull(skb, L2CAP_ENH_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700918 }
919}
920
921static u32 __pack_extended_control(struct l2cap_ctrl *control)
922{
923 u32 packed;
924
925 packed = control->reqseq << L2CAP_EXT_CTRL_REQSEQ_SHIFT;
926 packed |= control->final << L2CAP_EXT_CTRL_FINAL_SHIFT;
927
928 if (control->sframe) {
929 packed |= control->poll << L2CAP_EXT_CTRL_POLL_SHIFT;
930 packed |= control->super << L2CAP_EXT_CTRL_SUPER_SHIFT;
931 packed |= L2CAP_EXT_CTRL_FRAME_TYPE;
932 } else {
933 packed |= control->sar << L2CAP_EXT_CTRL_SAR_SHIFT;
934 packed |= control->txseq << L2CAP_EXT_CTRL_TXSEQ_SHIFT;
935 }
936
937 return packed;
938}
939
940static u16 __pack_enhanced_control(struct l2cap_ctrl *control)
941{
942 u16 packed;
943
944 packed = control->reqseq << L2CAP_CTRL_REQSEQ_SHIFT;
945 packed |= control->final << L2CAP_CTRL_FINAL_SHIFT;
946
947 if (control->sframe) {
948 packed |= control->poll << L2CAP_CTRL_POLL_SHIFT;
949 packed |= control->super << L2CAP_CTRL_SUPER_SHIFT;
950 packed |= L2CAP_CTRL_FRAME_TYPE;
951 } else {
952 packed |= control->sar << L2CAP_CTRL_SAR_SHIFT;
953 packed |= control->txseq << L2CAP_CTRL_TXSEQ_SHIFT;
954 }
955
956 return packed;
957}
958
959static inline void __pack_control(struct l2cap_chan *chan,
960 struct l2cap_ctrl *control,
961 struct sk_buff *skb)
962{
963 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
964 put_unaligned_le32(__pack_extended_control(control),
965 skb->data + L2CAP_HDR_SIZE);
966 } else {
967 put_unaligned_le16(__pack_enhanced_control(control),
968 skb->data + L2CAP_HDR_SIZE);
969 }
970}
971
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300972static inline unsigned int __ertm_hdr_size(struct l2cap_chan *chan)
973{
974 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
975 return L2CAP_EXT_HDR_SIZE;
976 else
977 return L2CAP_ENH_HDR_SIZE;
978}
979
Mat Martineaua67d7f62012-05-17 20:53:35 -0700980static struct sk_buff *l2cap_create_sframe_pdu(struct l2cap_chan *chan,
981 u32 control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300982{
983 struct sk_buff *skb;
984 struct l2cap_hdr *lh;
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300985 int hlen = __ertm_hdr_size(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300986
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300987 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300988 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300989
Mat Martineaua67d7f62012-05-17 20:53:35 -0700990 skb = bt_skb_alloc(hlen, GFP_KERNEL);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300991
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300992 if (!skb)
Mat Martineaua67d7f62012-05-17 20:53:35 -0700993 return ERR_PTR(-ENOMEM);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300994
995 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300996 lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300997 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +0300998
Mat Martineaua67d7f62012-05-17 20:53:35 -0700999 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
1000 put_unaligned_le32(control, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
1001 else
1002 put_unaligned_le16(control, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001003
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001004 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineaua67d7f62012-05-17 20:53:35 -07001005 u16 fcs = crc16(0, (u8 *)skb->data, skb->len);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03001006 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001007 }
1008
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001009 skb->priority = HCI_PRIO_MAX;
Mat Martineaua67d7f62012-05-17 20:53:35 -07001010 return skb;
1011}
1012
1013static void l2cap_send_sframe(struct l2cap_chan *chan,
1014 struct l2cap_ctrl *control)
1015{
1016 struct sk_buff *skb;
1017 u32 control_field;
1018
1019 BT_DBG("chan %p, control %p", chan, control);
1020
1021 if (!control->sframe)
1022 return;
1023
Mat Martineaub99e13a2012-10-23 15:24:19 -07001024 if (__chan_is_moving(chan))
1025 return;
1026
Mat Martineaua67d7f62012-05-17 20:53:35 -07001027 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state) &&
1028 !control->poll)
1029 control->final = 1;
1030
1031 if (control->super == L2CAP_SUPER_RR)
1032 clear_bit(CONN_RNR_SENT, &chan->conn_state);
1033 else if (control->super == L2CAP_SUPER_RNR)
1034 set_bit(CONN_RNR_SENT, &chan->conn_state);
1035
1036 if (control->super != L2CAP_SUPER_SREJ) {
1037 chan->last_acked_seq = control->reqseq;
1038 __clear_ack_timer(chan);
1039 }
1040
1041 BT_DBG("reqseq %d, final %d, poll %d, super %d", control->reqseq,
1042 control->final, control->poll, control->super);
1043
1044 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
1045 control_field = __pack_extended_control(control);
1046 else
1047 control_field = __pack_enhanced_control(control);
1048
1049 skb = l2cap_create_sframe_pdu(chan, control_field);
1050 if (!IS_ERR(skb))
1051 l2cap_do_send(chan, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001052}
1053
Mat Martineauc9e3d5e2012-05-17 20:53:48 -07001054static void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, bool poll)
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001055{
Mat Martineauc9e3d5e2012-05-17 20:53:48 -07001056 struct l2cap_ctrl control;
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001057
Mat Martineauc9e3d5e2012-05-17 20:53:48 -07001058 BT_DBG("chan %p, poll %d", chan, poll);
1059
1060 memset(&control, 0, sizeof(control));
1061 control.sframe = 1;
1062 control.poll = poll;
1063
1064 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
1065 control.super = L2CAP_SUPER_RNR;
1066 else
1067 control.super = L2CAP_SUPER_RR;
1068
1069 control.reqseq = chan->buffer_seq;
1070 l2cap_send_sframe(chan, &control);
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001071}
1072
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03001073static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan)
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03001074{
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001075 return !test_bit(CONF_CONNECT_PEND, &chan->conf_state);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03001076}
1077
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001078static bool __amp_capable(struct l2cap_chan *chan)
1079{
1080 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann1df7b172013-10-05 11:47:49 -07001081 struct hci_dev *hdev;
1082 bool amp_available = false;
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001083
Marcel Holtmann1df7b172013-10-05 11:47:49 -07001084 if (!conn->hs_enabled)
1085 return false;
1086
1087 if (!(conn->fixed_chan_mask & L2CAP_FC_A2MP))
1088 return false;
1089
1090 read_lock(&hci_dev_list_lock);
1091 list_for_each_entry(hdev, &hci_dev_list, list) {
1092 if (hdev->amp_type != AMP_TYPE_BREDR &&
1093 test_bit(HCI_UP, &hdev->flags)) {
1094 amp_available = true;
1095 break;
1096 }
1097 }
1098 read_unlock(&hci_dev_list_lock);
1099
1100 if (chan->chan_policy == BT_CHANNEL_POLICY_AMP_PREFERRED)
1101 return amp_available;
Marcel Holtmann848566b2013-10-01 22:59:22 -07001102
1103 return false;
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001104}
1105
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +02001106static bool l2cap_check_efs(struct l2cap_chan *chan)
1107{
1108 /* Check EFS parameters */
1109 return true;
1110}
1111
Andrei Emeltchenko2766be42012-09-27 17:26:21 +03001112void l2cap_send_conn_req(struct l2cap_chan *chan)
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +02001113{
1114 struct l2cap_conn *conn = chan->conn;
1115 struct l2cap_conn_req req;
1116
1117 req.scid = cpu_to_le16(chan->scid);
1118 req.psm = chan->psm;
1119
1120 chan->ident = l2cap_get_ident(conn);
1121
1122 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
1123
1124 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, sizeof(req), &req);
1125}
1126
Mat Martineau8eb200b2012-10-23 15:24:17 -07001127static void l2cap_send_create_chan_req(struct l2cap_chan *chan, u8 amp_id)
1128{
1129 struct l2cap_create_chan_req req;
1130 req.scid = cpu_to_le16(chan->scid);
1131 req.psm = chan->psm;
1132 req.amp_id = amp_id;
1133
1134 chan->ident = l2cap_get_ident(chan->conn);
1135
1136 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_REQ,
1137 sizeof(req), &req);
1138}
1139
Mat Martineau02b0fbb2012-10-23 15:24:10 -07001140static void l2cap_move_setup(struct l2cap_chan *chan)
1141{
1142 struct sk_buff *skb;
1143
1144 BT_DBG("chan %p", chan);
1145
1146 if (chan->mode != L2CAP_MODE_ERTM)
1147 return;
1148
1149 __clear_retrans_timer(chan);
1150 __clear_monitor_timer(chan);
1151 __clear_ack_timer(chan);
1152
1153 chan->retry_count = 0;
1154 skb_queue_walk(&chan->tx_q, skb) {
1155 if (bt_cb(skb)->control.retries)
1156 bt_cb(skb)->control.retries = 1;
1157 else
1158 break;
1159 }
1160
1161 chan->expected_tx_seq = chan->buffer_seq;
1162
1163 clear_bit(CONN_REJ_ACT, &chan->conn_state);
1164 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
1165 l2cap_seq_list_clear(&chan->retrans_list);
1166 l2cap_seq_list_clear(&chan->srej_list);
1167 skb_queue_purge(&chan->srej_q);
1168
1169 chan->tx_state = L2CAP_TX_STATE_XMIT;
1170 chan->rx_state = L2CAP_RX_STATE_MOVE;
1171
1172 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
1173}
1174
Mat Martineau5f3847a2012-10-23 15:24:12 -07001175static void l2cap_move_done(struct l2cap_chan *chan)
1176{
1177 u8 move_role = chan->move_role;
1178 BT_DBG("chan %p", chan);
1179
1180 chan->move_state = L2CAP_MOVE_STABLE;
1181 chan->move_role = L2CAP_MOVE_ROLE_NONE;
1182
1183 if (chan->mode != L2CAP_MODE_ERTM)
1184 return;
1185
1186 switch (move_role) {
1187 case L2CAP_MOVE_ROLE_INITIATOR:
1188 l2cap_tx(chan, NULL, NULL, L2CAP_EV_EXPLICIT_POLL);
1189 chan->rx_state = L2CAP_RX_STATE_WAIT_F;
1190 break;
1191 case L2CAP_MOVE_ROLE_RESPONDER:
1192 chan->rx_state = L2CAP_RX_STATE_WAIT_P;
1193 break;
1194 }
1195}
1196
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001197static void l2cap_chan_ready(struct l2cap_chan *chan)
1198{
Mat Martineau28270112012-05-17 21:14:09 -07001199 /* This clears all conf flags, including CONF_NOT_COMPLETE */
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001200 chan->conf_state = 0;
1201 __clear_chan_timer(chan);
1202
Andrei Emeltchenko54a59aa2012-05-27 22:27:53 -03001203 chan->state = BT_CONNECTED;
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001204
Andrei Emeltchenkofd83e2c2012-05-30 09:55:32 +03001205 chan->ops->ready(chan);
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001206}
1207
Johan Hedbergf1496de2013-05-13 14:15:56 +03001208static void l2cap_le_connect(struct l2cap_chan *chan)
1209{
1210 struct l2cap_conn *conn = chan->conn;
1211 struct l2cap_le_conn_req req;
1212
1213 req.psm = chan->psm;
1214 req.scid = cpu_to_le16(chan->scid);
1215 req.mtu = cpu_to_le16(chan->imtu);
1216 req.mps = __constant_cpu_to_le16(L2CAP_LE_DEFAULT_MPS);
Johan Hedberg0cd75f72013-05-17 13:09:05 +03001217 req.credits = cpu_to_le16(chan->rx_credits);
Johan Hedbergf1496de2013-05-13 14:15:56 +03001218
1219 chan->ident = l2cap_get_ident(conn);
1220
1221 l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CONN_REQ,
1222 sizeof(req), &req);
1223}
1224
1225static void l2cap_le_start(struct l2cap_chan *chan)
1226{
1227 struct l2cap_conn *conn = chan->conn;
1228
1229 if (!smp_conn_security(conn->hcon, chan->sec_level))
1230 return;
1231
1232 if (!chan->psm) {
1233 l2cap_chan_ready(chan);
1234 return;
1235 }
1236
1237 if (chan->state == BT_CONNECT)
1238 l2cap_le_connect(chan);
1239}
1240
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001241static void l2cap_start_connection(struct l2cap_chan *chan)
1242{
1243 if (__amp_capable(chan)) {
1244 BT_DBG("chan %p AMP capable: discover AMPs", chan);
1245 a2mp_discover_amp(chan);
Johan Hedbergf1496de2013-05-13 14:15:56 +03001246 } else if (chan->conn->hcon->type == LE_LINK) {
1247 l2cap_le_start(chan);
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001248 } else {
1249 l2cap_send_conn_req(chan);
1250 }
1251}
1252
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001253static void l2cap_do_start(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001254{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001255 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001256
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001257 if (conn->hcon->type == LE_LINK) {
Johan Hedberg96ac34f2013-05-13 11:15:07 +03001258 l2cap_le_start(chan);
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001259 return;
1260 }
1261
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001262 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01001263 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
1264 return;
1265
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001266 if (l2cap_chan_check_security(chan) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01001267 __l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001268 l2cap_start_connection(chan);
1269 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001270 } else {
1271 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001272 req.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001273
1274 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
1275 conn->info_ident = l2cap_get_ident(conn);
1276
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08001277 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001278
Gustavo Padovan2d792812012-10-06 10:07:01 +01001279 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
1280 sizeof(req), &req);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001281 }
1282}
1283
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001284static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
1285{
1286 u32 local_feat_mask = l2cap_feat_mask;
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03001287 if (!disable_ertm)
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001288 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
1289
1290 switch (mode) {
1291 case L2CAP_MODE_ERTM:
1292 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
1293 case L2CAP_MODE_STREAMING:
1294 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
1295 default:
1296 return 0x00;
1297 }
1298}
1299
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02001300static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err)
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001301{
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02001302 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001303 struct l2cap_disconn_req req;
1304
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001305 if (!conn)
1306 return;
1307
Andrei Emeltchenkoaad3d0e2012-09-06 15:05:42 +03001308 if (chan->mode == L2CAP_MODE_ERTM && chan->state == BT_CONNECTED) {
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03001309 __clear_retrans_timer(chan);
1310 __clear_monitor_timer(chan);
1311 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001312 }
1313
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001314 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
Gustavo Padovand1177732012-10-06 11:47:38 +01001315 l2cap_state_change(chan, BT_DISCONN);
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001316 return;
1317 }
1318
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001319 req.dcid = cpu_to_le16(chan->dcid);
1320 req.scid = cpu_to_le16(chan->scid);
Gustavo Padovan2d792812012-10-06 10:07:01 +01001321 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_DISCONN_REQ,
1322 sizeof(req), &req);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001323
Gustavo Padovanf8e73012013-10-15 19:24:46 -03001324 l2cap_state_change_and_error(chan, BT_DISCONN, err);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001325}
1326
Linus Torvalds1da177e2005-04-16 15:20:36 -07001327/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001328static void l2cap_conn_start(struct l2cap_conn *conn)
1329{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001330 struct l2cap_chan *chan, *tmp;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001331
1332 BT_DBG("conn %p", conn);
1333
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001334 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001335
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001336 list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001337 l2cap_chan_lock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001338
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001339 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001340 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001341 continue;
1342 }
1343
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001344 if (chan->state == BT_CONNECT) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001345 if (!l2cap_chan_check_security(chan) ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001346 !__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001347 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001348 continue;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02001349 }
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001350
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001351 if (!l2cap_mode_supported(chan->mode, conn->feat_mask)
Gustavo Padovan2d792812012-10-06 10:07:01 +01001352 && test_bit(CONF_STATE2_DEVICE,
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001353 &chan->conf_state)) {
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001354 l2cap_chan_close(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001355 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001356 continue;
1357 }
1358
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001359 l2cap_start_connection(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001360
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001361 } else if (chan->state == BT_CONNECT2) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001362 struct l2cap_conn_rsp rsp;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001363 char buf[128];
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001364 rsp.scid = cpu_to_le16(chan->dcid);
1365 rsp.dcid = cpu_to_le16(chan->scid);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001366
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001367 if (l2cap_chan_check_security(chan)) {
Marcel Holtmannbdc25782013-10-14 02:45:34 -07001368 if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001369 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1370 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08001371 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001372
1373 } else {
Gustavo Padovanacdcabf2013-10-21 14:21:39 -02001374 l2cap_state_change(chan, BT_CONFIG);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001375 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
1376 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001377 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001378 } else {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001379 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1380 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001381 }
1382
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001383 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001384 sizeof(rsp), &rsp);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001385
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001386 if (test_bit(CONF_REQ_SENT, &chan->conf_state) ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001387 rsp.result != L2CAP_CR_SUCCESS) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001388 l2cap_chan_unlock(chan);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001389 continue;
1390 }
1391
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001392 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001393 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001394 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03001395 chan->num_conf_req++;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001396 }
1397
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001398 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001399 }
1400
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001401 mutex_unlock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001402}
1403
Ido Yarivc2287682012-04-20 15:46:07 -03001404/* Find socket with cid and source/destination bdaddr.
Ville Tervob62f3282011-02-10 22:38:50 -03001405 * Returns closest match, locked.
1406 */
Andrei Emeltchenkod9b88702012-03-12 12:13:08 +02001407static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid,
Ido Yarivc2287682012-04-20 15:46:07 -03001408 bdaddr_t *src,
1409 bdaddr_t *dst)
Ville Tervob62f3282011-02-10 22:38:50 -03001410{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001411 struct l2cap_chan *c, *c1 = NULL;
Ville Tervob62f3282011-02-10 22:38:50 -03001412
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001413 read_lock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001414
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001415 list_for_each_entry(c, &chan_list, global_l) {
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001416 if (state && c->state != state)
Ville Tervob62f3282011-02-10 22:38:50 -03001417 continue;
1418
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001419 if (c->scid == cid) {
Ido Yarivc2287682012-04-20 15:46:07 -03001420 int src_match, dst_match;
1421 int src_any, dst_any;
1422
Ville Tervob62f3282011-02-10 22:38:50 -03001423 /* Exact match. */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001424 src_match = !bacmp(&c->src, src);
1425 dst_match = !bacmp(&c->dst, dst);
Ido Yarivc2287682012-04-20 15:46:07 -03001426 if (src_match && dst_match) {
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001427 read_unlock(&chan_list_lock);
1428 return c;
1429 }
Ville Tervob62f3282011-02-10 22:38:50 -03001430
1431 /* Closest match */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001432 src_any = !bacmp(&c->src, BDADDR_ANY);
1433 dst_any = !bacmp(&c->dst, BDADDR_ANY);
Ido Yarivc2287682012-04-20 15:46:07 -03001434 if ((src_match && dst_any) || (src_any && dst_match) ||
1435 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001436 c1 = c;
Ville Tervob62f3282011-02-10 22:38:50 -03001437 }
1438 }
Gustavo F. Padovan280f2942011-04-13 19:01:22 -03001439
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001440 read_unlock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001441
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001442 return c1;
Ville Tervob62f3282011-02-10 22:38:50 -03001443}
1444
1445static void l2cap_le_conn_ready(struct l2cap_conn *conn)
1446{
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001447 struct hci_conn *hcon = conn->hcon;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001448 struct l2cap_chan *chan, *pchan;
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001449 u8 dst_type;
Ville Tervob62f3282011-02-10 22:38:50 -03001450
1451 BT_DBG("");
1452
1453 /* Check if we have socket listening on cid */
Johan Hedberg073d1cf2013-04-29 19:35:35 +03001454 pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_ATT,
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001455 &hcon->src, &hcon->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001456 if (!pchan)
Ville Tervob62f3282011-02-10 22:38:50 -03001457 return;
1458
Johan Hedberg44f3b0f2013-04-29 19:35:45 +03001459 /* Client ATT sockets should override the server one */
1460 if (__l2cap_get_chan_by_dcid(conn, L2CAP_CID_ATT))
1461 return;
1462
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001463 dst_type = bdaddr_type(hcon, hcon->dst_type);
1464
1465 /* If device is blocked, do not create a channel for it */
1466 if (hci_blacklist_lookup(hcon->hdev, &hcon->dst, dst_type))
1467 return;
1468
Gustavo Padovan8ffb9292013-10-21 14:21:41 -02001469 l2cap_chan_lock(pchan);
Gustavo F. Padovan62f3a2c2011-04-14 18:34:34 -03001470
Gustavo Padovan80b98022012-05-27 22:27:51 -03001471 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001472 if (!chan)
Ville Tervob62f3282011-02-10 22:38:50 -03001473 goto clean;
1474
Johan Hedberg9f22398c2013-04-29 19:35:38 +03001475 chan->dcid = L2CAP_CID_ATT;
1476
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001477 bacpy(&chan->src, &hcon->src);
1478 bacpy(&chan->dst, &hcon->dst);
1479 chan->src_type = bdaddr_type(hcon, hcon->src_type);
1480 chan->dst_type = dst_type;
Ville Tervob62f3282011-02-10 22:38:50 -03001481
Johan Hedberg44f3b0f2013-04-29 19:35:45 +03001482 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001483
Ville Tervob62f3282011-02-10 22:38:50 -03001484clean:
Gustavo Padovan8ffb9292013-10-21 14:21:41 -02001485 l2cap_chan_unlock(pchan);
Ville Tervob62f3282011-02-10 22:38:50 -03001486}
1487
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001488static void l2cap_conn_ready(struct l2cap_conn *conn)
1489{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001490 struct l2cap_chan *chan;
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001491 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001492
1493 BT_DBG("conn %p", conn);
1494
Johan Hedbergd8729922013-04-29 19:35:39 +03001495 /* For outgoing pairing which doesn't necessarily have an
1496 * associated socket (e.g. mgmt_pair_device).
1497 */
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001498 if (hcon->out && hcon->type == LE_LINK)
1499 smp_conn_security(hcon, hcon->pending_sec_level);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03001500
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001501 mutex_lock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001502
Johan Hedberg44f3b0f2013-04-29 19:35:45 +03001503 if (hcon->type == LE_LINK)
1504 l2cap_le_conn_ready(conn);
1505
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001506 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001507
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001508 l2cap_chan_lock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001509
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001510 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
1511 l2cap_chan_unlock(chan);
1512 continue;
1513 }
1514
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001515 if (hcon->type == LE_LINK) {
Johan Hedbergf1496de2013-05-13 14:15:56 +03001516 l2cap_le_start(chan);
Vinicius Costa Gomes63128452011-06-17 22:46:26 -03001517 } else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Gustavo Padovan74e75742013-10-15 19:24:51 -03001518 l2cap_chan_ready(chan);
Anderson Brigliab501d6a2011-06-07 18:46:31 -03001519
Gustavo Padovan1c244f72012-12-07 03:29:10 -02001520 } else if (chan->state == BT_CONNECT) {
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001521 l2cap_do_start(chan);
Gustavo Padovan1c244f72012-12-07 03:29:10 -02001522 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001523
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001524 l2cap_chan_unlock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001525 }
1526
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001527 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001528}
1529
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001530/* Notify sockets that we cannot guaranty reliability anymore */
1531static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
1532{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001533 struct l2cap_chan *chan;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001534
1535 BT_DBG("conn %p", conn);
1536
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001537 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001538
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001539 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenkoecf61bd2011-10-11 14:04:32 +03001540 if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags))
Gustavo Padovan1d8b1fd2012-10-06 11:34:52 +01001541 l2cap_chan_set_err(chan, err);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001542 }
1543
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001544 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001545}
1546
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001547static void l2cap_info_timeout(struct work_struct *work)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001548{
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001549 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001550 info_timer.work);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001551
Marcel Holtmann984947d2009-02-06 23:35:19 +01001552 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01001553 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01001554
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001555 l2cap_conn_start(conn);
1556}
1557
David Herrmann2c8e1412013-04-06 20:28:45 +02001558/*
1559 * l2cap_user
1560 * External modules can register l2cap_user objects on l2cap_conn. The ->probe
1561 * callback is called during registration. The ->remove callback is called
1562 * during unregistration.
1563 * An l2cap_user object can either be explicitly unregistered or when the
1564 * underlying l2cap_conn object is deleted. This guarantees that l2cap->hcon,
1565 * l2cap->hchan, .. are valid as long as the remove callback hasn't been called.
1566 * External modules must own a reference to the l2cap_conn object if they intend
1567 * to call l2cap_unregister_user(). The l2cap_conn object might get destroyed at
1568 * any time if they don't.
1569 */
1570
1571int l2cap_register_user(struct l2cap_conn *conn, struct l2cap_user *user)
1572{
1573 struct hci_dev *hdev = conn->hcon->hdev;
1574 int ret;
1575
1576 /* We need to check whether l2cap_conn is registered. If it is not, we
1577 * must not register the l2cap_user. l2cap_conn_del() is unregisters
1578 * l2cap_conn objects, but doesn't provide its own locking. Instead, it
1579 * relies on the parent hci_conn object to be locked. This itself relies
1580 * on the hci_dev object to be locked. So we must lock the hci device
1581 * here, too. */
1582
1583 hci_dev_lock(hdev);
1584
1585 if (user->list.next || user->list.prev) {
1586 ret = -EINVAL;
1587 goto out_unlock;
1588 }
1589
1590 /* conn->hchan is NULL after l2cap_conn_del() was called */
1591 if (!conn->hchan) {
1592 ret = -ENODEV;
1593 goto out_unlock;
1594 }
1595
1596 ret = user->probe(conn, user);
1597 if (ret)
1598 goto out_unlock;
1599
1600 list_add(&user->list, &conn->users);
1601 ret = 0;
1602
1603out_unlock:
1604 hci_dev_unlock(hdev);
1605 return ret;
1606}
1607EXPORT_SYMBOL(l2cap_register_user);
1608
1609void l2cap_unregister_user(struct l2cap_conn *conn, struct l2cap_user *user)
1610{
1611 struct hci_dev *hdev = conn->hcon->hdev;
1612
1613 hci_dev_lock(hdev);
1614
1615 if (!user->list.next || !user->list.prev)
1616 goto out_unlock;
1617
1618 list_del(&user->list);
1619 user->list.next = NULL;
1620 user->list.prev = NULL;
1621 user->remove(conn, user);
1622
1623out_unlock:
1624 hci_dev_unlock(hdev);
1625}
1626EXPORT_SYMBOL(l2cap_unregister_user);
1627
1628static void l2cap_unregister_all_users(struct l2cap_conn *conn)
1629{
1630 struct l2cap_user *user;
1631
1632 while (!list_empty(&conn->users)) {
1633 user = list_first_entry(&conn->users, struct l2cap_user, list);
1634 list_del(&user->list);
1635 user->list.next = NULL;
1636 user->list.prev = NULL;
1637 user->remove(conn, user);
1638 }
1639}
1640
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001641static void l2cap_conn_del(struct hci_conn *hcon, int err)
1642{
1643 struct l2cap_conn *conn = hcon->l2cap_data;
1644 struct l2cap_chan *chan, *l;
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001645
1646 if (!conn)
1647 return;
1648
1649 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
1650
1651 kfree_skb(conn->rx_skb);
1652
David Herrmann2c8e1412013-04-06 20:28:45 +02001653 l2cap_unregister_all_users(conn);
1654
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001655 mutex_lock(&conn->chan_lock);
1656
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001657 /* Kill channels */
1658 list_for_each_entry_safe(chan, l, &conn->chan_l, list) {
Mat Martineau61d6ef32012-04-27 16:50:50 -07001659 l2cap_chan_hold(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001660 l2cap_chan_lock(chan);
1661
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001662 l2cap_chan_del(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001663
1664 l2cap_chan_unlock(chan);
1665
Gustavo Padovan80b98022012-05-27 22:27:51 -03001666 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07001667 l2cap_chan_put(chan);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001668 }
1669
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001670 mutex_unlock(&conn->chan_lock);
1671
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001672 hci_chan_del(conn->hchan);
1673
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001674 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
Ulisses Furquim127074b2012-01-30 18:26:29 -02001675 cancel_delayed_work_sync(&conn->info_timer);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001676
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001677 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) {
Ulisses Furquim127074b2012-01-30 18:26:29 -02001678 cancel_delayed_work_sync(&conn->security_timer);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -03001679 smp_chan_destroy(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001680 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001681
1682 hcon->l2cap_data = NULL;
David Herrmann9c903e32013-04-06 20:28:44 +02001683 conn->hchan = NULL;
1684 l2cap_conn_put(conn);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001685}
1686
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001687static void security_timeout(struct work_struct *work)
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001688{
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001689 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001690 security_timer.work);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001691
Johan Hedbergd06cc412012-06-06 18:44:11 +08001692 BT_DBG("conn %p", conn);
1693
1694 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) {
1695 smp_chan_destroy(conn);
1696 l2cap_conn_del(conn->hcon, ETIMEDOUT);
1697 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001698}
1699
Claudio Takahasibaf43252013-04-11 13:55:50 -03001700static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001701{
Marcel Holtmann01394182006-07-03 10:02:46 +02001702 struct l2cap_conn *conn = hcon->l2cap_data;
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001703 struct hci_chan *hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001704
Claudio Takahasibaf43252013-04-11 13:55:50 -03001705 if (conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001706 return conn;
1707
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001708 hchan = hci_chan_create(hcon);
1709 if (!hchan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001710 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001711
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03001712 conn = kzalloc(sizeof(struct l2cap_conn), GFP_KERNEL);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001713 if (!conn) {
1714 hci_chan_del(hchan);
1715 return NULL;
1716 }
1717
David Herrmann9c903e32013-04-06 20:28:44 +02001718 kref_init(&conn->ref);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001719 hcon->l2cap_data = conn;
1720 conn->hcon = hcon;
David Herrmann9c903e32013-04-06 20:28:44 +02001721 hci_conn_get(conn->hcon);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001722 conn->hchan = hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001723
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001724 BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan);
Marcel Holtmann01394182006-07-03 10:02:46 +02001725
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001726 switch (hcon->type) {
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001727 case LE_LINK:
1728 if (hcon->hdev->le_mtu) {
1729 conn->mtu = hcon->hdev->le_mtu;
1730 break;
1731 }
1732 /* fall through */
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001733 default:
Ville Tervoacd7d372011-02-10 22:38:49 -03001734 conn->mtu = hcon->hdev->acl_mtu;
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001735 break;
1736 }
Ville Tervoacd7d372011-02-10 22:38:49 -03001737
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001738 conn->feat_mask = 0;
1739
Marcel Holtmann848566b2013-10-01 22:59:22 -07001740 if (hcon->type == ACL_LINK)
1741 conn->hs_enabled = test_bit(HCI_HS_ENABLED,
1742 &hcon->hdev->dev_flags);
1743
Linus Torvalds1da177e2005-04-16 15:20:36 -07001744 spin_lock_init(&conn->lock);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001745 mutex_init(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001746
1747 INIT_LIST_HEAD(&conn->chan_l);
David Herrmann2c8e1412013-04-06 20:28:45 +02001748 INIT_LIST_HEAD(&conn->users);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001749
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001750 if (hcon->type == LE_LINK)
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001751 INIT_DELAYED_WORK(&conn->security_timer, security_timeout);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001752 else
Gustavo F. Padovan030013d2011-12-20 10:57:28 -02001753 INIT_DELAYED_WORK(&conn->info_timer, l2cap_info_timeout);
Dave Young45054dc2009-10-18 20:28:30 +00001754
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001755 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01001756
Linus Torvalds1da177e2005-04-16 15:20:36 -07001757 return conn;
1758}
1759
David Herrmann9c903e32013-04-06 20:28:44 +02001760static void l2cap_conn_free(struct kref *ref)
1761{
1762 struct l2cap_conn *conn = container_of(ref, struct l2cap_conn, ref);
1763
1764 hci_conn_put(conn->hcon);
1765 kfree(conn);
1766}
1767
1768void l2cap_conn_get(struct l2cap_conn *conn)
1769{
1770 kref_get(&conn->ref);
1771}
1772EXPORT_SYMBOL(l2cap_conn_get);
1773
1774void l2cap_conn_put(struct l2cap_conn *conn)
1775{
1776 kref_put(&conn->ref, l2cap_conn_free);
1777}
1778EXPORT_SYMBOL(l2cap_conn_put);
1779
Linus Torvalds1da177e2005-04-16 15:20:36 -07001780/* ---- Socket interface ---- */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001781
Ido Yarivc2287682012-04-20 15:46:07 -03001782/* Find socket with psm and source / destination bdaddr.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001783 * Returns closest match.
1784 */
Ido Yarivc2287682012-04-20 15:46:07 -03001785static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
1786 bdaddr_t *src,
Johan Hedbergbf20fd42013-05-14 13:23:13 +03001787 bdaddr_t *dst,
1788 u8 link_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001789{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001790 struct l2cap_chan *c, *c1 = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001791
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001792 read_lock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001793
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001794 list_for_each_entry(c, &chan_list, global_l) {
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001795 if (state && c->state != state)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001796 continue;
1797
Johan Hedbergbf20fd42013-05-14 13:23:13 +03001798 if (link_type == ACL_LINK && c->src_type != BDADDR_BREDR)
1799 continue;
1800
1801 if (link_type == LE_LINK && c->src_type == BDADDR_BREDR)
1802 continue;
1803
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001804 if (c->psm == psm) {
Ido Yarivc2287682012-04-20 15:46:07 -03001805 int src_match, dst_match;
1806 int src_any, dst_any;
1807
Linus Torvalds1da177e2005-04-16 15:20:36 -07001808 /* Exact match. */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001809 src_match = !bacmp(&c->src, src);
1810 dst_match = !bacmp(&c->dst, dst);
Ido Yarivc2287682012-04-20 15:46:07 -03001811 if (src_match && dst_match) {
Johannes Berga7567b22011-06-01 08:29:54 +02001812 read_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001813 return c;
1814 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001815
1816 /* Closest match */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001817 src_any = !bacmp(&c->src, BDADDR_ANY);
1818 dst_any = !bacmp(&c->dst, BDADDR_ANY);
Ido Yarivc2287682012-04-20 15:46:07 -03001819 if ((src_match && dst_any) || (src_any && dst_match) ||
1820 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001821 c1 = c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001822 }
1823 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001824
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001825 read_unlock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001826
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001827 return c1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001828}
1829
Andre Guedes8e9f9892012-04-24 21:02:55 -03001830int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
1831 bdaddr_t *dst, u8 dst_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001832{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001833 struct l2cap_conn *conn;
1834 struct hci_conn *hcon;
1835 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001836 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +02001837 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001838
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001839 BT_DBG("%pMR -> %pMR (type %u) psm 0x%2.2x", &chan->src, dst,
Syam Sidhardhanab195162012-07-27 23:51:22 +05301840 dst_type, __le16_to_cpu(psm));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001841
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001842 hdev = hci_get_route(dst, &chan->src);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001843 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001844 return -EHOSTUNREACH;
1845
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001846 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001847
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001848 l2cap_chan_lock(chan);
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001849
1850 /* PSM must be odd and lsb of upper byte must be 0 */
1851 if ((__le16_to_cpu(psm) & 0x0101) != 0x0001 && !cid &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01001852 chan->chan_type != L2CAP_CHAN_RAW) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001853 err = -EINVAL;
1854 goto done;
1855 }
1856
1857 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && !(psm || cid)) {
1858 err = -EINVAL;
1859 goto done;
1860 }
1861
1862 switch (chan->mode) {
1863 case L2CAP_MODE_BASIC:
Johan Hedberg38319712013-05-17 12:49:23 +03001864 case L2CAP_MODE_LE_FLOWCTL:
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001865 break;
1866 case L2CAP_MODE_ERTM:
1867 case L2CAP_MODE_STREAMING:
1868 if (!disable_ertm)
1869 break;
1870 /* fall through */
1871 default:
1872 err = -ENOTSUPP;
1873 goto done;
1874 }
1875
Gustavo Padovan0797e012012-05-27 22:27:54 -03001876 switch (chan->state) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001877 case BT_CONNECT:
1878 case BT_CONNECT2:
1879 case BT_CONFIG:
1880 /* Already connecting */
1881 err = 0;
1882 goto done;
1883
1884 case BT_CONNECTED:
1885 /* Already connected */
1886 err = -EISCONN;
1887 goto done;
1888
1889 case BT_OPEN:
1890 case BT_BOUND:
1891 /* Can connect */
1892 break;
1893
1894 default:
1895 err = -EBADFD;
1896 goto done;
1897 }
1898
1899 /* Set destination address and psm */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001900 bacpy(&chan->dst, dst);
Marcel Holtmann4f1654e2013-10-13 08:50:41 -07001901 chan->dst_type = dst_type;
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001902
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001903 chan->psm = psm;
1904 chan->dcid = cid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001905
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001906 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001907
Johan Hedbergf224ca52013-04-29 19:35:36 +03001908 if (bdaddr_type_is_le(dst_type))
Andre Guedes8e9f9892012-04-24 21:02:55 -03001909 hcon = hci_connect(hdev, LE_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001910 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001911 else
Andre Guedes8e9f9892012-04-24 21:02:55 -03001912 hcon = hci_connect(hdev, ACL_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001913 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001914
Ville Tervo30e76272011-02-22 16:10:53 -03001915 if (IS_ERR(hcon)) {
1916 err = PTR_ERR(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001917 goto done;
Ville Tervo30e76272011-02-22 16:10:53 -03001918 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001919
Claudio Takahasibaf43252013-04-11 13:55:50 -03001920 conn = l2cap_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001921 if (!conn) {
David Herrmann76a68ba2013-04-06 20:28:37 +02001922 hci_conn_drop(hcon);
Ville Tervo30e76272011-02-22 16:10:53 -03001923 err = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001924 goto done;
1925 }
1926
Johan Hedberg141d5702013-04-29 19:35:37 +03001927 if (cid && __l2cap_get_chan_by_dcid(conn, cid)) {
1928 hci_conn_drop(hcon);
1929 err = -EBUSY;
1930 goto done;
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001931 }
1932
Linus Torvalds1da177e2005-04-16 15:20:36 -07001933 /* Update source addr of the socket */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001934 bacpy(&chan->src, &hcon->src);
Marcel Holtmann4f1654e2013-10-13 08:50:41 -07001935 chan->src_type = bdaddr_type(hcon, hcon->src_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001936
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001937 l2cap_chan_unlock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001938 l2cap_chan_add(conn, chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001939 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001940
Johan Hedberg5ee98912013-04-29 19:35:43 +03001941 /* l2cap_chan_add takes its own ref so we can drop this one */
1942 hci_conn_drop(hcon);
1943
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001944 l2cap_state_change(chan, BT_CONNECT);
Gustavo Padovan8d836d72013-10-15 19:24:47 -03001945 __set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001946
1947 if (hcon->state == BT_CONNECTED) {
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001948 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001949 __clear_chan_timer(chan);
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001950 if (l2cap_chan_check_security(chan))
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001951 l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001952 } else
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001953 l2cap_do_start(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001954 }
1955
Ville Tervo30e76272011-02-22 16:10:53 -03001956 err = 0;
1957
Linus Torvalds1da177e2005-04-16 15:20:36 -07001958done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001959 l2cap_chan_unlock(chan);
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001960 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001961 hci_dev_put(hdev);
1962 return err;
1963}
1964
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001965static void l2cap_monitor_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001966{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001967 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001968 monitor_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001969
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03001970 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001971
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001972 l2cap_chan_lock(chan);
1973
Mat Martineau80909e02012-05-17 20:53:50 -07001974 if (!chan->conn) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001975 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001976 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001977 return;
1978 }
1979
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001980 l2cap_tx(chan, NULL, NULL, L2CAP_EV_MONITOR_TO);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001981
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001982 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001983 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001984}
1985
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001986static void l2cap_retrans_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001987{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001988 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001989 retrans_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001990
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03001991 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001992
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001993 l2cap_chan_lock(chan);
1994
Mat Martineau80909e02012-05-17 20:53:50 -07001995 if (!chan->conn) {
1996 l2cap_chan_unlock(chan);
1997 l2cap_chan_put(chan);
1998 return;
1999 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002000
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002001 l2cap_tx(chan, NULL, NULL, L2CAP_EV_RETRANS_TO);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02002002 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02002003 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002004}
2005
Gustavo Padovand6603662012-05-21 13:58:22 -03002006static void l2cap_streaming_send(struct l2cap_chan *chan,
2007 struct sk_buff_head *skbs)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002008{
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03002009 struct sk_buff *skb;
Mat Martineau37339372012-05-17 20:53:33 -07002010 struct l2cap_ctrl *control;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002011
Mat Martineau37339372012-05-17 20:53:33 -07002012 BT_DBG("chan %p, skbs %p", chan, skbs);
2013
Mat Martineaub99e13a2012-10-23 15:24:19 -07002014 if (__chan_is_moving(chan))
2015 return;
2016
Mat Martineau37339372012-05-17 20:53:33 -07002017 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2018
2019 while (!skb_queue_empty(&chan->tx_q)) {
2020
2021 skb = skb_dequeue(&chan->tx_q);
2022
2023 bt_cb(skb)->control.retries = 1;
2024 control = &bt_cb(skb)->control;
2025
2026 control->reqseq = 0;
2027 control->txseq = chan->next_tx_seq;
2028
2029 __pack_control(chan, control, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002030
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002031 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau37339372012-05-17 20:53:33 -07002032 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
2033 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002034 }
2035
Gustavo F. Padovan43434782011-04-12 18:31:57 -03002036 l2cap_do_send(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002037
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002038 BT_DBG("Sent txseq %u", control->txseq);
Mat Martineau37339372012-05-17 20:53:33 -07002039
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002040 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau37339372012-05-17 20:53:33 -07002041 chan->frames_sent++;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002042 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002043}
2044
Szymon Janc67c9e842011-07-28 16:24:33 +02002045static int l2cap_ertm_send(struct l2cap_chan *chan)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002046{
2047 struct sk_buff *skb, *tx_skb;
Mat Martineau18a48e72012-05-17 20:53:34 -07002048 struct l2cap_ctrl *control;
2049 int sent = 0;
2050
2051 BT_DBG("chan %p", chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002052
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03002053 if (chan->state != BT_CONNECTED)
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03002054 return -ENOTCONN;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002055
Mat Martineau94122bb2012-05-02 09:42:02 -07002056 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2057 return 0;
2058
Mat Martineaub99e13a2012-10-23 15:24:19 -07002059 if (__chan_is_moving(chan))
2060 return 0;
2061
Mat Martineau18a48e72012-05-17 20:53:34 -07002062 while (chan->tx_send_head &&
2063 chan->unacked_frames < chan->remote_tx_win &&
2064 chan->tx_state == L2CAP_TX_STATE_XMIT) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002065
Mat Martineau18a48e72012-05-17 20:53:34 -07002066 skb = chan->tx_send_head;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002067
Mat Martineau18a48e72012-05-17 20:53:34 -07002068 bt_cb(skb)->control.retries = 1;
2069 control = &bt_cb(skb)->control;
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03002070
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03002071 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
Mat Martineau18a48e72012-05-17 20:53:34 -07002072 control->final = 1;
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03002073
Mat Martineau18a48e72012-05-17 20:53:34 -07002074 control->reqseq = chan->buffer_seq;
2075 chan->last_acked_seq = chan->buffer_seq;
2076 control->txseq = chan->next_tx_seq;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002077
Mat Martineau18a48e72012-05-17 20:53:34 -07002078 __pack_control(chan, control, skb);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002079
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002080 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau18a48e72012-05-17 20:53:34 -07002081 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
2082 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002083 }
2084
Mat Martineau18a48e72012-05-17 20:53:34 -07002085 /* Clone after data has been modified. Data is assumed to be
2086 read-only (for locking purposes) on cloned sk_buffs.
2087 */
2088 tx_skb = skb_clone(skb, GFP_KERNEL);
2089
2090 if (!tx_skb)
2091 break;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03002092
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03002093 __set_retrans_timer(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002094
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002095 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau18a48e72012-05-17 20:53:34 -07002096 chan->unacked_frames++;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03002097 chan->frames_sent++;
Mat Martineau18a48e72012-05-17 20:53:34 -07002098 sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002099
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03002100 if (skb_queue_is_last(&chan->tx_q, skb))
2101 chan->tx_send_head = NULL;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002102 else
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03002103 chan->tx_send_head = skb_queue_next(&chan->tx_q, skb);
Mat Martineau18a48e72012-05-17 20:53:34 -07002104
2105 l2cap_do_send(chan, tx_skb);
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002106 BT_DBG("Sent txseq %u", control->txseq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002107 }
2108
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002109 BT_DBG("Sent %d, %u unacked, %u in ERTM queue", sent,
2110 chan->unacked_frames, skb_queue_len(&chan->tx_q));
Mat Martineau18a48e72012-05-17 20:53:34 -07002111
2112 return sent;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03002113}
2114
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002115static void l2cap_ertm_resend(struct l2cap_chan *chan)
2116{
2117 struct l2cap_ctrl control;
2118 struct sk_buff *skb;
2119 struct sk_buff *tx_skb;
2120 u16 seq;
2121
2122 BT_DBG("chan %p", chan);
2123
2124 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2125 return;
2126
Mat Martineaub99e13a2012-10-23 15:24:19 -07002127 if (__chan_is_moving(chan))
2128 return;
2129
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002130 while (chan->retrans_list.head != L2CAP_SEQ_LIST_CLEAR) {
2131 seq = l2cap_seq_list_pop(&chan->retrans_list);
2132
2133 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, seq);
2134 if (!skb) {
2135 BT_DBG("Error: Can't retransmit seq %d, frame missing",
Gustavo Padovan2d792812012-10-06 10:07:01 +01002136 seq);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002137 continue;
2138 }
2139
2140 bt_cb(skb)->control.retries++;
2141 control = bt_cb(skb)->control;
2142
2143 if (chan->max_tx != 0 &&
2144 bt_cb(skb)->control.retries > chan->max_tx) {
2145 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02002146 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002147 l2cap_seq_list_clear(&chan->retrans_list);
2148 break;
2149 }
2150
2151 control.reqseq = chan->buffer_seq;
2152 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
2153 control.final = 1;
2154 else
2155 control.final = 0;
2156
2157 if (skb_cloned(skb)) {
2158 /* Cloned sk_buffs are read-only, so we need a
2159 * writeable copy
2160 */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002161 tx_skb = skb_copy(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002162 } else {
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002163 tx_skb = skb_clone(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002164 }
2165
2166 if (!tx_skb) {
2167 l2cap_seq_list_clear(&chan->retrans_list);
2168 break;
2169 }
2170
2171 /* Update skb contents */
2172 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
2173 put_unaligned_le32(__pack_extended_control(&control),
2174 tx_skb->data + L2CAP_HDR_SIZE);
2175 } else {
2176 put_unaligned_le16(__pack_enhanced_control(&control),
2177 tx_skb->data + L2CAP_HDR_SIZE);
2178 }
2179
2180 if (chan->fcs == L2CAP_FCS_CRC16) {
2181 u16 fcs = crc16(0, (u8 *) tx_skb->data, tx_skb->len);
2182 put_unaligned_le16(fcs, skb_put(tx_skb,
2183 L2CAP_FCS_SIZE));
2184 }
2185
2186 l2cap_do_send(chan, tx_skb);
2187
2188 BT_DBG("Resent txseq %d", control.txseq);
2189
2190 chan->last_acked_seq = chan->buffer_seq;
2191 }
2192}
2193
Mat Martineauf80842a2012-05-17 20:53:46 -07002194static void l2cap_retransmit(struct l2cap_chan *chan,
2195 struct l2cap_ctrl *control)
2196{
2197 BT_DBG("chan %p, control %p", chan, control);
2198
2199 l2cap_seq_list_append(&chan->retrans_list, control->reqseq);
2200 l2cap_ertm_resend(chan);
2201}
2202
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002203static void l2cap_retransmit_all(struct l2cap_chan *chan,
2204 struct l2cap_ctrl *control)
2205{
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002206 struct sk_buff *skb;
2207
2208 BT_DBG("chan %p, control %p", chan, control);
2209
2210 if (control->poll)
2211 set_bit(CONN_SEND_FBIT, &chan->conn_state);
2212
2213 l2cap_seq_list_clear(&chan->retrans_list);
2214
2215 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2216 return;
2217
2218 if (chan->unacked_frames) {
2219 skb_queue_walk(&chan->tx_q, skb) {
2220 if (bt_cb(skb)->control.txseq == control->reqseq ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01002221 skb == chan->tx_send_head)
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002222 break;
2223 }
2224
2225 skb_queue_walk_from(&chan->tx_q, skb) {
2226 if (skb == chan->tx_send_head)
2227 break;
2228
2229 l2cap_seq_list_append(&chan->retrans_list,
2230 bt_cb(skb)->control.txseq);
2231 }
2232
2233 l2cap_ertm_resend(chan);
2234 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002235}
2236
Szymon Jancb17e73b2012-01-11 10:59:47 +01002237static void l2cap_send_ack(struct l2cap_chan *chan)
2238{
Mat Martineau0a0aba42012-05-17 20:53:39 -07002239 struct l2cap_ctrl control;
2240 u16 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
2241 chan->last_acked_seq);
2242 int threshold;
2243
2244 BT_DBG("chan %p last_acked_seq %d buffer_seq %d",
2245 chan, chan->last_acked_seq, chan->buffer_seq);
2246
2247 memset(&control, 0, sizeof(control));
2248 control.sframe = 1;
2249
2250 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
2251 chan->rx_state == L2CAP_RX_STATE_RECV) {
2252 __clear_ack_timer(chan);
2253 control.super = L2CAP_SUPER_RNR;
2254 control.reqseq = chan->buffer_seq;
2255 l2cap_send_sframe(chan, &control);
2256 } else {
2257 if (!test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) {
2258 l2cap_ertm_send(chan);
2259 /* If any i-frames were sent, they included an ack */
2260 if (chan->buffer_seq == chan->last_acked_seq)
2261 frames_to_ack = 0;
2262 }
2263
Mat Martineauc20f8e32012-07-10 05:47:07 -07002264 /* Ack now if the window is 3/4ths full.
Mat Martineau0a0aba42012-05-17 20:53:39 -07002265 * Calculate without mul or div
2266 */
Mat Martineauc20f8e32012-07-10 05:47:07 -07002267 threshold = chan->ack_win;
Mat Martineau0a0aba42012-05-17 20:53:39 -07002268 threshold += threshold << 1;
2269 threshold >>= 2;
2270
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002271 BT_DBG("frames_to_ack %u, threshold %d", frames_to_ack,
Mat Martineau0a0aba42012-05-17 20:53:39 -07002272 threshold);
2273
2274 if (frames_to_ack >= threshold) {
2275 __clear_ack_timer(chan);
2276 control.super = L2CAP_SUPER_RR;
2277 control.reqseq = chan->buffer_seq;
2278 l2cap_send_sframe(chan, &control);
2279 frames_to_ack = 0;
2280 }
2281
2282 if (frames_to_ack)
2283 __set_ack_timer(chan);
2284 }
Szymon Jancb17e73b2012-01-11 10:59:47 +01002285}
2286
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002287static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
2288 struct msghdr *msg, int len,
2289 int count, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002290{
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002291 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002292 struct sk_buff **frag;
Gustavo Padovan90338942012-04-06 20:15:47 -03002293 int sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002294
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03002295 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002296 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002297
2298 sent += count;
2299 len -= count;
2300
2301 /* Continuation fragments (no L2CAP header) */
2302 frag = &skb_shinfo(skb)->frag_list;
2303 while (len) {
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002304 struct sk_buff *tmp;
2305
Linus Torvalds1da177e2005-04-16 15:20:36 -07002306 count = min_t(unsigned int, conn->mtu, len);
2307
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002308 tmp = chan->ops->alloc_skb(chan, count,
2309 msg->msg_flags & MSG_DONTWAIT);
2310 if (IS_ERR(tmp))
2311 return PTR_ERR(tmp);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002312
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002313 *frag = tmp;
2314
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002315 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
2316 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002317
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002318 (*frag)->priority = skb->priority;
2319
Linus Torvalds1da177e2005-04-16 15:20:36 -07002320 sent += count;
2321 len -= count;
2322
Gustavo Padovan2d0ed3d2012-05-11 13:16:12 -03002323 skb->len += (*frag)->len;
2324 skb->data_len += (*frag)->len;
2325
Linus Torvalds1da177e2005-04-16 15:20:36 -07002326 frag = &(*frag)->next;
2327 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002328
2329 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002330}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002331
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002332static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002333 struct msghdr *msg, size_t len,
2334 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002335{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002336 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002337 struct sk_buff *skb;
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002338 int err, count, hlen = L2CAP_HDR_SIZE + L2CAP_PSMLEN_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002339 struct l2cap_hdr *lh;
2340
Marcel Holtmann43b1b8d2013-10-12 06:01:26 -07002341 BT_DBG("chan %p psm 0x%2.2x len %zu priority %u", chan,
2342 __le16_to_cpu(chan->psm), len, priority);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002343
2344 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002345
2346 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002347 msg->msg_flags & MSG_DONTWAIT);
2348 if (IS_ERR(skb))
2349 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002350
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002351 skb->priority = priority;
2352
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002353 /* Create L2CAP header */
2354 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002355 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenkodaf6a78c2012-05-03 10:55:52 +03002356 lh->len = cpu_to_le16(len + L2CAP_PSMLEN_SIZE);
Marcel Holtmann43b1b8d2013-10-12 06:01:26 -07002357 put_unaligned(chan->psm, (__le16 *) skb_put(skb, L2CAP_PSMLEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002358
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002359 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002360 if (unlikely(err < 0)) {
2361 kfree_skb(skb);
2362 return ERR_PTR(err);
2363 }
2364 return skb;
2365}
2366
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002367static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002368 struct msghdr *msg, size_t len,
2369 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002370{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002371 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002372 struct sk_buff *skb;
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002373 int err, count;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002374 struct l2cap_hdr *lh;
2375
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002376 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002377
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002378 count = min_t(unsigned int, (conn->mtu - L2CAP_HDR_SIZE), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002379
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002380 skb = chan->ops->alloc_skb(chan, count + L2CAP_HDR_SIZE,
Gustavo Padovan90338942012-04-06 20:15:47 -03002381 msg->msg_flags & MSG_DONTWAIT);
2382 if (IS_ERR(skb))
2383 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002384
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002385 skb->priority = priority;
2386
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002387 /* 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 Padovan6ff9b5e2012-05-02 11:56:17 -03002390 lh->len = cpu_to_le16(len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002391
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002392 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002393 if (unlikely(err < 0)) {
2394 kfree_skb(skb);
2395 return ERR_PTR(err);
2396 }
2397 return skb;
2398}
2399
Luiz Augusto von Dentzab0ff762011-09-12 20:00:50 +03002400static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002401 struct msghdr *msg, size_t len,
2402 u16 sdulen)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002403{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002404 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002405 struct sk_buff *skb;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002406 int err, count, hlen;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002407 struct l2cap_hdr *lh;
2408
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002409 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002410
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03002411 if (!conn)
2412 return ERR_PTR(-ENOTCONN);
2413
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002414 hlen = __ertm_hdr_size(chan);
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002415
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002416 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002417 hlen += L2CAP_SDULEN_SIZE;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002418
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002419 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002420 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002421
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002422 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002423
2424 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002425 msg->msg_flags & MSG_DONTWAIT);
2426 if (IS_ERR(skb))
2427 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002428
2429 /* Create L2CAP header */
2430 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002431 lh->cid = cpu_to_le16(chan->dcid);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002432 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002433
Mat Martineau18a48e72012-05-17 20:53:34 -07002434 /* Control header is populated later */
2435 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
2436 put_unaligned_le32(0, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
2437 else
2438 put_unaligned_le16(0, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002439
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002440 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002441 put_unaligned_le16(sdulen, skb_put(skb, L2CAP_SDULEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002442
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002443 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002444 if (unlikely(err < 0)) {
2445 kfree_skb(skb);
2446 return ERR_PTR(err);
2447 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002448
Mat Martineau18a48e72012-05-17 20:53:34 -07002449 bt_cb(skb)->control.fcs = chan->fcs;
Mat Martineau3ce35142012-04-25 16:36:14 -07002450 bt_cb(skb)->control.retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002451 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002452}
2453
Mat Martineau94122bb2012-05-02 09:42:02 -07002454static int l2cap_segment_sdu(struct l2cap_chan *chan,
2455 struct sk_buff_head *seg_queue,
2456 struct msghdr *msg, size_t len)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002457{
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002458 struct sk_buff *skb;
Mat Martineau94122bb2012-05-02 09:42:02 -07002459 u16 sdu_len;
2460 size_t pdu_len;
Mat Martineau94122bb2012-05-02 09:42:02 -07002461 u8 sar;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002462
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002463 BT_DBG("chan %p, msg %p, len %zu", chan, msg, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002464
Mat Martineau94122bb2012-05-02 09:42:02 -07002465 /* It is critical that ERTM PDUs fit in a single HCI fragment,
2466 * so fragmented skbs are not used. The HCI layer's handling
2467 * of fragmented skbs is not compatible with ERTM's queueing.
2468 */
2469
2470 /* PDU size is derived from the HCI MTU */
2471 pdu_len = chan->conn->mtu;
2472
Mat Martineaua5495742012-10-23 15:24:21 -07002473 /* Constrain PDU size for BR/EDR connections */
2474 if (!chan->hs_hcon)
2475 pdu_len = min_t(size_t, pdu_len, L2CAP_BREDR_MAX_PAYLOAD);
Mat Martineau94122bb2012-05-02 09:42:02 -07002476
2477 /* Adjust for largest possible L2CAP overhead. */
Gustavo Padovan35d401d2012-05-25 18:57:05 -03002478 if (chan->fcs)
2479 pdu_len -= L2CAP_FCS_SIZE;
2480
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002481 pdu_len -= __ertm_hdr_size(chan);
Mat Martineau94122bb2012-05-02 09:42:02 -07002482
2483 /* Remote device may have requested smaller PDUs */
2484 pdu_len = min_t(size_t, pdu_len, chan->remote_mps);
2485
2486 if (len <= pdu_len) {
2487 sar = L2CAP_SAR_UNSEGMENTED;
2488 sdu_len = 0;
2489 pdu_len = len;
2490 } else {
2491 sar = L2CAP_SAR_START;
2492 sdu_len = len;
2493 pdu_len -= L2CAP_SDULEN_SIZE;
2494 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002495
2496 while (len > 0) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002497 skb = l2cap_create_iframe_pdu(chan, msg, pdu_len, sdu_len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002498
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002499 if (IS_ERR(skb)) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002500 __skb_queue_purge(seg_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002501 return PTR_ERR(skb);
2502 }
2503
Mat Martineau94122bb2012-05-02 09:42:02 -07002504 bt_cb(skb)->control.sar = sar;
2505 __skb_queue_tail(seg_queue, skb);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002506
Mat Martineau94122bb2012-05-02 09:42:02 -07002507 len -= pdu_len;
2508 if (sdu_len) {
2509 sdu_len = 0;
2510 pdu_len += L2CAP_SDULEN_SIZE;
2511 }
2512
2513 if (len <= pdu_len) {
2514 sar = L2CAP_SAR_END;
2515 pdu_len = len;
2516 } else {
2517 sar = L2CAP_SAR_CONTINUE;
2518 }
2519 }
2520
Gustavo Padovanf0f62792012-05-29 13:29:17 -03002521 return 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002522}
2523
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002524int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01002525 u32 priority)
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002526{
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002527 struct sk_buff *skb;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002528 int err;
Mat Martineau94122bb2012-05-02 09:42:02 -07002529 struct sk_buff_head seg_queue;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002530
Seung-Woo Kim31e8ce82013-11-05 18:46:33 +09002531 if (!chan->conn)
2532 return -ENOTCONN;
2533
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002534 /* Connectionless channel */
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002535 if (chan->chan_type == L2CAP_CHAN_CONN_LESS) {
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002536 skb = l2cap_create_connless_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002537 if (IS_ERR(skb))
2538 return PTR_ERR(skb);
2539
2540 l2cap_do_send(chan, skb);
2541 return len;
2542 }
2543
2544 switch (chan->mode) {
Johan Hedberg38319712013-05-17 12:49:23 +03002545 case L2CAP_MODE_LE_FLOWCTL:
Johan Hedbergfad5fc82013-12-05 09:45:01 +02002546 if (!chan->tx_credits)
2547 return -EAGAIN;
2548
2549 /* fall through */
2550 case L2CAP_MODE_BASIC:
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002551 /* Check outgoing MTU */
2552 if (len > chan->omtu)
2553 return -EMSGSIZE;
2554
2555 /* Create a basic PDU */
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002556 skb = l2cap_create_basic_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002557 if (IS_ERR(skb))
2558 return PTR_ERR(skb);
2559
2560 l2cap_do_send(chan, skb);
2561 err = len;
2562 break;
2563
2564 case L2CAP_MODE_ERTM:
2565 case L2CAP_MODE_STREAMING:
Mat Martineau94122bb2012-05-02 09:42:02 -07002566 /* Check outgoing MTU */
2567 if (len > chan->omtu) {
2568 err = -EMSGSIZE;
2569 break;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002570 }
2571
Mat Martineau94122bb2012-05-02 09:42:02 -07002572 __skb_queue_head_init(&seg_queue);
2573
2574 /* Do segmentation before calling in to the state machine,
2575 * since it's possible to block while waiting for memory
2576 * allocation.
2577 */
2578 err = l2cap_segment_sdu(chan, &seg_queue, msg, len);
2579
2580 /* The channel could have been closed while segmenting,
2581 * check that it is still connected.
2582 */
2583 if (chan->state != BT_CONNECTED) {
2584 __skb_queue_purge(&seg_queue);
2585 err = -ENOTCONN;
2586 }
2587
2588 if (err)
2589 break;
2590
Mat Martineau37339372012-05-17 20:53:33 -07002591 if (chan->mode == L2CAP_MODE_ERTM)
Gustavo Padovand6603662012-05-21 13:58:22 -03002592 l2cap_tx(chan, NULL, &seg_queue, L2CAP_EV_DATA_REQUEST);
Mat Martineau37339372012-05-17 20:53:33 -07002593 else
Gustavo Padovand6603662012-05-21 13:58:22 -03002594 l2cap_streaming_send(chan, &seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002595
Gustavo Padovand6603662012-05-21 13:58:22 -03002596 err = len;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002597
Mat Martineau94122bb2012-05-02 09:42:02 -07002598 /* If the skbs were not queued for sending, they'll still be in
2599 * seg_queue and need to be purged.
2600 */
2601 __skb_queue_purge(&seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002602 break;
2603
2604 default:
2605 BT_DBG("bad state %1.1x", chan->mode);
2606 err = -EBADFD;
2607 }
2608
2609 return err;
2610}
2611
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002612static void l2cap_send_srej(struct l2cap_chan *chan, u16 txseq)
2613{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002614 struct l2cap_ctrl control;
2615 u16 seq;
2616
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002617 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002618
2619 memset(&control, 0, sizeof(control));
2620 control.sframe = 1;
2621 control.super = L2CAP_SUPER_SREJ;
2622
2623 for (seq = chan->expected_tx_seq; seq != txseq;
2624 seq = __next_seq(chan, seq)) {
2625 if (!l2cap_ertm_seq_in_queue(&chan->srej_q, seq)) {
2626 control.reqseq = seq;
2627 l2cap_send_sframe(chan, &control);
2628 l2cap_seq_list_append(&chan->srej_list, seq);
2629 }
2630 }
2631
2632 chan->expected_tx_seq = __next_seq(chan, txseq);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002633}
2634
2635static void l2cap_send_srej_tail(struct l2cap_chan *chan)
2636{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002637 struct l2cap_ctrl control;
2638
2639 BT_DBG("chan %p", chan);
2640
2641 if (chan->srej_list.tail == L2CAP_SEQ_LIST_CLEAR)
2642 return;
2643
2644 memset(&control, 0, sizeof(control));
2645 control.sframe = 1;
2646 control.super = L2CAP_SUPER_SREJ;
2647 control.reqseq = chan->srej_list.tail;
2648 l2cap_send_sframe(chan, &control);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002649}
2650
2651static void l2cap_send_srej_list(struct l2cap_chan *chan, u16 txseq)
2652{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002653 struct l2cap_ctrl control;
2654 u16 initial_head;
2655 u16 seq;
2656
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002657 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002658
2659 memset(&control, 0, sizeof(control));
2660 control.sframe = 1;
2661 control.super = L2CAP_SUPER_SREJ;
2662
2663 /* Capture initial list head to allow only one pass through the list. */
2664 initial_head = chan->srej_list.head;
2665
2666 do {
2667 seq = l2cap_seq_list_pop(&chan->srej_list);
2668 if (seq == txseq || seq == L2CAP_SEQ_LIST_CLEAR)
2669 break;
2670
2671 control.reqseq = seq;
2672 l2cap_send_sframe(chan, &control);
2673 l2cap_seq_list_append(&chan->srej_list, seq);
2674 } while (chan->srej_list.head != initial_head);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002675}
2676
Mat Martineau608bcc62012-05-17 20:53:32 -07002677static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq)
2678{
2679 struct sk_buff *acked_skb;
2680 u16 ackseq;
2681
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002682 BT_DBG("chan %p, reqseq %u", chan, reqseq);
Mat Martineau608bcc62012-05-17 20:53:32 -07002683
2684 if (chan->unacked_frames == 0 || reqseq == chan->expected_ack_seq)
2685 return;
2686
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002687 BT_DBG("expected_ack_seq %u, unacked_frames %u",
Mat Martineau608bcc62012-05-17 20:53:32 -07002688 chan->expected_ack_seq, chan->unacked_frames);
2689
2690 for (ackseq = chan->expected_ack_seq; ackseq != reqseq;
2691 ackseq = __next_seq(chan, ackseq)) {
2692
2693 acked_skb = l2cap_ertm_seq_in_queue(&chan->tx_q, ackseq);
2694 if (acked_skb) {
2695 skb_unlink(acked_skb, &chan->tx_q);
2696 kfree_skb(acked_skb);
2697 chan->unacked_frames--;
2698 }
2699 }
2700
2701 chan->expected_ack_seq = reqseq;
2702
2703 if (chan->unacked_frames == 0)
2704 __clear_retrans_timer(chan);
2705
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002706 BT_DBG("unacked_frames %u", chan->unacked_frames);
Mat Martineau608bcc62012-05-17 20:53:32 -07002707}
2708
2709static void l2cap_abort_rx_srej_sent(struct l2cap_chan *chan)
2710{
2711 BT_DBG("chan %p", chan);
2712
2713 chan->expected_tx_seq = chan->buffer_seq;
2714 l2cap_seq_list_clear(&chan->srej_list);
2715 skb_queue_purge(&chan->srej_q);
2716 chan->rx_state = L2CAP_RX_STATE_RECV;
2717}
2718
Gustavo Padovand6603662012-05-21 13:58:22 -03002719static void l2cap_tx_state_xmit(struct l2cap_chan *chan,
2720 struct l2cap_ctrl *control,
2721 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002722{
Mat Martineau608bcc62012-05-17 20:53:32 -07002723 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2724 event);
2725
2726 switch (event) {
2727 case L2CAP_EV_DATA_REQUEST:
2728 if (chan->tx_send_head == NULL)
2729 chan->tx_send_head = skb_peek(skbs);
2730
2731 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2732 l2cap_ertm_send(chan);
2733 break;
2734 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2735 BT_DBG("Enter LOCAL_BUSY");
2736 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2737
2738 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2739 /* The SREJ_SENT state must be aborted if we are to
2740 * enter the LOCAL_BUSY state.
2741 */
2742 l2cap_abort_rx_srej_sent(chan);
2743 }
2744
2745 l2cap_send_ack(chan);
2746
2747 break;
2748 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2749 BT_DBG("Exit LOCAL_BUSY");
2750 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2751
2752 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2753 struct l2cap_ctrl local_control;
2754
2755 memset(&local_control, 0, sizeof(local_control));
2756 local_control.sframe = 1;
2757 local_control.super = L2CAP_SUPER_RR;
2758 local_control.poll = 1;
2759 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002760 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002761
2762 chan->retry_count = 1;
2763 __set_monitor_timer(chan);
2764 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2765 }
2766 break;
2767 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2768 l2cap_process_reqseq(chan, control->reqseq);
2769 break;
2770 case L2CAP_EV_EXPLICIT_POLL:
2771 l2cap_send_rr_or_rnr(chan, 1);
2772 chan->retry_count = 1;
2773 __set_monitor_timer(chan);
2774 __clear_ack_timer(chan);
2775 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2776 break;
2777 case L2CAP_EV_RETRANS_TO:
2778 l2cap_send_rr_or_rnr(chan, 1);
2779 chan->retry_count = 1;
2780 __set_monitor_timer(chan);
2781 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2782 break;
2783 case L2CAP_EV_RECV_FBIT:
2784 /* Nothing to process */
2785 break;
2786 default:
2787 break;
2788 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002789}
2790
Gustavo Padovand6603662012-05-21 13:58:22 -03002791static void l2cap_tx_state_wait_f(struct l2cap_chan *chan,
2792 struct l2cap_ctrl *control,
2793 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002794{
Mat Martineau608bcc62012-05-17 20:53:32 -07002795 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2796 event);
2797
2798 switch (event) {
2799 case L2CAP_EV_DATA_REQUEST:
2800 if (chan->tx_send_head == NULL)
2801 chan->tx_send_head = skb_peek(skbs);
2802 /* Queue data, but don't send. */
2803 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2804 break;
2805 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2806 BT_DBG("Enter LOCAL_BUSY");
2807 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2808
2809 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2810 /* The SREJ_SENT state must be aborted if we are to
2811 * enter the LOCAL_BUSY state.
2812 */
2813 l2cap_abort_rx_srej_sent(chan);
2814 }
2815
2816 l2cap_send_ack(chan);
2817
2818 break;
2819 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2820 BT_DBG("Exit LOCAL_BUSY");
2821 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2822
2823 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2824 struct l2cap_ctrl local_control;
2825 memset(&local_control, 0, sizeof(local_control));
2826 local_control.sframe = 1;
2827 local_control.super = L2CAP_SUPER_RR;
2828 local_control.poll = 1;
2829 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002830 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002831
2832 chan->retry_count = 1;
2833 __set_monitor_timer(chan);
2834 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2835 }
2836 break;
2837 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2838 l2cap_process_reqseq(chan, control->reqseq);
2839
2840 /* Fall through */
2841
2842 case L2CAP_EV_RECV_FBIT:
2843 if (control && control->final) {
2844 __clear_monitor_timer(chan);
2845 if (chan->unacked_frames > 0)
2846 __set_retrans_timer(chan);
2847 chan->retry_count = 0;
2848 chan->tx_state = L2CAP_TX_STATE_XMIT;
2849 BT_DBG("recv fbit tx_state 0x2.2%x", chan->tx_state);
2850 }
2851 break;
2852 case L2CAP_EV_EXPLICIT_POLL:
2853 /* Ignore */
2854 break;
2855 case L2CAP_EV_MONITOR_TO:
2856 if (chan->max_tx == 0 || chan->retry_count < chan->max_tx) {
2857 l2cap_send_rr_or_rnr(chan, 1);
2858 __set_monitor_timer(chan);
2859 chan->retry_count++;
2860 } else {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02002861 l2cap_send_disconn_req(chan, ECONNABORTED);
Mat Martineau608bcc62012-05-17 20:53:32 -07002862 }
2863 break;
2864 default:
2865 break;
2866 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002867}
2868
Gustavo Padovand6603662012-05-21 13:58:22 -03002869static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
2870 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002871{
Mat Martineau608bcc62012-05-17 20:53:32 -07002872 BT_DBG("chan %p, control %p, skbs %p, event %d, state %d",
2873 chan, control, skbs, event, chan->tx_state);
2874
2875 switch (chan->tx_state) {
2876 case L2CAP_TX_STATE_XMIT:
Gustavo Padovand6603662012-05-21 13:58:22 -03002877 l2cap_tx_state_xmit(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002878 break;
2879 case L2CAP_TX_STATE_WAIT_F:
Gustavo Padovand6603662012-05-21 13:58:22 -03002880 l2cap_tx_state_wait_f(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002881 break;
2882 default:
2883 /* Ignore event */
2884 break;
2885 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002886}
2887
Mat Martineau4b51dae92012-05-17 20:53:37 -07002888static void l2cap_pass_to_tx(struct l2cap_chan *chan,
2889 struct l2cap_ctrl *control)
2890{
2891 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002892 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_REQSEQ_AND_FBIT);
Mat Martineau4b51dae92012-05-17 20:53:37 -07002893}
2894
Mat Martineauf80842a2012-05-17 20:53:46 -07002895static void l2cap_pass_to_tx_fbit(struct l2cap_chan *chan,
2896 struct l2cap_ctrl *control)
2897{
2898 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002899 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_FBIT);
Mat Martineauf80842a2012-05-17 20:53:46 -07002900}
2901
Linus Torvalds1da177e2005-04-16 15:20:36 -07002902/* Copy frame to all raw sockets on that connection */
2903static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2904{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002905 struct sk_buff *nskb;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002906 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002907
2908 BT_DBG("conn %p", conn);
2909
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002910 mutex_lock(&conn->chan_lock);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002911
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002912 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002913 if (chan->chan_type != L2CAP_CHAN_RAW)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002914 continue;
2915
Gustavo Padovan7f5396a2013-10-21 18:22:25 -02002916 /* Don't send frame to the channel it came from */
2917 if (bt_cb(skb)->chan == chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002918 continue;
Gustavo Padovan7f5396a2013-10-21 18:22:25 -02002919
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002920 nskb = skb_clone(skb, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002921 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002922 continue;
Gustavo Padovan80b98022012-05-27 22:27:51 -03002923 if (chan->ops->recv(chan, nskb))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002924 kfree_skb(nskb);
2925 }
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002926
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002927 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002928}
2929
2930/* ---- L2CAP signalling commands ---- */
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002931static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code,
2932 u8 ident, u16 dlen, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002933{
2934 struct sk_buff *skb, **frag;
2935 struct l2cap_cmd_hdr *cmd;
2936 struct l2cap_hdr *lh;
2937 int len, count;
2938
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002939 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %u",
2940 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002941
Anderson Lizardo300b9622013-06-02 16:30:40 -04002942 if (conn->mtu < L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE)
2943 return NULL;
2944
Linus Torvalds1da177e2005-04-16 15:20:36 -07002945 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2946 count = min_t(unsigned int, conn->mtu, len);
2947
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002948 skb = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002949 if (!skb)
2950 return NULL;
2951
2952 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002953 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002954
2955 if (conn->hcon->type == LE_LINK)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002956 lh->cid = __constant_cpu_to_le16(L2CAP_CID_LE_SIGNALING);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002957 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002958 lh->cid = __constant_cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002959
2960 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2961 cmd->code = code;
2962 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002963 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002964
2965 if (dlen) {
2966 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2967 memcpy(skb_put(skb, count), data, count);
2968 data += count;
2969 }
2970
2971 len -= skb->len;
2972
2973 /* Continuation fragments (no L2CAP header) */
2974 frag = &skb_shinfo(skb)->frag_list;
2975 while (len) {
2976 count = min_t(unsigned int, conn->mtu, len);
2977
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002978 *frag = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002979 if (!*frag)
2980 goto fail;
2981
2982 memcpy(skb_put(*frag, count), data, count);
2983
2984 len -= count;
2985 data += count;
2986
2987 frag = &(*frag)->next;
2988 }
2989
2990 return skb;
2991
2992fail:
2993 kfree_skb(skb);
2994 return NULL;
2995}
2996
Gustavo Padovan2d792812012-10-06 10:07:01 +01002997static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen,
2998 unsigned long *val)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002999{
3000 struct l2cap_conf_opt *opt = *ptr;
3001 int len;
3002
3003 len = L2CAP_CONF_OPT_SIZE + opt->len;
3004 *ptr += len;
3005
3006 *type = opt->type;
3007 *olen = opt->len;
3008
3009 switch (opt->len) {
3010 case 1:
3011 *val = *((u8 *) opt->val);
3012 break;
3013
3014 case 2:
steven miaobfaaeb32010-10-16 18:29:47 -04003015 *val = get_unaligned_le16(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003016 break;
3017
3018 case 4:
steven miaobfaaeb32010-10-16 18:29:47 -04003019 *val = get_unaligned_le32(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003020 break;
3021
3022 default:
3023 *val = (unsigned long) opt->val;
3024 break;
3025 }
3026
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03003027 BT_DBG("type 0x%2.2x len %u val 0x%lx", *type, opt->len, *val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003028 return len;
3029}
3030
Linus Torvalds1da177e2005-04-16 15:20:36 -07003031static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
3032{
3033 struct l2cap_conf_opt *opt = *ptr;
3034
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03003035 BT_DBG("type 0x%2.2x len %u val 0x%lx", type, len, val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003036
3037 opt->type = type;
3038 opt->len = len;
3039
3040 switch (len) {
3041 case 1:
3042 *((u8 *) opt->val) = val;
3043 break;
3044
3045 case 2:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02003046 put_unaligned_le16(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003047 break;
3048
3049 case 4:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02003050 put_unaligned_le32(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003051 break;
3052
3053 default:
3054 memcpy(opt->val, (void *) val, len);
3055 break;
3056 }
3057
3058 *ptr += L2CAP_CONF_OPT_SIZE + len;
3059}
3060
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003061static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan)
3062{
3063 struct l2cap_conf_efs efs;
3064
Szymon Janc1ec918c2011-11-16 09:32:21 +01003065 switch (chan->mode) {
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003066 case L2CAP_MODE_ERTM:
3067 efs.id = chan->local_id;
3068 efs.stype = chan->local_stype;
3069 efs.msdu = cpu_to_le16(chan->local_msdu);
3070 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003071 efs.acc_lat = __constant_cpu_to_le32(L2CAP_DEFAULT_ACC_LAT);
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03003072 efs.flush_to = __constant_cpu_to_le32(L2CAP_EFS_DEFAULT_FLUSH_TO);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003073 break;
3074
3075 case L2CAP_MODE_STREAMING:
3076 efs.id = 1;
3077 efs.stype = L2CAP_SERV_BESTEFFORT;
3078 efs.msdu = cpu_to_le16(chan->local_msdu);
3079 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
3080 efs.acc_lat = 0;
3081 efs.flush_to = 0;
3082 break;
3083
3084 default:
3085 return;
3086 }
3087
3088 l2cap_add_conf_opt(ptr, L2CAP_CONF_EFS, sizeof(efs),
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03003089 (unsigned long) &efs);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003090}
3091
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003092static void l2cap_ack_timeout(struct work_struct *work)
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003093{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003094 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau03625202012-05-17 20:53:51 -07003095 ack_timer.work);
3096 u16 frames_to_ack;
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003097
Gustavo F. Padovan2fb9b3d2011-12-22 16:56:05 -02003098 BT_DBG("chan %p", chan);
3099
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003100 l2cap_chan_lock(chan);
3101
Mat Martineau03625202012-05-17 20:53:51 -07003102 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
3103 chan->last_acked_seq);
3104
3105 if (frames_to_ack)
3106 l2cap_send_rr_or_rnr(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003107
3108 l2cap_chan_unlock(chan);
Szymon Janc09bfb2e2012-01-11 10:59:49 +01003109 l2cap_chan_put(chan);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003110}
3111
Andrei Emeltchenko466f8002012-05-29 13:59:01 +03003112int l2cap_ertm_init(struct l2cap_chan *chan)
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003113{
Mat Martineau3c588192012-04-11 10:48:42 -07003114 int err;
3115
Mat Martineau105bdf92012-04-27 16:50:48 -07003116 chan->next_tx_seq = 0;
3117 chan->expected_tx_seq = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03003118 chan->expected_ack_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03003119 chan->unacked_frames = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03003120 chan->buffer_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03003121 chan->frames_sent = 0;
Mat Martineau105bdf92012-04-27 16:50:48 -07003122 chan->last_acked_seq = 0;
3123 chan->sdu = NULL;
3124 chan->sdu_last_frag = NULL;
3125 chan->sdu_len = 0;
3126
Mat Martineaud34c34f2012-05-14 14:49:27 -07003127 skb_queue_head_init(&chan->tx_q);
3128
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003129 chan->local_amp_id = AMP_ID_BREDR;
3130 chan->move_id = AMP_ID_BREDR;
Mat Martineau08333282012-10-23 15:24:06 -07003131 chan->move_state = L2CAP_MOVE_STABLE;
3132 chan->move_role = L2CAP_MOVE_ROLE_NONE;
3133
Mat Martineau105bdf92012-04-27 16:50:48 -07003134 if (chan->mode != L2CAP_MODE_ERTM)
3135 return 0;
3136
3137 chan->rx_state = L2CAP_RX_STATE_RECV;
3138 chan->tx_state = L2CAP_TX_STATE_XMIT;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003139
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003140 INIT_DELAYED_WORK(&chan->retrans_timer, l2cap_retrans_timeout);
3141 INIT_DELAYED_WORK(&chan->monitor_timer, l2cap_monitor_timeout);
3142 INIT_DELAYED_WORK(&chan->ack_timer, l2cap_ack_timeout);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003143
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -03003144 skb_queue_head_init(&chan->srej_q);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003145
Mat Martineau3c588192012-04-11 10:48:42 -07003146 err = l2cap_seq_list_init(&chan->srej_list, chan->tx_win);
3147 if (err < 0)
3148 return err;
3149
Mat Martineau9dc9aff2012-05-17 16:20:14 -07003150 err = l2cap_seq_list_init(&chan->retrans_list, chan->remote_tx_win);
3151 if (err < 0)
3152 l2cap_seq_list_free(&chan->srej_list);
3153
3154 return err;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003155}
3156
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003157static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
3158{
3159 switch (mode) {
3160 case L2CAP_MODE_STREAMING:
3161 case L2CAP_MODE_ERTM:
3162 if (l2cap_mode_supported(mode, remote_feat_mask))
3163 return mode;
3164 /* fall through */
3165 default:
3166 return L2CAP_MODE_BASIC;
3167 }
3168}
3169
Marcel Holtmann848566b2013-10-01 22:59:22 -07003170static inline bool __l2cap_ews_supported(struct l2cap_conn *conn)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003171{
Marcel Holtmann848566b2013-10-01 22:59:22 -07003172 return conn->hs_enabled && conn->feat_mask & L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003173}
3174
Marcel Holtmann848566b2013-10-01 22:59:22 -07003175static inline bool __l2cap_efs_supported(struct l2cap_conn *conn)
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003176{
Marcel Holtmann848566b2013-10-01 22:59:22 -07003177 return conn->hs_enabled && conn->feat_mask & L2CAP_FEAT_EXT_FLOW;
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003178}
3179
Mat Martineau36c86c82012-10-23 15:24:20 -07003180static void __l2cap_set_ertm_timeouts(struct l2cap_chan *chan,
3181 struct l2cap_conf_rfc *rfc)
3182{
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003183 if (chan->local_amp_id != AMP_ID_BREDR && chan->hs_hcon) {
Mat Martineau36c86c82012-10-23 15:24:20 -07003184 u64 ertm_to = chan->hs_hcon->hdev->amp_be_flush_to;
3185
3186 /* Class 1 devices have must have ERTM timeouts
3187 * exceeding the Link Supervision Timeout. The
3188 * default Link Supervision Timeout for AMP
3189 * controllers is 10 seconds.
3190 *
3191 * Class 1 devices use 0xffffffff for their
3192 * best-effort flush timeout, so the clamping logic
3193 * will result in a timeout that meets the above
3194 * requirement. ERTM timeouts are 16-bit values, so
3195 * the maximum timeout is 65.535 seconds.
3196 */
3197
3198 /* Convert timeout to milliseconds and round */
3199 ertm_to = DIV_ROUND_UP_ULL(ertm_to, 1000);
3200
3201 /* This is the recommended formula for class 2 devices
3202 * that start ERTM timers when packets are sent to the
3203 * controller.
3204 */
3205 ertm_to = 3 * ertm_to + 500;
3206
3207 if (ertm_to > 0xffff)
3208 ertm_to = 0xffff;
3209
3210 rfc->retrans_timeout = cpu_to_le16((u16) ertm_to);
3211 rfc->monitor_timeout = rfc->retrans_timeout;
3212 } else {
3213 rfc->retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
3214 rfc->monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
3215 }
3216}
3217
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003218static inline void l2cap_txwin_setup(struct l2cap_chan *chan)
3219{
3220 if (chan->tx_win > L2CAP_DEFAULT_TX_WINDOW &&
Marcel Holtmann848566b2013-10-01 22:59:22 -07003221 __l2cap_ews_supported(chan->conn)) {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003222 /* use extended control field */
3223 set_bit(FLAG_EXT_CTRL, &chan->flags);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003224 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
3225 } else {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003226 chan->tx_win = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003227 L2CAP_DEFAULT_TX_WINDOW);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003228 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
3229 }
Mat Martineauc20f8e32012-07-10 05:47:07 -07003230 chan->ack_win = chan->tx_win;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003231}
3232
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003233static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003234{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003235 struct l2cap_conf_req *req = data;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003236 struct l2cap_conf_rfc rfc = { .mode = chan->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07003237 void *ptr = req->data;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003238 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003239
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03003240 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003241
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003242 if (chan->num_conf_req || chan->num_conf_rsp)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003243 goto done;
3244
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003245 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003246 case L2CAP_MODE_STREAMING:
3247 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003248 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state))
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003249 break;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003250
Marcel Holtmann848566b2013-10-01 22:59:22 -07003251 if (__l2cap_efs_supported(chan->conn))
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003252 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3253
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03003254 /* fall through */
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003255 default:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003256 chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003257 break;
3258 }
3259
3260done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003261 if (chan->imtu != L2CAP_DEFAULT_MTU)
3262 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovan7990681c2011-01-24 16:01:43 -02003263
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003264 switch (chan->mode) {
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003265 case L2CAP_MODE_BASIC:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003266 if (!(chan->conn->feat_mask & L2CAP_FEAT_ERTM) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003267 !(chan->conn->feat_mask & L2CAP_FEAT_STREAMING))
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003268 break;
3269
Gustavo F. Padovan62547752010-06-08 20:05:31 -03003270 rfc.mode = L2CAP_MODE_BASIC;
3271 rfc.txwin_size = 0;
3272 rfc.max_transmit = 0;
3273 rfc.retrans_timeout = 0;
3274 rfc.monitor_timeout = 0;
3275 rfc.max_pdu_size = 0;
3276
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003277 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003278 (unsigned long) &rfc);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003279 break;
3280
3281 case L2CAP_MODE_ERTM:
3282 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003283 rfc.max_transmit = chan->max_tx;
Mat Martineau36c86c82012-10-23 15:24:20 -07003284
3285 __l2cap_set_ertm_timeouts(chan, &rfc);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003286
3287 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003288 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3289 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003290 rfc.max_pdu_size = cpu_to_le16(size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003291
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003292 l2cap_txwin_setup(chan);
3293
3294 rfc.txwin_size = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003295 L2CAP_DEFAULT_TX_WINDOW);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003296
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003297 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003298 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003299
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003300 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3301 l2cap_add_opt_efs(&ptr, chan);
3302
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003303 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3304 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003305 chan->tx_win);
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003306
3307 if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
3308 if (chan->fcs == L2CAP_FCS_NONE ||
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003309 test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003310 chan->fcs = L2CAP_FCS_NONE;
3311 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
3312 chan->fcs);
3313 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003314 break;
3315
3316 case L2CAP_MODE_STREAMING:
Mat Martineau273759e2012-05-17 20:53:53 -07003317 l2cap_txwin_setup(chan);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003318 rfc.mode = L2CAP_MODE_STREAMING;
3319 rfc.txwin_size = 0;
3320 rfc.max_transmit = 0;
3321 rfc.retrans_timeout = 0;
3322 rfc.monitor_timeout = 0;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003323
3324 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003325 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3326 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003327 rfc.max_pdu_size = cpu_to_le16(size);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003328
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003329 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003330 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003331
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003332 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3333 l2cap_add_opt_efs(&ptr, chan);
3334
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003335 if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
3336 if (chan->fcs == L2CAP_FCS_NONE ||
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003337 test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003338 chan->fcs = L2CAP_FCS_NONE;
3339 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
3340 chan->fcs);
3341 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003342 break;
3343 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003344
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003345 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003346 req->flags = __constant_cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003347
3348 return ptr - data;
3349}
3350
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003351static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003352{
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003353 struct l2cap_conf_rsp *rsp = data;
3354 void *ptr = rsp->data;
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003355 void *req = chan->conf_req;
3356 int len = chan->conf_len;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003357 int type, hint, olen;
3358 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003359 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003360 struct l2cap_conf_efs efs;
3361 u8 remote_efs = 0;
Marcel Holtmann861d6882007-10-20 13:37:06 +02003362 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003363 u16 result = L2CAP_CONF_SUCCESS;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003364 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003365
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003366 BT_DBG("chan %p", chan);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01003367
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003368 while (len >= L2CAP_CONF_OPT_SIZE) {
3369 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003370
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03003371 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003372 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003373
3374 switch (type) {
3375 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02003376 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003377 break;
3378
3379 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003380 chan->flush_to = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003381 break;
3382
3383 case L2CAP_CONF_QOS:
3384 break;
3385
Marcel Holtmann6464f352007-10-20 13:39:51 +02003386 case L2CAP_CONF_RFC:
3387 if (olen == sizeof(rfc))
3388 memcpy(&rfc, (void *) val, olen);
3389 break;
3390
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003391 case L2CAP_CONF_FCS:
3392 if (val == L2CAP_FCS_NONE)
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003393 set_bit(CONF_RECV_NO_FCS, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003394 break;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003395
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003396 case L2CAP_CONF_EFS:
3397 remote_efs = 1;
3398 if (olen == sizeof(efs))
3399 memcpy(&efs, (void *) val, olen);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003400 break;
3401
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003402 case L2CAP_CONF_EWS:
Marcel Holtmann848566b2013-10-01 22:59:22 -07003403 if (!chan->conn->hs_enabled)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003404 return -ECONNREFUSED;
3405
3406 set_bit(FLAG_EXT_CTRL, &chan->flags);
3407 set_bit(CONF_EWS_RECV, &chan->conf_state);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003408 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003409 chan->remote_tx_win = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003410 break;
3411
3412 default:
3413 if (hint)
3414 break;
3415
3416 result = L2CAP_CONF_UNKNOWN;
3417 *((u8 *) ptr++) = type;
3418 break;
3419 }
3420 }
3421
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003422 if (chan->num_conf_rsp || chan->num_conf_req > 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003423 goto done;
3424
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003425 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003426 case L2CAP_MODE_STREAMING:
3427 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003428 if (!test_bit(CONF_STATE2_DEVICE, &chan->conf_state)) {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003429 chan->mode = l2cap_select_mode(rfc.mode,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003430 chan->conn->feat_mask);
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003431 break;
3432 }
3433
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003434 if (remote_efs) {
Marcel Holtmann848566b2013-10-01 22:59:22 -07003435 if (__l2cap_efs_supported(chan->conn))
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003436 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3437 else
3438 return -ECONNREFUSED;
3439 }
3440
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003441 if (chan->mode != rfc.mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003442 return -ECONNREFUSED;
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03003443
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003444 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003445 }
3446
3447done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003448 if (chan->mode != rfc.mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003449 result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003450 rfc.mode = chan->mode;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003451
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003452 if (chan->num_conf_rsp == 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003453 return -ECONNREFUSED;
3454
Gustavo Padovan2d792812012-10-06 10:07:01 +01003455 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3456 (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003457 }
3458
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003459 if (result == L2CAP_CONF_SUCCESS) {
3460 /* Configure output options and let the other side know
3461 * which ones we don't like. */
3462
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003463 if (mtu < L2CAP_DEFAULT_MIN_MTU)
3464 result = L2CAP_CONF_UNACCEPT;
3465 else {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003466 chan->omtu = mtu;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003467 set_bit(CONF_MTU_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003468 }
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003469 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003470
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003471 if (remote_efs) {
3472 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003473 efs.stype != L2CAP_SERV_NOTRAFIC &&
3474 efs.stype != chan->local_stype) {
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003475
3476 result = L2CAP_CONF_UNACCEPT;
3477
3478 if (chan->num_conf_req >= 1)
3479 return -ECONNREFUSED;
3480
3481 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003482 sizeof(efs),
3483 (unsigned long) &efs);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003484 } else {
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003485 /* Send PENDING Conf Rsp */
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003486 result = L2CAP_CONF_PENDING;
3487 set_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003488 }
3489 }
3490
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003491 switch (rfc.mode) {
3492 case L2CAP_MODE_BASIC:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003493 chan->fcs = L2CAP_FCS_NONE;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003494 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003495 break;
3496
3497 case L2CAP_MODE_ERTM:
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003498 if (!test_bit(CONF_EWS_RECV, &chan->conf_state))
3499 chan->remote_tx_win = rfc.txwin_size;
3500 else
3501 rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW;
3502
Gustavo F. Padovan2c03a7a2011-03-25 20:15:28 -03003503 chan->remote_max_tx = rfc.max_transmit;
Mat Martineau86b1b262010-08-05 15:54:22 -07003504
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003505 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003506 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3507 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003508 rfc.max_pdu_size = cpu_to_le16(size);
3509 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003510
Mat Martineau36c86c82012-10-23 15:24:20 -07003511 __l2cap_set_ertm_timeouts(chan, &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003512
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003513 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003514
3515 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003516 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003517
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003518 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3519 chan->remote_id = efs.id;
3520 chan->remote_stype = efs.stype;
3521 chan->remote_msdu = le16_to_cpu(efs.msdu);
3522 chan->remote_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003523 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003524 chan->remote_acc_lat =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003525 le32_to_cpu(efs.acc_lat);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003526 chan->remote_sdu_itime =
3527 le32_to_cpu(efs.sdu_itime);
3528 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003529 sizeof(efs),
3530 (unsigned long) &efs);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003531 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003532 break;
3533
3534 case L2CAP_MODE_STREAMING:
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003535 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003536 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3537 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003538 rfc.max_pdu_size = cpu_to_le16(size);
3539 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003540
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003541 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003542
Gustavo Padovan2d792812012-10-06 10:07:01 +01003543 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3544 (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003545
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003546 break;
3547
3548 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02003549 result = L2CAP_CONF_UNACCEPT;
3550
3551 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003552 rfc.mode = chan->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003553 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003554
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003555 if (result == L2CAP_CONF_SUCCESS)
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003556 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003557 }
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003558 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003559 rsp->result = cpu_to_le16(result);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003560 rsp->flags = __constant_cpu_to_le16(0);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003561
3562 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003563}
3564
Gustavo Padovan2d792812012-10-06 10:07:01 +01003565static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len,
3566 void *data, u16 *result)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003567{
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003568 struct l2cap_conf_req *req = data;
3569 void *ptr = req->data;
3570 int type, olen;
3571 unsigned long val;
Mat Martineau36e999a2011-12-08 17:23:21 -08003572 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003573 struct l2cap_conf_efs efs;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003574
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003575 BT_DBG("chan %p, rsp %p, len %d, req %p", chan, rsp, len, data);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003576
3577 while (len >= L2CAP_CONF_OPT_SIZE) {
3578 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3579
3580 switch (type) {
3581 case L2CAP_CONF_MTU:
3582 if (val < L2CAP_DEFAULT_MIN_MTU) {
3583 *result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003584 chan->imtu = L2CAP_DEFAULT_MIN_MTU;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003585 } else
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003586 chan->imtu = val;
3587 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003588 break;
3589
3590 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003591 chan->flush_to = val;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003592 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003593 2, chan->flush_to);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003594 break;
3595
3596 case L2CAP_CONF_RFC:
3597 if (olen == sizeof(rfc))
3598 memcpy(&rfc, (void *)val, olen);
3599
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003600 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003601 rfc.mode != chan->mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003602 return -ECONNREFUSED;
3603
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003604 chan->fcs = 0;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003605
3606 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003607 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003608 break;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003609
3610 case L2CAP_CONF_EWS:
Mat Martineauc20f8e32012-07-10 05:47:07 -07003611 chan->ack_win = min_t(u16, val, chan->ack_win);
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003612 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Mat Martineauc20f8e32012-07-10 05:47:07 -07003613 chan->tx_win);
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003614 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003615
3616 case L2CAP_CONF_EFS:
3617 if (olen == sizeof(efs))
3618 memcpy(&efs, (void *)val, olen);
3619
3620 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003621 efs.stype != L2CAP_SERV_NOTRAFIC &&
3622 efs.stype != chan->local_stype)
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003623 return -ECONNREFUSED;
3624
Gustavo Padovan2d792812012-10-06 10:07:01 +01003625 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs),
3626 (unsigned long) &efs);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003627 break;
Andrei Emeltchenkocbabee72012-11-29 17:46:07 +02003628
3629 case L2CAP_CONF_FCS:
3630 if (*result == L2CAP_CONF_PENDING)
3631 if (val == L2CAP_FCS_NONE)
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003632 set_bit(CONF_RECV_NO_FCS,
Andrei Emeltchenkocbabee72012-11-29 17:46:07 +02003633 &chan->conf_state);
3634 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003635 }
3636 }
3637
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003638 if (chan->mode == L2CAP_MODE_BASIC && chan->mode != rfc.mode)
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003639 return -ECONNREFUSED;
3640
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003641 chan->mode = rfc.mode;
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003642
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003643 if (*result == L2CAP_CONF_SUCCESS || *result == L2CAP_CONF_PENDING) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003644 switch (rfc.mode) {
3645 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003646 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3647 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
3648 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003649 if (!test_bit(FLAG_EXT_CTRL, &chan->flags))
3650 chan->ack_win = min_t(u16, chan->ack_win,
3651 rfc.txwin_size);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003652
3653 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3654 chan->local_msdu = le16_to_cpu(efs.msdu);
3655 chan->local_sdu_itime =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003656 le32_to_cpu(efs.sdu_itime);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003657 chan->local_acc_lat = le32_to_cpu(efs.acc_lat);
3658 chan->local_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003659 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003660 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003661 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003662
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003663 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003664 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003665 }
3666 }
3667
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003668 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003669 req->flags = __constant_cpu_to_le16(0);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003670
3671 return ptr - data;
3672}
3673
Gustavo Padovan2d792812012-10-06 10:07:01 +01003674static int l2cap_build_conf_rsp(struct l2cap_chan *chan, void *data,
3675 u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003676{
3677 struct l2cap_conf_rsp *rsp = data;
3678 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003679
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003680 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003681
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003682 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003683 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003684 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003685
3686 return ptr - data;
3687}
3688
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03003689void __l2cap_le_connect_rsp_defer(struct l2cap_chan *chan)
3690{
3691 struct l2cap_le_conn_rsp rsp;
3692 struct l2cap_conn *conn = chan->conn;
3693
3694 BT_DBG("chan %p", chan);
3695
3696 rsp.dcid = cpu_to_le16(chan->scid);
3697 rsp.mtu = cpu_to_le16(chan->imtu);
3698 rsp.mps = __constant_cpu_to_le16(L2CAP_LE_DEFAULT_MPS);
Johan Hedberg0cd75f72013-05-17 13:09:05 +03003699 rsp.credits = cpu_to_le16(chan->rx_credits);
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03003700 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
3701
3702 l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CONN_RSP, sizeof(rsp),
3703 &rsp);
3704}
3705
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003706void __l2cap_connect_rsp_defer(struct l2cap_chan *chan)
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003707{
3708 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003709 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003710 u8 buf[128];
Andrei Emeltchenko439f34a2012-10-31 15:46:28 +02003711 u8 rsp_code;
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003712
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003713 rsp.scid = cpu_to_le16(chan->dcid);
3714 rsp.dcid = cpu_to_le16(chan->scid);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003715 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
3716 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Andrei Emeltchenko439f34a2012-10-31 15:46:28 +02003717
3718 if (chan->hs_hcon)
3719 rsp_code = L2CAP_CREATE_CHAN_RSP;
3720 else
3721 rsp_code = L2CAP_CONN_RSP;
3722
3723 BT_DBG("chan %p rsp_code %u", chan, rsp_code);
3724
3725 l2cap_send_cmd(conn, chan->ident, rsp_code, sizeof(rsp), &rsp);
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003726
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003727 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003728 return;
3729
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003730 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003731 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003732 chan->num_conf_req++;
3733}
3734
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003735static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003736{
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003737 int type, olen;
3738 unsigned long val;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003739 /* Use sane default values in case a misbehaving remote device
3740 * did not send an RFC or extended window size option.
3741 */
3742 u16 txwin_ext = chan->ack_win;
3743 struct l2cap_conf_rfc rfc = {
3744 .mode = chan->mode,
3745 .retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO),
3746 .monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO),
3747 .max_pdu_size = cpu_to_le16(chan->imtu),
3748 .txwin_size = min_t(u16, chan->ack_win, L2CAP_DEFAULT_TX_WINDOW),
3749 };
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003750
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003751 BT_DBG("chan %p, rsp %p, len %d", chan, rsp, len);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003752
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003753 if ((chan->mode != L2CAP_MODE_ERTM) && (chan->mode != L2CAP_MODE_STREAMING))
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003754 return;
3755
3756 while (len >= L2CAP_CONF_OPT_SIZE) {
3757 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3758
Mat Martineauc20f8e32012-07-10 05:47:07 -07003759 switch (type) {
3760 case L2CAP_CONF_RFC:
3761 if (olen == sizeof(rfc))
3762 memcpy(&rfc, (void *)val, olen);
Szymon Janc8f321f82012-06-08 11:33:33 +02003763 break;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003764 case L2CAP_CONF_EWS:
3765 txwin_ext = val;
3766 break;
3767 }
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003768 }
3769
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003770 switch (rfc.mode) {
3771 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003772 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3773 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003774 chan->mps = le16_to_cpu(rfc.max_pdu_size);
3775 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3776 chan->ack_win = min_t(u16, chan->ack_win, txwin_ext);
3777 else
3778 chan->ack_win = min_t(u16, chan->ack_win,
3779 rfc.txwin_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003780 break;
3781 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003782 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003783 }
3784}
3785
Gustavo Padovan2d792812012-10-06 10:07:01 +01003786static inline int l2cap_command_rej(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003787 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3788 u8 *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003789{
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003790 struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003791
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003792 if (cmd_len < sizeof(*rej))
3793 return -EPROTO;
3794
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003795 if (rej->reason != L2CAP_REJ_NOT_UNDERSTOOD)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003796 return 0;
3797
3798 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003799 cmd->ident == conn->info_ident) {
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02003800 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01003801
3802 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003803 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003804
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003805 l2cap_conn_start(conn);
3806 }
3807
3808 return 0;
3809}
3810
Mat Martineau17009152012-10-23 15:24:07 -07003811static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
3812 struct l2cap_cmd_hdr *cmd,
3813 u8 *data, u8 rsp_code, u8 amp_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003814{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003815 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
3816 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003817 struct l2cap_chan *chan = NULL, *pchan;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003818 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003819
3820 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003821 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003822
Andrei Emeltchenko097db762012-03-09 14:16:17 +02003823 BT_DBG("psm 0x%2.2x scid 0x%4.4x", __le16_to_cpu(psm), scid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003824
3825 /* Check if we have socket listening on psm */
Marcel Holtmann6f59b902013-10-13 05:24:01 -07003826 pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, &conn->hcon->src,
Johan Hedbergbf20fd42013-05-14 13:23:13 +03003827 &conn->hcon->dst, ACL_LINK);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003828 if (!pchan) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003829 result = L2CAP_CR_BAD_PSM;
3830 goto sendresp;
3831 }
3832
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003833 mutex_lock(&conn->chan_lock);
Gustavo Padovan8ffb9292013-10-21 14:21:41 -02003834 l2cap_chan_lock(pchan);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00003835
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003836 /* Check if the ACL is secure enough (if not SDP) */
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +03003837 if (psm != __constant_cpu_to_le16(L2CAP_PSM_SDP) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003838 !hci_conn_check_link_mode(conn->hcon)) {
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003839 conn->disc_reason = HCI_ERROR_AUTH_FAILURE;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003840 result = L2CAP_CR_SEC_BLOCK;
3841 goto response;
3842 }
3843
Linus Torvalds1da177e2005-04-16 15:20:36 -07003844 result = L2CAP_CR_NO_MEM;
3845
Gustavo Padovan2dfa1002012-05-27 22:27:58 -03003846 /* Check if we already have channel with that dcid */
3847 if (__l2cap_get_chan_by_dcid(conn, scid))
3848 goto response;
3849
Gustavo Padovan80b98022012-05-27 22:27:51 -03003850 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003851 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003852 goto response;
3853
Syam Sidhardhan330b6c12013-08-06 01:59:12 +09003854 /* For certain devices (ex: HID mouse), support for authentication,
3855 * pairing and bonding is optional. For such devices, inorder to avoid
3856 * the ACL alive for too long after L2CAP disconnection, reset the ACL
3857 * disc_timeout back to HCI_DISCONN_TIMEOUT during L2CAP connect.
3858 */
3859 conn->hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
3860
Marcel Holtmann7eafc592013-10-13 08:12:47 -07003861 bacpy(&chan->src, &conn->hcon->src);
3862 bacpy(&chan->dst, &conn->hcon->dst);
Marcel Holtmann4f1654e2013-10-13 08:50:41 -07003863 chan->src_type = bdaddr_type(conn->hcon, conn->hcon->src_type);
3864 chan->dst_type = bdaddr_type(conn->hcon, conn->hcon->dst_type);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003865 chan->psm = psm;
3866 chan->dcid = scid;
Mat Martineau17009152012-10-23 15:24:07 -07003867 chan->local_amp_id = amp_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003868
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003869 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003870
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003871 dcid = chan->scid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003872
Gustavo Padovan8d836d72013-10-15 19:24:47 -03003873 __set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003874
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003875 chan->ident = cmd->ident;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003876
Marcel Holtmann984947d2009-02-06 23:35:19 +01003877 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02003878 if (l2cap_chan_check_security(chan)) {
Marcel Holtmannbdc25782013-10-14 02:45:34 -07003879 if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02003880 l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003881 result = L2CAP_CR_PEND;
3882 status = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08003883 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003884 } else {
Mat Martineau17009152012-10-23 15:24:07 -07003885 /* Force pending result for AMP controllers.
3886 * The connection will succeed after the
3887 * physical link is up.
3888 */
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003889 if (amp_id == AMP_ID_BREDR) {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02003890 l2cap_state_change(chan, BT_CONFIG);
Mat Martineau17009152012-10-23 15:24:07 -07003891 result = L2CAP_CR_SUCCESS;
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003892 } else {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02003893 l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003894 result = L2CAP_CR_PEND;
Mat Martineau17009152012-10-23 15:24:07 -07003895 }
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003896 status = L2CAP_CS_NO_INFO;
3897 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003898 } else {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02003899 l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003900 result = L2CAP_CR_PEND;
3901 status = L2CAP_CS_AUTHEN_PEND;
3902 }
3903 } else {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02003904 l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003905 result = L2CAP_CR_PEND;
3906 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003907 }
3908
Linus Torvalds1da177e2005-04-16 15:20:36 -07003909response:
Gustavo Padovan8ffb9292013-10-21 14:21:41 -02003910 l2cap_chan_unlock(pchan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003911 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003912
3913sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003914 rsp.scid = cpu_to_le16(scid);
3915 rsp.dcid = cpu_to_le16(dcid);
3916 rsp.result = cpu_to_le16(result);
3917 rsp.status = cpu_to_le16(status);
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003918 l2cap_send_cmd(conn, cmd->ident, rsp_code, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003919
3920 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
3921 struct l2cap_info_req info;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003922 info.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003923
3924 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
3925 conn->info_ident = l2cap_get_ident(conn);
3926
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08003927 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003928
Gustavo Padovan2d792812012-10-06 10:07:01 +01003929 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
3930 sizeof(info), &info);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003931 }
3932
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003933 if (chan && !test_bit(CONF_REQ_SENT, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003934 result == L2CAP_CR_SUCCESS) {
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003935 u8 buf[128];
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003936 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003937 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003938 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003939 chan->num_conf_req++;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003940 }
Mat Martineau17009152012-10-23 15:24:07 -07003941
3942 return chan;
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003943}
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003944
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003945static int l2cap_connect_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003946 struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003947{
Jaganath Kanakkassery7b064ed2013-01-10 10:28:35 +05303948 struct hci_dev *hdev = conn->hcon->hdev;
3949 struct hci_conn *hcon = conn->hcon;
3950
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003951 if (cmd_len < sizeof(struct l2cap_conn_req))
3952 return -EPROTO;
3953
Jaganath Kanakkassery7b064ed2013-01-10 10:28:35 +05303954 hci_dev_lock(hdev);
3955 if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
3956 !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &hcon->flags))
3957 mgmt_device_connected(hdev, &hcon->dst, hcon->type,
3958 hcon->dst_type, 0, NULL, 0,
3959 hcon->dev_class);
3960 hci_dev_unlock(hdev);
3961
Gustavo Padovan300229f2012-10-12 19:40:40 +08003962 l2cap_connect(conn, cmd, data, L2CAP_CONN_RSP, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003963 return 0;
3964}
3965
Mat Martineau5909cf32012-10-23 15:24:08 -07003966static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003967 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3968 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003969{
3970 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
3971 u16 scid, dcid, result, status;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003972 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003973 u8 req[128];
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003974 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003975
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003976 if (cmd_len < sizeof(*rsp))
3977 return -EPROTO;
3978
Linus Torvalds1da177e2005-04-16 15:20:36 -07003979 scid = __le16_to_cpu(rsp->scid);
3980 dcid = __le16_to_cpu(rsp->dcid);
3981 result = __le16_to_cpu(rsp->result);
3982 status = __le16_to_cpu(rsp->status);
3983
Andrei Emeltchenko1b009c92012-02-21 12:54:54 +02003984 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 +01003985 dcid, scid, result, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003986
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003987 mutex_lock(&conn->chan_lock);
3988
Linus Torvalds1da177e2005-04-16 15:20:36 -07003989 if (scid) {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003990 chan = __l2cap_get_chan_by_scid(conn, scid);
3991 if (!chan) {
Johan Hedberg21870b52013-09-16 13:05:14 +03003992 err = -EBADSLT;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003993 goto unlock;
3994 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003995 } else {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003996 chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
3997 if (!chan) {
Johan Hedberg21870b52013-09-16 13:05:14 +03003998 err = -EBADSLT;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003999 goto unlock;
4000 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004001 }
4002
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004003 err = 0;
4004
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004005 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004006
Linus Torvalds1da177e2005-04-16 15:20:36 -07004007 switch (result) {
4008 case L2CAP_CR_SUCCESS:
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03004009 l2cap_state_change(chan, BT_CONFIG);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03004010 chan->ident = 0;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03004011 chan->dcid = dcid;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004012 clear_bit(CONF_CONNECT_PEND, &chan->conf_state);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01004013
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004014 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03004015 break;
4016
Linus Torvalds1da177e2005-04-16 15:20:36 -07004017 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004018 l2cap_build_conf_req(chan, req), req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004019 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004020 break;
4021
4022 case L2CAP_CR_PEND:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004023 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004024 break;
4025
4026 default:
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004027 l2cap_chan_del(chan, ECONNREFUSED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004028 break;
4029 }
4030
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004031 l2cap_chan_unlock(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004032
4033unlock:
4034 mutex_unlock(&conn->chan_lock);
4035
4036 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004037}
4038
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004039static inline void set_default_fcs(struct l2cap_chan *chan)
Mat Martineau8c462b62010-08-24 15:35:42 -07004040{
4041 /* FCS is enabled only in ERTM or streaming mode, if one or both
4042 * sides request it.
4043 */
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03004044 if (chan->mode != L2CAP_MODE_ERTM && chan->mode != L2CAP_MODE_STREAMING)
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004045 chan->fcs = L2CAP_FCS_NONE;
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02004046 else if (!test_bit(CONF_RECV_NO_FCS, &chan->conf_state))
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004047 chan->fcs = L2CAP_FCS_CRC16;
Mat Martineau8c462b62010-08-24 15:35:42 -07004048}
4049
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03004050static void l2cap_send_efs_conf_rsp(struct l2cap_chan *chan, void *data,
4051 u8 ident, u16 flags)
4052{
4053 struct l2cap_conn *conn = chan->conn;
4054
4055 BT_DBG("conn %p chan %p ident %d flags 0x%4.4x", conn, chan, ident,
4056 flags);
4057
4058 clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
4059 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
4060
4061 l2cap_send_cmd(conn, ident, L2CAP_CONF_RSP,
4062 l2cap_build_conf_rsp(chan, data,
4063 L2CAP_CONF_SUCCESS, flags), data);
4064}
4065
Johan Hedberg662d6522013-10-16 11:20:47 +03004066static void cmd_reject_invalid_cid(struct l2cap_conn *conn, u8 ident,
4067 u16 scid, u16 dcid)
4068{
4069 struct l2cap_cmd_rej_cid rej;
4070
4071 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_INVALID_CID);
4072 rej.scid = __cpu_to_le16(scid);
4073 rej.dcid = __cpu_to_le16(dcid);
4074
4075 l2cap_send_cmd(conn, ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
4076}
4077
Gustavo Padovan2d792812012-10-06 10:07:01 +01004078static inline int l2cap_config_req(struct l2cap_conn *conn,
4079 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4080 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004081{
4082 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
4083 u16 dcid, flags;
4084 u8 rsp[64];
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004085 struct l2cap_chan *chan;
Mat Martineau3c588192012-04-11 10:48:42 -07004086 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004087
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004088 if (cmd_len < sizeof(*req))
4089 return -EPROTO;
4090
Linus Torvalds1da177e2005-04-16 15:20:36 -07004091 dcid = __le16_to_cpu(req->dcid);
4092 flags = __le16_to_cpu(req->flags);
4093
4094 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
4095
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03004096 chan = l2cap_get_chan_by_scid(conn, dcid);
Johan Hedberg662d6522013-10-16 11:20:47 +03004097 if (!chan) {
4098 cmd_reject_invalid_cid(conn, cmd->ident, dcid, 0);
4099 return 0;
4100 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004101
David S. Miller033b1142011-07-21 13:38:42 -07004102 if (chan->state != BT_CONFIG && chan->state != BT_CONNECT2) {
Johan Hedberg662d6522013-10-16 11:20:47 +03004103 cmd_reject_invalid_cid(conn, cmd->ident, chan->scid,
4104 chan->dcid);
Marcel Holtmann354f60a2006-11-18 22:15:20 +01004105 goto unlock;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03004106 }
Marcel Holtmann354f60a2006-11-18 22:15:20 +01004107
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004108 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07004109 len = cmd_len - sizeof(*req);
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004110 if (chan->conf_len + len > sizeof(chan->conf_req)) {
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004111 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004112 l2cap_build_conf_rsp(chan, rsp,
4113 L2CAP_CONF_REJECT, flags), rsp);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004114 goto unlock;
4115 }
4116
4117 /* Store config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004118 memcpy(chan->conf_req + chan->conf_len, req->data, len);
4119 chan->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004120
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03004121 if (flags & L2CAP_CONF_FLAG_CONTINUATION) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004122 /* Incomplete config. Send empty response. */
4123 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004124 l2cap_build_conf_rsp(chan, rsp,
4125 L2CAP_CONF_SUCCESS, flags), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004126 goto unlock;
4127 }
4128
4129 /* Complete config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004130 len = l2cap_parse_conf_req(chan, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004131 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004132 l2cap_send_disconn_req(chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004133 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004134 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004135
Mat Martineau1500109b2012-10-23 15:24:15 -07004136 chan->ident = cmd->ident;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004137 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004138 chan->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004139
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004140 /* Reset config buffer. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004141 chan->conf_len = 0;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004142
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004143 if (!test_bit(CONF_OUTPUT_DONE, &chan->conf_state))
Marcel Holtmann876d9482007-10-20 13:35:42 +02004144 goto unlock;
4145
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004146 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004147 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004148
Mat Martineau105bdf92012-04-27 16:50:48 -07004149 if (chan->mode == L2CAP_MODE_ERTM ||
4150 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07004151 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03004152
Mat Martineau3c588192012-04-11 10:48:42 -07004153 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004154 l2cap_send_disconn_req(chan, -err);
Mat Martineau3c588192012-04-11 10:48:42 -07004155 else
4156 l2cap_chan_ready(chan);
4157
Marcel Holtmann876d9482007-10-20 13:35:42 +02004158 goto unlock;
4159 }
4160
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004161 if (!test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004162 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004163 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004164 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004165 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004166 }
4167
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004168 /* Got Conf Rsp PENDING from remote side and asume we sent
4169 Conf Rsp PENDING in the code above */
4170 if (test_bit(CONF_REM_CONF_PEND, &chan->conf_state) &&
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03004171 test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004172
4173 /* check compatibility */
4174
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004175 /* Send rsp for BR/EDR channel */
Andrei Emeltchenkof351bc72012-10-31 15:46:35 +02004176 if (!chan->hs_hcon)
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004177 l2cap_send_efs_conf_rsp(chan, rsp, cmd->ident, flags);
4178 else
4179 chan->ident = cmd->ident;
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004180 }
4181
Linus Torvalds1da177e2005-04-16 15:20:36 -07004182unlock:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004183 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07004184 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004185}
4186
Gustavo Padovan2d792812012-10-06 10:07:01 +01004187static inline int l2cap_config_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004188 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4189 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004190{
4191 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
4192 u16 scid, flags, result;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004193 struct l2cap_chan *chan;
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004194 int len = cmd_len - sizeof(*rsp);
Mat Martineau3c588192012-04-11 10:48:42 -07004195 int err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004196
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004197 if (cmd_len < sizeof(*rsp))
4198 return -EPROTO;
4199
Linus Torvalds1da177e2005-04-16 15:20:36 -07004200 scid = __le16_to_cpu(rsp->scid);
4201 flags = __le16_to_cpu(rsp->flags);
4202 result = __le16_to_cpu(rsp->result);
4203
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02004204 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x len %d", scid, flags,
4205 result, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004206
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03004207 chan = l2cap_get_chan_by_scid(conn, scid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004208 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004209 return 0;
4210
4211 switch (result) {
4212 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004213 l2cap_conf_rfc_get(chan, rsp->data, len);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004214 clear_bit(CONF_REM_CONF_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004215 break;
4216
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004217 case L2CAP_CONF_PENDING:
4218 set_bit(CONF_REM_CONF_PEND, &chan->conf_state);
4219
4220 if (test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
4221 char buf[64];
4222
4223 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004224 buf, &result);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004225 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004226 l2cap_send_disconn_req(chan, ECONNRESET);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004227 goto done;
4228 }
4229
Andrei Emeltchenkof351bc72012-10-31 15:46:35 +02004230 if (!chan->hs_hcon) {
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004231 l2cap_send_efs_conf_rsp(chan, buf, cmd->ident,
4232 0);
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +02004233 } else {
4234 if (l2cap_check_efs(chan)) {
4235 amp_create_logical_link(chan);
4236 chan->ident = cmd->ident;
4237 }
4238 }
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004239 }
4240 goto done;
4241
Linus Torvalds1da177e2005-04-16 15:20:36 -07004242 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004243 if (chan->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004244 char req[64];
4245
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02004246 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004247 l2cap_send_disconn_req(chan, ECONNRESET);
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02004248 goto done;
4249 }
4250
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004251 /* throw out any old stored conf requests */
4252 result = L2CAP_CONF_SUCCESS;
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03004253 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004254 req, &result);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004255 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004256 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004257 goto done;
4258 }
4259
4260 l2cap_send_cmd(conn, l2cap_get_ident(conn),
Gustavo Padovan2d792812012-10-06 10:07:01 +01004261 L2CAP_CONF_REQ, len, req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004262 chan->num_conf_req++;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004263 if (result != L2CAP_CONF_SUCCESS)
4264 goto done;
4265 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004266 }
4267
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09004268 default:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004269 l2cap_chan_set_err(chan, ECONNRESET);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02004270
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08004271 __set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004272 l2cap_send_disconn_req(chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004273 goto done;
4274 }
4275
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03004276 if (flags & L2CAP_CONF_FLAG_CONTINUATION)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004277 goto done;
4278
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004279 set_bit(CONF_INPUT_DONE, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004280
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004281 if (test_bit(CONF_OUTPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004282 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004283
Mat Martineau105bdf92012-04-27 16:50:48 -07004284 if (chan->mode == L2CAP_MODE_ERTM ||
4285 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07004286 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03004287
Mat Martineau3c588192012-04-11 10:48:42 -07004288 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004289 l2cap_send_disconn_req(chan, -err);
Mat Martineau3c588192012-04-11 10:48:42 -07004290 else
4291 l2cap_chan_ready(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004292 }
4293
4294done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004295 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07004296 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004297}
4298
Gustavo Padovan2d792812012-10-06 10:07:01 +01004299static inline int l2cap_disconnect_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004300 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4301 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004302{
4303 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
4304 struct l2cap_disconn_rsp rsp;
4305 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004306 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004307
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004308 if (cmd_len != sizeof(*req))
4309 return -EPROTO;
4310
Linus Torvalds1da177e2005-04-16 15:20:36 -07004311 scid = __le16_to_cpu(req->scid);
4312 dcid = __le16_to_cpu(req->dcid);
4313
4314 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
4315
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004316 mutex_lock(&conn->chan_lock);
4317
4318 chan = __l2cap_get_chan_by_scid(conn, dcid);
4319 if (!chan) {
4320 mutex_unlock(&conn->chan_lock);
Johan Hedberg662d6522013-10-16 11:20:47 +03004321 cmd_reject_invalid_cid(conn, cmd->ident, dcid, scid);
4322 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004323 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004324
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004325 l2cap_chan_lock(chan);
4326
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03004327 rsp.dcid = cpu_to_le16(chan->scid);
4328 rsp.scid = cpu_to_le16(chan->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004329 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
4330
Gustavo Padovan5ec1bbe2013-10-15 19:24:48 -03004331 chan->ops->set_shutdown(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004332
Mat Martineau61d6ef32012-04-27 16:50:50 -07004333 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004334 l2cap_chan_del(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004335
4336 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004337
Gustavo Padovan80b98022012-05-27 22:27:51 -03004338 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004339 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004340
4341 mutex_unlock(&conn->chan_lock);
4342
Linus Torvalds1da177e2005-04-16 15:20:36 -07004343 return 0;
4344}
4345
Gustavo Padovan2d792812012-10-06 10:07:01 +01004346static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004347 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4348 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004349{
4350 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
4351 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004352 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004353
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004354 if (cmd_len != sizeof(*rsp))
4355 return -EPROTO;
4356
Linus Torvalds1da177e2005-04-16 15:20:36 -07004357 scid = __le16_to_cpu(rsp->scid);
4358 dcid = __le16_to_cpu(rsp->dcid);
4359
4360 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
4361
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004362 mutex_lock(&conn->chan_lock);
4363
4364 chan = __l2cap_get_chan_by_scid(conn, scid);
4365 if (!chan) {
4366 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004367 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004368 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004369
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004370 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004371
Mat Martineau61d6ef32012-04-27 16:50:50 -07004372 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004373 l2cap_chan_del(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004374
4375 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004376
Gustavo Padovan80b98022012-05-27 22:27:51 -03004377 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004378 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004379
4380 mutex_unlock(&conn->chan_lock);
4381
Linus Torvalds1da177e2005-04-16 15:20:36 -07004382 return 0;
4383}
4384
Gustavo Padovan2d792812012-10-06 10:07:01 +01004385static inline int l2cap_information_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004386 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4387 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004388{
4389 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004390 u16 type;
4391
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004392 if (cmd_len != sizeof(*req))
4393 return -EPROTO;
4394
Linus Torvalds1da177e2005-04-16 15:20:36 -07004395 type = __le16_to_cpu(req->type);
4396
4397 BT_DBG("type 0x%4.4x", type);
4398
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004399 if (type == L2CAP_IT_FEAT_MASK) {
4400 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07004401 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004402 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004403 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
4404 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03004405 if (!disable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004406 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
Gustavo Padovan2d792812012-10-06 10:07:01 +01004407 | L2CAP_FEAT_FCS;
Marcel Holtmann848566b2013-10-01 22:59:22 -07004408 if (conn->hs_enabled)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03004409 feat_mask |= L2CAP_FEAT_EXT_FLOW
Gustavo Padovan2d792812012-10-06 10:07:01 +01004410 | L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03004411
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03004412 put_unaligned_le32(feat_mask, rsp->data);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004413 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4414 buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004415 } else if (type == L2CAP_IT_FIXED_CHAN) {
4416 u8 buf[12];
4417 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Mat Martineau50a147c2011-11-02 16:18:34 -07004418
Marcel Holtmann848566b2013-10-01 22:59:22 -07004419 if (conn->hs_enabled)
Mat Martineau50a147c2011-11-02 16:18:34 -07004420 l2cap_fixed_chan[0] |= L2CAP_FC_A2MP;
4421 else
4422 l2cap_fixed_chan[0] &= ~L2CAP_FC_A2MP;
4423
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004424 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
4425 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Andrei Emeltchenkoc6337ea2011-10-20 17:02:44 +03004426 memcpy(rsp->data, l2cap_fixed_chan, sizeof(l2cap_fixed_chan));
Gustavo Padovan2d792812012-10-06 10:07:01 +01004427 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4428 buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004429 } else {
4430 struct l2cap_info_rsp rsp;
4431 rsp.type = cpu_to_le16(type);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004432 rsp.result = __constant_cpu_to_le16(L2CAP_IR_NOTSUPP);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004433 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(rsp),
4434 &rsp);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004435 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004436
4437 return 0;
4438}
4439
Gustavo Padovan2d792812012-10-06 10:07:01 +01004440static inline int l2cap_information_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004441 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4442 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004443{
4444 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
4445 u16 type, result;
4446
Jaganath Kanakkassery3f6fa3d2013-06-21 19:55:11 +05304447 if (cmd_len < sizeof(*rsp))
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004448 return -EPROTO;
4449
Linus Torvalds1da177e2005-04-16 15:20:36 -07004450 type = __le16_to_cpu(rsp->type);
4451 result = __le16_to_cpu(rsp->result);
4452
4453 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
4454
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004455 /* L2CAP Info req/rsp are unbound to channels, add extra checks */
4456 if (cmd->ident != conn->info_ident ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01004457 conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004458 return 0;
4459
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02004460 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004461
Ville Tervoadb08ed2010-08-04 09:43:33 +03004462 if (result != L2CAP_IR_SUCCESS) {
4463 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4464 conn->info_ident = 0;
4465
4466 l2cap_conn_start(conn);
4467
4468 return 0;
4469 }
4470
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004471 switch (type) {
4472 case L2CAP_IT_FEAT_MASK:
Harvey Harrison83985312008-05-02 16:25:46 -07004473 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004474
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07004475 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004476 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004477 req.type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004478
4479 conn->info_ident = l2cap_get_ident(conn);
4480
4481 l2cap_send_cmd(conn, conn->info_ident,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004482 L2CAP_INFO_REQ, sizeof(req), &req);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004483 } else {
4484 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4485 conn->info_ident = 0;
4486
4487 l2cap_conn_start(conn);
4488 }
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004489 break;
4490
4491 case L2CAP_IT_FIXED_CHAN:
4492 conn->fixed_chan_mask = rsp->data[0];
Marcel Holtmann984947d2009-02-06 23:35:19 +01004493 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004494 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004495
4496 l2cap_conn_start(conn);
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004497 break;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004498 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004499
Linus Torvalds1da177e2005-04-16 15:20:36 -07004500 return 0;
4501}
4502
Mat Martineau17009152012-10-23 15:24:07 -07004503static int l2cap_create_channel_req(struct l2cap_conn *conn,
4504 struct l2cap_cmd_hdr *cmd,
4505 u16 cmd_len, void *data)
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004506{
4507 struct l2cap_create_chan_req *req = data;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004508 struct l2cap_create_chan_rsp rsp;
Mat Martineau17009152012-10-23 15:24:07 -07004509 struct l2cap_chan *chan;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004510 struct hci_dev *hdev;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004511 u16 psm, scid;
4512
4513 if (cmd_len != sizeof(*req))
4514 return -EPROTO;
4515
Marcel Holtmann848566b2013-10-01 22:59:22 -07004516 if (!conn->hs_enabled)
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004517 return -EINVAL;
4518
4519 psm = le16_to_cpu(req->psm);
4520 scid = le16_to_cpu(req->scid);
4521
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004522 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 -07004523
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004524 /* For controller id 0 make BR/EDR connection */
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004525 if (req->amp_id == AMP_ID_BREDR) {
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004526 l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4527 req->amp_id);
4528 return 0;
4529 }
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004530
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004531 /* Validate AMP controller id */
4532 hdev = hci_dev_get(req->amp_id);
4533 if (!hdev)
4534 goto error;
Mat Martineau17009152012-10-23 15:24:07 -07004535
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004536 if (hdev->dev_type != HCI_AMP || !test_bit(HCI_UP, &hdev->flags)) {
Mat Martineau17009152012-10-23 15:24:07 -07004537 hci_dev_put(hdev);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004538 goto error;
Mat Martineau17009152012-10-23 15:24:07 -07004539 }
4540
4541 chan = l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4542 req->amp_id);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004543 if (chan) {
4544 struct amp_mgr *mgr = conn->hcon->amp_mgr;
4545 struct hci_conn *hs_hcon;
4546
Marcel Holtmann98e0f7e2013-10-13 02:23:40 -07004547 hs_hcon = hci_conn_hash_lookup_ba(hdev, AMP_LINK,
4548 &conn->hcon->dst);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004549 if (!hs_hcon) {
4550 hci_dev_put(hdev);
Johan Hedberg662d6522013-10-16 11:20:47 +03004551 cmd_reject_invalid_cid(conn, cmd->ident, chan->scid,
4552 chan->dcid);
4553 return 0;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004554 }
4555
4556 BT_DBG("mgr %p bredr_chan %p hs_hcon %p", mgr, chan, hs_hcon);
4557
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004558 mgr->bredr_chan = chan;
4559 chan->hs_hcon = hs_hcon;
Andrei Emeltchenkofd45bf42012-11-20 17:16:22 +02004560 chan->fcs = L2CAP_FCS_NONE;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004561 conn->mtu = hdev->block_mtu;
4562 }
4563
4564 hci_dev_put(hdev);
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004565
4566 return 0;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004567
4568error:
4569 rsp.dcid = 0;
4570 rsp.scid = cpu_to_le16(scid);
4571 rsp.result = __constant_cpu_to_le16(L2CAP_CR_BAD_AMP);
4572 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
4573
4574 l2cap_send_cmd(conn, cmd->ident, L2CAP_CREATE_CHAN_RSP,
4575 sizeof(rsp), &rsp);
4576
Johan Hedbergdc280802013-09-16 13:05:13 +03004577 return 0;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004578}
4579
Mat Martineau8eb200b2012-10-23 15:24:17 -07004580static void l2cap_send_move_chan_req(struct l2cap_chan *chan, u8 dest_amp_id)
4581{
4582 struct l2cap_move_chan_req req;
4583 u8 ident;
4584
4585 BT_DBG("chan %p, dest_amp_id %d", chan, dest_amp_id);
4586
4587 ident = l2cap_get_ident(chan->conn);
4588 chan->ident = ident;
4589
4590 req.icid = cpu_to_le16(chan->scid);
4591 req.dest_amp_id = dest_amp_id;
4592
4593 l2cap_send_cmd(chan->conn, ident, L2CAP_MOVE_CHAN_REQ, sizeof(req),
4594 &req);
4595
4596 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4597}
4598
Mat Martineau1500109b2012-10-23 15:24:15 -07004599static void l2cap_send_move_chan_rsp(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004600{
4601 struct l2cap_move_chan_rsp rsp;
4602
Mat Martineau1500109b2012-10-23 15:24:15 -07004603 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004604
Mat Martineau1500109b2012-10-23 15:24:15 -07004605 rsp.icid = cpu_to_le16(chan->dcid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004606 rsp.result = cpu_to_le16(result);
4607
Mat Martineau1500109b2012-10-23 15:24:15 -07004608 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_RSP,
4609 sizeof(rsp), &rsp);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004610}
4611
Mat Martineau5b155ef2012-10-23 15:24:14 -07004612static void l2cap_send_move_chan_cfm(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004613{
4614 struct l2cap_move_chan_cfm cfm;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004615
Mat Martineau5b155ef2012-10-23 15:24:14 -07004616 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004617
Mat Martineau5b155ef2012-10-23 15:24:14 -07004618 chan->ident = l2cap_get_ident(chan->conn);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004619
Mat Martineau5b155ef2012-10-23 15:24:14 -07004620 cfm.icid = cpu_to_le16(chan->scid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004621 cfm.result = cpu_to_le16(result);
4622
Mat Martineau5b155ef2012-10-23 15:24:14 -07004623 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_CFM,
4624 sizeof(cfm), &cfm);
4625
4626 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4627}
4628
4629static void l2cap_send_move_chan_cfm_icid(struct l2cap_conn *conn, u16 icid)
4630{
4631 struct l2cap_move_chan_cfm cfm;
4632
4633 BT_DBG("conn %p, icid 0x%4.4x", conn, icid);
4634
4635 cfm.icid = cpu_to_le16(icid);
4636 cfm.result = __constant_cpu_to_le16(L2CAP_MC_UNCONFIRMED);
4637
4638 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_MOVE_CHAN_CFM,
4639 sizeof(cfm), &cfm);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004640}
4641
4642static void l2cap_send_move_chan_cfm_rsp(struct l2cap_conn *conn, u8 ident,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004643 u16 icid)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004644{
4645 struct l2cap_move_chan_cfm_rsp rsp;
4646
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004647 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004648
4649 rsp.icid = cpu_to_le16(icid);
4650 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM_RSP, sizeof(rsp), &rsp);
4651}
4652
Mat Martineau5f3847a2012-10-23 15:24:12 -07004653static void __release_logical_link(struct l2cap_chan *chan)
4654{
4655 chan->hs_hchan = NULL;
4656 chan->hs_hcon = NULL;
4657
4658 /* Placeholder - release the logical link */
4659}
4660
Mat Martineau1500109b2012-10-23 15:24:15 -07004661static void l2cap_logical_fail(struct l2cap_chan *chan)
4662{
4663 /* Logical link setup failed */
4664 if (chan->state != BT_CONNECTED) {
4665 /* Create channel failure, disconnect */
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004666 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineau1500109b2012-10-23 15:24:15 -07004667 return;
4668 }
4669
4670 switch (chan->move_role) {
4671 case L2CAP_MOVE_ROLE_RESPONDER:
4672 l2cap_move_done(chan);
4673 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_SUPP);
4674 break;
4675 case L2CAP_MOVE_ROLE_INITIATOR:
4676 if (chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_COMP ||
4677 chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_CFM) {
4678 /* Remote has only sent pending or
4679 * success responses, clean up
4680 */
4681 l2cap_move_done(chan);
4682 }
4683
4684 /* Other amp move states imply that the move
4685 * has already aborted
4686 */
4687 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4688 break;
4689 }
4690}
4691
4692static void l2cap_logical_finish_create(struct l2cap_chan *chan,
4693 struct hci_chan *hchan)
4694{
4695 struct l2cap_conf_rsp rsp;
Mat Martineau1500109b2012-10-23 15:24:15 -07004696
Andrei Emeltchenko336178a2012-10-31 15:46:27 +02004697 chan->hs_hchan = hchan;
Mat Martineau1500109b2012-10-23 15:24:15 -07004698 chan->hs_hcon->l2cap_data = chan->conn;
4699
Andrei Emeltchenko35ba9562012-10-25 15:20:43 +03004700 l2cap_send_efs_conf_rsp(chan, &rsp, chan->ident, 0);
Mat Martineau1500109b2012-10-23 15:24:15 -07004701
4702 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Andrei Emeltchenkofe79c6f2012-10-25 15:20:42 +03004703 int err;
Mat Martineau1500109b2012-10-23 15:24:15 -07004704
4705 set_default_fcs(chan);
4706
4707 err = l2cap_ertm_init(chan);
4708 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004709 l2cap_send_disconn_req(chan, -err);
Mat Martineau1500109b2012-10-23 15:24:15 -07004710 else
4711 l2cap_chan_ready(chan);
4712 }
4713}
4714
4715static void l2cap_logical_finish_move(struct l2cap_chan *chan,
4716 struct hci_chan *hchan)
4717{
4718 chan->hs_hcon = hchan->conn;
4719 chan->hs_hcon->l2cap_data = chan->conn;
4720
4721 BT_DBG("move_state %d", chan->move_state);
4722
4723 switch (chan->move_state) {
4724 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
4725 /* Move confirm will be sent after a success
4726 * response is received
4727 */
4728 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4729 break;
4730 case L2CAP_MOVE_WAIT_LOGICAL_CFM:
4731 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4732 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4733 } else if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
4734 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
4735 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4736 } else if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
4737 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4738 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
4739 }
4740 break;
4741 default:
4742 /* Move was not in expected state, free the channel */
4743 __release_logical_link(chan);
4744
4745 chan->move_state = L2CAP_MOVE_STABLE;
4746 }
4747}
4748
4749/* Call with chan locked */
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03004750void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan,
4751 u8 status)
Mat Martineau5b155ef2012-10-23 15:24:14 -07004752{
Mat Martineau1500109b2012-10-23 15:24:15 -07004753 BT_DBG("chan %p, hchan %p, status %d", chan, hchan, status);
4754
4755 if (status) {
4756 l2cap_logical_fail(chan);
4757 __release_logical_link(chan);
4758 return;
4759 }
4760
4761 if (chan->state != BT_CONNECTED) {
4762 /* Ignore logical link if channel is on BR/EDR */
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004763 if (chan->local_amp_id != AMP_ID_BREDR)
Mat Martineau1500109b2012-10-23 15:24:15 -07004764 l2cap_logical_finish_create(chan, hchan);
4765 } else {
4766 l2cap_logical_finish_move(chan, hchan);
4767 }
Mat Martineau5b155ef2012-10-23 15:24:14 -07004768}
4769
Mat Martineau3f7a56c2012-10-23 15:24:23 -07004770void l2cap_move_start(struct l2cap_chan *chan)
4771{
4772 BT_DBG("chan %p", chan);
4773
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004774 if (chan->local_amp_id == AMP_ID_BREDR) {
Mat Martineau3f7a56c2012-10-23 15:24:23 -07004775 if (chan->chan_policy != BT_CHANNEL_POLICY_AMP_PREFERRED)
4776 return;
4777 chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
4778 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
4779 /* Placeholder - start physical link setup */
4780 } else {
4781 chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
4782 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4783 chan->move_id = 0;
4784 l2cap_move_setup(chan);
4785 l2cap_send_move_chan_req(chan, 0);
4786 }
4787}
4788
Mat Martineau8eb200b2012-10-23 15:24:17 -07004789static void l2cap_do_create(struct l2cap_chan *chan, int result,
4790 u8 local_amp_id, u8 remote_amp_id)
4791{
Andrei Emeltchenko62748ca2012-11-20 17:16:19 +02004792 BT_DBG("chan %p state %s %u -> %u", chan, state_to_string(chan->state),
4793 local_amp_id, remote_amp_id);
4794
Andrei Emeltchenko12d6cc62012-11-14 17:39:31 +02004795 chan->fcs = L2CAP_FCS_NONE;
4796
Andrei Emeltchenko62748ca2012-11-20 17:16:19 +02004797 /* Outgoing channel on AMP */
4798 if (chan->state == BT_CONNECT) {
4799 if (result == L2CAP_CR_SUCCESS) {
4800 chan->local_amp_id = local_amp_id;
4801 l2cap_send_create_chan_req(chan, remote_amp_id);
4802 } else {
4803 /* Revert to BR/EDR connect */
4804 l2cap_send_conn_req(chan);
4805 }
4806
4807 return;
4808 }
4809
4810 /* Incoming channel on AMP */
4811 if (__l2cap_no_conn_pending(chan)) {
Mat Martineau8eb200b2012-10-23 15:24:17 -07004812 struct l2cap_conn_rsp rsp;
4813 char buf[128];
4814 rsp.scid = cpu_to_le16(chan->dcid);
4815 rsp.dcid = cpu_to_le16(chan->scid);
4816
Mat Martineau8eb200b2012-10-23 15:24:17 -07004817 if (result == L2CAP_CR_SUCCESS) {
4818 /* Send successful response */
Andrei Emeltchenko62cd50e2012-11-14 17:39:32 +02004819 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
4820 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004821 } else {
4822 /* Send negative response */
Andrei Emeltchenko62cd50e2012-11-14 17:39:32 +02004823 rsp.result = __constant_cpu_to_le16(L2CAP_CR_NO_MEM);
4824 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004825 }
4826
4827 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_RSP,
4828 sizeof(rsp), &rsp);
4829
4830 if (result == L2CAP_CR_SUCCESS) {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02004831 l2cap_state_change(chan, BT_CONFIG);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004832 set_bit(CONF_REQ_SENT, &chan->conf_state);
4833 l2cap_send_cmd(chan->conn, l2cap_get_ident(chan->conn),
4834 L2CAP_CONF_REQ,
4835 l2cap_build_conf_req(chan, buf), buf);
4836 chan->num_conf_req++;
4837 }
Mat Martineau8eb200b2012-10-23 15:24:17 -07004838 }
4839}
4840
4841static void l2cap_do_move_initiate(struct l2cap_chan *chan, u8 local_amp_id,
4842 u8 remote_amp_id)
4843{
4844 l2cap_move_setup(chan);
4845 chan->move_id = local_amp_id;
4846 chan->move_state = L2CAP_MOVE_WAIT_RSP;
4847
4848 l2cap_send_move_chan_req(chan, remote_amp_id);
4849}
4850
4851static void l2cap_do_move_respond(struct l2cap_chan *chan, int result)
4852{
4853 struct hci_chan *hchan = NULL;
4854
4855 /* Placeholder - get hci_chan for logical link */
4856
4857 if (hchan) {
4858 if (hchan->state == BT_CONNECTED) {
4859 /* Logical link is ready to go */
4860 chan->hs_hcon = hchan->conn;
4861 chan->hs_hcon->l2cap_data = chan->conn;
4862 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4863 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
4864
4865 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
4866 } else {
4867 /* Wait for logical link to be ready */
4868 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4869 }
4870 } else {
4871 /* Logical link not available */
4872 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_ALLOWED);
4873 }
4874}
4875
4876static void l2cap_do_move_cancel(struct l2cap_chan *chan, int result)
4877{
4878 if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
4879 u8 rsp_result;
4880 if (result == -EINVAL)
4881 rsp_result = L2CAP_MR_BAD_ID;
4882 else
4883 rsp_result = L2CAP_MR_NOT_ALLOWED;
4884
4885 l2cap_send_move_chan_rsp(chan, rsp_result);
4886 }
4887
4888 chan->move_role = L2CAP_MOVE_ROLE_NONE;
4889 chan->move_state = L2CAP_MOVE_STABLE;
4890
4891 /* Restart data transmission */
4892 l2cap_ertm_send(chan);
4893}
4894
Andrei Emeltchenkoa514b172012-11-14 17:39:30 +02004895/* Invoke with locked chan */
4896void __l2cap_physical_cfm(struct l2cap_chan *chan, int result)
Mat Martineau8eb200b2012-10-23 15:24:17 -07004897{
Andrei Emeltchenko770bfef2012-10-31 15:46:29 +02004898 u8 local_amp_id = chan->local_amp_id;
Andrei Emeltchenkofffadc02012-11-01 15:37:03 +02004899 u8 remote_amp_id = chan->remote_amp_id;
Andrei Emeltchenko770bfef2012-10-31 15:46:29 +02004900
Mat Martineau8eb200b2012-10-23 15:24:17 -07004901 BT_DBG("chan %p, result %d, local_amp_id %d, remote_amp_id %d",
4902 chan, result, local_amp_id, remote_amp_id);
4903
Mat Martineau8eb200b2012-10-23 15:24:17 -07004904 if (chan->state == BT_DISCONN || chan->state == BT_CLOSED) {
4905 l2cap_chan_unlock(chan);
4906 return;
4907 }
4908
4909 if (chan->state != BT_CONNECTED) {
4910 l2cap_do_create(chan, result, local_amp_id, remote_amp_id);
4911 } else if (result != L2CAP_MR_SUCCESS) {
4912 l2cap_do_move_cancel(chan, result);
4913 } else {
4914 switch (chan->move_role) {
4915 case L2CAP_MOVE_ROLE_INITIATOR:
4916 l2cap_do_move_initiate(chan, local_amp_id,
4917 remote_amp_id);
4918 break;
4919 case L2CAP_MOVE_ROLE_RESPONDER:
4920 l2cap_do_move_respond(chan, result);
4921 break;
4922 default:
4923 l2cap_do_move_cancel(chan, result);
4924 break;
4925 }
4926 }
Mat Martineau8eb200b2012-10-23 15:24:17 -07004927}
4928
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004929static inline int l2cap_move_channel_req(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004930 struct l2cap_cmd_hdr *cmd,
4931 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004932{
4933 struct l2cap_move_chan_req *req = data;
Mat Martineau1500109b2012-10-23 15:24:15 -07004934 struct l2cap_move_chan_rsp rsp;
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004935 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004936 u16 icid = 0;
4937 u16 result = L2CAP_MR_NOT_ALLOWED;
4938
4939 if (cmd_len != sizeof(*req))
4940 return -EPROTO;
4941
4942 icid = le16_to_cpu(req->icid);
4943
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004944 BT_DBG("icid 0x%4.4x, dest_amp_id %d", icid, req->dest_amp_id);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004945
Marcel Holtmann848566b2013-10-01 22:59:22 -07004946 if (!conn->hs_enabled)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004947 return -EINVAL;
4948
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004949 chan = l2cap_get_chan_by_dcid(conn, icid);
4950 if (!chan) {
Mat Martineau1500109b2012-10-23 15:24:15 -07004951 rsp.icid = cpu_to_le16(icid);
4952 rsp.result = __constant_cpu_to_le16(L2CAP_MR_NOT_ALLOWED);
4953 l2cap_send_cmd(conn, cmd->ident, L2CAP_MOVE_CHAN_RSP,
4954 sizeof(rsp), &rsp);
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004955 return 0;
4956 }
4957
Mat Martineau1500109b2012-10-23 15:24:15 -07004958 chan->ident = cmd->ident;
4959
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004960 if (chan->scid < L2CAP_CID_DYN_START ||
4961 chan->chan_policy == BT_CHANNEL_POLICY_BREDR_ONLY ||
4962 (chan->mode != L2CAP_MODE_ERTM &&
4963 chan->mode != L2CAP_MODE_STREAMING)) {
4964 result = L2CAP_MR_NOT_ALLOWED;
4965 goto send_move_response;
4966 }
4967
4968 if (chan->local_amp_id == req->dest_amp_id) {
4969 result = L2CAP_MR_SAME_ID;
4970 goto send_move_response;
4971 }
4972
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004973 if (req->dest_amp_id != AMP_ID_BREDR) {
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004974 struct hci_dev *hdev;
4975 hdev = hci_dev_get(req->dest_amp_id);
4976 if (!hdev || hdev->dev_type != HCI_AMP ||
4977 !test_bit(HCI_UP, &hdev->flags)) {
4978 if (hdev)
4979 hci_dev_put(hdev);
4980
4981 result = L2CAP_MR_BAD_ID;
4982 goto send_move_response;
4983 }
4984 hci_dev_put(hdev);
4985 }
4986
4987 /* Detect a move collision. Only send a collision response
4988 * if this side has "lost", otherwise proceed with the move.
4989 * The winner has the larger bd_addr.
4990 */
4991 if ((__chan_is_moving(chan) ||
4992 chan->move_role != L2CAP_MOVE_ROLE_NONE) &&
Marcel Holtmann6f59b902013-10-13 05:24:01 -07004993 bacmp(&conn->hcon->src, &conn->hcon->dst) > 0) {
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004994 result = L2CAP_MR_COLLISION;
4995 goto send_move_response;
4996 }
4997
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004998 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
4999 l2cap_move_setup(chan);
5000 chan->move_id = req->dest_amp_id;
5001 icid = chan->dcid;
5002
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07005003 if (req->dest_amp_id == AMP_ID_BREDR) {
Mat Martineau02b0fbb2012-10-23 15:24:10 -07005004 /* Moving to BR/EDR */
5005 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5006 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
5007 result = L2CAP_MR_PEND;
5008 } else {
5009 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
5010 result = L2CAP_MR_SUCCESS;
5011 }
5012 } else {
5013 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
5014 /* Placeholder - uncomment when amp functions are available */
5015 /*amp_accept_physical(chan, req->dest_amp_id);*/
5016 result = L2CAP_MR_PEND;
5017 }
5018
5019send_move_response:
Mat Martineau1500109b2012-10-23 15:24:15 -07005020 l2cap_send_move_chan_rsp(chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005021
Mat Martineau02b0fbb2012-10-23 15:24:10 -07005022 l2cap_chan_unlock(chan);
5023
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005024 return 0;
5025}
5026
Mat Martineau5b155ef2012-10-23 15:24:14 -07005027static void l2cap_move_continue(struct l2cap_conn *conn, u16 icid, u16 result)
5028{
5029 struct l2cap_chan *chan;
5030 struct hci_chan *hchan = NULL;
5031
5032 chan = l2cap_get_chan_by_scid(conn, icid);
5033 if (!chan) {
5034 l2cap_send_move_chan_cfm_icid(conn, icid);
5035 return;
5036 }
5037
5038 __clear_chan_timer(chan);
5039 if (result == L2CAP_MR_PEND)
5040 __set_chan_timer(chan, L2CAP_MOVE_ERTX_TIMEOUT);
5041
5042 switch (chan->move_state) {
5043 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
5044 /* Move confirm will be sent when logical link
5045 * is complete.
5046 */
5047 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
5048 break;
5049 case L2CAP_MOVE_WAIT_RSP_SUCCESS:
5050 if (result == L2CAP_MR_PEND) {
5051 break;
5052 } else if (test_bit(CONN_LOCAL_BUSY,
5053 &chan->conn_state)) {
5054 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
5055 } else {
5056 /* Logical link is up or moving to BR/EDR,
5057 * proceed with move
5058 */
5059 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
5060 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
5061 }
5062 break;
5063 case L2CAP_MOVE_WAIT_RSP:
5064 /* Moving to AMP */
5065 if (result == L2CAP_MR_SUCCESS) {
5066 /* Remote is ready, send confirm immediately
5067 * after logical link is ready
5068 */
5069 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
5070 } else {
5071 /* Both logical link and move success
5072 * are required to confirm
5073 */
5074 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_COMP;
5075 }
5076
5077 /* Placeholder - get hci_chan for logical link */
5078 if (!hchan) {
5079 /* Logical link not available */
5080 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
5081 break;
5082 }
5083
5084 /* If the logical link is not yet connected, do not
5085 * send confirmation.
5086 */
5087 if (hchan->state != BT_CONNECTED)
5088 break;
5089
5090 /* Logical link is already ready to go */
5091
5092 chan->hs_hcon = hchan->conn;
5093 chan->hs_hcon->l2cap_data = chan->conn;
5094
5095 if (result == L2CAP_MR_SUCCESS) {
5096 /* Can confirm now */
5097 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
5098 } else {
5099 /* Now only need move success
5100 * to confirm
5101 */
5102 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
5103 }
5104
5105 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
5106 break;
5107 default:
5108 /* Any other amp move state means the move failed. */
5109 chan->move_id = chan->local_amp_id;
5110 l2cap_move_done(chan);
5111 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
5112 }
5113
5114 l2cap_chan_unlock(chan);
5115}
5116
5117static void l2cap_move_fail(struct l2cap_conn *conn, u8 ident, u16 icid,
5118 u16 result)
5119{
5120 struct l2cap_chan *chan;
5121
5122 chan = l2cap_get_chan_by_ident(conn, ident);
5123 if (!chan) {
5124 /* Could not locate channel, icid is best guess */
5125 l2cap_send_move_chan_cfm_icid(conn, icid);
5126 return;
5127 }
5128
5129 __clear_chan_timer(chan);
5130
5131 if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
5132 if (result == L2CAP_MR_COLLISION) {
5133 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
5134 } else {
5135 /* Cleanup - cancel move */
5136 chan->move_id = chan->local_amp_id;
5137 l2cap_move_done(chan);
5138 }
5139 }
5140
5141 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
5142
5143 l2cap_chan_unlock(chan);
5144}
5145
5146static int l2cap_move_channel_rsp(struct l2cap_conn *conn,
5147 struct l2cap_cmd_hdr *cmd,
5148 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005149{
5150 struct l2cap_move_chan_rsp *rsp = data;
5151 u16 icid, result;
5152
5153 if (cmd_len != sizeof(*rsp))
5154 return -EPROTO;
5155
5156 icid = le16_to_cpu(rsp->icid);
5157 result = le16_to_cpu(rsp->result);
5158
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005159 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005160
Mat Martineau5b155ef2012-10-23 15:24:14 -07005161 if (result == L2CAP_MR_SUCCESS || result == L2CAP_MR_PEND)
5162 l2cap_move_continue(conn, icid, result);
5163 else
5164 l2cap_move_fail(conn, cmd->ident, icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005165
5166 return 0;
5167}
5168
Mat Martineau5f3847a2012-10-23 15:24:12 -07005169static int l2cap_move_channel_confirm(struct l2cap_conn *conn,
5170 struct l2cap_cmd_hdr *cmd,
5171 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005172{
5173 struct l2cap_move_chan_cfm *cfm = data;
Mat Martineau5f3847a2012-10-23 15:24:12 -07005174 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005175 u16 icid, result;
5176
5177 if (cmd_len != sizeof(*cfm))
5178 return -EPROTO;
5179
5180 icid = le16_to_cpu(cfm->icid);
5181 result = le16_to_cpu(cfm->result);
5182
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005183 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005184
Mat Martineau5f3847a2012-10-23 15:24:12 -07005185 chan = l2cap_get_chan_by_dcid(conn, icid);
5186 if (!chan) {
5187 /* Spec requires a response even if the icid was not found */
5188 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
5189 return 0;
5190 }
5191
5192 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM) {
5193 if (result == L2CAP_MC_CONFIRMED) {
5194 chan->local_amp_id = chan->move_id;
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07005195 if (chan->local_amp_id == AMP_ID_BREDR)
Mat Martineau5f3847a2012-10-23 15:24:12 -07005196 __release_logical_link(chan);
5197 } else {
5198 chan->move_id = chan->local_amp_id;
5199 }
5200
5201 l2cap_move_done(chan);
5202 }
5203
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005204 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
5205
Mat Martineau5f3847a2012-10-23 15:24:12 -07005206 l2cap_chan_unlock(chan);
5207
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005208 return 0;
5209}
5210
5211static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005212 struct l2cap_cmd_hdr *cmd,
5213 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005214{
5215 struct l2cap_move_chan_cfm_rsp *rsp = data;
Mat Martineau3fd71a02012-10-23 15:24:16 -07005216 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005217 u16 icid;
5218
5219 if (cmd_len != sizeof(*rsp))
5220 return -EPROTO;
5221
5222 icid = le16_to_cpu(rsp->icid);
5223
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005224 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005225
Mat Martineau3fd71a02012-10-23 15:24:16 -07005226 chan = l2cap_get_chan_by_scid(conn, icid);
5227 if (!chan)
5228 return 0;
5229
5230 __clear_chan_timer(chan);
5231
5232 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM_RSP) {
5233 chan->local_amp_id = chan->move_id;
5234
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07005235 if (chan->local_amp_id == AMP_ID_BREDR && chan->hs_hchan)
Mat Martineau3fd71a02012-10-23 15:24:16 -07005236 __release_logical_link(chan);
5237
5238 l2cap_move_done(chan);
5239 }
5240
5241 l2cap_chan_unlock(chan);
5242
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005243 return 0;
5244}
5245
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03005246static inline int l2cap_check_conn_param(u16 min, u16 max, u16 latency,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005247 u16 to_multiplier)
Claudio Takahaside731152011-02-11 19:28:55 -02005248{
5249 u16 max_latency;
5250
5251 if (min > max || min < 6 || max > 3200)
5252 return -EINVAL;
5253
5254 if (to_multiplier < 10 || to_multiplier > 3200)
5255 return -EINVAL;
5256
5257 if (max >= to_multiplier * 8)
5258 return -EINVAL;
5259
5260 max_latency = (to_multiplier * 8 / max) - 1;
5261 if (latency > 499 || latency > max_latency)
5262 return -EINVAL;
5263
5264 return 0;
5265}
5266
5267static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005268 struct l2cap_cmd_hdr *cmd,
Johan Hedberg203e6392013-05-15 10:07:15 +03005269 u16 cmd_len, u8 *data)
Claudio Takahaside731152011-02-11 19:28:55 -02005270{
5271 struct hci_conn *hcon = conn->hcon;
5272 struct l2cap_conn_param_update_req *req;
5273 struct l2cap_conn_param_update_rsp rsp;
Johan Hedberg203e6392013-05-15 10:07:15 +03005274 u16 min, max, latency, to_multiplier;
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005275 int err;
Claudio Takahaside731152011-02-11 19:28:55 -02005276
5277 if (!(hcon->link_mode & HCI_LM_MASTER))
5278 return -EINVAL;
5279
Claudio Takahaside731152011-02-11 19:28:55 -02005280 if (cmd_len != sizeof(struct l2cap_conn_param_update_req))
5281 return -EPROTO;
5282
5283 req = (struct l2cap_conn_param_update_req *) data;
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03005284 min = __le16_to_cpu(req->min);
5285 max = __le16_to_cpu(req->max);
Claudio Takahaside731152011-02-11 19:28:55 -02005286 latency = __le16_to_cpu(req->latency);
5287 to_multiplier = __le16_to_cpu(req->to_multiplier);
5288
5289 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 +01005290 min, max, latency, to_multiplier);
Claudio Takahaside731152011-02-11 19:28:55 -02005291
5292 memset(&rsp, 0, sizeof(rsp));
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005293
5294 err = l2cap_check_conn_param(min, max, latency, to_multiplier);
5295 if (err)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005296 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
Claudio Takahaside731152011-02-11 19:28:55 -02005297 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005298 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED);
Claudio Takahaside731152011-02-11 19:28:55 -02005299
5300 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005301 sizeof(rsp), &rsp);
Claudio Takahaside731152011-02-11 19:28:55 -02005302
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005303 if (!err)
5304 hci_le_conn_update(hcon, min, max, latency, to_multiplier);
5305
Claudio Takahaside731152011-02-11 19:28:55 -02005306 return 0;
5307}
5308
Johan Hedbergf1496de2013-05-13 14:15:56 +03005309static int l2cap_le_connect_rsp(struct l2cap_conn *conn,
5310 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5311 u8 *data)
5312{
5313 struct l2cap_le_conn_rsp *rsp = (struct l2cap_le_conn_rsp *) data;
5314 u16 dcid, mtu, mps, credits, result;
5315 struct l2cap_chan *chan;
5316 int err;
5317
5318 if (cmd_len < sizeof(*rsp))
5319 return -EPROTO;
5320
5321 dcid = __le16_to_cpu(rsp->dcid);
5322 mtu = __le16_to_cpu(rsp->mtu);
5323 mps = __le16_to_cpu(rsp->mps);
5324 credits = __le16_to_cpu(rsp->credits);
5325 result = __le16_to_cpu(rsp->result);
5326
5327 if (result == L2CAP_CR_SUCCESS && (mtu < 23 || mps < 23))
5328 return -EPROTO;
5329
5330 BT_DBG("dcid 0x%4.4x mtu %u mps %u credits %u result 0x%2.2x",
5331 dcid, mtu, mps, credits, result);
5332
5333 mutex_lock(&conn->chan_lock);
5334
5335 chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
5336 if (!chan) {
5337 err = -EBADSLT;
5338 goto unlock;
5339 }
5340
5341 err = 0;
5342
5343 l2cap_chan_lock(chan);
5344
5345 switch (result) {
5346 case L2CAP_CR_SUCCESS:
5347 chan->ident = 0;
5348 chan->dcid = dcid;
5349 chan->omtu = mtu;
5350 chan->remote_mps = mps;
Johan Hedberg0cd75f72013-05-17 13:09:05 +03005351 chan->tx_credits = credits;
Johan Hedbergf1496de2013-05-13 14:15:56 +03005352 l2cap_chan_ready(chan);
5353 break;
5354
5355 default:
5356 l2cap_chan_del(chan, ECONNREFUSED);
5357 break;
5358 }
5359
5360 l2cap_chan_unlock(chan);
5361
5362unlock:
5363 mutex_unlock(&conn->chan_lock);
5364
5365 return err;
5366}
5367
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005368static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005369 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5370 u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005371{
5372 int err = 0;
5373
5374 switch (cmd->code) {
5375 case L2CAP_COMMAND_REJ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005376 l2cap_command_rej(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005377 break;
5378
5379 case L2CAP_CONN_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005380 err = l2cap_connect_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005381 break;
5382
5383 case L2CAP_CONN_RSP:
Mat Martineauf5a25982012-10-11 17:48:21 +03005384 case L2CAP_CREATE_CHAN_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005385 l2cap_connect_create_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005386 break;
5387
5388 case L2CAP_CONF_REQ:
5389 err = l2cap_config_req(conn, cmd, cmd_len, data);
5390 break;
5391
5392 case L2CAP_CONF_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005393 l2cap_config_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005394 break;
5395
5396 case L2CAP_DISCONN_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005397 err = l2cap_disconnect_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005398 break;
5399
5400 case L2CAP_DISCONN_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005401 l2cap_disconnect_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005402 break;
5403
5404 case L2CAP_ECHO_REQ:
5405 l2cap_send_cmd(conn, cmd->ident, L2CAP_ECHO_RSP, cmd_len, data);
5406 break;
5407
5408 case L2CAP_ECHO_RSP:
5409 break;
5410
5411 case L2CAP_INFO_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005412 err = l2cap_information_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005413 break;
5414
5415 case L2CAP_INFO_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005416 l2cap_information_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005417 break;
5418
Mat Martineauf94ff6f2011-11-02 16:18:32 -07005419 case L2CAP_CREATE_CHAN_REQ:
5420 err = l2cap_create_channel_req(conn, cmd, cmd_len, data);
5421 break;
5422
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005423 case L2CAP_MOVE_CHAN_REQ:
5424 err = l2cap_move_channel_req(conn, cmd, cmd_len, data);
5425 break;
5426
5427 case L2CAP_MOVE_CHAN_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005428 l2cap_move_channel_rsp(conn, cmd, cmd_len, data);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005429 break;
5430
5431 case L2CAP_MOVE_CHAN_CFM:
5432 err = l2cap_move_channel_confirm(conn, cmd, cmd_len, data);
5433 break;
5434
5435 case L2CAP_MOVE_CHAN_CFM_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005436 l2cap_move_channel_confirm_rsp(conn, cmd, cmd_len, data);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005437 break;
5438
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005439 default:
5440 BT_ERR("Unknown BR/EDR signaling command 0x%2.2x", cmd->code);
5441 err = -EINVAL;
5442 break;
5443 }
5444
5445 return err;
5446}
5447
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005448static int l2cap_le_connect_req(struct l2cap_conn *conn,
5449 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5450 u8 *data)
5451{
5452 struct l2cap_le_conn_req *req = (struct l2cap_le_conn_req *) data;
5453 struct l2cap_le_conn_rsp rsp;
5454 struct l2cap_chan *chan, *pchan;
Johan Hedberg0cd75f72013-05-17 13:09:05 +03005455 u16 dcid, scid, credits, mtu, mps;
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005456 __le16 psm;
5457 u8 result;
5458
5459 if (cmd_len != sizeof(*req))
5460 return -EPROTO;
5461
5462 scid = __le16_to_cpu(req->scid);
5463 mtu = __le16_to_cpu(req->mtu);
5464 mps = __le16_to_cpu(req->mps);
5465 psm = req->psm;
5466 dcid = 0;
Johan Hedberg0cd75f72013-05-17 13:09:05 +03005467 credits = 0;
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005468
5469 if (mtu < 23 || mps < 23)
5470 return -EPROTO;
5471
5472 BT_DBG("psm 0x%2.2x scid 0x%4.4x mtu %u mps %u", __le16_to_cpu(psm),
5473 scid, mtu, mps);
5474
5475 /* Check if we have socket listening on psm */
5476 pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, &conn->hcon->src,
5477 &conn->hcon->dst, LE_LINK);
5478 if (!pchan) {
5479 result = L2CAP_CR_BAD_PSM;
5480 chan = NULL;
5481 goto response;
5482 }
5483
5484 mutex_lock(&conn->chan_lock);
5485 l2cap_chan_lock(pchan);
5486
5487 if (!smp_sufficient_security(conn->hcon, pchan->sec_level)) {
5488 result = L2CAP_CR_AUTHENTICATION;
5489 chan = NULL;
5490 goto response_unlock;
5491 }
5492
5493 /* Check if we already have channel with that dcid */
5494 if (__l2cap_get_chan_by_dcid(conn, scid)) {
5495 result = L2CAP_CR_NO_MEM;
5496 chan = NULL;
5497 goto response_unlock;
5498 }
5499
5500 chan = pchan->ops->new_connection(pchan);
5501 if (!chan) {
5502 result = L2CAP_CR_NO_MEM;
5503 goto response_unlock;
5504 }
5505
5506 bacpy(&chan->src, &conn->hcon->src);
5507 bacpy(&chan->dst, &conn->hcon->dst);
5508 chan->src_type = bdaddr_type(conn->hcon, conn->hcon->src_type);
5509 chan->dst_type = bdaddr_type(conn->hcon, conn->hcon->dst_type);
5510 chan->psm = psm;
5511 chan->dcid = scid;
5512 chan->omtu = mtu;
5513 chan->remote_mps = mps;
Johan Hedberg0cd75f72013-05-17 13:09:05 +03005514 chan->tx_credits = __le16_to_cpu(req->credits);
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005515
5516 __l2cap_chan_add(conn, chan);
5517 dcid = chan->scid;
Johan Hedberg0cd75f72013-05-17 13:09:05 +03005518 credits = chan->rx_credits;
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005519
5520 __set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
5521
5522 chan->ident = cmd->ident;
5523
5524 if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
5525 l2cap_state_change(chan, BT_CONNECT2);
5526 result = L2CAP_CR_PEND;
5527 chan->ops->defer(chan);
5528 } else {
5529 l2cap_chan_ready(chan);
5530 result = L2CAP_CR_SUCCESS;
5531 }
5532
5533response_unlock:
5534 l2cap_chan_unlock(pchan);
5535 mutex_unlock(&conn->chan_lock);
5536
5537 if (result == L2CAP_CR_PEND)
5538 return 0;
5539
5540response:
5541 if (chan) {
5542 rsp.mtu = cpu_to_le16(chan->imtu);
5543 rsp.mps = __constant_cpu_to_le16(L2CAP_LE_DEFAULT_MPS);
5544 } else {
5545 rsp.mtu = 0;
5546 rsp.mps = 0;
5547 }
5548
5549 rsp.dcid = cpu_to_le16(dcid);
Johan Hedberg0cd75f72013-05-17 13:09:05 +03005550 rsp.credits = cpu_to_le16(credits);
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005551 rsp.result = cpu_to_le16(result);
5552
5553 l2cap_send_cmd(conn, cmd->ident, L2CAP_LE_CONN_RSP, sizeof(rsp), &rsp);
5554
5555 return 0;
5556}
5557
Johan Hedbergfad5fc82013-12-05 09:45:01 +02005558static inline int l2cap_le_credits(struct l2cap_conn *conn,
5559 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5560 u8 *data)
5561{
5562 struct l2cap_le_credits *pkt;
5563 struct l2cap_chan *chan;
5564 u16 cid, credits;
5565
5566 if (cmd_len != sizeof(*pkt))
5567 return -EPROTO;
5568
5569 pkt = (struct l2cap_le_credits *) data;
5570 cid = __le16_to_cpu(pkt->cid);
5571 credits = __le16_to_cpu(pkt->credits);
5572
5573 BT_DBG("cid 0x%4.4x credits 0x%4.4x", cid, credits);
5574
5575 chan = l2cap_get_chan_by_dcid(conn, cid);
5576 if (!chan)
5577 return -EBADSLT;
5578
5579 chan->tx_credits += credits;
5580
5581 while (chan->tx_credits && !skb_queue_empty(&chan->tx_q)) {
5582 l2cap_do_send(chan, skb_dequeue(&chan->tx_q));
5583 chan->tx_credits--;
5584 }
5585
5586 if (chan->tx_credits)
5587 chan->ops->resume(chan);
5588
5589 l2cap_chan_unlock(chan);
5590
5591 return 0;
5592}
5593
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005594static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn,
Johan Hedberg203e6392013-05-15 10:07:15 +03005595 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5596 u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005597{
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005598 int err = 0;
5599
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005600 switch (cmd->code) {
5601 case L2CAP_COMMAND_REJ:
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005602 break;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005603
5604 case L2CAP_CONN_PARAM_UPDATE_REQ:
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005605 err = l2cap_conn_param_update_req(conn, cmd, cmd_len, data);
5606 break;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005607
5608 case L2CAP_CONN_PARAM_UPDATE_RSP:
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005609 break;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005610
Johan Hedbergf1496de2013-05-13 14:15:56 +03005611 case L2CAP_LE_CONN_RSP:
5612 l2cap_le_connect_rsp(conn, cmd, cmd_len, data);
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005613 break;
Johan Hedbergf1496de2013-05-13 14:15:56 +03005614
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005615 case L2CAP_LE_CONN_REQ:
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005616 err = l2cap_le_connect_req(conn, cmd, cmd_len, data);
5617 break;
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005618
Johan Hedbergfad5fc82013-12-05 09:45:01 +02005619 case L2CAP_LE_CREDITS:
5620 err = l2cap_le_credits(conn, cmd, cmd_len, data);
5621 break;
5622
Johan Hedberg3defe012013-05-15 10:16:06 +03005623 case L2CAP_DISCONN_REQ:
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005624 err = l2cap_disconnect_req(conn, cmd, cmd_len, data);
5625 break;
Johan Hedberg3defe012013-05-15 10:16:06 +03005626
5627 case L2CAP_DISCONN_RSP:
5628 l2cap_disconnect_rsp(conn, cmd, cmd_len, data);
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005629 break;
Johan Hedberg3defe012013-05-15 10:16:06 +03005630
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005631 default:
5632 BT_ERR("Unknown LE signaling command 0x%2.2x", cmd->code);
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005633 err = -EINVAL;
5634 break;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005635 }
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005636
5637 return err;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005638}
5639
Johan Hedbergc5623552013-04-29 19:35:33 +03005640static inline void l2cap_le_sig_channel(struct l2cap_conn *conn,
5641 struct sk_buff *skb)
5642{
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005643 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005644 struct l2cap_cmd_hdr *cmd;
5645 u16 len;
Johan Hedbergc5623552013-04-29 19:35:33 +03005646 int err;
5647
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005648 if (hcon->type != LE_LINK)
Marcel Holtmann3b166292013-10-02 08:28:21 -07005649 goto drop;
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005650
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005651 if (skb->len < L2CAP_CMD_HDR_SIZE)
5652 goto drop;
Johan Hedbergc5623552013-04-29 19:35:33 +03005653
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005654 cmd = (void *) skb->data;
5655 skb_pull(skb, L2CAP_CMD_HDR_SIZE);
Johan Hedbergc5623552013-04-29 19:35:33 +03005656
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005657 len = le16_to_cpu(cmd->len);
Johan Hedbergc5623552013-04-29 19:35:33 +03005658
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005659 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd->code, len, cmd->ident);
Johan Hedbergc5623552013-04-29 19:35:33 +03005660
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005661 if (len != skb->len || !cmd->ident) {
5662 BT_DBG("corrupted command");
5663 goto drop;
5664 }
Johan Hedbergc5623552013-04-29 19:35:33 +03005665
Johan Hedberg203e6392013-05-15 10:07:15 +03005666 err = l2cap_le_sig_cmd(conn, cmd, len, skb->data);
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005667 if (err) {
5668 struct l2cap_cmd_rej_unk rej;
Johan Hedbergc5623552013-04-29 19:35:33 +03005669
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005670 BT_ERR("Wrong link type (%d)", err);
Johan Hedbergc5623552013-04-29 19:35:33 +03005671
Johan Hedberga5211492013-10-16 11:20:49 +03005672 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005673 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
5674 sizeof(rej), &rej);
Johan Hedbergc5623552013-04-29 19:35:33 +03005675 }
5676
Marcel Holtmann3b166292013-10-02 08:28:21 -07005677drop:
Johan Hedbergc5623552013-04-29 19:35:33 +03005678 kfree_skb(skb);
5679}
5680
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005681static inline void l2cap_sig_channel(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005682 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005683{
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005684 struct hci_conn *hcon = conn->hcon;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005685 u8 *data = skb->data;
5686 int len = skb->len;
5687 struct l2cap_cmd_hdr cmd;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005688 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005689
5690 l2cap_raw_recv(conn, skb);
5691
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005692 if (hcon->type != ACL_LINK)
Marcel Holtmann3b166292013-10-02 08:28:21 -07005693 goto drop;
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005694
Linus Torvalds1da177e2005-04-16 15:20:36 -07005695 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07005696 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005697 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
5698 data += L2CAP_CMD_HDR_SIZE;
5699 len -= L2CAP_CMD_HDR_SIZE;
5700
Al Viro88219a02007-07-29 00:17:25 -07005701 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005702
Gustavo Padovan2d792812012-10-06 10:07:01 +01005703 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len,
5704 cmd.ident);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005705
Al Viro88219a02007-07-29 00:17:25 -07005706 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005707 BT_DBG("corrupted command");
5708 break;
5709 }
5710
Johan Hedbergc5623552013-04-29 19:35:33 +03005711 err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005712 if (err) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03005713 struct l2cap_cmd_rej_unk rej;
Gustavo F. Padovan2c6d1a22011-03-23 14:38:32 -03005714
5715 BT_ERR("Wrong link type (%d)", err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005716
Johan Hedberga5211492013-10-16 11:20:49 +03005717 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
Gustavo Padovan2d792812012-10-06 10:07:01 +01005718 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ,
5719 sizeof(rej), &rej);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005720 }
5721
Al Viro88219a02007-07-29 00:17:25 -07005722 data += cmd_len;
5723 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005724 }
5725
Marcel Holtmann3b166292013-10-02 08:28:21 -07005726drop:
Linus Torvalds1da177e2005-04-16 15:20:36 -07005727 kfree_skb(skb);
5728}
5729
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005730static int l2cap_check_fcs(struct l2cap_chan *chan, struct sk_buff *skb)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005731{
5732 u16 our_fcs, rcv_fcs;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03005733 int hdr_size;
5734
5735 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
5736 hdr_size = L2CAP_EXT_HDR_SIZE;
5737 else
5738 hdr_size = L2CAP_ENH_HDR_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005739
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005740 if (chan->fcs == L2CAP_FCS_CRC16) {
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005741 skb_trim(skb, skb->len - L2CAP_FCS_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005742 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
5743 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
5744
5745 if (our_fcs != rcv_fcs)
João Paulo Rechi Vita7a560e52010-06-22 13:56:27 -03005746 return -EBADMSG;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005747 }
5748 return 0;
5749}
5750
Mat Martineau6ea00482012-05-17 20:53:52 -07005751static void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan)
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005752{
Mat Martineaue31f7632012-05-17 20:53:41 -07005753 struct l2cap_ctrl control;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005754
Mat Martineaue31f7632012-05-17 20:53:41 -07005755 BT_DBG("chan %p", chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005756
Mat Martineaue31f7632012-05-17 20:53:41 -07005757 memset(&control, 0, sizeof(control));
5758 control.sframe = 1;
5759 control.final = 1;
5760 control.reqseq = chan->buffer_seq;
5761 set_bit(CONN_SEND_FBIT, &chan->conn_state);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005762
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03005763 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
Mat Martineaue31f7632012-05-17 20:53:41 -07005764 control.super = L2CAP_SUPER_RNR;
5765 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005766 }
5767
Mat Martineaue31f7632012-05-17 20:53:41 -07005768 if (test_and_clear_bit(CONN_REMOTE_BUSY, &chan->conn_state) &&
5769 chan->unacked_frames > 0)
5770 __set_retrans_timer(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005771
Mat Martineaue31f7632012-05-17 20:53:41 -07005772 /* Send pending iframes */
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03005773 l2cap_ertm_send(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005774
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03005775 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
Mat Martineaue31f7632012-05-17 20:53:41 -07005776 test_bit(CONN_SEND_FBIT, &chan->conn_state)) {
5777 /* F-bit wasn't sent in an s-frame or i-frame yet, so
5778 * send it now.
5779 */
5780 control.super = L2CAP_SUPER_RR;
5781 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005782 }
5783}
5784
Gustavo Padovan2d792812012-10-06 10:07:01 +01005785static void append_skb_frag(struct sk_buff *skb, struct sk_buff *new_frag,
5786 struct sk_buff **last_frag)
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005787{
Mat Martineau84084a32011-07-22 14:54:00 -07005788 /* skb->len reflects data in skb as well as all fragments
5789 * skb->data_len reflects only data in fragments
5790 */
5791 if (!skb_has_frag_list(skb))
5792 skb_shinfo(skb)->frag_list = new_frag;
5793
5794 new_frag->next = NULL;
5795
5796 (*last_frag)->next = new_frag;
5797 *last_frag = new_frag;
5798
5799 skb->len += new_frag->len;
5800 skb->data_len += new_frag->len;
5801 skb->truesize += new_frag->truesize;
5802}
5803
Mat Martineau4b51dae92012-05-17 20:53:37 -07005804static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb,
5805 struct l2cap_ctrl *control)
Mat Martineau84084a32011-07-22 14:54:00 -07005806{
5807 int err = -EINVAL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005808
Mat Martineau4b51dae92012-05-17 20:53:37 -07005809 switch (control->sar) {
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005810 case L2CAP_SAR_UNSEGMENTED:
Mat Martineau84084a32011-07-22 14:54:00 -07005811 if (chan->sdu)
5812 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005813
Gustavo Padovan80b98022012-05-27 22:27:51 -03005814 err = chan->ops->recv(chan, skb);
Mat Martineau84084a32011-07-22 14:54:00 -07005815 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005816
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005817 case L2CAP_SAR_START:
Mat Martineau84084a32011-07-22 14:54:00 -07005818 if (chan->sdu)
5819 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005820
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005821 chan->sdu_len = get_unaligned_le16(skb->data);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005822 skb_pull(skb, L2CAP_SDULEN_SIZE);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005823
Mat Martineau84084a32011-07-22 14:54:00 -07005824 if (chan->sdu_len > chan->imtu) {
5825 err = -EMSGSIZE;
5826 break;
5827 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005828
Mat Martineau84084a32011-07-22 14:54:00 -07005829 if (skb->len >= chan->sdu_len)
5830 break;
5831
5832 chan->sdu = skb;
5833 chan->sdu_last_frag = skb;
5834
5835 skb = NULL;
5836 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005837 break;
5838
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005839 case L2CAP_SAR_CONTINUE:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005840 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07005841 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005842
Mat Martineau84084a32011-07-22 14:54:00 -07005843 append_skb_frag(chan->sdu, skb,
5844 &chan->sdu_last_frag);
5845 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005846
Mat Martineau84084a32011-07-22 14:54:00 -07005847 if (chan->sdu->len >= chan->sdu_len)
5848 break;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03005849
Mat Martineau84084a32011-07-22 14:54:00 -07005850 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005851 break;
5852
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005853 case L2CAP_SAR_END:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005854 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07005855 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005856
Mat Martineau84084a32011-07-22 14:54:00 -07005857 append_skb_frag(chan->sdu, skb,
5858 &chan->sdu_last_frag);
5859 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005860
Mat Martineau84084a32011-07-22 14:54:00 -07005861 if (chan->sdu->len != chan->sdu_len)
5862 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005863
Gustavo Padovan80b98022012-05-27 22:27:51 -03005864 err = chan->ops->recv(chan, chan->sdu);
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03005865
Mat Martineau84084a32011-07-22 14:54:00 -07005866 if (!err) {
5867 /* Reassembly complete */
5868 chan->sdu = NULL;
5869 chan->sdu_last_frag = NULL;
5870 chan->sdu_len = 0;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03005871 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005872 break;
5873 }
5874
Mat Martineau84084a32011-07-22 14:54:00 -07005875 if (err) {
5876 kfree_skb(skb);
5877 kfree_skb(chan->sdu);
5878 chan->sdu = NULL;
5879 chan->sdu_last_frag = NULL;
5880 chan->sdu_len = 0;
5881 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005882
Mat Martineau84084a32011-07-22 14:54:00 -07005883 return err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005884}
5885
Mat Martineau32b32732012-10-23 15:24:11 -07005886static int l2cap_resegment(struct l2cap_chan *chan)
5887{
5888 /* Placeholder */
5889 return 0;
5890}
5891
Mat Martineaue3281402011-07-07 09:39:02 -07005892void l2cap_chan_busy(struct l2cap_chan *chan, int busy)
Gustavo F. Padovan712132eb2010-06-21 19:39:50 -03005893{
Mat Martineau61aa4f52012-05-17 20:53:40 -07005894 u8 event;
5895
5896 if (chan->mode != L2CAP_MODE_ERTM)
5897 return;
5898
5899 event = busy ? L2CAP_EV_LOCAL_BUSY_DETECTED : L2CAP_EV_LOCAL_BUSY_CLEAR;
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03005900 l2cap_tx(chan, NULL, NULL, event);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03005901}
5902
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005903static int l2cap_rx_queued_iframes(struct l2cap_chan *chan)
5904{
Mat Martineau63838722012-05-17 20:53:45 -07005905 int err = 0;
5906 /* Pass sequential frames to l2cap_reassemble_sdu()
5907 * until a gap is encountered.
5908 */
5909
5910 BT_DBG("chan %p", chan);
5911
5912 while (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5913 struct sk_buff *skb;
5914 BT_DBG("Searching for skb with txseq %d (queue len %d)",
5915 chan->buffer_seq, skb_queue_len(&chan->srej_q));
5916
5917 skb = l2cap_ertm_seq_in_queue(&chan->srej_q, chan->buffer_seq);
5918
5919 if (!skb)
5920 break;
5921
5922 skb_unlink(skb, &chan->srej_q);
5923 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
5924 err = l2cap_reassemble_sdu(chan, skb, &bt_cb(skb)->control);
5925 if (err)
5926 break;
5927 }
5928
5929 if (skb_queue_empty(&chan->srej_q)) {
5930 chan->rx_state = L2CAP_RX_STATE_RECV;
5931 l2cap_send_ack(chan);
5932 }
5933
5934 return err;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005935}
5936
5937static void l2cap_handle_srej(struct l2cap_chan *chan,
5938 struct l2cap_ctrl *control)
5939{
Mat Martineauf80842a2012-05-17 20:53:46 -07005940 struct sk_buff *skb;
5941
5942 BT_DBG("chan %p, control %p", chan, control);
5943
5944 if (control->reqseq == chan->next_tx_seq) {
5945 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005946 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineauf80842a2012-05-17 20:53:46 -07005947 return;
5948 }
5949
5950 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
5951
5952 if (skb == NULL) {
5953 BT_DBG("Seq %d not available for retransmission",
5954 control->reqseq);
5955 return;
5956 }
5957
5958 if (chan->max_tx != 0 && bt_cb(skb)->control.retries >= chan->max_tx) {
5959 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005960 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineauf80842a2012-05-17 20:53:46 -07005961 return;
5962 }
5963
5964 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5965
5966 if (control->poll) {
5967 l2cap_pass_to_tx(chan, control);
5968
5969 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5970 l2cap_retransmit(chan, control);
5971 l2cap_ertm_send(chan);
5972
5973 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
5974 set_bit(CONN_SREJ_ACT, &chan->conn_state);
5975 chan->srej_save_reqseq = control->reqseq;
5976 }
5977 } else {
5978 l2cap_pass_to_tx_fbit(chan, control);
5979
5980 if (control->final) {
5981 if (chan->srej_save_reqseq != control->reqseq ||
5982 !test_and_clear_bit(CONN_SREJ_ACT,
5983 &chan->conn_state))
5984 l2cap_retransmit(chan, control);
5985 } else {
5986 l2cap_retransmit(chan, control);
5987 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
5988 set_bit(CONN_SREJ_ACT, &chan->conn_state);
5989 chan->srej_save_reqseq = control->reqseq;
5990 }
5991 }
5992 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005993}
5994
5995static void l2cap_handle_rej(struct l2cap_chan *chan,
5996 struct l2cap_ctrl *control)
5997{
Mat Martineaufcd289d2012-05-17 20:53:47 -07005998 struct sk_buff *skb;
5999
6000 BT_DBG("chan %p, control %p", chan, control);
6001
6002 if (control->reqseq == chan->next_tx_seq) {
6003 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006004 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaufcd289d2012-05-17 20:53:47 -07006005 return;
6006 }
6007
6008 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
6009
6010 if (chan->max_tx && skb &&
6011 bt_cb(skb)->control.retries >= chan->max_tx) {
6012 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006013 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaufcd289d2012-05-17 20:53:47 -07006014 return;
6015 }
6016
6017 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6018
6019 l2cap_pass_to_tx(chan, control);
6020
6021 if (control->final) {
6022 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state))
6023 l2cap_retransmit_all(chan, control);
6024 } else {
6025 l2cap_retransmit_all(chan, control);
6026 l2cap_ertm_send(chan);
6027 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F)
6028 set_bit(CONN_REJ_ACT, &chan->conn_state);
6029 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006030}
6031
Mat Martineau4b51dae92012-05-17 20:53:37 -07006032static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq)
6033{
6034 BT_DBG("chan %p, txseq %d", chan, txseq);
6035
6036 BT_DBG("last_acked_seq %d, expected_tx_seq %d", chan->last_acked_seq,
6037 chan->expected_tx_seq);
6038
6039 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
6040 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
Gustavo Padovan2d792812012-10-06 10:07:01 +01006041 chan->tx_win) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07006042 /* See notes below regarding "double poll" and
6043 * invalid packets.
6044 */
6045 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
6046 BT_DBG("Invalid/Ignore - after SREJ");
6047 return L2CAP_TXSEQ_INVALID_IGNORE;
6048 } else {
6049 BT_DBG("Invalid - in window after SREJ sent");
6050 return L2CAP_TXSEQ_INVALID;
6051 }
6052 }
6053
6054 if (chan->srej_list.head == txseq) {
6055 BT_DBG("Expected SREJ");
6056 return L2CAP_TXSEQ_EXPECTED_SREJ;
6057 }
6058
6059 if (l2cap_ertm_seq_in_queue(&chan->srej_q, txseq)) {
6060 BT_DBG("Duplicate SREJ - txseq already stored");
6061 return L2CAP_TXSEQ_DUPLICATE_SREJ;
6062 }
6063
6064 if (l2cap_seq_list_contains(&chan->srej_list, txseq)) {
6065 BT_DBG("Unexpected SREJ - not requested");
6066 return L2CAP_TXSEQ_UNEXPECTED_SREJ;
6067 }
6068 }
6069
6070 if (chan->expected_tx_seq == txseq) {
6071 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
6072 chan->tx_win) {
6073 BT_DBG("Invalid - txseq outside tx window");
6074 return L2CAP_TXSEQ_INVALID;
6075 } else {
6076 BT_DBG("Expected");
6077 return L2CAP_TXSEQ_EXPECTED;
6078 }
6079 }
6080
6081 if (__seq_offset(chan, txseq, chan->last_acked_seq) <
Gustavo Padovan2d792812012-10-06 10:07:01 +01006082 __seq_offset(chan, chan->expected_tx_seq, chan->last_acked_seq)) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07006083 BT_DBG("Duplicate - expected_tx_seq later than txseq");
6084 return L2CAP_TXSEQ_DUPLICATE;
6085 }
6086
6087 if (__seq_offset(chan, txseq, chan->last_acked_seq) >= chan->tx_win) {
6088 /* A source of invalid packets is a "double poll" condition,
6089 * where delays cause us to send multiple poll packets. If
6090 * the remote stack receives and processes both polls,
6091 * sequence numbers can wrap around in such a way that a
6092 * resent frame has a sequence number that looks like new data
6093 * with a sequence gap. This would trigger an erroneous SREJ
6094 * request.
6095 *
6096 * Fortunately, this is impossible with a tx window that's
6097 * less than half of the maximum sequence number, which allows
6098 * invalid frames to be safely ignored.
6099 *
6100 * With tx window sizes greater than half of the tx window
6101 * maximum, the frame is invalid and cannot be ignored. This
6102 * causes a disconnect.
6103 */
6104
6105 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
6106 BT_DBG("Invalid/Ignore - txseq outside tx window");
6107 return L2CAP_TXSEQ_INVALID_IGNORE;
6108 } else {
6109 BT_DBG("Invalid - txseq outside tx window");
6110 return L2CAP_TXSEQ_INVALID;
6111 }
6112 } else {
6113 BT_DBG("Unexpected - txseq indicates missing frames");
6114 return L2CAP_TXSEQ_UNEXPECTED;
6115 }
6116}
6117
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006118static int l2cap_rx_state_recv(struct l2cap_chan *chan,
6119 struct l2cap_ctrl *control,
6120 struct sk_buff *skb, u8 event)
6121{
6122 int err = 0;
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006123 bool skb_in_use = false;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006124
6125 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
6126 event);
6127
6128 switch (event) {
6129 case L2CAP_EV_RECV_IFRAME:
6130 switch (l2cap_classify_txseq(chan, control->txseq)) {
6131 case L2CAP_TXSEQ_EXPECTED:
6132 l2cap_pass_to_tx(chan, control);
6133
6134 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
6135 BT_DBG("Busy, discarding expected seq %d",
6136 control->txseq);
6137 break;
6138 }
6139
6140 chan->expected_tx_seq = __next_seq(chan,
6141 control->txseq);
6142
6143 chan->buffer_seq = chan->expected_tx_seq;
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006144 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006145
6146 err = l2cap_reassemble_sdu(chan, skb, control);
6147 if (err)
6148 break;
6149
6150 if (control->final) {
6151 if (!test_and_clear_bit(CONN_REJ_ACT,
6152 &chan->conn_state)) {
6153 control->final = 0;
6154 l2cap_retransmit_all(chan, control);
6155 l2cap_ertm_send(chan);
6156 }
6157 }
6158
6159 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
6160 l2cap_send_ack(chan);
6161 break;
6162 case L2CAP_TXSEQ_UNEXPECTED:
6163 l2cap_pass_to_tx(chan, control);
6164
6165 /* Can't issue SREJ frames in the local busy state.
6166 * Drop this frame, it will be seen as missing
6167 * when local busy is exited.
6168 */
6169 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
6170 BT_DBG("Busy, discarding unexpected seq %d",
6171 control->txseq);
6172 break;
6173 }
6174
6175 /* There was a gap in the sequence, so an SREJ
6176 * must be sent for each missing frame. The
6177 * current frame is stored for later use.
6178 */
6179 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006180 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006181 BT_DBG("Queued %p (queue len %d)", skb,
6182 skb_queue_len(&chan->srej_q));
6183
6184 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
6185 l2cap_seq_list_clear(&chan->srej_list);
6186 l2cap_send_srej(chan, control->txseq);
6187
6188 chan->rx_state = L2CAP_RX_STATE_SREJ_SENT;
6189 break;
6190 case L2CAP_TXSEQ_DUPLICATE:
6191 l2cap_pass_to_tx(chan, control);
6192 break;
6193 case L2CAP_TXSEQ_INVALID_IGNORE:
6194 break;
6195 case L2CAP_TXSEQ_INVALID:
6196 default:
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006197 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006198 break;
6199 }
6200 break;
6201 case L2CAP_EV_RECV_RR:
6202 l2cap_pass_to_tx(chan, control);
6203 if (control->final) {
6204 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6205
Mat Martineaue6a3ee62012-10-23 15:24:22 -07006206 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state) &&
6207 !__chan_is_moving(chan)) {
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006208 control->final = 0;
6209 l2cap_retransmit_all(chan, control);
6210 }
6211
6212 l2cap_ertm_send(chan);
6213 } else if (control->poll) {
6214 l2cap_send_i_or_rr_or_rnr(chan);
6215 } else {
6216 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6217 &chan->conn_state) &&
6218 chan->unacked_frames)
6219 __set_retrans_timer(chan);
6220
6221 l2cap_ertm_send(chan);
6222 }
6223 break;
6224 case L2CAP_EV_RECV_RNR:
6225 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6226 l2cap_pass_to_tx(chan, control);
6227 if (control && control->poll) {
6228 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6229 l2cap_send_rr_or_rnr(chan, 0);
6230 }
6231 __clear_retrans_timer(chan);
6232 l2cap_seq_list_clear(&chan->retrans_list);
6233 break;
6234 case L2CAP_EV_RECV_REJ:
6235 l2cap_handle_rej(chan, control);
6236 break;
6237 case L2CAP_EV_RECV_SREJ:
6238 l2cap_handle_srej(chan, control);
6239 break;
6240 default:
6241 break;
6242 }
6243
6244 if (skb && !skb_in_use) {
6245 BT_DBG("Freeing %p", skb);
6246 kfree_skb(skb);
6247 }
6248
6249 return err;
6250}
6251
6252static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan,
6253 struct l2cap_ctrl *control,
6254 struct sk_buff *skb, u8 event)
6255{
6256 int err = 0;
6257 u16 txseq = control->txseq;
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006258 bool skb_in_use = false;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006259
6260 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
6261 event);
6262
6263 switch (event) {
6264 case L2CAP_EV_RECV_IFRAME:
6265 switch (l2cap_classify_txseq(chan, txseq)) {
6266 case L2CAP_TXSEQ_EXPECTED:
6267 /* Keep frame for reassembly later */
6268 l2cap_pass_to_tx(chan, control);
6269 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006270 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006271 BT_DBG("Queued %p (queue len %d)", skb,
6272 skb_queue_len(&chan->srej_q));
6273
6274 chan->expected_tx_seq = __next_seq(chan, txseq);
6275 break;
6276 case L2CAP_TXSEQ_EXPECTED_SREJ:
6277 l2cap_seq_list_pop(&chan->srej_list);
6278
6279 l2cap_pass_to_tx(chan, control);
6280 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006281 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006282 BT_DBG("Queued %p (queue len %d)", skb,
6283 skb_queue_len(&chan->srej_q));
6284
6285 err = l2cap_rx_queued_iframes(chan);
6286 if (err)
6287 break;
6288
6289 break;
6290 case L2CAP_TXSEQ_UNEXPECTED:
6291 /* Got a frame that can't be reassembled yet.
6292 * Save it for later, and send SREJs to cover
6293 * the missing frames.
6294 */
6295 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006296 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006297 BT_DBG("Queued %p (queue len %d)", skb,
6298 skb_queue_len(&chan->srej_q));
6299
6300 l2cap_pass_to_tx(chan, control);
6301 l2cap_send_srej(chan, control->txseq);
6302 break;
6303 case L2CAP_TXSEQ_UNEXPECTED_SREJ:
6304 /* This frame was requested with an SREJ, but
6305 * some expected retransmitted frames are
6306 * missing. Request retransmission of missing
6307 * SREJ'd frames.
6308 */
6309 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006310 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006311 BT_DBG("Queued %p (queue len %d)", skb,
6312 skb_queue_len(&chan->srej_q));
6313
6314 l2cap_pass_to_tx(chan, control);
6315 l2cap_send_srej_list(chan, control->txseq);
6316 break;
6317 case L2CAP_TXSEQ_DUPLICATE_SREJ:
6318 /* We've already queued this frame. Drop this copy. */
6319 l2cap_pass_to_tx(chan, control);
6320 break;
6321 case L2CAP_TXSEQ_DUPLICATE:
6322 /* Expecting a later sequence number, so this frame
6323 * was already received. Ignore it completely.
6324 */
6325 break;
6326 case L2CAP_TXSEQ_INVALID_IGNORE:
6327 break;
6328 case L2CAP_TXSEQ_INVALID:
6329 default:
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006330 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006331 break;
6332 }
6333 break;
6334 case L2CAP_EV_RECV_RR:
6335 l2cap_pass_to_tx(chan, control);
6336 if (control->final) {
6337 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6338
6339 if (!test_and_clear_bit(CONN_REJ_ACT,
6340 &chan->conn_state)) {
6341 control->final = 0;
6342 l2cap_retransmit_all(chan, control);
6343 }
6344
6345 l2cap_ertm_send(chan);
6346 } else if (control->poll) {
6347 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6348 &chan->conn_state) &&
6349 chan->unacked_frames) {
6350 __set_retrans_timer(chan);
6351 }
6352
6353 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6354 l2cap_send_srej_tail(chan);
6355 } else {
6356 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6357 &chan->conn_state) &&
6358 chan->unacked_frames)
6359 __set_retrans_timer(chan);
6360
6361 l2cap_send_ack(chan);
6362 }
6363 break;
6364 case L2CAP_EV_RECV_RNR:
6365 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6366 l2cap_pass_to_tx(chan, control);
6367 if (control->poll) {
6368 l2cap_send_srej_tail(chan);
6369 } else {
6370 struct l2cap_ctrl rr_control;
6371 memset(&rr_control, 0, sizeof(rr_control));
6372 rr_control.sframe = 1;
6373 rr_control.super = L2CAP_SUPER_RR;
6374 rr_control.reqseq = chan->buffer_seq;
6375 l2cap_send_sframe(chan, &rr_control);
6376 }
6377
6378 break;
6379 case L2CAP_EV_RECV_REJ:
6380 l2cap_handle_rej(chan, control);
6381 break;
6382 case L2CAP_EV_RECV_SREJ:
6383 l2cap_handle_srej(chan, control);
6384 break;
6385 }
6386
6387 if (skb && !skb_in_use) {
6388 BT_DBG("Freeing %p", skb);
6389 kfree_skb(skb);
6390 }
6391
6392 return err;
6393}
6394
Mat Martineau32b32732012-10-23 15:24:11 -07006395static int l2cap_finish_move(struct l2cap_chan *chan)
6396{
6397 BT_DBG("chan %p", chan);
6398
6399 chan->rx_state = L2CAP_RX_STATE_RECV;
6400
6401 if (chan->hs_hcon)
6402 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
6403 else
6404 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
6405
6406 return l2cap_resegment(chan);
6407}
6408
6409static int l2cap_rx_state_wait_p(struct l2cap_chan *chan,
6410 struct l2cap_ctrl *control,
6411 struct sk_buff *skb, u8 event)
6412{
6413 int err;
6414
6415 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
6416 event);
6417
6418 if (!control->poll)
6419 return -EPROTO;
6420
6421 l2cap_process_reqseq(chan, control->reqseq);
6422
6423 if (!skb_queue_empty(&chan->tx_q))
6424 chan->tx_send_head = skb_peek(&chan->tx_q);
6425 else
6426 chan->tx_send_head = NULL;
6427
6428 /* Rewind next_tx_seq to the point expected
6429 * by the receiver.
6430 */
6431 chan->next_tx_seq = control->reqseq;
6432 chan->unacked_frames = 0;
6433
6434 err = l2cap_finish_move(chan);
6435 if (err)
6436 return err;
6437
6438 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6439 l2cap_send_i_or_rr_or_rnr(chan);
6440
6441 if (event == L2CAP_EV_RECV_IFRAME)
6442 return -EPROTO;
6443
6444 return l2cap_rx_state_recv(chan, control, NULL, event);
6445}
6446
6447static int l2cap_rx_state_wait_f(struct l2cap_chan *chan,
6448 struct l2cap_ctrl *control,
6449 struct sk_buff *skb, u8 event)
6450{
6451 int err;
6452
6453 if (!control->final)
6454 return -EPROTO;
6455
6456 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6457
6458 chan->rx_state = L2CAP_RX_STATE_RECV;
6459 l2cap_process_reqseq(chan, control->reqseq);
6460
6461 if (!skb_queue_empty(&chan->tx_q))
6462 chan->tx_send_head = skb_peek(&chan->tx_q);
6463 else
6464 chan->tx_send_head = NULL;
6465
6466 /* Rewind next_tx_seq to the point expected
6467 * by the receiver.
6468 */
6469 chan->next_tx_seq = control->reqseq;
6470 chan->unacked_frames = 0;
6471
6472 if (chan->hs_hcon)
6473 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
6474 else
6475 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
6476
6477 err = l2cap_resegment(chan);
6478
6479 if (!err)
6480 err = l2cap_rx_state_recv(chan, control, skb, event);
6481
6482 return err;
6483}
6484
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006485static bool __valid_reqseq(struct l2cap_chan *chan, u16 reqseq)
6486{
6487 /* Make sure reqseq is for a packet that has been sent but not acked */
6488 u16 unacked;
6489
6490 unacked = __seq_offset(chan, chan->next_tx_seq, chan->expected_ack_seq);
6491 return __seq_offset(chan, chan->next_tx_seq, reqseq) <= unacked;
6492}
6493
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006494static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
6495 struct sk_buff *skb, u8 event)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006496{
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006497 int err = 0;
6498
6499 BT_DBG("chan %p, control %p, skb %p, event %d, state %d", chan,
6500 control, skb, event, chan->rx_state);
6501
6502 if (__valid_reqseq(chan, control->reqseq)) {
6503 switch (chan->rx_state) {
6504 case L2CAP_RX_STATE_RECV:
6505 err = l2cap_rx_state_recv(chan, control, skb, event);
6506 break;
6507 case L2CAP_RX_STATE_SREJ_SENT:
6508 err = l2cap_rx_state_srej_sent(chan, control, skb,
6509 event);
6510 break;
Mat Martineau32b32732012-10-23 15:24:11 -07006511 case L2CAP_RX_STATE_WAIT_P:
6512 err = l2cap_rx_state_wait_p(chan, control, skb, event);
6513 break;
6514 case L2CAP_RX_STATE_WAIT_F:
6515 err = l2cap_rx_state_wait_f(chan, control, skb, event);
6516 break;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006517 default:
6518 /* shut it down */
6519 break;
6520 }
6521 } else {
6522 BT_DBG("Invalid reqseq %d (next_tx_seq %d, expected_ack_seq %d",
6523 control->reqseq, chan->next_tx_seq,
6524 chan->expected_ack_seq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006525 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006526 }
6527
6528 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006529}
6530
6531static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
6532 struct sk_buff *skb)
6533{
Mat Martineau4b51dae92012-05-17 20:53:37 -07006534 int err = 0;
6535
6536 BT_DBG("chan %p, control %p, skb %p, state %d", chan, control, skb,
6537 chan->rx_state);
6538
6539 if (l2cap_classify_txseq(chan, control->txseq) ==
6540 L2CAP_TXSEQ_EXPECTED) {
6541 l2cap_pass_to_tx(chan, control);
6542
6543 BT_DBG("buffer_seq %d->%d", chan->buffer_seq,
6544 __next_seq(chan, chan->buffer_seq));
6545
6546 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
6547
6548 l2cap_reassemble_sdu(chan, skb, control);
6549 } else {
6550 if (chan->sdu) {
6551 kfree_skb(chan->sdu);
6552 chan->sdu = NULL;
6553 }
6554 chan->sdu_last_frag = NULL;
6555 chan->sdu_len = 0;
6556
6557 if (skb) {
6558 BT_DBG("Freeing %p", skb);
6559 kfree_skb(skb);
6560 }
6561 }
6562
6563 chan->last_acked_seq = control->txseq;
6564 chan->expected_tx_seq = __next_seq(chan, control->txseq);
6565
6566 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006567}
6568
6569static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
6570{
6571 struct l2cap_ctrl *control = &bt_cb(skb)->control;
6572 u16 len;
6573 u8 event;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006574
Mat Martineaub76bbd62012-04-11 10:48:43 -07006575 __unpack_control(chan, skb);
6576
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006577 len = skb->len;
6578
6579 /*
6580 * We can just drop the corrupted I-frame here.
6581 * Receiver will miss it and start proper recovery
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006582 * procedures and ask for retransmission.
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006583 */
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006584 if (l2cap_check_fcs(chan, skb))
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006585 goto drop;
6586
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006587 if (!control->sframe && control->sar == L2CAP_SAR_START)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03006588 len -= L2CAP_SDULEN_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006589
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006590 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03006591 len -= L2CAP_FCS_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006592
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006593 if (len > chan->mps) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006594 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006595 goto drop;
6596 }
6597
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006598 if (!control->sframe) {
6599 int err;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006600
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006601 BT_DBG("iframe sar %d, reqseq %d, final %d, txseq %d",
6602 control->sar, control->reqseq, control->final,
6603 control->txseq);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03006604
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006605 /* Validate F-bit - F=0 always valid, F=1 only
6606 * valid in TX WAIT_F
6607 */
6608 if (control->final && chan->tx_state != L2CAP_TX_STATE_WAIT_F)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006609 goto drop;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006610
6611 if (chan->mode != L2CAP_MODE_STREAMING) {
6612 event = L2CAP_EV_RECV_IFRAME;
6613 err = l2cap_rx(chan, control, skb, event);
6614 } else {
6615 err = l2cap_stream_rx(chan, control, skb);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006616 }
6617
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006618 if (err)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006619 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006620 } else {
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006621 const u8 rx_func_to_event[4] = {
6622 L2CAP_EV_RECV_RR, L2CAP_EV_RECV_REJ,
6623 L2CAP_EV_RECV_RNR, L2CAP_EV_RECV_SREJ
6624 };
6625
6626 /* Only I-frames are expected in streaming mode */
6627 if (chan->mode == L2CAP_MODE_STREAMING)
6628 goto drop;
6629
6630 BT_DBG("sframe reqseq %d, final %d, poll %d, super %d",
6631 control->reqseq, control->final, control->poll,
6632 control->super);
6633
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006634 if (len != 0) {
Andrei Emeltchenko1bb166e2012-11-20 17:16:21 +02006635 BT_ERR("Trailing bytes: %d in sframe", len);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006636 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006637 goto drop;
6638 }
6639
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006640 /* Validate F and P bits */
6641 if (control->final && (control->poll ||
6642 chan->tx_state != L2CAP_TX_STATE_WAIT_F))
6643 goto drop;
6644
6645 event = rx_func_to_event[control->super];
6646 if (l2cap_rx(chan, control, skb, event))
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006647 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006648 }
6649
6650 return 0;
6651
6652drop:
6653 kfree_skb(skb);
6654 return 0;
6655}
6656
Johan Hedbergb1c325c2013-12-05 09:43:34 +02006657static void l2cap_chan_le_send_credits(struct l2cap_chan *chan)
6658{
6659 struct l2cap_conn *conn = chan->conn;
6660 struct l2cap_le_credits pkt;
6661 u16 return_credits;
6662
6663 /* We return more credits to the sender only after the amount of
6664 * credits falls below half of the initial amount.
6665 */
6666 if (chan->rx_credits >= (L2CAP_LE_MAX_CREDITS + 1) / 2)
6667 return;
6668
6669 return_credits = L2CAP_LE_MAX_CREDITS - chan->rx_credits;
6670
6671 BT_DBG("chan %p returning %u credits to sender", chan, return_credits);
6672
6673 chan->rx_credits += return_credits;
6674
6675 pkt.cid = cpu_to_le16(chan->scid);
6676 pkt.credits = cpu_to_le16(return_credits);
6677
6678 chan->ident = l2cap_get_ident(conn);
6679
6680 l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CREDITS, sizeof(pkt), &pkt);
6681}
6682
Johan Hedbergfad5fc82013-12-05 09:45:01 +02006683static int l2cap_le_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
6684{
6685 if (!chan->rx_credits)
6686 return -ENOBUFS;
6687
6688 if (chan->imtu < skb->len)
6689 return -ENOBUFS;
6690
6691 chan->rx_credits--;
6692 BT_DBG("rx_credits %u -> %u", chan->rx_credits + 1, chan->rx_credits);
6693
6694 l2cap_chan_le_send_credits(chan);
6695
6696 return chan->ops->recv(chan, skb);
6697}
6698
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006699static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid,
6700 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006701{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006702 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006703
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03006704 chan = l2cap_get_chan_by_scid(conn, cid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006705 if (!chan) {
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006706 if (cid == L2CAP_CID_A2MP) {
6707 chan = a2mp_channel_create(conn, skb);
6708 if (!chan) {
6709 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006710 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006711 }
6712
6713 l2cap_chan_lock(chan);
6714 } else {
6715 BT_DBG("unknown cid 0x%4.4x", cid);
6716 /* Drop packet and return */
6717 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006718 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006719 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006720 }
6721
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03006722 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006723
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03006724 if (chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006725 goto drop;
6726
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006727 switch (chan->mode) {
Johan Hedberg38319712013-05-17 12:49:23 +03006728 case L2CAP_MODE_LE_FLOWCTL:
Johan Hedbergfad5fc82013-12-05 09:45:01 +02006729 if (l2cap_le_data_rcv(chan, skb) < 0)
6730 goto drop;
6731
6732 goto done;
6733
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006734 case L2CAP_MODE_BASIC:
6735 /* If socket recv buffers overflows we drop data here
6736 * which is *bad* because L2CAP has to be reliable.
6737 * But we don't have any other choice. L2CAP doesn't
6738 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006739
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006740 if (chan->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006741 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006742
Gustavo Padovan80b98022012-05-27 22:27:51 -03006743 if (!chan->ops->recv(chan, skb))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006744 goto done;
6745 break;
6746
6747 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03006748 case L2CAP_MODE_STREAMING:
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006749 l2cap_data_rcv(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03006750 goto done;
6751
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006752 default:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006753 BT_DBG("chan %p: bad mode 0x%2.2x", chan, chan->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006754 break;
6755 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006756
6757drop:
6758 kfree_skb(skb);
6759
6760done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006761 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006762}
6763
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03006764static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm,
6765 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006766{
Marcel Holtmannae4fd2d2013-10-03 00:03:39 -07006767 struct hci_conn *hcon = conn->hcon;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006768 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006769
Marcel Holtmannae4fd2d2013-10-03 00:03:39 -07006770 if (hcon->type != ACL_LINK)
6771 goto drop;
6772
Johan Hedbergbf20fd42013-05-14 13:23:13 +03006773 chan = l2cap_global_chan_by_psm(0, psm, &hcon->src, &hcon->dst,
6774 ACL_LINK);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006775 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006776 goto drop;
6777
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02006778 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006779
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03006780 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006781 goto drop;
6782
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03006783 if (chan->imtu < skb->len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006784 goto drop;
6785
Marcel Holtmann2edf8702013-10-13 12:55:29 -07006786 /* Store remote BD_ADDR and PSM for msg_name */
Marcel Holtmann06ae3312013-10-18 03:43:00 -07006787 bacpy(&bt_cb(skb)->bdaddr, &hcon->dst);
Marcel Holtmann2edf8702013-10-13 12:55:29 -07006788 bt_cb(skb)->psm = psm;
6789
Gustavo Padovan80b98022012-05-27 22:27:51 -03006790 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03006791 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006792
6793drop:
6794 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006795}
6796
Marcel Holtmann72f78352013-04-23 00:59:00 -07006797static void l2cap_att_channel(struct l2cap_conn *conn,
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03006798 struct sk_buff *skb)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006799{
Marcel Holtmannb99707d2013-10-03 02:54:11 -07006800 struct hci_conn *hcon = conn->hcon;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006801 struct l2cap_chan *chan;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006802
Marcel Holtmannb99707d2013-10-03 02:54:11 -07006803 if (hcon->type != LE_LINK)
6804 goto drop;
6805
Johan Hedbergaf1c0132013-04-29 19:35:42 +03006806 chan = l2cap_global_chan_by_scid(BT_CONNECTED, L2CAP_CID_ATT,
Marcel Holtmann06ae3312013-10-18 03:43:00 -07006807 &hcon->src, &hcon->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006808 if (!chan)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006809 goto drop;
6810
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02006811 BT_DBG("chan %p, len %d", chan, skb->len);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006812
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07006813 if (hci_blacklist_lookup(hcon->hdev, &hcon->dst, hcon->dst_type))
6814 goto drop;
6815
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03006816 if (chan->imtu < skb->len)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006817 goto drop;
6818
Gustavo Padovan80b98022012-05-27 22:27:51 -03006819 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03006820 return;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006821
6822drop:
6823 kfree_skb(skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006824}
6825
Linus Torvalds1da177e2005-04-16 15:20:36 -07006826static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
6827{
6828 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07006829 u16 cid, len;
6830 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006831
6832 skb_pull(skb, L2CAP_HDR_SIZE);
6833 cid = __le16_to_cpu(lh->cid);
6834 len = __le16_to_cpu(lh->len);
6835
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006836 if (len != skb->len) {
6837 kfree_skb(skb);
6838 return;
6839 }
6840
Linus Torvalds1da177e2005-04-16 15:20:36 -07006841 BT_DBG("len %d, cid 0x%4.4x", len, cid);
6842
6843 switch (cid) {
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03006844 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006845 l2cap_sig_channel(conn, skb);
6846 break;
6847
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03006848 case L2CAP_CID_CONN_LESS:
Andrei Emeltchenko097db762012-03-09 14:16:17 +02006849 psm = get_unaligned((__le16 *) skb->data);
Andrei Emeltchenko0181a702012-05-29 10:04:05 +03006850 skb_pull(skb, L2CAP_PSMLEN_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006851 l2cap_conless_channel(conn, psm, skb);
6852 break;
6853
Johan Hedberg073d1cf2013-04-29 19:35:35 +03006854 case L2CAP_CID_ATT:
Marcel Holtmann72f78352013-04-23 00:59:00 -07006855 l2cap_att_channel(conn, skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006856 break;
6857
Marcel Holtmanna2877622013-10-02 23:46:54 -07006858 case L2CAP_CID_LE_SIGNALING:
6859 l2cap_le_sig_channel(conn, skb);
6860 break;
6861
Anderson Brigliab501d6a2011-06-07 18:46:31 -03006862 case L2CAP_CID_SMP:
6863 if (smp_sig_channel(conn, skb))
6864 l2cap_conn_del(conn->hcon, EACCES);
6865 break;
6866
Linus Torvalds1da177e2005-04-16 15:20:36 -07006867 default:
6868 l2cap_data_channel(conn, cid, skb);
6869 break;
6870 }
6871}
6872
6873/* ---- L2CAP interface with lower layer (HCI) ---- */
6874
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006875int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006876{
6877 int exact = 0, lm1 = 0, lm2 = 0;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006878 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006879
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03006880 BT_DBG("hdev %s, bdaddr %pMR", hdev->name, bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006881
6882 /* Find listening sockets and check their link_mode */
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006883 read_lock(&chan_list_lock);
6884 list_for_each_entry(c, &chan_list, global_l) {
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03006885 if (c->state != BT_LISTEN)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006886 continue;
6887
Marcel Holtmann7eafc592013-10-13 08:12:47 -07006888 if (!bacmp(&c->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006889 lm1 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03006890 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006891 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006892 exact++;
Marcel Holtmann7eafc592013-10-13 08:12:47 -07006893 } else if (!bacmp(&c->src, BDADDR_ANY)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006894 lm2 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03006895 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006896 lm2 |= HCI_LM_MASTER;
6897 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006898 }
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006899 read_unlock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006900
6901 return exact ? lm1 : lm2;
6902}
6903
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03006904void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006905{
Marcel Holtmann01394182006-07-03 10:02:46 +02006906 struct l2cap_conn *conn;
6907
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03006908 BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006909
Linus Torvalds1da177e2005-04-16 15:20:36 -07006910 if (!status) {
Claudio Takahasibaf43252013-04-11 13:55:50 -03006911 conn = l2cap_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006912 if (conn)
6913 l2cap_conn_ready(conn);
Andrei Emeltchenkoba6fc312012-10-31 15:46:26 +02006914 } else {
Joe Perchese1750722011-06-29 18:18:29 -07006915 l2cap_conn_del(hcon, bt_to_errno(status));
Andrei Emeltchenkoba6fc312012-10-31 15:46:26 +02006916 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006917}
6918
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006919int l2cap_disconn_ind(struct hci_conn *hcon)
Marcel Holtmann2950f212009-02-12 14:02:50 +01006920{
6921 struct l2cap_conn *conn = hcon->l2cap_data;
6922
6923 BT_DBG("hcon %p", hcon);
6924
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006925 if (!conn)
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02006926 return HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01006927 return conn->disc_reason;
6928}
6929
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03006930void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006931{
6932 BT_DBG("hcon %p reason %d", hcon, reason);
6933
Joe Perchese1750722011-06-29 18:18:29 -07006934 l2cap_conn_del(hcon, bt_to_errno(reason));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006935}
6936
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006937static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006938{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03006939 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED)
Marcel Holtmann255c7602009-02-04 21:07:19 +01006940 return;
6941
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006942 if (encrypt == 0x00) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006943 if (chan->sec_level == BT_SECURITY_MEDIUM) {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006944 __set_chan_timer(chan, L2CAP_ENC_TIMEOUT);
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006945 } else if (chan->sec_level == BT_SECURITY_HIGH)
Gustavo F. Padovan0f852722011-05-04 19:42:50 -03006946 l2cap_chan_close(chan, ECONNREFUSED);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006947 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006948 if (chan->sec_level == BT_SECURITY_MEDIUM)
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03006949 __clear_chan_timer(chan);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006950 }
6951}
6952
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006953int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006954{
Marcel Holtmann40be4922008-07-14 20:13:50 +02006955 struct l2cap_conn *conn = hcon->l2cap_data;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006956 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006957
Marcel Holtmann01394182006-07-03 10:02:46 +02006958 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006959 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02006960
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03006961 BT_DBG("conn %p status 0x%2.2x encrypt %u", conn, status, encrypt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006962
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03006963 if (hcon->type == LE_LINK) {
Hemant Gupta35d4adcc2012-04-18 14:46:26 +05306964 if (!status && encrypt)
6965 smp_distribute_keys(conn, 0);
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02006966 cancel_delayed_work(&conn->security_timer);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03006967 }
6968
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006969 mutex_lock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006970
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006971 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006972 l2cap_chan_lock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006973
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03006974 BT_DBG("chan %p scid 0x%4.4x state %s", chan, chan->scid,
6975 state_to_string(chan->state));
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006976
Andrei Emeltchenko78eb2f92012-07-19 17:03:47 +03006977 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
6978 l2cap_chan_unlock(chan);
6979 continue;
6980 }
6981
Johan Hedberg073d1cf2013-04-29 19:35:35 +03006982 if (chan->scid == L2CAP_CID_ATT) {
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006983 if (!status && encrypt) {
6984 chan->sec_level = hcon->sec_level;
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02006985 l2cap_chan_ready(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006986 }
6987
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006988 l2cap_chan_unlock(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006989 continue;
6990 }
6991
Andrei Emeltchenko96eff462012-11-15 18:14:53 +02006992 if (!__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006993 l2cap_chan_unlock(chan);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01006994 continue;
6995 }
6996
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03006997 if (!status && (chan->state == BT_CONNECTED ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01006998 chan->state == BT_CONFIG)) {
Marcel Holtmannd97c8992013-10-14 02:53:54 -07006999 chan->ops->resume(chan);
Gustavo F. Padovan43434782011-04-12 18:31:57 -03007000 l2cap_check_encryption(chan, encrypt);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02007001 l2cap_chan_unlock(chan);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02007002 continue;
7003 }
7004
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03007005 if (chan->state == BT_CONNECT) {
Johan Hedberg6d3c15d2013-12-02 22:13:24 +02007006 if (!status)
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03007007 l2cap_start_connection(chan);
Johan Hedberg6d3c15d2013-12-02 22:13:24 +02007008 else
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08007009 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03007010 } else if (chan->state == BT_CONNECT2) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +02007011 struct l2cap_conn_rsp rsp;
Johan Hedbergdf3c3932011-06-14 12:48:19 +03007012 __u16 res, stat;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02007013
7014 if (!status) {
Marcel Holtmannbdc25782013-10-14 02:45:34 -07007015 if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
Johan Hedbergdf3c3932011-06-14 12:48:19 +03007016 res = L2CAP_CR_PEND;
7017 stat = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08007018 chan->ops->defer(chan);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03007019 } else {
Gustavo Padovanacdcabf2013-10-21 14:21:39 -02007020 l2cap_state_change(chan, BT_CONFIG);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03007021 res = L2CAP_CR_SUCCESS;
7022 stat = L2CAP_CS_NO_INFO;
7023 }
Marcel Holtmannb1235d72008-07-14 20:13:54 +02007024 } else {
Gustavo Padovanacdcabf2013-10-21 14:21:39 -02007025 l2cap_state_change(chan, BT_DISCONN);
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08007026 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03007027 res = L2CAP_CR_SEC_BLOCK;
7028 stat = L2CAP_CS_NO_INFO;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02007029 }
7030
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03007031 rsp.scid = cpu_to_le16(chan->dcid);
7032 rsp.dcid = cpu_to_le16(chan->scid);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03007033 rsp.result = cpu_to_le16(res);
7034 rsp.status = cpu_to_le16(stat);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03007035 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01007036 sizeof(rsp), &rsp);
Mat Martineau2d369352012-05-23 14:59:30 -07007037
7038 if (!test_bit(CONF_REQ_SENT, &chan->conf_state) &&
7039 res == L2CAP_CR_SUCCESS) {
7040 char buf[128];
7041 set_bit(CONF_REQ_SENT, &chan->conf_state);
7042 l2cap_send_cmd(conn, l2cap_get_ident(conn),
7043 L2CAP_CONF_REQ,
7044 l2cap_build_conf_req(chan, buf),
7045 buf);
7046 chan->num_conf_req++;
7047 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07007048 }
7049
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02007050 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007051 }
7052
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02007053 mutex_unlock(&conn->chan_lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02007054
Linus Torvalds1da177e2005-04-16 15:20:36 -07007055 return 0;
7056}
7057
Ulisses Furquim686ebf22011-12-21 10:11:33 -02007058int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007059{
7060 struct l2cap_conn *conn = hcon->l2cap_data;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03007061 struct l2cap_hdr *hdr;
7062 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007063
Andrei Emeltchenko1d13a252012-10-15 11:58:41 +03007064 /* For AMP controller do not create l2cap conn */
7065 if (!conn && hcon->hdev->dev_type != HCI_BREDR)
7066 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007067
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02007068 if (!conn)
Claudio Takahasibaf43252013-04-11 13:55:50 -03007069 conn = l2cap_conn_add(hcon);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02007070
7071 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007072 goto drop;
7073
7074 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
7075
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03007076 switch (flags) {
7077 case ACL_START:
7078 case ACL_START_NO_FLUSH:
7079 case ACL_COMPLETE:
Linus Torvalds1da177e2005-04-16 15:20:36 -07007080 if (conn->rx_len) {
7081 BT_ERR("Unexpected start frame (len %d)", skb->len);
7082 kfree_skb(conn->rx_skb);
7083 conn->rx_skb = NULL;
7084 conn->rx_len = 0;
7085 l2cap_conn_unreliable(conn, ECOMM);
7086 }
7087
Andrei Emeltchenkoaae7fe22010-09-15 14:28:43 +03007088 /* Start fragment always begin with Basic L2CAP header */
7089 if (skb->len < L2CAP_HDR_SIZE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07007090 BT_ERR("Frame is too short (len %d)", skb->len);
7091 l2cap_conn_unreliable(conn, ECOMM);
7092 goto drop;
7093 }
7094
7095 hdr = (struct l2cap_hdr *) skb->data;
7096 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
7097
7098 if (len == skb->len) {
7099 /* Complete frame received */
7100 l2cap_recv_frame(conn, skb);
7101 return 0;
7102 }
7103
7104 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
7105
7106 if (skb->len > len) {
7107 BT_ERR("Frame is too long (len %d, expected len %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01007108 skb->len, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007109 l2cap_conn_unreliable(conn, ECOMM);
7110 goto drop;
7111 }
7112
7113 /* Allocate skb for the complete frame (with header) */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03007114 conn->rx_skb = bt_skb_alloc(len, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03007115 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007116 goto drop;
7117
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03007118 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01007119 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007120 conn->rx_len = len - skb->len;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03007121 break;
7122
7123 case ACL_CONT:
Linus Torvalds1da177e2005-04-16 15:20:36 -07007124 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
7125
7126 if (!conn->rx_len) {
7127 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
7128 l2cap_conn_unreliable(conn, ECOMM);
7129 goto drop;
7130 }
7131
7132 if (skb->len > conn->rx_len) {
7133 BT_ERR("Fragment is too long (len %d, expected %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01007134 skb->len, conn->rx_len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007135 kfree_skb(conn->rx_skb);
7136 conn->rx_skb = NULL;
7137 conn->rx_len = 0;
7138 l2cap_conn_unreliable(conn, ECOMM);
7139 goto drop;
7140 }
7141
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03007142 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01007143 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007144 conn->rx_len -= skb->len;
7145
7146 if (!conn->rx_len) {
Johan Hedbergc4e5baf2013-10-10 13:33:37 +02007147 /* Complete frame received. l2cap_recv_frame
7148 * takes ownership of the skb so set the global
7149 * rx_skb pointer to NULL first.
7150 */
7151 struct sk_buff *rx_skb = conn->rx_skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007152 conn->rx_skb = NULL;
Johan Hedbergc4e5baf2013-10-10 13:33:37 +02007153 l2cap_recv_frame(conn, rx_skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007154 }
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03007155 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007156 }
7157
7158drop:
7159 kfree_skb(skb);
7160 return 0;
7161}
7162
Marcel Holtmannaef7d972010-03-21 05:27:45 +01007163static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007164{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007165 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007166
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02007167 read_lock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007168
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007169 list_for_each_entry(c, &chan_list, global_l) {
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +03007170 seq_printf(f, "%pMR %pMR %d %d 0x%4.4x 0x%4.4x %d %d %d %d\n",
Marcel Holtmann7eafc592013-10-13 08:12:47 -07007171 &c->src, &c->dst,
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +03007172 c->state, __le16_to_cpu(c->psm),
7173 c->scid, c->dcid, c->imtu, c->omtu,
7174 c->sec_level, c->mode);
Andrei Emeltchenko61e1b4b2012-01-19 11:19:50 +02007175 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07007176
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02007177 read_unlock(&chan_list_lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08007178
Marcel Holtmannaef7d972010-03-21 05:27:45 +01007179 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007180}
7181
Marcel Holtmannaef7d972010-03-21 05:27:45 +01007182static int l2cap_debugfs_open(struct inode *inode, struct file *file)
7183{
7184 return single_open(file, l2cap_debugfs_show, inode->i_private);
7185}
7186
7187static const struct file_operations l2cap_debugfs_fops = {
7188 .open = l2cap_debugfs_open,
7189 .read = seq_read,
7190 .llseek = seq_lseek,
7191 .release = single_release,
7192};
7193
7194static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007195
Gustavo F. Padovan64274512011-02-07 20:08:52 -02007196int __init l2cap_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007197{
7198 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08007199
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02007200 err = l2cap_init_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07007201 if (err < 0)
7202 return err;
7203
Marcel Holtmann1120e4b2013-10-17 17:24:16 -07007204 if (IS_ERR_OR_NULL(bt_debugfs))
7205 return 0;
7206
7207 l2cap_debugfs = debugfs_create_file("l2cap", 0444, bt_debugfs,
7208 NULL, &l2cap_debugfs_fops);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007209
Linus Torvalds1da177e2005-04-16 15:20:36 -07007210 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007211}
7212
Gustavo F. Padovan64274512011-02-07 20:08:52 -02007213void l2cap_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007214{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01007215 debugfs_remove(l2cap_debugfs);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02007216 l2cap_cleanup_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07007217}
7218
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03007219module_param(disable_ertm, bool, 0644);
7220MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode");