blob: 5941c65728b232a4a16d3c3fee55575923f7ef5c [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{
Johan Hedberge77af752013-10-08 10:31:00 +0200216 u16 cid, dyn_end;
Marcel Holtmann01394182006-07-03 10:02:46 +0200217
Johan Hedberge77af752013-10-08 10:31:00 +0200218 if (conn->hcon->type == LE_LINK)
219 dyn_end = L2CAP_CID_LE_DYN_END;
220 else
221 dyn_end = L2CAP_CID_DYN_END;
222
223 for (cid = L2CAP_CID_DYN_START; cid < dyn_end; cid++) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300224 if (!__l2cap_get_chan_by_scid(conn, cid))
Marcel Holtmann01394182006-07-03 10:02:46 +0200225 return cid;
226 }
227
228 return 0;
229}
230
Gustavo Padovanf93fa272013-10-21 14:21:40 -0200231static void l2cap_state_change(struct l2cap_chan *chan, int state)
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300232{
Andrei Emeltchenko42d2d872012-02-17 11:40:57 +0200233 BT_DBG("chan %p %s -> %s", chan, state_to_string(chan->state),
Gustavo Padovan2d792812012-10-06 10:07:01 +0100234 state_to_string(state));
Gustavo F. Padovanbadaaa02011-11-23 20:11:46 -0200235
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300236 chan->state = state;
Gustavo Padovan53f52122013-10-15 19:24:45 -0300237 chan->ops->state_change(chan, state, 0);
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300238}
239
Gustavo Padovanf8e73012013-10-15 19:24:46 -0300240static inline void l2cap_state_change_and_error(struct l2cap_chan *chan,
241 int state, int err)
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +0200242{
Gustavo Padovanf8e73012013-10-15 19:24:46 -0300243 chan->state = state;
Gustavo Padovan53f52122013-10-15 19:24:45 -0300244 chan->ops->state_change(chan, chan->state, err);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +0200245}
246
247static inline void l2cap_chan_set_err(struct l2cap_chan *chan, int err)
248{
Gustavo Padovanf8e73012013-10-15 19:24:46 -0300249 chan->ops->state_change(chan, chan->state, err);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +0200250}
251
Mat Martineau4239d162012-05-17 20:53:49 -0700252static void __set_retrans_timer(struct l2cap_chan *chan)
253{
254 if (!delayed_work_pending(&chan->monitor_timer) &&
255 chan->retrans_timeout) {
256 l2cap_set_timer(chan, &chan->retrans_timer,
257 msecs_to_jiffies(chan->retrans_timeout));
258 }
259}
260
261static void __set_monitor_timer(struct l2cap_chan *chan)
262{
263 __clear_retrans_timer(chan);
264 if (chan->monitor_timeout) {
265 l2cap_set_timer(chan, &chan->monitor_timer,
266 msecs_to_jiffies(chan->monitor_timeout));
267 }
268}
269
Mat Martineau608bcc62012-05-17 20:53:32 -0700270static struct sk_buff *l2cap_ertm_seq_in_queue(struct sk_buff_head *head,
271 u16 seq)
272{
273 struct sk_buff *skb;
274
275 skb_queue_walk(head, skb) {
276 if (bt_cb(skb)->control.txseq == seq)
277 return skb;
278 }
279
280 return NULL;
281}
282
Mat Martineau3c588192012-04-11 10:48:42 -0700283/* ---- L2CAP sequence number lists ---- */
284
285/* For ERTM, ordered lists of sequence numbers must be tracked for
286 * SREJ requests that are received and for frames that are to be
287 * retransmitted. These seq_list functions implement a singly-linked
288 * list in an array, where membership in the list can also be checked
289 * in constant time. Items can also be added to the tail of the list
290 * and removed from the head in constant time, without further memory
291 * allocs or frees.
292 */
293
294static int l2cap_seq_list_init(struct l2cap_seq_list *seq_list, u16 size)
295{
296 size_t alloc_size, i;
297
298 /* Allocated size is a power of 2 to map sequence numbers
299 * (which may be up to 14 bits) in to a smaller array that is
300 * sized for the negotiated ERTM transmit windows.
301 */
302 alloc_size = roundup_pow_of_two(size);
303
304 seq_list->list = kmalloc(sizeof(u16) * alloc_size, GFP_KERNEL);
305 if (!seq_list->list)
306 return -ENOMEM;
307
308 seq_list->mask = alloc_size - 1;
309 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
310 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
311 for (i = 0; i < alloc_size; i++)
312 seq_list->list[i] = L2CAP_SEQ_LIST_CLEAR;
313
314 return 0;
315}
316
317static inline void l2cap_seq_list_free(struct l2cap_seq_list *seq_list)
318{
319 kfree(seq_list->list);
320}
321
322static inline bool l2cap_seq_list_contains(struct l2cap_seq_list *seq_list,
323 u16 seq)
324{
325 /* Constant-time check for list membership */
326 return seq_list->list[seq & seq_list->mask] != L2CAP_SEQ_LIST_CLEAR;
327}
328
329static u16 l2cap_seq_list_remove(struct l2cap_seq_list *seq_list, u16 seq)
330{
331 u16 mask = seq_list->mask;
332
333 if (seq_list->head == L2CAP_SEQ_LIST_CLEAR) {
334 /* In case someone tries to pop the head of an empty list */
335 return L2CAP_SEQ_LIST_CLEAR;
336 } else if (seq_list->head == seq) {
337 /* Head can be removed in constant time */
338 seq_list->head = seq_list->list[seq & mask];
339 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_CLEAR;
340
341 if (seq_list->head == L2CAP_SEQ_LIST_TAIL) {
342 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
343 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
344 }
345 } else {
346 /* Walk the list to find the sequence number */
347 u16 prev = seq_list->head;
348 while (seq_list->list[prev & mask] != seq) {
349 prev = seq_list->list[prev & mask];
350 if (prev == L2CAP_SEQ_LIST_TAIL)
351 return L2CAP_SEQ_LIST_CLEAR;
352 }
353
354 /* Unlink the number from the list and clear it */
355 seq_list->list[prev & mask] = seq_list->list[seq & mask];
356 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_CLEAR;
357 if (seq_list->tail == seq)
358 seq_list->tail = prev;
359 }
360 return seq;
361}
362
363static inline u16 l2cap_seq_list_pop(struct l2cap_seq_list *seq_list)
364{
365 /* Remove the head in constant time */
366 return l2cap_seq_list_remove(seq_list, seq_list->head);
367}
368
369static void l2cap_seq_list_clear(struct l2cap_seq_list *seq_list)
370{
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300371 u16 i;
Mat Martineau3c588192012-04-11 10:48:42 -0700372
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300373 if (seq_list->head == L2CAP_SEQ_LIST_CLEAR)
374 return;
375
376 for (i = 0; i <= seq_list->mask; i++)
377 seq_list->list[i] = L2CAP_SEQ_LIST_CLEAR;
378
379 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
380 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
Mat Martineau3c588192012-04-11 10:48:42 -0700381}
382
383static void l2cap_seq_list_append(struct l2cap_seq_list *seq_list, u16 seq)
384{
385 u16 mask = seq_list->mask;
386
387 /* All appends happen in constant time */
388
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300389 if (seq_list->list[seq & mask] != L2CAP_SEQ_LIST_CLEAR)
390 return;
Mat Martineau3c588192012-04-11 10:48:42 -0700391
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300392 if (seq_list->tail == L2CAP_SEQ_LIST_CLEAR)
393 seq_list->head = seq;
394 else
395 seq_list->list[seq_list->tail & mask] = seq;
396
397 seq_list->tail = seq;
398 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_TAIL;
Mat Martineau3c588192012-04-11 10:48:42 -0700399}
400
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300401static void l2cap_chan_timeout(struct work_struct *work)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300402{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300403 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100404 chan_timer.work);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200405 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300406 int reason;
407
Andrei Emeltchenkoe05dcc32012-02-17 11:40:56 +0200408 BT_DBG("chan %p state %s", chan, state_to_string(chan->state));
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300409
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200410 mutex_lock(&conn->chan_lock);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200411 l2cap_chan_lock(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300412
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300413 if (chan->state == BT_CONNECTED || chan->state == BT_CONFIG)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300414 reason = ECONNREFUSED;
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300415 else if (chan->state == BT_CONNECT &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100416 chan->sec_level != BT_SECURITY_SDP)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300417 reason = ECONNREFUSED;
418 else
419 reason = ETIMEDOUT;
420
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300421 l2cap_chan_close(chan, reason);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300422
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200423 l2cap_chan_unlock(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300424
Gustavo Padovan80b98022012-05-27 22:27:51 -0300425 chan->ops->close(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200426 mutex_unlock(&conn->chan_lock);
427
Ulisses Furquim371fd832011-12-21 20:02:36 -0200428 l2cap_chan_put(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300429}
430
Gustavo Padovaneef1d9b2012-03-25 13:59:16 -0300431struct l2cap_chan *l2cap_chan_create(void)
Marcel Holtmann01394182006-07-03 10:02:46 +0200432{
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300433 struct l2cap_chan *chan;
Marcel Holtmann01394182006-07-03 10:02:46 +0200434
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300435 chan = kzalloc(sizeof(*chan), GFP_ATOMIC);
436 if (!chan)
437 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200438
Andrei Emeltchenkoc03b3552012-02-21 12:54:56 +0200439 mutex_init(&chan->lock);
440
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200441 write_lock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300442 list_add(&chan->global_l, &chan_list);
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200443 write_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300444
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300445 INIT_DELAYED_WORK(&chan->chan_timer, l2cap_chan_timeout);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300446
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300447 chan->state = BT_OPEN;
448
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530449 kref_init(&chan->kref);
Gustavo F. Padovan71ba0e52011-05-17 14:34:52 -0300450
Mat Martineau28270112012-05-17 21:14:09 -0700451 /* This flag is cleared in l2cap_chan_ready() */
452 set_bit(CONF_NOT_COMPLETE, &chan->conf_state);
453
Gustavo Padovaneef1d9b2012-03-25 13:59:16 -0300454 BT_DBG("chan %p", chan);
Szymon Jancabc545b2011-11-03 16:05:44 +0100455
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300456 return chan;
Marcel Holtmann01394182006-07-03 10:02:46 +0200457}
458
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530459static void l2cap_chan_destroy(struct kref *kref)
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300460{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530461 struct l2cap_chan *chan = container_of(kref, struct l2cap_chan, kref);
462
Jaganath Kanakkassery4af66c62012-07-13 18:17:55 +0530463 BT_DBG("chan %p", chan);
464
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200465 write_lock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300466 list_del(&chan->global_l);
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200467 write_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300468
Jaganath Kanakkassery4af66c62012-07-13 18:17:55 +0530469 kfree(chan);
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300470}
471
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530472void l2cap_chan_hold(struct l2cap_chan *c)
473{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530474 BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->kref.refcount));
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530475
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530476 kref_get(&c->kref);
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530477}
478
479void l2cap_chan_put(struct l2cap_chan *c)
480{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530481 BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->kref.refcount));
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530482
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530483 kref_put(&c->kref, l2cap_chan_destroy);
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530484}
485
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +0300486void l2cap_chan_set_defaults(struct l2cap_chan *chan)
487{
488 chan->fcs = L2CAP_FCS_CRC16;
489 chan->max_tx = L2CAP_DEFAULT_MAX_TX;
490 chan->tx_win = L2CAP_DEFAULT_TX_WINDOW;
491 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
Mat Martineauc20f8e32012-07-10 05:47:07 -0700492 chan->ack_win = L2CAP_DEFAULT_TX_WINDOW;
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +0300493 chan->sec_level = BT_SECURITY_LOW;
494
495 set_bit(FLAG_FORCE_ACTIVE, &chan->flags);
496}
497
Johan Hedberg38319712013-05-17 12:49:23 +0300498void l2cap_le_flowctl_init(struct l2cap_chan *chan)
499{
500 chan->imtu = L2CAP_DEFAULT_MTU;
501 chan->omtu = L2CAP_LE_MIN_MTU;
502 chan->mode = L2CAP_MODE_LE_FLOWCTL;
Johan Hedberg0cd75f72013-05-17 13:09:05 +0300503 chan->tx_credits = 0;
504 chan->rx_credits = L2CAP_LE_MAX_CREDITS;
Johan Hedberg3916aed2013-10-07 15:35:26 +0200505
506 if (chan->imtu < L2CAP_LE_DEFAULT_MPS)
507 chan->mps = chan->imtu;
508 else
509 chan->mps = L2CAP_LE_DEFAULT_MPS;
Johan Hedberg38319712013-05-17 12:49:23 +0300510}
511
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +0300512void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Marcel Holtmann01394182006-07-03 10:02:46 +0200513{
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300514 BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
Andrei Emeltchenko097db762012-03-09 14:16:17 +0200515 __le16_to_cpu(chan->psm), chan->dcid);
Marcel Holtmann01394182006-07-03 10:02:46 +0200516
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +0200517 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +0100518
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300519 chan->conn = conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200520
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200521 switch (chan->chan_type) {
522 case L2CAP_CHAN_CONN_ORIENTED:
Ville Tervob62f3282011-02-10 22:38:50 -0300523 if (conn->hcon->type == LE_LINK) {
Johan Hedbergaeddd072013-10-07 16:15:25 +0200524 if (chan->dcid == L2CAP_CID_ATT) {
525 chan->omtu = L2CAP_DEFAULT_MTU;
Johan Hedberg9f22398c2013-04-29 19:35:38 +0300526 chan->scid = L2CAP_CID_ATT;
Johan Hedbergaeddd072013-10-07 16:15:25 +0200527 } else {
Johan Hedberg9f22398c2013-04-29 19:35:38 +0300528 chan->scid = l2cap_alloc_cid(conn);
Johan Hedbergaeddd072013-10-07 16:15:25 +0200529 }
Ville Tervob62f3282011-02-10 22:38:50 -0300530 } else {
531 /* Alloc CID for connection-oriented socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300532 chan->scid = l2cap_alloc_cid(conn);
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300533 chan->omtu = L2CAP_DEFAULT_MTU;
Ville Tervob62f3282011-02-10 22:38:50 -0300534 }
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200535 break;
536
537 case L2CAP_CHAN_CONN_LESS:
Marcel Holtmann01394182006-07-03 10:02:46 +0200538 /* Connectionless socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300539 chan->scid = L2CAP_CID_CONN_LESS;
540 chan->dcid = L2CAP_CID_CONN_LESS;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300541 chan->omtu = L2CAP_DEFAULT_MTU;
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200542 break;
543
Andrei Emeltchenko416fa752012-05-29 13:59:16 +0300544 case L2CAP_CHAN_CONN_FIX_A2MP:
545 chan->scid = L2CAP_CID_A2MP;
546 chan->dcid = L2CAP_CID_A2MP;
547 chan->omtu = L2CAP_A2MP_DEFAULT_MTU;
548 chan->imtu = L2CAP_A2MP_DEFAULT_MTU;
549 break;
550
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200551 default:
Marcel Holtmann01394182006-07-03 10:02:46 +0200552 /* Raw socket can send/recv signalling messages only */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300553 chan->scid = L2CAP_CID_SIGNALING;
554 chan->dcid = L2CAP_CID_SIGNALING;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300555 chan->omtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann01394182006-07-03 10:02:46 +0200556 }
557
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300558 chan->local_id = L2CAP_BESTEFFORT_ID;
559 chan->local_stype = L2CAP_SERV_BESTEFFORT;
560 chan->local_msdu = L2CAP_DEFAULT_MAX_SDU_SIZE;
561 chan->local_sdu_itime = L2CAP_DEFAULT_SDU_ITIME;
562 chan->local_acc_lat = L2CAP_DEFAULT_ACC_LAT;
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +0300563 chan->local_flush_to = L2CAP_EFS_DEFAULT_FLUSH_TO;
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300564
Ulisses Furquim371fd832011-12-21 20:02:36 -0200565 l2cap_chan_hold(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300566
Johan Hedberg5ee98912013-04-29 19:35:43 +0300567 hci_conn_hold(conn->hcon);
568
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200569 list_add(&chan->list, &conn->chan_l);
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200570}
571
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300572void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200573{
574 mutex_lock(&conn->chan_lock);
575 __l2cap_chan_add(conn, chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200576 mutex_unlock(&conn->chan_lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200577}
578
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300579void l2cap_chan_del(struct l2cap_chan *chan, int err)
Marcel Holtmann01394182006-07-03 10:02:46 +0200580{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300581 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200582
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300583 __clear_chan_timer(chan);
Marcel Holtmann01394182006-07-03 10:02:46 +0200584
Gustavo F. Padovan49208c92011-04-04 15:59:54 -0300585 BT_DBG("chan %p, conn %p, err %d", chan, conn, err);
Marcel Holtmann01394182006-07-03 10:02:46 +0200586
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900587 if (conn) {
Andrei Emeltchenko56f60982012-10-15 11:58:44 +0300588 struct amp_mgr *mgr = conn->hcon->amp_mgr;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300589 /* Delete from channel list */
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200590 list_del(&chan->list);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -0200591
Ulisses Furquim371fd832011-12-21 20:02:36 -0200592 l2cap_chan_put(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300593
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300594 chan->conn = NULL;
Andrei Emeltchenko3cabbfd2012-05-31 11:01:37 +0300595
596 if (chan->chan_type != L2CAP_CHAN_CONN_FIX_A2MP)
David Herrmann76a68ba2013-04-06 20:28:37 +0200597 hci_conn_drop(conn->hcon);
Andrei Emeltchenko56f60982012-10-15 11:58:44 +0300598
599 if (mgr && mgr->bredr_chan == chan)
600 mgr->bredr_chan = NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200601 }
602
Andrei Emeltchenko419e08c2012-10-31 15:46:34 +0200603 if (chan->hs_hchan) {
604 struct hci_chan *hs_hchan = chan->hs_hchan;
605
606 BT_DBG("chan %p disconnect hs_hchan %p", chan, hs_hchan);
607 amp_disconnect_logical_link(hs_hchan);
608 }
609
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100610 chan->ops->teardown(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200611
Mat Martineau28270112012-05-17 21:14:09 -0700612 if (test_bit(CONF_NOT_COMPLETE, &chan->conf_state))
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300613 return;
Gustavo F. Padovan2ead70b2011-04-01 15:13:36 -0300614
Gustavo Padovanee556f62012-05-18 20:22:38 -0300615 switch(chan->mode) {
616 case L2CAP_MODE_BASIC:
617 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300618
Johan Hedberg38319712013-05-17 12:49:23 +0300619 case L2CAP_MODE_LE_FLOWCTL:
Johan Hedberg177f8f22013-05-31 17:54:51 +0300620 skb_queue_purge(&chan->tx_q);
Johan Hedberg38319712013-05-17 12:49:23 +0300621 break;
622
Gustavo Padovanee556f62012-05-18 20:22:38 -0300623 case L2CAP_MODE_ERTM:
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -0300624 __clear_retrans_timer(chan);
625 __clear_monitor_timer(chan);
626 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300627
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -0300628 skb_queue_purge(&chan->srej_q);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300629
Mat Martineau3c588192012-04-11 10:48:42 -0700630 l2cap_seq_list_free(&chan->srej_list);
631 l2cap_seq_list_free(&chan->retrans_list);
Gustavo Padovanee556f62012-05-18 20:22:38 -0300632
633 /* fall through */
634
635 case L2CAP_MODE_STREAMING:
636 skb_queue_purge(&chan->tx_q);
637 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300638 }
Gustavo Padovanee556f62012-05-18 20:22:38 -0300639
640 return;
Marcel Holtmann01394182006-07-03 10:02:46 +0200641}
642
Johan Hedberg27e2d4c2013-05-14 13:27:21 +0300643static void l2cap_chan_le_connect_reject(struct l2cap_chan *chan)
644{
645 struct l2cap_conn *conn = chan->conn;
646 struct l2cap_le_conn_rsp rsp;
647 u16 result;
648
649 if (test_bit(FLAG_DEFER_SETUP, &chan->flags))
650 result = L2CAP_CR_AUTHORIZATION;
651 else
652 result = L2CAP_CR_BAD_PSM;
653
654 l2cap_state_change(chan, BT_DISCONN);
655
656 rsp.dcid = cpu_to_le16(chan->scid);
657 rsp.mtu = cpu_to_le16(chan->imtu);
Johan Hedberg3916aed2013-10-07 15:35:26 +0200658 rsp.mps = cpu_to_le16(chan->mps);
Johan Hedberg0cd75f72013-05-17 13:09:05 +0300659 rsp.credits = cpu_to_le16(chan->rx_credits);
Johan Hedberg27e2d4c2013-05-14 13:27:21 +0300660 rsp.result = cpu_to_le16(result);
661
662 l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CONN_RSP, sizeof(rsp),
663 &rsp);
664}
665
Johan Hedberg791d60f2013-05-14 22:24:44 +0300666static void l2cap_chan_connect_reject(struct l2cap_chan *chan)
667{
668 struct l2cap_conn *conn = chan->conn;
669 struct l2cap_conn_rsp rsp;
670 u16 result;
671
672 if (test_bit(FLAG_DEFER_SETUP, &chan->flags))
673 result = L2CAP_CR_SEC_BLOCK;
674 else
675 result = L2CAP_CR_BAD_PSM;
676
677 l2cap_state_change(chan, BT_DISCONN);
678
679 rsp.scid = cpu_to_le16(chan->dcid);
680 rsp.dcid = cpu_to_le16(chan->scid);
681 rsp.result = cpu_to_le16(result);
682 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
683
684 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
685}
686
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300687void l2cap_chan_close(struct l2cap_chan *chan, int reason)
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300688{
689 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300690
Marcel Holtmann7eafc592013-10-13 08:12:47 -0700691 BT_DBG("chan %p state %s", chan, state_to_string(chan->state));
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300692
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300693 switch (chan->state) {
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300694 case BT_LISTEN:
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100695 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300696 break;
697
698 case BT_CONNECTED:
699 case BT_CONFIG:
Johan Hedbergcea04ce32013-05-14 22:46:01 +0300700 /* ATT uses L2CAP_CHAN_CONN_ORIENTED so we must also
701 * check for chan->psm.
702 */
703 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && chan->psm) {
Gustavo Padovan8d836d72013-10-15 19:24:47 -0300704 __set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +0200705 l2cap_send_disconn_req(chan, reason);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300706 } else
707 l2cap_chan_del(chan, reason);
708 break;
709
710 case BT_CONNECT2:
Johan Hedberg791d60f2013-05-14 22:24:44 +0300711 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED) {
712 if (conn->hcon->type == ACL_LINK)
713 l2cap_chan_connect_reject(chan);
Johan Hedberg27e2d4c2013-05-14 13:27:21 +0300714 else if (conn->hcon->type == LE_LINK)
715 l2cap_chan_le_connect_reject(chan);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300716 }
717
718 l2cap_chan_del(chan, reason);
719 break;
720
721 case BT_CONNECT:
722 case BT_DISCONN:
723 l2cap_chan_del(chan, reason);
724 break;
725
726 default:
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100727 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300728 break;
729 }
730}
731
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300732static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530733{
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700734 switch (chan->chan_type) {
735 case L2CAP_CHAN_RAW:
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300736 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530737 case BT_SECURITY_HIGH:
738 return HCI_AT_DEDICATED_BONDING_MITM;
739 case BT_SECURITY_MEDIUM:
740 return HCI_AT_DEDICATED_BONDING;
741 default:
742 return HCI_AT_NO_BONDING;
743 }
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700744 break;
Marcel Holtmann3124b842013-10-12 07:19:32 -0700745 case L2CAP_CHAN_CONN_LESS:
746 if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_3DSP)) {
747 if (chan->sec_level == BT_SECURITY_LOW)
748 chan->sec_level = BT_SECURITY_SDP;
749 }
750 if (chan->sec_level == BT_SECURITY_HIGH)
751 return HCI_AT_NO_BONDING_MITM;
752 else
753 return HCI_AT_NO_BONDING;
754 break;
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700755 case L2CAP_CHAN_CONN_ORIENTED:
756 if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_SDP)) {
757 if (chan->sec_level == BT_SECURITY_LOW)
758 chan->sec_level = BT_SECURITY_SDP;
Johan Hedberg8556edd32011-01-19 12:06:50 +0530759
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700760 if (chan->sec_level == BT_SECURITY_HIGH)
761 return HCI_AT_NO_BONDING_MITM;
762 else
763 return HCI_AT_NO_BONDING;
764 }
765 /* fall through */
766 default:
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300767 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530768 case BT_SECURITY_HIGH:
769 return HCI_AT_GENERAL_BONDING_MITM;
770 case BT_SECURITY_MEDIUM:
771 return HCI_AT_GENERAL_BONDING;
772 default:
773 return HCI_AT_NO_BONDING;
774 }
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700775 break;
Johan Hedberg8556edd32011-01-19 12:06:50 +0530776 }
777}
778
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200779/* Service level security */
Gustavo F. Padovand45fc422011-11-05 19:54:24 -0200780int l2cap_chan_check_security(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200781{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300782 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100783 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200784
Johan Hedberga17de2f2013-05-14 13:25:37 +0300785 if (conn->hcon->type == LE_LINK)
786 return smp_conn_security(conn->hcon, chan->sec_level);
787
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300788 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100789
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300790 return hci_conn_security(conn->hcon, chan->sec_level, auth_type);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200791}
792
Johannes Bergb5ad8b72011-06-01 08:54:45 +0200793static u8 l2cap_get_ident(struct l2cap_conn *conn)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200794{
795 u8 id;
796
797 /* Get next available identificator.
798 * 1 - 128 are used by kernel.
799 * 129 - 199 are reserved.
800 * 200 - 254 are used by utilities like l2ping, etc.
801 */
802
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200803 spin_lock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200804
805 if (++conn->tx_ident > 128)
806 conn->tx_ident = 1;
807
808 id = conn->tx_ident;
809
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200810 spin_unlock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200811
812 return id;
813}
814
Gustavo Padovan2d792812012-10-06 10:07:01 +0100815static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
816 void *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200817{
818 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200819 u8 flags;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200820
821 BT_DBG("code 0x%2.2x", code);
822
823 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300824 return;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200825
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200826 if (lmp_no_flush_capable(conn->hcon->hdev))
827 flags = ACL_START_NO_FLUSH;
828 else
829 flags = ACL_START;
830
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700831 bt_cb(skb)->force_active = BT_POWER_FORCE_ACTIVE_ON;
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +0200832 skb->priority = HCI_PRIO_MAX;
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700833
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200834 hci_send_acl(conn->hchan, skb, flags);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200835}
836
Mat Martineau02b0fbb2012-10-23 15:24:10 -0700837static bool __chan_is_moving(struct l2cap_chan *chan)
838{
839 return chan->move_state != L2CAP_MOVE_STABLE &&
840 chan->move_state != L2CAP_MOVE_WAIT_PREPARE;
841}
842
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200843static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb)
844{
845 struct hci_conn *hcon = chan->conn->hcon;
846 u16 flags;
847
848 BT_DBG("chan %p, skb %p len %d priority %u", chan, skb, skb->len,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100849 skb->priority);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200850
Mat Martineaud5f8a752012-10-23 15:24:18 -0700851 if (chan->hs_hcon && !__chan_is_moving(chan)) {
852 if (chan->hs_hchan)
853 hci_send_acl(chan->hs_hchan, skb, ACL_COMPLETE);
854 else
855 kfree_skb(skb);
856
857 return;
858 }
859
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200860 if (!test_bit(FLAG_FLUSHABLE, &chan->flags) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100861 lmp_no_flush_capable(hcon->hdev))
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200862 flags = ACL_START_NO_FLUSH;
863 else
864 flags = ACL_START;
865
866 bt_cb(skb)->force_active = test_bit(FLAG_FORCE_ACTIVE, &chan->flags);
867 hci_send_acl(chan->conn->hchan, skb, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700868}
869
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700870static void __unpack_enhanced_control(u16 enh, struct l2cap_ctrl *control)
871{
872 control->reqseq = (enh & L2CAP_CTRL_REQSEQ) >> L2CAP_CTRL_REQSEQ_SHIFT;
873 control->final = (enh & L2CAP_CTRL_FINAL) >> L2CAP_CTRL_FINAL_SHIFT;
874
875 if (enh & L2CAP_CTRL_FRAME_TYPE) {
876 /* S-Frame */
877 control->sframe = 1;
878 control->poll = (enh & L2CAP_CTRL_POLL) >> L2CAP_CTRL_POLL_SHIFT;
879 control->super = (enh & L2CAP_CTRL_SUPERVISE) >> L2CAP_CTRL_SUPER_SHIFT;
880
881 control->sar = 0;
882 control->txseq = 0;
883 } else {
884 /* I-Frame */
885 control->sframe = 0;
886 control->sar = (enh & L2CAP_CTRL_SAR) >> L2CAP_CTRL_SAR_SHIFT;
887 control->txseq = (enh & L2CAP_CTRL_TXSEQ) >> L2CAP_CTRL_TXSEQ_SHIFT;
888
889 control->poll = 0;
890 control->super = 0;
891 }
892}
893
894static void __unpack_extended_control(u32 ext, struct l2cap_ctrl *control)
895{
896 control->reqseq = (ext & L2CAP_EXT_CTRL_REQSEQ) >> L2CAP_EXT_CTRL_REQSEQ_SHIFT;
897 control->final = (ext & L2CAP_EXT_CTRL_FINAL) >> L2CAP_EXT_CTRL_FINAL_SHIFT;
898
899 if (ext & L2CAP_EXT_CTRL_FRAME_TYPE) {
900 /* S-Frame */
901 control->sframe = 1;
902 control->poll = (ext & L2CAP_EXT_CTRL_POLL) >> L2CAP_EXT_CTRL_POLL_SHIFT;
903 control->super = (ext & L2CAP_EXT_CTRL_SUPERVISE) >> L2CAP_EXT_CTRL_SUPER_SHIFT;
904
905 control->sar = 0;
906 control->txseq = 0;
907 } else {
908 /* I-Frame */
909 control->sframe = 0;
910 control->sar = (ext & L2CAP_EXT_CTRL_SAR) >> L2CAP_EXT_CTRL_SAR_SHIFT;
911 control->txseq = (ext & L2CAP_EXT_CTRL_TXSEQ) >> L2CAP_EXT_CTRL_TXSEQ_SHIFT;
912
913 control->poll = 0;
914 control->super = 0;
915 }
916}
917
918static inline void __unpack_control(struct l2cap_chan *chan,
919 struct sk_buff *skb)
920{
921 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
922 __unpack_extended_control(get_unaligned_le32(skb->data),
923 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700924 skb_pull(skb, L2CAP_EXT_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700925 } else {
926 __unpack_enhanced_control(get_unaligned_le16(skb->data),
927 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700928 skb_pull(skb, L2CAP_ENH_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700929 }
930}
931
932static u32 __pack_extended_control(struct l2cap_ctrl *control)
933{
934 u32 packed;
935
936 packed = control->reqseq << L2CAP_EXT_CTRL_REQSEQ_SHIFT;
937 packed |= control->final << L2CAP_EXT_CTRL_FINAL_SHIFT;
938
939 if (control->sframe) {
940 packed |= control->poll << L2CAP_EXT_CTRL_POLL_SHIFT;
941 packed |= control->super << L2CAP_EXT_CTRL_SUPER_SHIFT;
942 packed |= L2CAP_EXT_CTRL_FRAME_TYPE;
943 } else {
944 packed |= control->sar << L2CAP_EXT_CTRL_SAR_SHIFT;
945 packed |= control->txseq << L2CAP_EXT_CTRL_TXSEQ_SHIFT;
946 }
947
948 return packed;
949}
950
951static u16 __pack_enhanced_control(struct l2cap_ctrl *control)
952{
953 u16 packed;
954
955 packed = control->reqseq << L2CAP_CTRL_REQSEQ_SHIFT;
956 packed |= control->final << L2CAP_CTRL_FINAL_SHIFT;
957
958 if (control->sframe) {
959 packed |= control->poll << L2CAP_CTRL_POLL_SHIFT;
960 packed |= control->super << L2CAP_CTRL_SUPER_SHIFT;
961 packed |= L2CAP_CTRL_FRAME_TYPE;
962 } else {
963 packed |= control->sar << L2CAP_CTRL_SAR_SHIFT;
964 packed |= control->txseq << L2CAP_CTRL_TXSEQ_SHIFT;
965 }
966
967 return packed;
968}
969
970static inline void __pack_control(struct l2cap_chan *chan,
971 struct l2cap_ctrl *control,
972 struct sk_buff *skb)
973{
974 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
975 put_unaligned_le32(__pack_extended_control(control),
976 skb->data + L2CAP_HDR_SIZE);
977 } else {
978 put_unaligned_le16(__pack_enhanced_control(control),
979 skb->data + L2CAP_HDR_SIZE);
980 }
981}
982
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300983static inline unsigned int __ertm_hdr_size(struct l2cap_chan *chan)
984{
985 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
986 return L2CAP_EXT_HDR_SIZE;
987 else
988 return L2CAP_ENH_HDR_SIZE;
989}
990
Mat Martineaua67d7f62012-05-17 20:53:35 -0700991static struct sk_buff *l2cap_create_sframe_pdu(struct l2cap_chan *chan,
992 u32 control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300993{
994 struct sk_buff *skb;
995 struct l2cap_hdr *lh;
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300996 int hlen = __ertm_hdr_size(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300997
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300998 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300999 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001000
Mat Martineaua67d7f62012-05-17 20:53:35 -07001001 skb = bt_skb_alloc(hlen, GFP_KERNEL);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001002
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001003 if (!skb)
Mat Martineaua67d7f62012-05-17 20:53:35 -07001004 return ERR_PTR(-ENOMEM);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001005
1006 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001007 lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001008 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03001009
Mat Martineaua67d7f62012-05-17 20:53:35 -07001010 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
1011 put_unaligned_le32(control, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
1012 else
1013 put_unaligned_le16(control, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001014
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001015 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineaua67d7f62012-05-17 20:53:35 -07001016 u16 fcs = crc16(0, (u8 *)skb->data, skb->len);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03001017 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001018 }
1019
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001020 skb->priority = HCI_PRIO_MAX;
Mat Martineaua67d7f62012-05-17 20:53:35 -07001021 return skb;
1022}
1023
1024static void l2cap_send_sframe(struct l2cap_chan *chan,
1025 struct l2cap_ctrl *control)
1026{
1027 struct sk_buff *skb;
1028 u32 control_field;
1029
1030 BT_DBG("chan %p, control %p", chan, control);
1031
1032 if (!control->sframe)
1033 return;
1034
Mat Martineaub99e13a2012-10-23 15:24:19 -07001035 if (__chan_is_moving(chan))
1036 return;
1037
Mat Martineaua67d7f62012-05-17 20:53:35 -07001038 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state) &&
1039 !control->poll)
1040 control->final = 1;
1041
1042 if (control->super == L2CAP_SUPER_RR)
1043 clear_bit(CONN_RNR_SENT, &chan->conn_state);
1044 else if (control->super == L2CAP_SUPER_RNR)
1045 set_bit(CONN_RNR_SENT, &chan->conn_state);
1046
1047 if (control->super != L2CAP_SUPER_SREJ) {
1048 chan->last_acked_seq = control->reqseq;
1049 __clear_ack_timer(chan);
1050 }
1051
1052 BT_DBG("reqseq %d, final %d, poll %d, super %d", control->reqseq,
1053 control->final, control->poll, control->super);
1054
1055 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
1056 control_field = __pack_extended_control(control);
1057 else
1058 control_field = __pack_enhanced_control(control);
1059
1060 skb = l2cap_create_sframe_pdu(chan, control_field);
1061 if (!IS_ERR(skb))
1062 l2cap_do_send(chan, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001063}
1064
Mat Martineauc9e3d5e2012-05-17 20:53:48 -07001065static void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, bool poll)
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001066{
Mat Martineauc9e3d5e2012-05-17 20:53:48 -07001067 struct l2cap_ctrl control;
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001068
Mat Martineauc9e3d5e2012-05-17 20:53:48 -07001069 BT_DBG("chan %p, poll %d", chan, poll);
1070
1071 memset(&control, 0, sizeof(control));
1072 control.sframe = 1;
1073 control.poll = poll;
1074
1075 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
1076 control.super = L2CAP_SUPER_RNR;
1077 else
1078 control.super = L2CAP_SUPER_RR;
1079
1080 control.reqseq = chan->buffer_seq;
1081 l2cap_send_sframe(chan, &control);
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001082}
1083
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03001084static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan)
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03001085{
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001086 return !test_bit(CONF_CONNECT_PEND, &chan->conf_state);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03001087}
1088
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001089static bool __amp_capable(struct l2cap_chan *chan)
1090{
1091 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann1df7b172013-10-05 11:47:49 -07001092 struct hci_dev *hdev;
1093 bool amp_available = false;
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001094
Marcel Holtmann1df7b172013-10-05 11:47:49 -07001095 if (!conn->hs_enabled)
1096 return false;
1097
1098 if (!(conn->fixed_chan_mask & L2CAP_FC_A2MP))
1099 return false;
1100
1101 read_lock(&hci_dev_list_lock);
1102 list_for_each_entry(hdev, &hci_dev_list, list) {
1103 if (hdev->amp_type != AMP_TYPE_BREDR &&
1104 test_bit(HCI_UP, &hdev->flags)) {
1105 amp_available = true;
1106 break;
1107 }
1108 }
1109 read_unlock(&hci_dev_list_lock);
1110
1111 if (chan->chan_policy == BT_CHANNEL_POLICY_AMP_PREFERRED)
1112 return amp_available;
Marcel Holtmann848566b2013-10-01 22:59:22 -07001113
1114 return false;
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001115}
1116
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +02001117static bool l2cap_check_efs(struct l2cap_chan *chan)
1118{
1119 /* Check EFS parameters */
1120 return true;
1121}
1122
Andrei Emeltchenko2766be42012-09-27 17:26:21 +03001123void l2cap_send_conn_req(struct l2cap_chan *chan)
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +02001124{
1125 struct l2cap_conn *conn = chan->conn;
1126 struct l2cap_conn_req req;
1127
1128 req.scid = cpu_to_le16(chan->scid);
1129 req.psm = chan->psm;
1130
1131 chan->ident = l2cap_get_ident(conn);
1132
1133 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
1134
1135 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, sizeof(req), &req);
1136}
1137
Mat Martineau8eb200b2012-10-23 15:24:17 -07001138static void l2cap_send_create_chan_req(struct l2cap_chan *chan, u8 amp_id)
1139{
1140 struct l2cap_create_chan_req req;
1141 req.scid = cpu_to_le16(chan->scid);
1142 req.psm = chan->psm;
1143 req.amp_id = amp_id;
1144
1145 chan->ident = l2cap_get_ident(chan->conn);
1146
1147 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_REQ,
1148 sizeof(req), &req);
1149}
1150
Mat Martineau02b0fbb2012-10-23 15:24:10 -07001151static void l2cap_move_setup(struct l2cap_chan *chan)
1152{
1153 struct sk_buff *skb;
1154
1155 BT_DBG("chan %p", chan);
1156
1157 if (chan->mode != L2CAP_MODE_ERTM)
1158 return;
1159
1160 __clear_retrans_timer(chan);
1161 __clear_monitor_timer(chan);
1162 __clear_ack_timer(chan);
1163
1164 chan->retry_count = 0;
1165 skb_queue_walk(&chan->tx_q, skb) {
1166 if (bt_cb(skb)->control.retries)
1167 bt_cb(skb)->control.retries = 1;
1168 else
1169 break;
1170 }
1171
1172 chan->expected_tx_seq = chan->buffer_seq;
1173
1174 clear_bit(CONN_REJ_ACT, &chan->conn_state);
1175 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
1176 l2cap_seq_list_clear(&chan->retrans_list);
1177 l2cap_seq_list_clear(&chan->srej_list);
1178 skb_queue_purge(&chan->srej_q);
1179
1180 chan->tx_state = L2CAP_TX_STATE_XMIT;
1181 chan->rx_state = L2CAP_RX_STATE_MOVE;
1182
1183 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
1184}
1185
Mat Martineau5f3847a2012-10-23 15:24:12 -07001186static void l2cap_move_done(struct l2cap_chan *chan)
1187{
1188 u8 move_role = chan->move_role;
1189 BT_DBG("chan %p", chan);
1190
1191 chan->move_state = L2CAP_MOVE_STABLE;
1192 chan->move_role = L2CAP_MOVE_ROLE_NONE;
1193
1194 if (chan->mode != L2CAP_MODE_ERTM)
1195 return;
1196
1197 switch (move_role) {
1198 case L2CAP_MOVE_ROLE_INITIATOR:
1199 l2cap_tx(chan, NULL, NULL, L2CAP_EV_EXPLICIT_POLL);
1200 chan->rx_state = L2CAP_RX_STATE_WAIT_F;
1201 break;
1202 case L2CAP_MOVE_ROLE_RESPONDER:
1203 chan->rx_state = L2CAP_RX_STATE_WAIT_P;
1204 break;
1205 }
1206}
1207
Johan Hedberg177f8f22013-05-31 17:54:51 +03001208static void l2cap_le_flowctl_start(struct l2cap_chan *chan)
1209{
1210 chan->sdu = NULL;
1211 chan->sdu_last_frag = NULL;
1212 chan->sdu_len = 0;
1213
Johan Hedberg3916aed2013-10-07 15:35:26 +02001214 if (chan->imtu < L2CAP_LE_DEFAULT_MPS)
1215 chan->mps = chan->imtu;
1216 else
1217 chan->mps = L2CAP_LE_DEFAULT_MPS;
1218
Johan Hedberg177f8f22013-05-31 17:54:51 +03001219 skb_queue_head_init(&chan->tx_q);
Johan Hedberg029727a2013-10-07 14:44:48 +02001220
1221 if (!chan->tx_credits)
1222 chan->ops->suspend(chan);
Johan Hedberg177f8f22013-05-31 17:54:51 +03001223}
1224
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001225static void l2cap_chan_ready(struct l2cap_chan *chan)
1226{
Mat Martineau28270112012-05-17 21:14:09 -07001227 /* This clears all conf flags, including CONF_NOT_COMPLETE */
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001228 chan->conf_state = 0;
1229 __clear_chan_timer(chan);
1230
Johan Hedberg177f8f22013-05-31 17:54:51 +03001231 if (chan->mode == L2CAP_MODE_LE_FLOWCTL)
1232 l2cap_le_flowctl_start(chan);
1233
Andrei Emeltchenko54a59aa2012-05-27 22:27:53 -03001234 chan->state = BT_CONNECTED;
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001235
Andrei Emeltchenkofd83e2c2012-05-30 09:55:32 +03001236 chan->ops->ready(chan);
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001237}
1238
Johan Hedbergf1496de2013-05-13 14:15:56 +03001239static void l2cap_le_connect(struct l2cap_chan *chan)
1240{
1241 struct l2cap_conn *conn = chan->conn;
1242 struct l2cap_le_conn_req req;
1243
Johan Hedberg595177f2013-12-02 22:12:22 +02001244 if (test_and_set_bit(FLAG_LE_CONN_REQ_SENT, &chan->flags))
1245 return;
1246
Johan Hedbergf1496de2013-05-13 14:15:56 +03001247 req.psm = chan->psm;
1248 req.scid = cpu_to_le16(chan->scid);
1249 req.mtu = cpu_to_le16(chan->imtu);
Johan Hedberg3916aed2013-10-07 15:35:26 +02001250 req.mps = cpu_to_le16(chan->mps);
Johan Hedberg0cd75f72013-05-17 13:09:05 +03001251 req.credits = cpu_to_le16(chan->rx_credits);
Johan Hedbergf1496de2013-05-13 14:15:56 +03001252
1253 chan->ident = l2cap_get_ident(conn);
1254
1255 l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CONN_REQ,
1256 sizeof(req), &req);
1257}
1258
1259static void l2cap_le_start(struct l2cap_chan *chan)
1260{
1261 struct l2cap_conn *conn = chan->conn;
1262
1263 if (!smp_conn_security(conn->hcon, chan->sec_level))
1264 return;
1265
1266 if (!chan->psm) {
1267 l2cap_chan_ready(chan);
1268 return;
1269 }
1270
1271 if (chan->state == BT_CONNECT)
1272 l2cap_le_connect(chan);
1273}
1274
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001275static void l2cap_start_connection(struct l2cap_chan *chan)
1276{
1277 if (__amp_capable(chan)) {
1278 BT_DBG("chan %p AMP capable: discover AMPs", chan);
1279 a2mp_discover_amp(chan);
Johan Hedbergf1496de2013-05-13 14:15:56 +03001280 } else if (chan->conn->hcon->type == LE_LINK) {
1281 l2cap_le_start(chan);
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001282 } else {
1283 l2cap_send_conn_req(chan);
1284 }
1285}
1286
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001287static void l2cap_do_start(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001288{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001289 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001290
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001291 if (conn->hcon->type == LE_LINK) {
Johan Hedberg96ac34f2013-05-13 11:15:07 +03001292 l2cap_le_start(chan);
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001293 return;
1294 }
1295
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001296 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01001297 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
1298 return;
1299
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001300 if (l2cap_chan_check_security(chan) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01001301 __l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001302 l2cap_start_connection(chan);
1303 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001304 } else {
1305 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001306 req.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001307
1308 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
1309 conn->info_ident = l2cap_get_ident(conn);
1310
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08001311 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001312
Gustavo Padovan2d792812012-10-06 10:07:01 +01001313 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
1314 sizeof(req), &req);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001315 }
1316}
1317
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001318static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
1319{
1320 u32 local_feat_mask = l2cap_feat_mask;
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03001321 if (!disable_ertm)
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001322 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
1323
1324 switch (mode) {
1325 case L2CAP_MODE_ERTM:
1326 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
1327 case L2CAP_MODE_STREAMING:
1328 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
1329 default:
1330 return 0x00;
1331 }
1332}
1333
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02001334static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err)
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001335{
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02001336 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001337 struct l2cap_disconn_req req;
1338
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001339 if (!conn)
1340 return;
1341
Andrei Emeltchenkoaad3d0e2012-09-06 15:05:42 +03001342 if (chan->mode == L2CAP_MODE_ERTM && chan->state == BT_CONNECTED) {
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03001343 __clear_retrans_timer(chan);
1344 __clear_monitor_timer(chan);
1345 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001346 }
1347
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001348 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
Gustavo Padovand1177732012-10-06 11:47:38 +01001349 l2cap_state_change(chan, BT_DISCONN);
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001350 return;
1351 }
1352
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001353 req.dcid = cpu_to_le16(chan->dcid);
1354 req.scid = cpu_to_le16(chan->scid);
Gustavo Padovan2d792812012-10-06 10:07:01 +01001355 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_DISCONN_REQ,
1356 sizeof(req), &req);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001357
Gustavo Padovanf8e73012013-10-15 19:24:46 -03001358 l2cap_state_change_and_error(chan, BT_DISCONN, err);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001359}
1360
Linus Torvalds1da177e2005-04-16 15:20:36 -07001361/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001362static void l2cap_conn_start(struct l2cap_conn *conn)
1363{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001364 struct l2cap_chan *chan, *tmp;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001365
1366 BT_DBG("conn %p", conn);
1367
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001368 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001369
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001370 list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001371 l2cap_chan_lock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001372
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001373 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001374 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001375 continue;
1376 }
1377
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001378 if (chan->state == BT_CONNECT) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001379 if (!l2cap_chan_check_security(chan) ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001380 !__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001381 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001382 continue;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02001383 }
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001384
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001385 if (!l2cap_mode_supported(chan->mode, conn->feat_mask)
Gustavo Padovan2d792812012-10-06 10:07:01 +01001386 && test_bit(CONF_STATE2_DEVICE,
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001387 &chan->conf_state)) {
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001388 l2cap_chan_close(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001389 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001390 continue;
1391 }
1392
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001393 l2cap_start_connection(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001394
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001395 } else if (chan->state == BT_CONNECT2) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001396 struct l2cap_conn_rsp rsp;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001397 char buf[128];
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001398 rsp.scid = cpu_to_le16(chan->dcid);
1399 rsp.dcid = cpu_to_le16(chan->scid);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001400
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001401 if (l2cap_chan_check_security(chan)) {
Marcel Holtmannbdc25782013-10-14 02:45:34 -07001402 if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001403 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1404 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08001405 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001406
1407 } else {
Gustavo Padovanacdcabf2013-10-21 14:21:39 -02001408 l2cap_state_change(chan, BT_CONFIG);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001409 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
1410 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001411 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001412 } else {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001413 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1414 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001415 }
1416
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001417 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001418 sizeof(rsp), &rsp);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001419
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001420 if (test_bit(CONF_REQ_SENT, &chan->conf_state) ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001421 rsp.result != L2CAP_CR_SUCCESS) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001422 l2cap_chan_unlock(chan);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001423 continue;
1424 }
1425
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001426 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001427 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001428 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03001429 chan->num_conf_req++;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001430 }
1431
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001432 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001433 }
1434
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001435 mutex_unlock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001436}
1437
Ido Yarivc2287682012-04-20 15:46:07 -03001438/* Find socket with cid and source/destination bdaddr.
Ville Tervob62f3282011-02-10 22:38:50 -03001439 * Returns closest match, locked.
1440 */
Andrei Emeltchenkod9b88702012-03-12 12:13:08 +02001441static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid,
Ido Yarivc2287682012-04-20 15:46:07 -03001442 bdaddr_t *src,
1443 bdaddr_t *dst)
Ville Tervob62f3282011-02-10 22:38:50 -03001444{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001445 struct l2cap_chan *c, *c1 = NULL;
Ville Tervob62f3282011-02-10 22:38:50 -03001446
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001447 read_lock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001448
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001449 list_for_each_entry(c, &chan_list, global_l) {
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001450 if (state && c->state != state)
Ville Tervob62f3282011-02-10 22:38:50 -03001451 continue;
1452
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001453 if (c->scid == cid) {
Ido Yarivc2287682012-04-20 15:46:07 -03001454 int src_match, dst_match;
1455 int src_any, dst_any;
1456
Ville Tervob62f3282011-02-10 22:38:50 -03001457 /* Exact match. */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001458 src_match = !bacmp(&c->src, src);
1459 dst_match = !bacmp(&c->dst, dst);
Ido Yarivc2287682012-04-20 15:46:07 -03001460 if (src_match && dst_match) {
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001461 read_unlock(&chan_list_lock);
1462 return c;
1463 }
Ville Tervob62f3282011-02-10 22:38:50 -03001464
1465 /* Closest match */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001466 src_any = !bacmp(&c->src, BDADDR_ANY);
1467 dst_any = !bacmp(&c->dst, BDADDR_ANY);
Ido Yarivc2287682012-04-20 15:46:07 -03001468 if ((src_match && dst_any) || (src_any && dst_match) ||
1469 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001470 c1 = c;
Ville Tervob62f3282011-02-10 22:38:50 -03001471 }
1472 }
Gustavo F. Padovan280f2942011-04-13 19:01:22 -03001473
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001474 read_unlock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001475
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001476 return c1;
Ville Tervob62f3282011-02-10 22:38:50 -03001477}
1478
1479static void l2cap_le_conn_ready(struct l2cap_conn *conn)
1480{
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001481 struct hci_conn *hcon = conn->hcon;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001482 struct l2cap_chan *chan, *pchan;
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001483 u8 dst_type;
Ville Tervob62f3282011-02-10 22:38:50 -03001484
1485 BT_DBG("");
1486
1487 /* Check if we have socket listening on cid */
Johan Hedberg073d1cf2013-04-29 19:35:35 +03001488 pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_ATT,
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001489 &hcon->src, &hcon->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001490 if (!pchan)
Ville Tervob62f3282011-02-10 22:38:50 -03001491 return;
1492
Johan Hedberg44f3b0f2013-04-29 19:35:45 +03001493 /* Client ATT sockets should override the server one */
1494 if (__l2cap_get_chan_by_dcid(conn, L2CAP_CID_ATT))
1495 return;
1496
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001497 dst_type = bdaddr_type(hcon, hcon->dst_type);
1498
1499 /* If device is blocked, do not create a channel for it */
1500 if (hci_blacklist_lookup(hcon->hdev, &hcon->dst, dst_type))
1501 return;
1502
Gustavo Padovan8ffb9292013-10-21 14:21:41 -02001503 l2cap_chan_lock(pchan);
Gustavo F. Padovan62f3a2c2011-04-14 18:34:34 -03001504
Gustavo Padovan80b98022012-05-27 22:27:51 -03001505 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001506 if (!chan)
Ville Tervob62f3282011-02-10 22:38:50 -03001507 goto clean;
1508
Johan Hedberg9f22398c2013-04-29 19:35:38 +03001509 chan->dcid = L2CAP_CID_ATT;
1510
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001511 bacpy(&chan->src, &hcon->src);
1512 bacpy(&chan->dst, &hcon->dst);
1513 chan->src_type = bdaddr_type(hcon, hcon->src_type);
1514 chan->dst_type = dst_type;
Ville Tervob62f3282011-02-10 22:38:50 -03001515
Johan Hedberg44f3b0f2013-04-29 19:35:45 +03001516 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001517
Ville Tervob62f3282011-02-10 22:38:50 -03001518clean:
Gustavo Padovan8ffb9292013-10-21 14:21:41 -02001519 l2cap_chan_unlock(pchan);
Ville Tervob62f3282011-02-10 22:38:50 -03001520}
1521
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001522static void l2cap_conn_ready(struct l2cap_conn *conn)
1523{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001524 struct l2cap_chan *chan;
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001525 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001526
1527 BT_DBG("conn %p", conn);
1528
Johan Hedbergd8729922013-04-29 19:35:39 +03001529 /* For outgoing pairing which doesn't necessarily have an
1530 * associated socket (e.g. mgmt_pair_device).
1531 */
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001532 if (hcon->out && hcon->type == LE_LINK)
1533 smp_conn_security(hcon, hcon->pending_sec_level);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03001534
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001535 mutex_lock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001536
Johan Hedberg44f3b0f2013-04-29 19:35:45 +03001537 if (hcon->type == LE_LINK)
1538 l2cap_le_conn_ready(conn);
1539
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001540 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001541
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001542 l2cap_chan_lock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001543
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001544 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
1545 l2cap_chan_unlock(chan);
1546 continue;
1547 }
1548
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001549 if (hcon->type == LE_LINK) {
Johan Hedbergf1496de2013-05-13 14:15:56 +03001550 l2cap_le_start(chan);
Vinicius Costa Gomes63128452011-06-17 22:46:26 -03001551 } else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Gustavo Padovan74e75742013-10-15 19:24:51 -03001552 l2cap_chan_ready(chan);
Anderson Brigliab501d6a2011-06-07 18:46:31 -03001553
Gustavo Padovan1c244f72012-12-07 03:29:10 -02001554 } else if (chan->state == BT_CONNECT) {
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001555 l2cap_do_start(chan);
Gustavo Padovan1c244f72012-12-07 03:29:10 -02001556 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001557
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001558 l2cap_chan_unlock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001559 }
1560
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001561 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001562}
1563
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001564/* Notify sockets that we cannot guaranty reliability anymore */
1565static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
1566{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001567 struct l2cap_chan *chan;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001568
1569 BT_DBG("conn %p", conn);
1570
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001571 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001572
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001573 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenkoecf61bd2011-10-11 14:04:32 +03001574 if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags))
Gustavo Padovan1d8b1fd2012-10-06 11:34:52 +01001575 l2cap_chan_set_err(chan, err);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001576 }
1577
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001578 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001579}
1580
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001581static void l2cap_info_timeout(struct work_struct *work)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001582{
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001583 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001584 info_timer.work);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001585
Marcel Holtmann984947d2009-02-06 23:35:19 +01001586 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01001587 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01001588
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001589 l2cap_conn_start(conn);
1590}
1591
David Herrmann2c8e1412013-04-06 20:28:45 +02001592/*
1593 * l2cap_user
1594 * External modules can register l2cap_user objects on l2cap_conn. The ->probe
1595 * callback is called during registration. The ->remove callback is called
1596 * during unregistration.
1597 * An l2cap_user object can either be explicitly unregistered or when the
1598 * underlying l2cap_conn object is deleted. This guarantees that l2cap->hcon,
1599 * l2cap->hchan, .. are valid as long as the remove callback hasn't been called.
1600 * External modules must own a reference to the l2cap_conn object if they intend
1601 * to call l2cap_unregister_user(). The l2cap_conn object might get destroyed at
1602 * any time if they don't.
1603 */
1604
1605int l2cap_register_user(struct l2cap_conn *conn, struct l2cap_user *user)
1606{
1607 struct hci_dev *hdev = conn->hcon->hdev;
1608 int ret;
1609
1610 /* We need to check whether l2cap_conn is registered. If it is not, we
1611 * must not register the l2cap_user. l2cap_conn_del() is unregisters
1612 * l2cap_conn objects, but doesn't provide its own locking. Instead, it
1613 * relies on the parent hci_conn object to be locked. This itself relies
1614 * on the hci_dev object to be locked. So we must lock the hci device
1615 * here, too. */
1616
1617 hci_dev_lock(hdev);
1618
1619 if (user->list.next || user->list.prev) {
1620 ret = -EINVAL;
1621 goto out_unlock;
1622 }
1623
1624 /* conn->hchan is NULL after l2cap_conn_del() was called */
1625 if (!conn->hchan) {
1626 ret = -ENODEV;
1627 goto out_unlock;
1628 }
1629
1630 ret = user->probe(conn, user);
1631 if (ret)
1632 goto out_unlock;
1633
1634 list_add(&user->list, &conn->users);
1635 ret = 0;
1636
1637out_unlock:
1638 hci_dev_unlock(hdev);
1639 return ret;
1640}
1641EXPORT_SYMBOL(l2cap_register_user);
1642
1643void l2cap_unregister_user(struct l2cap_conn *conn, struct l2cap_user *user)
1644{
1645 struct hci_dev *hdev = conn->hcon->hdev;
1646
1647 hci_dev_lock(hdev);
1648
1649 if (!user->list.next || !user->list.prev)
1650 goto out_unlock;
1651
1652 list_del(&user->list);
1653 user->list.next = NULL;
1654 user->list.prev = NULL;
1655 user->remove(conn, user);
1656
1657out_unlock:
1658 hci_dev_unlock(hdev);
1659}
1660EXPORT_SYMBOL(l2cap_unregister_user);
1661
1662static void l2cap_unregister_all_users(struct l2cap_conn *conn)
1663{
1664 struct l2cap_user *user;
1665
1666 while (!list_empty(&conn->users)) {
1667 user = list_first_entry(&conn->users, struct l2cap_user, list);
1668 list_del(&user->list);
1669 user->list.next = NULL;
1670 user->list.prev = NULL;
1671 user->remove(conn, user);
1672 }
1673}
1674
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001675static void l2cap_conn_del(struct hci_conn *hcon, int err)
1676{
1677 struct l2cap_conn *conn = hcon->l2cap_data;
1678 struct l2cap_chan *chan, *l;
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001679
1680 if (!conn)
1681 return;
1682
1683 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
1684
1685 kfree_skb(conn->rx_skb);
1686
David Herrmann2c8e1412013-04-06 20:28:45 +02001687 l2cap_unregister_all_users(conn);
1688
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001689 mutex_lock(&conn->chan_lock);
1690
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001691 /* Kill channels */
1692 list_for_each_entry_safe(chan, l, &conn->chan_l, list) {
Mat Martineau61d6ef32012-04-27 16:50:50 -07001693 l2cap_chan_hold(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001694 l2cap_chan_lock(chan);
1695
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001696 l2cap_chan_del(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001697
1698 l2cap_chan_unlock(chan);
1699
Gustavo Padovan80b98022012-05-27 22:27:51 -03001700 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07001701 l2cap_chan_put(chan);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001702 }
1703
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001704 mutex_unlock(&conn->chan_lock);
1705
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001706 hci_chan_del(conn->hchan);
1707
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001708 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
Ulisses Furquim127074b2012-01-30 18:26:29 -02001709 cancel_delayed_work_sync(&conn->info_timer);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001710
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001711 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) {
Ulisses Furquim127074b2012-01-30 18:26:29 -02001712 cancel_delayed_work_sync(&conn->security_timer);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -03001713 smp_chan_destroy(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001714 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001715
1716 hcon->l2cap_data = NULL;
David Herrmann9c903e32013-04-06 20:28:44 +02001717 conn->hchan = NULL;
1718 l2cap_conn_put(conn);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001719}
1720
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001721static void security_timeout(struct work_struct *work)
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001722{
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001723 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001724 security_timer.work);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001725
Johan Hedbergd06cc412012-06-06 18:44:11 +08001726 BT_DBG("conn %p", conn);
1727
1728 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) {
1729 smp_chan_destroy(conn);
1730 l2cap_conn_del(conn->hcon, ETIMEDOUT);
1731 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001732}
1733
Claudio Takahasibaf43252013-04-11 13:55:50 -03001734static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001735{
Marcel Holtmann01394182006-07-03 10:02:46 +02001736 struct l2cap_conn *conn = hcon->l2cap_data;
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001737 struct hci_chan *hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001738
Claudio Takahasibaf43252013-04-11 13:55:50 -03001739 if (conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001740 return conn;
1741
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001742 hchan = hci_chan_create(hcon);
1743 if (!hchan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001744 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001745
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03001746 conn = kzalloc(sizeof(struct l2cap_conn), GFP_KERNEL);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001747 if (!conn) {
1748 hci_chan_del(hchan);
1749 return NULL;
1750 }
1751
David Herrmann9c903e32013-04-06 20:28:44 +02001752 kref_init(&conn->ref);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001753 hcon->l2cap_data = conn;
1754 conn->hcon = hcon;
David Herrmann9c903e32013-04-06 20:28:44 +02001755 hci_conn_get(conn->hcon);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001756 conn->hchan = hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001757
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001758 BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan);
Marcel Holtmann01394182006-07-03 10:02:46 +02001759
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001760 switch (hcon->type) {
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001761 case LE_LINK:
1762 if (hcon->hdev->le_mtu) {
1763 conn->mtu = hcon->hdev->le_mtu;
1764 break;
1765 }
1766 /* fall through */
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001767 default:
Ville Tervoacd7d372011-02-10 22:38:49 -03001768 conn->mtu = hcon->hdev->acl_mtu;
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001769 break;
1770 }
Ville Tervoacd7d372011-02-10 22:38:49 -03001771
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001772 conn->feat_mask = 0;
1773
Marcel Holtmann848566b2013-10-01 22:59:22 -07001774 if (hcon->type == ACL_LINK)
1775 conn->hs_enabled = test_bit(HCI_HS_ENABLED,
1776 &hcon->hdev->dev_flags);
1777
Linus Torvalds1da177e2005-04-16 15:20:36 -07001778 spin_lock_init(&conn->lock);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001779 mutex_init(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001780
1781 INIT_LIST_HEAD(&conn->chan_l);
David Herrmann2c8e1412013-04-06 20:28:45 +02001782 INIT_LIST_HEAD(&conn->users);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001783
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001784 if (hcon->type == LE_LINK)
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001785 INIT_DELAYED_WORK(&conn->security_timer, security_timeout);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001786 else
Gustavo F. Padovan030013d2011-12-20 10:57:28 -02001787 INIT_DELAYED_WORK(&conn->info_timer, l2cap_info_timeout);
Dave Young45054dc2009-10-18 20:28:30 +00001788
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001789 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01001790
Linus Torvalds1da177e2005-04-16 15:20:36 -07001791 return conn;
1792}
1793
David Herrmann9c903e32013-04-06 20:28:44 +02001794static void l2cap_conn_free(struct kref *ref)
1795{
1796 struct l2cap_conn *conn = container_of(ref, struct l2cap_conn, ref);
1797
1798 hci_conn_put(conn->hcon);
1799 kfree(conn);
1800}
1801
1802void l2cap_conn_get(struct l2cap_conn *conn)
1803{
1804 kref_get(&conn->ref);
1805}
1806EXPORT_SYMBOL(l2cap_conn_get);
1807
1808void l2cap_conn_put(struct l2cap_conn *conn)
1809{
1810 kref_put(&conn->ref, l2cap_conn_free);
1811}
1812EXPORT_SYMBOL(l2cap_conn_put);
1813
Linus Torvalds1da177e2005-04-16 15:20:36 -07001814/* ---- Socket interface ---- */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001815
Ido Yarivc2287682012-04-20 15:46:07 -03001816/* Find socket with psm and source / destination bdaddr.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001817 * Returns closest match.
1818 */
Ido Yarivc2287682012-04-20 15:46:07 -03001819static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
1820 bdaddr_t *src,
Johan Hedbergbf20fd42013-05-14 13:23:13 +03001821 bdaddr_t *dst,
1822 u8 link_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001823{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001824 struct l2cap_chan *c, *c1 = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001825
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001826 read_lock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001827
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001828 list_for_each_entry(c, &chan_list, global_l) {
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001829 if (state && c->state != state)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001830 continue;
1831
Johan Hedbergbf20fd42013-05-14 13:23:13 +03001832 if (link_type == ACL_LINK && c->src_type != BDADDR_BREDR)
1833 continue;
1834
1835 if (link_type == LE_LINK && c->src_type == BDADDR_BREDR)
1836 continue;
1837
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001838 if (c->psm == psm) {
Ido Yarivc2287682012-04-20 15:46:07 -03001839 int src_match, dst_match;
1840 int src_any, dst_any;
1841
Linus Torvalds1da177e2005-04-16 15:20:36 -07001842 /* Exact match. */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001843 src_match = !bacmp(&c->src, src);
1844 dst_match = !bacmp(&c->dst, dst);
Ido Yarivc2287682012-04-20 15:46:07 -03001845 if (src_match && dst_match) {
Johannes Berga7567b22011-06-01 08:29:54 +02001846 read_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001847 return c;
1848 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001849
1850 /* Closest match */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001851 src_any = !bacmp(&c->src, BDADDR_ANY);
1852 dst_any = !bacmp(&c->dst, BDADDR_ANY);
Ido Yarivc2287682012-04-20 15:46:07 -03001853 if ((src_match && dst_any) || (src_any && dst_match) ||
1854 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001855 c1 = c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001856 }
1857 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001858
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001859 read_unlock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001860
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001861 return c1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001862}
1863
Johan Hedberg49460962013-10-08 13:55:46 +02001864static bool is_valid_psm(u16 psm, u8 dst_type)
1865{
1866 if (!psm)
1867 return false;
1868
1869 if (bdaddr_type_is_le(dst_type))
1870 return (psm < 0x00ff);
1871
1872 /* PSM must be odd and lsb of upper byte must be 0 */
1873 return ((psm & 0x0101) == 0x0001);
1874}
1875
Andre Guedes8e9f9892012-04-24 21:02:55 -03001876int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
1877 bdaddr_t *dst, u8 dst_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001878{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001879 struct l2cap_conn *conn;
1880 struct hci_conn *hcon;
1881 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001882 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +02001883 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001884
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001885 BT_DBG("%pMR -> %pMR (type %u) psm 0x%2.2x", &chan->src, dst,
Syam Sidhardhanab195162012-07-27 23:51:22 +05301886 dst_type, __le16_to_cpu(psm));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001887
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001888 hdev = hci_get_route(dst, &chan->src);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001889 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001890 return -EHOSTUNREACH;
1891
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001892 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001893
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001894 l2cap_chan_lock(chan);
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001895
Johan Hedberg49460962013-10-08 13:55:46 +02001896 if (!is_valid_psm(__le16_to_cpu(psm), dst_type) && !cid &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01001897 chan->chan_type != L2CAP_CHAN_RAW) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001898 err = -EINVAL;
1899 goto done;
1900 }
1901
1902 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && !(psm || cid)) {
1903 err = -EINVAL;
1904 goto done;
1905 }
1906
1907 switch (chan->mode) {
1908 case L2CAP_MODE_BASIC:
Johan Hedberg38319712013-05-17 12:49:23 +03001909 case L2CAP_MODE_LE_FLOWCTL:
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001910 break;
1911 case L2CAP_MODE_ERTM:
1912 case L2CAP_MODE_STREAMING:
1913 if (!disable_ertm)
1914 break;
1915 /* fall through */
1916 default:
1917 err = -ENOTSUPP;
1918 goto done;
1919 }
1920
Gustavo Padovan0797e012012-05-27 22:27:54 -03001921 switch (chan->state) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001922 case BT_CONNECT:
1923 case BT_CONNECT2:
1924 case BT_CONFIG:
1925 /* Already connecting */
1926 err = 0;
1927 goto done;
1928
1929 case BT_CONNECTED:
1930 /* Already connected */
1931 err = -EISCONN;
1932 goto done;
1933
1934 case BT_OPEN:
1935 case BT_BOUND:
1936 /* Can connect */
1937 break;
1938
1939 default:
1940 err = -EBADFD;
1941 goto done;
1942 }
1943
1944 /* Set destination address and psm */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001945 bacpy(&chan->dst, dst);
Marcel Holtmann4f1654e2013-10-13 08:50:41 -07001946 chan->dst_type = dst_type;
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001947
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001948 chan->psm = psm;
1949 chan->dcid = cid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001950
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001951 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001952
Johan Hedbergf224ca52013-04-29 19:35:36 +03001953 if (bdaddr_type_is_le(dst_type))
Andre Guedes8e9f9892012-04-24 21:02:55 -03001954 hcon = hci_connect(hdev, LE_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001955 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001956 else
Andre Guedes8e9f9892012-04-24 21:02:55 -03001957 hcon = hci_connect(hdev, ACL_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001958 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001959
Ville Tervo30e76272011-02-22 16:10:53 -03001960 if (IS_ERR(hcon)) {
1961 err = PTR_ERR(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001962 goto done;
Ville Tervo30e76272011-02-22 16:10:53 -03001963 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001964
Claudio Takahasibaf43252013-04-11 13:55:50 -03001965 conn = l2cap_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001966 if (!conn) {
David Herrmann76a68ba2013-04-06 20:28:37 +02001967 hci_conn_drop(hcon);
Ville Tervo30e76272011-02-22 16:10:53 -03001968 err = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001969 goto done;
1970 }
1971
Johan Hedberg141d5702013-04-29 19:35:37 +03001972 if (cid && __l2cap_get_chan_by_dcid(conn, cid)) {
1973 hci_conn_drop(hcon);
1974 err = -EBUSY;
1975 goto done;
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001976 }
1977
Linus Torvalds1da177e2005-04-16 15:20:36 -07001978 /* Update source addr of the socket */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001979 bacpy(&chan->src, &hcon->src);
Marcel Holtmann4f1654e2013-10-13 08:50:41 -07001980 chan->src_type = bdaddr_type(hcon, hcon->src_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001981
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001982 l2cap_chan_unlock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001983 l2cap_chan_add(conn, chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001984 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001985
Johan Hedberg5ee98912013-04-29 19:35:43 +03001986 /* l2cap_chan_add takes its own ref so we can drop this one */
1987 hci_conn_drop(hcon);
1988
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001989 l2cap_state_change(chan, BT_CONNECT);
Gustavo Padovan8d836d72013-10-15 19:24:47 -03001990 __set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001991
1992 if (hcon->state == BT_CONNECTED) {
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001993 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001994 __clear_chan_timer(chan);
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001995 if (l2cap_chan_check_security(chan))
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001996 l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001997 } else
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001998 l2cap_do_start(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001999 }
2000
Ville Tervo30e76272011-02-22 16:10:53 -03002001 err = 0;
2002
Linus Torvalds1da177e2005-04-16 15:20:36 -07002003done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02002004 l2cap_chan_unlock(chan);
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03002005 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002006 hci_dev_put(hdev);
2007 return err;
2008}
2009
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002010static void l2cap_monitor_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002011{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002012 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07002013 monitor_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002014
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03002015 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03002016
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02002017 l2cap_chan_lock(chan);
2018
Mat Martineau80909e02012-05-17 20:53:50 -07002019 if (!chan->conn) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02002020 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02002021 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002022 return;
2023 }
2024
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002025 l2cap_tx(chan, NULL, NULL, L2CAP_EV_MONITOR_TO);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002026
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02002027 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02002028 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002029}
2030
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002031static void l2cap_retrans_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002032{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002033 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07002034 retrans_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002035
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03002036 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03002037
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02002038 l2cap_chan_lock(chan);
2039
Mat Martineau80909e02012-05-17 20:53:50 -07002040 if (!chan->conn) {
2041 l2cap_chan_unlock(chan);
2042 l2cap_chan_put(chan);
2043 return;
2044 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002045
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002046 l2cap_tx(chan, NULL, NULL, L2CAP_EV_RETRANS_TO);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02002047 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02002048 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002049}
2050
Gustavo Padovand6603662012-05-21 13:58:22 -03002051static void l2cap_streaming_send(struct l2cap_chan *chan,
2052 struct sk_buff_head *skbs)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002053{
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03002054 struct sk_buff *skb;
Mat Martineau37339372012-05-17 20:53:33 -07002055 struct l2cap_ctrl *control;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002056
Mat Martineau37339372012-05-17 20:53:33 -07002057 BT_DBG("chan %p, skbs %p", chan, skbs);
2058
Mat Martineaub99e13a2012-10-23 15:24:19 -07002059 if (__chan_is_moving(chan))
2060 return;
2061
Mat Martineau37339372012-05-17 20:53:33 -07002062 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2063
2064 while (!skb_queue_empty(&chan->tx_q)) {
2065
2066 skb = skb_dequeue(&chan->tx_q);
2067
2068 bt_cb(skb)->control.retries = 1;
2069 control = &bt_cb(skb)->control;
2070
2071 control->reqseq = 0;
2072 control->txseq = chan->next_tx_seq;
2073
2074 __pack_control(chan, control, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002075
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002076 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau37339372012-05-17 20:53:33 -07002077 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
2078 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002079 }
2080
Gustavo F. Padovan43434782011-04-12 18:31:57 -03002081 l2cap_do_send(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002082
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002083 BT_DBG("Sent txseq %u", control->txseq);
Mat Martineau37339372012-05-17 20:53:33 -07002084
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002085 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau37339372012-05-17 20:53:33 -07002086 chan->frames_sent++;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002087 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002088}
2089
Szymon Janc67c9e842011-07-28 16:24:33 +02002090static int l2cap_ertm_send(struct l2cap_chan *chan)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002091{
2092 struct sk_buff *skb, *tx_skb;
Mat Martineau18a48e72012-05-17 20:53:34 -07002093 struct l2cap_ctrl *control;
2094 int sent = 0;
2095
2096 BT_DBG("chan %p", chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002097
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03002098 if (chan->state != BT_CONNECTED)
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03002099 return -ENOTCONN;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002100
Mat Martineau94122bb2012-05-02 09:42:02 -07002101 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2102 return 0;
2103
Mat Martineaub99e13a2012-10-23 15:24:19 -07002104 if (__chan_is_moving(chan))
2105 return 0;
2106
Mat Martineau18a48e72012-05-17 20:53:34 -07002107 while (chan->tx_send_head &&
2108 chan->unacked_frames < chan->remote_tx_win &&
2109 chan->tx_state == L2CAP_TX_STATE_XMIT) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002110
Mat Martineau18a48e72012-05-17 20:53:34 -07002111 skb = chan->tx_send_head;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002112
Mat Martineau18a48e72012-05-17 20:53:34 -07002113 bt_cb(skb)->control.retries = 1;
2114 control = &bt_cb(skb)->control;
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03002115
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03002116 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
Mat Martineau18a48e72012-05-17 20:53:34 -07002117 control->final = 1;
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03002118
Mat Martineau18a48e72012-05-17 20:53:34 -07002119 control->reqseq = chan->buffer_seq;
2120 chan->last_acked_seq = chan->buffer_seq;
2121 control->txseq = chan->next_tx_seq;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002122
Mat Martineau18a48e72012-05-17 20:53:34 -07002123 __pack_control(chan, control, skb);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002124
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002125 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau18a48e72012-05-17 20:53:34 -07002126 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
2127 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002128 }
2129
Mat Martineau18a48e72012-05-17 20:53:34 -07002130 /* Clone after data has been modified. Data is assumed to be
2131 read-only (for locking purposes) on cloned sk_buffs.
2132 */
2133 tx_skb = skb_clone(skb, GFP_KERNEL);
2134
2135 if (!tx_skb)
2136 break;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03002137
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03002138 __set_retrans_timer(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002139
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002140 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau18a48e72012-05-17 20:53:34 -07002141 chan->unacked_frames++;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03002142 chan->frames_sent++;
Mat Martineau18a48e72012-05-17 20:53:34 -07002143 sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002144
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03002145 if (skb_queue_is_last(&chan->tx_q, skb))
2146 chan->tx_send_head = NULL;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002147 else
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03002148 chan->tx_send_head = skb_queue_next(&chan->tx_q, skb);
Mat Martineau18a48e72012-05-17 20:53:34 -07002149
2150 l2cap_do_send(chan, tx_skb);
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002151 BT_DBG("Sent txseq %u", control->txseq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002152 }
2153
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002154 BT_DBG("Sent %d, %u unacked, %u in ERTM queue", sent,
2155 chan->unacked_frames, skb_queue_len(&chan->tx_q));
Mat Martineau18a48e72012-05-17 20:53:34 -07002156
2157 return sent;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03002158}
2159
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002160static void l2cap_ertm_resend(struct l2cap_chan *chan)
2161{
2162 struct l2cap_ctrl control;
2163 struct sk_buff *skb;
2164 struct sk_buff *tx_skb;
2165 u16 seq;
2166
2167 BT_DBG("chan %p", chan);
2168
2169 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2170 return;
2171
Mat Martineaub99e13a2012-10-23 15:24:19 -07002172 if (__chan_is_moving(chan))
2173 return;
2174
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002175 while (chan->retrans_list.head != L2CAP_SEQ_LIST_CLEAR) {
2176 seq = l2cap_seq_list_pop(&chan->retrans_list);
2177
2178 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, seq);
2179 if (!skb) {
2180 BT_DBG("Error: Can't retransmit seq %d, frame missing",
Gustavo Padovan2d792812012-10-06 10:07:01 +01002181 seq);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002182 continue;
2183 }
2184
2185 bt_cb(skb)->control.retries++;
2186 control = bt_cb(skb)->control;
2187
2188 if (chan->max_tx != 0 &&
2189 bt_cb(skb)->control.retries > chan->max_tx) {
2190 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02002191 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002192 l2cap_seq_list_clear(&chan->retrans_list);
2193 break;
2194 }
2195
2196 control.reqseq = chan->buffer_seq;
2197 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
2198 control.final = 1;
2199 else
2200 control.final = 0;
2201
2202 if (skb_cloned(skb)) {
2203 /* Cloned sk_buffs are read-only, so we need a
2204 * writeable copy
2205 */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002206 tx_skb = skb_copy(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002207 } else {
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002208 tx_skb = skb_clone(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002209 }
2210
2211 if (!tx_skb) {
2212 l2cap_seq_list_clear(&chan->retrans_list);
2213 break;
2214 }
2215
2216 /* Update skb contents */
2217 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
2218 put_unaligned_le32(__pack_extended_control(&control),
2219 tx_skb->data + L2CAP_HDR_SIZE);
2220 } else {
2221 put_unaligned_le16(__pack_enhanced_control(&control),
2222 tx_skb->data + L2CAP_HDR_SIZE);
2223 }
2224
2225 if (chan->fcs == L2CAP_FCS_CRC16) {
2226 u16 fcs = crc16(0, (u8 *) tx_skb->data, tx_skb->len);
2227 put_unaligned_le16(fcs, skb_put(tx_skb,
2228 L2CAP_FCS_SIZE));
2229 }
2230
2231 l2cap_do_send(chan, tx_skb);
2232
2233 BT_DBG("Resent txseq %d", control.txseq);
2234
2235 chan->last_acked_seq = chan->buffer_seq;
2236 }
2237}
2238
Mat Martineauf80842a2012-05-17 20:53:46 -07002239static void l2cap_retransmit(struct l2cap_chan *chan,
2240 struct l2cap_ctrl *control)
2241{
2242 BT_DBG("chan %p, control %p", chan, control);
2243
2244 l2cap_seq_list_append(&chan->retrans_list, control->reqseq);
2245 l2cap_ertm_resend(chan);
2246}
2247
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002248static void l2cap_retransmit_all(struct l2cap_chan *chan,
2249 struct l2cap_ctrl *control)
2250{
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002251 struct sk_buff *skb;
2252
2253 BT_DBG("chan %p, control %p", chan, control);
2254
2255 if (control->poll)
2256 set_bit(CONN_SEND_FBIT, &chan->conn_state);
2257
2258 l2cap_seq_list_clear(&chan->retrans_list);
2259
2260 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2261 return;
2262
2263 if (chan->unacked_frames) {
2264 skb_queue_walk(&chan->tx_q, skb) {
2265 if (bt_cb(skb)->control.txseq == control->reqseq ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01002266 skb == chan->tx_send_head)
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002267 break;
2268 }
2269
2270 skb_queue_walk_from(&chan->tx_q, skb) {
2271 if (skb == chan->tx_send_head)
2272 break;
2273
2274 l2cap_seq_list_append(&chan->retrans_list,
2275 bt_cb(skb)->control.txseq);
2276 }
2277
2278 l2cap_ertm_resend(chan);
2279 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002280}
2281
Szymon Jancb17e73b2012-01-11 10:59:47 +01002282static void l2cap_send_ack(struct l2cap_chan *chan)
2283{
Mat Martineau0a0aba42012-05-17 20:53:39 -07002284 struct l2cap_ctrl control;
2285 u16 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
2286 chan->last_acked_seq);
2287 int threshold;
2288
2289 BT_DBG("chan %p last_acked_seq %d buffer_seq %d",
2290 chan, chan->last_acked_seq, chan->buffer_seq);
2291
2292 memset(&control, 0, sizeof(control));
2293 control.sframe = 1;
2294
2295 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
2296 chan->rx_state == L2CAP_RX_STATE_RECV) {
2297 __clear_ack_timer(chan);
2298 control.super = L2CAP_SUPER_RNR;
2299 control.reqseq = chan->buffer_seq;
2300 l2cap_send_sframe(chan, &control);
2301 } else {
2302 if (!test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) {
2303 l2cap_ertm_send(chan);
2304 /* If any i-frames were sent, they included an ack */
2305 if (chan->buffer_seq == chan->last_acked_seq)
2306 frames_to_ack = 0;
2307 }
2308
Mat Martineauc20f8e32012-07-10 05:47:07 -07002309 /* Ack now if the window is 3/4ths full.
Mat Martineau0a0aba42012-05-17 20:53:39 -07002310 * Calculate without mul or div
2311 */
Mat Martineauc20f8e32012-07-10 05:47:07 -07002312 threshold = chan->ack_win;
Mat Martineau0a0aba42012-05-17 20:53:39 -07002313 threshold += threshold << 1;
2314 threshold >>= 2;
2315
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002316 BT_DBG("frames_to_ack %u, threshold %d", frames_to_ack,
Mat Martineau0a0aba42012-05-17 20:53:39 -07002317 threshold);
2318
2319 if (frames_to_ack >= threshold) {
2320 __clear_ack_timer(chan);
2321 control.super = L2CAP_SUPER_RR;
2322 control.reqseq = chan->buffer_seq;
2323 l2cap_send_sframe(chan, &control);
2324 frames_to_ack = 0;
2325 }
2326
2327 if (frames_to_ack)
2328 __set_ack_timer(chan);
2329 }
Szymon Jancb17e73b2012-01-11 10:59:47 +01002330}
2331
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002332static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
2333 struct msghdr *msg, int len,
2334 int count, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002335{
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002336 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002337 struct sk_buff **frag;
Gustavo Padovan90338942012-04-06 20:15:47 -03002338 int sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002339
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03002340 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002341 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002342
2343 sent += count;
2344 len -= count;
2345
2346 /* Continuation fragments (no L2CAP header) */
2347 frag = &skb_shinfo(skb)->frag_list;
2348 while (len) {
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002349 struct sk_buff *tmp;
2350
Linus Torvalds1da177e2005-04-16 15:20:36 -07002351 count = min_t(unsigned int, conn->mtu, len);
2352
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002353 tmp = chan->ops->alloc_skb(chan, count,
2354 msg->msg_flags & MSG_DONTWAIT);
2355 if (IS_ERR(tmp))
2356 return PTR_ERR(tmp);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002357
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002358 *frag = tmp;
2359
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002360 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
2361 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002362
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002363 (*frag)->priority = skb->priority;
2364
Linus Torvalds1da177e2005-04-16 15:20:36 -07002365 sent += count;
2366 len -= count;
2367
Gustavo Padovan2d0ed3d2012-05-11 13:16:12 -03002368 skb->len += (*frag)->len;
2369 skb->data_len += (*frag)->len;
2370
Linus Torvalds1da177e2005-04-16 15:20:36 -07002371 frag = &(*frag)->next;
2372 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002373
2374 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002375}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002376
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002377static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002378 struct msghdr *msg, size_t len,
2379 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002380{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002381 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002382 struct sk_buff *skb;
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002383 int err, count, hlen = L2CAP_HDR_SIZE + L2CAP_PSMLEN_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002384 struct l2cap_hdr *lh;
2385
Marcel Holtmann43b1b8d2013-10-12 06:01:26 -07002386 BT_DBG("chan %p psm 0x%2.2x len %zu priority %u", chan,
2387 __le16_to_cpu(chan->psm), len, priority);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002388
2389 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002390
2391 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002392 msg->msg_flags & MSG_DONTWAIT);
2393 if (IS_ERR(skb))
2394 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002395
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002396 skb->priority = priority;
2397
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002398 /* Create L2CAP header */
2399 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002400 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenkodaf6a78c2012-05-03 10:55:52 +03002401 lh->len = cpu_to_le16(len + L2CAP_PSMLEN_SIZE);
Marcel Holtmann43b1b8d2013-10-12 06:01:26 -07002402 put_unaligned(chan->psm, (__le16 *) skb_put(skb, L2CAP_PSMLEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002403
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002404 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002405 if (unlikely(err < 0)) {
2406 kfree_skb(skb);
2407 return ERR_PTR(err);
2408 }
2409 return skb;
2410}
2411
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002412static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002413 struct msghdr *msg, size_t len,
2414 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002415{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002416 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002417 struct sk_buff *skb;
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002418 int err, count;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002419 struct l2cap_hdr *lh;
2420
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002421 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002422
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002423 count = min_t(unsigned int, (conn->mtu - L2CAP_HDR_SIZE), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002424
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002425 skb = chan->ops->alloc_skb(chan, count + L2CAP_HDR_SIZE,
Gustavo Padovan90338942012-04-06 20:15:47 -03002426 msg->msg_flags & MSG_DONTWAIT);
2427 if (IS_ERR(skb))
2428 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002429
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002430 skb->priority = priority;
2431
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002432 /* Create L2CAP header */
2433 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002434 lh->cid = cpu_to_le16(chan->dcid);
Gustavo Padovan6ff9b5e2012-05-02 11:56:17 -03002435 lh->len = cpu_to_le16(len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002436
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002437 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002438 if (unlikely(err < 0)) {
2439 kfree_skb(skb);
2440 return ERR_PTR(err);
2441 }
2442 return skb;
2443}
2444
Luiz Augusto von Dentzab0ff762011-09-12 20:00:50 +03002445static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002446 struct msghdr *msg, size_t len,
2447 u16 sdulen)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002448{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002449 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002450 struct sk_buff *skb;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002451 int err, count, hlen;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002452 struct l2cap_hdr *lh;
2453
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002454 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002455
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03002456 if (!conn)
2457 return ERR_PTR(-ENOTCONN);
2458
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002459 hlen = __ertm_hdr_size(chan);
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002460
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002461 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002462 hlen += L2CAP_SDULEN_SIZE;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002463
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002464 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002465 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002466
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002467 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002468
2469 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002470 msg->msg_flags & MSG_DONTWAIT);
2471 if (IS_ERR(skb))
2472 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002473
2474 /* Create L2CAP header */
2475 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002476 lh->cid = cpu_to_le16(chan->dcid);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002477 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002478
Mat Martineau18a48e72012-05-17 20:53:34 -07002479 /* Control header is populated later */
2480 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
2481 put_unaligned_le32(0, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
2482 else
2483 put_unaligned_le16(0, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002484
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002485 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002486 put_unaligned_le16(sdulen, skb_put(skb, L2CAP_SDULEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002487
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002488 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002489 if (unlikely(err < 0)) {
2490 kfree_skb(skb);
2491 return ERR_PTR(err);
2492 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002493
Mat Martineau18a48e72012-05-17 20:53:34 -07002494 bt_cb(skb)->control.fcs = chan->fcs;
Mat Martineau3ce35142012-04-25 16:36:14 -07002495 bt_cb(skb)->control.retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002496 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002497}
2498
Mat Martineau94122bb2012-05-02 09:42:02 -07002499static int l2cap_segment_sdu(struct l2cap_chan *chan,
2500 struct sk_buff_head *seg_queue,
2501 struct msghdr *msg, size_t len)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002502{
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002503 struct sk_buff *skb;
Mat Martineau94122bb2012-05-02 09:42:02 -07002504 u16 sdu_len;
2505 size_t pdu_len;
Mat Martineau94122bb2012-05-02 09:42:02 -07002506 u8 sar;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002507
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002508 BT_DBG("chan %p, msg %p, len %zu", chan, msg, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002509
Mat Martineau94122bb2012-05-02 09:42:02 -07002510 /* It is critical that ERTM PDUs fit in a single HCI fragment,
2511 * so fragmented skbs are not used. The HCI layer's handling
2512 * of fragmented skbs is not compatible with ERTM's queueing.
2513 */
2514
2515 /* PDU size is derived from the HCI MTU */
2516 pdu_len = chan->conn->mtu;
2517
Mat Martineaua5495742012-10-23 15:24:21 -07002518 /* Constrain PDU size for BR/EDR connections */
2519 if (!chan->hs_hcon)
2520 pdu_len = min_t(size_t, pdu_len, L2CAP_BREDR_MAX_PAYLOAD);
Mat Martineau94122bb2012-05-02 09:42:02 -07002521
2522 /* Adjust for largest possible L2CAP overhead. */
Gustavo Padovan35d401d2012-05-25 18:57:05 -03002523 if (chan->fcs)
2524 pdu_len -= L2CAP_FCS_SIZE;
2525
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002526 pdu_len -= __ertm_hdr_size(chan);
Mat Martineau94122bb2012-05-02 09:42:02 -07002527
2528 /* Remote device may have requested smaller PDUs */
2529 pdu_len = min_t(size_t, pdu_len, chan->remote_mps);
2530
2531 if (len <= pdu_len) {
2532 sar = L2CAP_SAR_UNSEGMENTED;
2533 sdu_len = 0;
2534 pdu_len = len;
2535 } else {
2536 sar = L2CAP_SAR_START;
2537 sdu_len = len;
2538 pdu_len -= L2CAP_SDULEN_SIZE;
2539 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002540
2541 while (len > 0) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002542 skb = l2cap_create_iframe_pdu(chan, msg, pdu_len, sdu_len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002543
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002544 if (IS_ERR(skb)) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002545 __skb_queue_purge(seg_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002546 return PTR_ERR(skb);
2547 }
2548
Mat Martineau94122bb2012-05-02 09:42:02 -07002549 bt_cb(skb)->control.sar = sar;
2550 __skb_queue_tail(seg_queue, skb);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002551
Mat Martineau94122bb2012-05-02 09:42:02 -07002552 len -= pdu_len;
2553 if (sdu_len) {
2554 sdu_len = 0;
2555 pdu_len += L2CAP_SDULEN_SIZE;
2556 }
2557
2558 if (len <= pdu_len) {
2559 sar = L2CAP_SAR_END;
2560 pdu_len = len;
2561 } else {
2562 sar = L2CAP_SAR_CONTINUE;
2563 }
2564 }
2565
Gustavo Padovanf0f62792012-05-29 13:29:17 -03002566 return 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002567}
2568
Johan Hedberg177f8f22013-05-31 17:54:51 +03002569static struct sk_buff *l2cap_create_le_flowctl_pdu(struct l2cap_chan *chan,
2570 struct msghdr *msg,
2571 size_t len, u16 sdulen)
2572{
2573 struct l2cap_conn *conn = chan->conn;
2574 struct sk_buff *skb;
2575 int err, count, hlen;
2576 struct l2cap_hdr *lh;
2577
2578 BT_DBG("chan %p len %zu", chan, len);
2579
2580 if (!conn)
2581 return ERR_PTR(-ENOTCONN);
2582
2583 hlen = L2CAP_HDR_SIZE;
2584
2585 if (sdulen)
2586 hlen += L2CAP_SDULEN_SIZE;
2587
2588 count = min_t(unsigned int, (conn->mtu - hlen), len);
2589
2590 skb = chan->ops->alloc_skb(chan, count + hlen,
2591 msg->msg_flags & MSG_DONTWAIT);
2592 if (IS_ERR(skb))
2593 return skb;
2594
2595 /* Create L2CAP header */
2596 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
2597 lh->cid = cpu_to_le16(chan->dcid);
2598 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
2599
2600 if (sdulen)
2601 put_unaligned_le16(sdulen, skb_put(skb, L2CAP_SDULEN_SIZE));
2602
2603 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
2604 if (unlikely(err < 0)) {
2605 kfree_skb(skb);
2606 return ERR_PTR(err);
2607 }
2608
2609 return skb;
2610}
2611
2612static int l2cap_segment_le_sdu(struct l2cap_chan *chan,
2613 struct sk_buff_head *seg_queue,
2614 struct msghdr *msg, size_t len)
2615{
2616 struct sk_buff *skb;
2617 size_t pdu_len;
2618 u16 sdu_len;
2619
2620 BT_DBG("chan %p, msg %p, len %zu", chan, msg, len);
2621
2622 pdu_len = chan->conn->mtu - L2CAP_HDR_SIZE;
2623
2624 pdu_len = min_t(size_t, pdu_len, chan->remote_mps);
2625
2626 sdu_len = len;
2627 pdu_len -= L2CAP_SDULEN_SIZE;
2628
2629 while (len > 0) {
2630 if (len <= pdu_len)
2631 pdu_len = len;
2632
2633 skb = l2cap_create_le_flowctl_pdu(chan, msg, pdu_len, sdu_len);
2634 if (IS_ERR(skb)) {
2635 __skb_queue_purge(seg_queue);
2636 return PTR_ERR(skb);
2637 }
2638
2639 __skb_queue_tail(seg_queue, skb);
2640
2641 len -= pdu_len;
2642
2643 if (sdu_len) {
2644 sdu_len = 0;
2645 pdu_len += L2CAP_SDULEN_SIZE;
2646 }
2647 }
2648
2649 return 0;
2650}
2651
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002652int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01002653 u32 priority)
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002654{
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002655 struct sk_buff *skb;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002656 int err;
Mat Martineau94122bb2012-05-02 09:42:02 -07002657 struct sk_buff_head seg_queue;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002658
Seung-Woo Kim31e8ce82013-11-05 18:46:33 +09002659 if (!chan->conn)
2660 return -ENOTCONN;
2661
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002662 /* Connectionless channel */
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002663 if (chan->chan_type == L2CAP_CHAN_CONN_LESS) {
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002664 skb = l2cap_create_connless_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002665 if (IS_ERR(skb))
2666 return PTR_ERR(skb);
2667
2668 l2cap_do_send(chan, skb);
2669 return len;
2670 }
2671
2672 switch (chan->mode) {
Johan Hedberg38319712013-05-17 12:49:23 +03002673 case L2CAP_MODE_LE_FLOWCTL:
Johan Hedberg177f8f22013-05-31 17:54:51 +03002674 /* Check outgoing MTU */
2675 if (len > chan->omtu)
2676 return -EMSGSIZE;
2677
Johan Hedbergfad5fc82013-12-05 09:45:01 +02002678 if (!chan->tx_credits)
2679 return -EAGAIN;
2680
Johan Hedberg177f8f22013-05-31 17:54:51 +03002681 __skb_queue_head_init(&seg_queue);
2682
2683 err = l2cap_segment_le_sdu(chan, &seg_queue, msg, len);
2684
2685 if (chan->state != BT_CONNECTED) {
2686 __skb_queue_purge(&seg_queue);
2687 err = -ENOTCONN;
2688 }
2689
2690 if (err)
2691 return err;
2692
2693 skb_queue_splice_tail_init(&seg_queue, &chan->tx_q);
2694
2695 while (chan->tx_credits && !skb_queue_empty(&chan->tx_q)) {
2696 l2cap_do_send(chan, skb_dequeue(&chan->tx_q));
2697 chan->tx_credits--;
2698 }
2699
2700 if (!chan->tx_credits)
2701 chan->ops->suspend(chan);
2702
2703 err = len;
2704
2705 break;
2706
Johan Hedbergfad5fc82013-12-05 09:45:01 +02002707 case L2CAP_MODE_BASIC:
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002708 /* Check outgoing MTU */
2709 if (len > chan->omtu)
2710 return -EMSGSIZE;
2711
2712 /* Create a basic PDU */
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002713 skb = l2cap_create_basic_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002714 if (IS_ERR(skb))
2715 return PTR_ERR(skb);
2716
2717 l2cap_do_send(chan, skb);
2718 err = len;
2719 break;
2720
2721 case L2CAP_MODE_ERTM:
2722 case L2CAP_MODE_STREAMING:
Mat Martineau94122bb2012-05-02 09:42:02 -07002723 /* Check outgoing MTU */
2724 if (len > chan->omtu) {
2725 err = -EMSGSIZE;
2726 break;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002727 }
2728
Mat Martineau94122bb2012-05-02 09:42:02 -07002729 __skb_queue_head_init(&seg_queue);
2730
2731 /* Do segmentation before calling in to the state machine,
2732 * since it's possible to block while waiting for memory
2733 * allocation.
2734 */
2735 err = l2cap_segment_sdu(chan, &seg_queue, msg, len);
2736
2737 /* The channel could have been closed while segmenting,
2738 * check that it is still connected.
2739 */
2740 if (chan->state != BT_CONNECTED) {
2741 __skb_queue_purge(&seg_queue);
2742 err = -ENOTCONN;
2743 }
2744
2745 if (err)
2746 break;
2747
Mat Martineau37339372012-05-17 20:53:33 -07002748 if (chan->mode == L2CAP_MODE_ERTM)
Gustavo Padovand6603662012-05-21 13:58:22 -03002749 l2cap_tx(chan, NULL, &seg_queue, L2CAP_EV_DATA_REQUEST);
Mat Martineau37339372012-05-17 20:53:33 -07002750 else
Gustavo Padovand6603662012-05-21 13:58:22 -03002751 l2cap_streaming_send(chan, &seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002752
Gustavo Padovand6603662012-05-21 13:58:22 -03002753 err = len;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002754
Mat Martineau94122bb2012-05-02 09:42:02 -07002755 /* If the skbs were not queued for sending, they'll still be in
2756 * seg_queue and need to be purged.
2757 */
2758 __skb_queue_purge(&seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002759 break;
2760
2761 default:
2762 BT_DBG("bad state %1.1x", chan->mode);
2763 err = -EBADFD;
2764 }
2765
2766 return err;
2767}
2768
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002769static void l2cap_send_srej(struct l2cap_chan *chan, u16 txseq)
2770{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002771 struct l2cap_ctrl control;
2772 u16 seq;
2773
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002774 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002775
2776 memset(&control, 0, sizeof(control));
2777 control.sframe = 1;
2778 control.super = L2CAP_SUPER_SREJ;
2779
2780 for (seq = chan->expected_tx_seq; seq != txseq;
2781 seq = __next_seq(chan, seq)) {
2782 if (!l2cap_ertm_seq_in_queue(&chan->srej_q, seq)) {
2783 control.reqseq = seq;
2784 l2cap_send_sframe(chan, &control);
2785 l2cap_seq_list_append(&chan->srej_list, seq);
2786 }
2787 }
2788
2789 chan->expected_tx_seq = __next_seq(chan, txseq);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002790}
2791
2792static void l2cap_send_srej_tail(struct l2cap_chan *chan)
2793{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002794 struct l2cap_ctrl control;
2795
2796 BT_DBG("chan %p", chan);
2797
2798 if (chan->srej_list.tail == L2CAP_SEQ_LIST_CLEAR)
2799 return;
2800
2801 memset(&control, 0, sizeof(control));
2802 control.sframe = 1;
2803 control.super = L2CAP_SUPER_SREJ;
2804 control.reqseq = chan->srej_list.tail;
2805 l2cap_send_sframe(chan, &control);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002806}
2807
2808static void l2cap_send_srej_list(struct l2cap_chan *chan, u16 txseq)
2809{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002810 struct l2cap_ctrl control;
2811 u16 initial_head;
2812 u16 seq;
2813
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002814 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002815
2816 memset(&control, 0, sizeof(control));
2817 control.sframe = 1;
2818 control.super = L2CAP_SUPER_SREJ;
2819
2820 /* Capture initial list head to allow only one pass through the list. */
2821 initial_head = chan->srej_list.head;
2822
2823 do {
2824 seq = l2cap_seq_list_pop(&chan->srej_list);
2825 if (seq == txseq || seq == L2CAP_SEQ_LIST_CLEAR)
2826 break;
2827
2828 control.reqseq = seq;
2829 l2cap_send_sframe(chan, &control);
2830 l2cap_seq_list_append(&chan->srej_list, seq);
2831 } while (chan->srej_list.head != initial_head);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002832}
2833
Mat Martineau608bcc62012-05-17 20:53:32 -07002834static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq)
2835{
2836 struct sk_buff *acked_skb;
2837 u16 ackseq;
2838
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002839 BT_DBG("chan %p, reqseq %u", chan, reqseq);
Mat Martineau608bcc62012-05-17 20:53:32 -07002840
2841 if (chan->unacked_frames == 0 || reqseq == chan->expected_ack_seq)
2842 return;
2843
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002844 BT_DBG("expected_ack_seq %u, unacked_frames %u",
Mat Martineau608bcc62012-05-17 20:53:32 -07002845 chan->expected_ack_seq, chan->unacked_frames);
2846
2847 for (ackseq = chan->expected_ack_seq; ackseq != reqseq;
2848 ackseq = __next_seq(chan, ackseq)) {
2849
2850 acked_skb = l2cap_ertm_seq_in_queue(&chan->tx_q, ackseq);
2851 if (acked_skb) {
2852 skb_unlink(acked_skb, &chan->tx_q);
2853 kfree_skb(acked_skb);
2854 chan->unacked_frames--;
2855 }
2856 }
2857
2858 chan->expected_ack_seq = reqseq;
2859
2860 if (chan->unacked_frames == 0)
2861 __clear_retrans_timer(chan);
2862
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002863 BT_DBG("unacked_frames %u", chan->unacked_frames);
Mat Martineau608bcc62012-05-17 20:53:32 -07002864}
2865
2866static void l2cap_abort_rx_srej_sent(struct l2cap_chan *chan)
2867{
2868 BT_DBG("chan %p", chan);
2869
2870 chan->expected_tx_seq = chan->buffer_seq;
2871 l2cap_seq_list_clear(&chan->srej_list);
2872 skb_queue_purge(&chan->srej_q);
2873 chan->rx_state = L2CAP_RX_STATE_RECV;
2874}
2875
Gustavo Padovand6603662012-05-21 13:58:22 -03002876static void l2cap_tx_state_xmit(struct l2cap_chan *chan,
2877 struct l2cap_ctrl *control,
2878 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002879{
Mat Martineau608bcc62012-05-17 20:53:32 -07002880 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2881 event);
2882
2883 switch (event) {
2884 case L2CAP_EV_DATA_REQUEST:
2885 if (chan->tx_send_head == NULL)
2886 chan->tx_send_head = skb_peek(skbs);
2887
2888 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2889 l2cap_ertm_send(chan);
2890 break;
2891 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2892 BT_DBG("Enter LOCAL_BUSY");
2893 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2894
2895 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2896 /* The SREJ_SENT state must be aborted if we are to
2897 * enter the LOCAL_BUSY state.
2898 */
2899 l2cap_abort_rx_srej_sent(chan);
2900 }
2901
2902 l2cap_send_ack(chan);
2903
2904 break;
2905 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2906 BT_DBG("Exit LOCAL_BUSY");
2907 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2908
2909 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2910 struct l2cap_ctrl local_control;
2911
2912 memset(&local_control, 0, sizeof(local_control));
2913 local_control.sframe = 1;
2914 local_control.super = L2CAP_SUPER_RR;
2915 local_control.poll = 1;
2916 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002917 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002918
2919 chan->retry_count = 1;
2920 __set_monitor_timer(chan);
2921 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2922 }
2923 break;
2924 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2925 l2cap_process_reqseq(chan, control->reqseq);
2926 break;
2927 case L2CAP_EV_EXPLICIT_POLL:
2928 l2cap_send_rr_or_rnr(chan, 1);
2929 chan->retry_count = 1;
2930 __set_monitor_timer(chan);
2931 __clear_ack_timer(chan);
2932 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2933 break;
2934 case L2CAP_EV_RETRANS_TO:
2935 l2cap_send_rr_or_rnr(chan, 1);
2936 chan->retry_count = 1;
2937 __set_monitor_timer(chan);
2938 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2939 break;
2940 case L2CAP_EV_RECV_FBIT:
2941 /* Nothing to process */
2942 break;
2943 default:
2944 break;
2945 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002946}
2947
Gustavo Padovand6603662012-05-21 13:58:22 -03002948static void l2cap_tx_state_wait_f(struct l2cap_chan *chan,
2949 struct l2cap_ctrl *control,
2950 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002951{
Mat Martineau608bcc62012-05-17 20:53:32 -07002952 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2953 event);
2954
2955 switch (event) {
2956 case L2CAP_EV_DATA_REQUEST:
2957 if (chan->tx_send_head == NULL)
2958 chan->tx_send_head = skb_peek(skbs);
2959 /* Queue data, but don't send. */
2960 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2961 break;
2962 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2963 BT_DBG("Enter LOCAL_BUSY");
2964 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2965
2966 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2967 /* The SREJ_SENT state must be aborted if we are to
2968 * enter the LOCAL_BUSY state.
2969 */
2970 l2cap_abort_rx_srej_sent(chan);
2971 }
2972
2973 l2cap_send_ack(chan);
2974
2975 break;
2976 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2977 BT_DBG("Exit LOCAL_BUSY");
2978 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2979
2980 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2981 struct l2cap_ctrl local_control;
2982 memset(&local_control, 0, sizeof(local_control));
2983 local_control.sframe = 1;
2984 local_control.super = L2CAP_SUPER_RR;
2985 local_control.poll = 1;
2986 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002987 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002988
2989 chan->retry_count = 1;
2990 __set_monitor_timer(chan);
2991 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2992 }
2993 break;
2994 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2995 l2cap_process_reqseq(chan, control->reqseq);
2996
2997 /* Fall through */
2998
2999 case L2CAP_EV_RECV_FBIT:
3000 if (control && control->final) {
3001 __clear_monitor_timer(chan);
3002 if (chan->unacked_frames > 0)
3003 __set_retrans_timer(chan);
3004 chan->retry_count = 0;
3005 chan->tx_state = L2CAP_TX_STATE_XMIT;
3006 BT_DBG("recv fbit tx_state 0x2.2%x", chan->tx_state);
3007 }
3008 break;
3009 case L2CAP_EV_EXPLICIT_POLL:
3010 /* Ignore */
3011 break;
3012 case L2CAP_EV_MONITOR_TO:
3013 if (chan->max_tx == 0 || chan->retry_count < chan->max_tx) {
3014 l2cap_send_rr_or_rnr(chan, 1);
3015 __set_monitor_timer(chan);
3016 chan->retry_count++;
3017 } else {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02003018 l2cap_send_disconn_req(chan, ECONNABORTED);
Mat Martineau608bcc62012-05-17 20:53:32 -07003019 }
3020 break;
3021 default:
3022 break;
3023 }
Mat Martineau608bcc62012-05-17 20:53:32 -07003024}
3025
Gustavo Padovand6603662012-05-21 13:58:22 -03003026static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
3027 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07003028{
Mat Martineau608bcc62012-05-17 20:53:32 -07003029 BT_DBG("chan %p, control %p, skbs %p, event %d, state %d",
3030 chan, control, skbs, event, chan->tx_state);
3031
3032 switch (chan->tx_state) {
3033 case L2CAP_TX_STATE_XMIT:
Gustavo Padovand6603662012-05-21 13:58:22 -03003034 l2cap_tx_state_xmit(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07003035 break;
3036 case L2CAP_TX_STATE_WAIT_F:
Gustavo Padovand6603662012-05-21 13:58:22 -03003037 l2cap_tx_state_wait_f(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07003038 break;
3039 default:
3040 /* Ignore event */
3041 break;
3042 }
Mat Martineau608bcc62012-05-17 20:53:32 -07003043}
3044
Mat Martineau4b51dae92012-05-17 20:53:37 -07003045static void l2cap_pass_to_tx(struct l2cap_chan *chan,
3046 struct l2cap_ctrl *control)
3047{
3048 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03003049 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_REQSEQ_AND_FBIT);
Mat Martineau4b51dae92012-05-17 20:53:37 -07003050}
3051
Mat Martineauf80842a2012-05-17 20:53:46 -07003052static void l2cap_pass_to_tx_fbit(struct l2cap_chan *chan,
3053 struct l2cap_ctrl *control)
3054{
3055 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03003056 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_FBIT);
Mat Martineauf80842a2012-05-17 20:53:46 -07003057}
3058
Linus Torvalds1da177e2005-04-16 15:20:36 -07003059/* Copy frame to all raw sockets on that connection */
3060static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
3061{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003062 struct sk_buff *nskb;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003063 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003064
3065 BT_DBG("conn %p", conn);
3066
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003067 mutex_lock(&conn->chan_lock);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02003068
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003069 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03003070 if (chan->chan_type != L2CAP_CHAN_RAW)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003071 continue;
3072
Gustavo Padovan7f5396a2013-10-21 18:22:25 -02003073 /* Don't send frame to the channel it came from */
3074 if (bt_cb(skb)->chan == chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003075 continue;
Gustavo Padovan7f5396a2013-10-21 18:22:25 -02003076
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03003077 nskb = skb_clone(skb, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003078 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003079 continue;
Gustavo Padovan80b98022012-05-27 22:27:51 -03003080 if (chan->ops->recv(chan, nskb))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003081 kfree_skb(nskb);
3082 }
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02003083
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003084 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003085}
3086
3087/* ---- L2CAP signalling commands ---- */
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03003088static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code,
3089 u8 ident, u16 dlen, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003090{
3091 struct sk_buff *skb, **frag;
3092 struct l2cap_cmd_hdr *cmd;
3093 struct l2cap_hdr *lh;
3094 int len, count;
3095
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03003096 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %u",
3097 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003098
Anderson Lizardo300b9622013-06-02 16:30:40 -04003099 if (conn->mtu < L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE)
3100 return NULL;
3101
Linus Torvalds1da177e2005-04-16 15:20:36 -07003102 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
3103 count = min_t(unsigned int, conn->mtu, len);
3104
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03003105 skb = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003106 if (!skb)
3107 return NULL;
3108
3109 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003110 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02003111
3112 if (conn->hcon->type == LE_LINK)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003113 lh->cid = __constant_cpu_to_le16(L2CAP_CID_LE_SIGNALING);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02003114 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003115 lh->cid = __constant_cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003116
3117 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
3118 cmd->code = code;
3119 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003120 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003121
3122 if (dlen) {
3123 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
3124 memcpy(skb_put(skb, count), data, count);
3125 data += count;
3126 }
3127
3128 len -= skb->len;
3129
3130 /* Continuation fragments (no L2CAP header) */
3131 frag = &skb_shinfo(skb)->frag_list;
3132 while (len) {
3133 count = min_t(unsigned int, conn->mtu, len);
3134
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03003135 *frag = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003136 if (!*frag)
3137 goto fail;
3138
3139 memcpy(skb_put(*frag, count), data, count);
3140
3141 len -= count;
3142 data += count;
3143
3144 frag = &(*frag)->next;
3145 }
3146
3147 return skb;
3148
3149fail:
3150 kfree_skb(skb);
3151 return NULL;
3152}
3153
Gustavo Padovan2d792812012-10-06 10:07:01 +01003154static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen,
3155 unsigned long *val)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003156{
3157 struct l2cap_conf_opt *opt = *ptr;
3158 int len;
3159
3160 len = L2CAP_CONF_OPT_SIZE + opt->len;
3161 *ptr += len;
3162
3163 *type = opt->type;
3164 *olen = opt->len;
3165
3166 switch (opt->len) {
3167 case 1:
3168 *val = *((u8 *) opt->val);
3169 break;
3170
3171 case 2:
steven miaobfaaeb32010-10-16 18:29:47 -04003172 *val = get_unaligned_le16(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003173 break;
3174
3175 case 4:
steven miaobfaaeb32010-10-16 18:29:47 -04003176 *val = get_unaligned_le32(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003177 break;
3178
3179 default:
3180 *val = (unsigned long) opt->val;
3181 break;
3182 }
3183
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03003184 BT_DBG("type 0x%2.2x len %u val 0x%lx", *type, opt->len, *val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003185 return len;
3186}
3187
Linus Torvalds1da177e2005-04-16 15:20:36 -07003188static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
3189{
3190 struct l2cap_conf_opt *opt = *ptr;
3191
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03003192 BT_DBG("type 0x%2.2x len %u val 0x%lx", type, len, val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003193
3194 opt->type = type;
3195 opt->len = len;
3196
3197 switch (len) {
3198 case 1:
3199 *((u8 *) opt->val) = val;
3200 break;
3201
3202 case 2:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02003203 put_unaligned_le16(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003204 break;
3205
3206 case 4:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02003207 put_unaligned_le32(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003208 break;
3209
3210 default:
3211 memcpy(opt->val, (void *) val, len);
3212 break;
3213 }
3214
3215 *ptr += L2CAP_CONF_OPT_SIZE + len;
3216}
3217
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003218static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan)
3219{
3220 struct l2cap_conf_efs efs;
3221
Szymon Janc1ec918c2011-11-16 09:32:21 +01003222 switch (chan->mode) {
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003223 case L2CAP_MODE_ERTM:
3224 efs.id = chan->local_id;
3225 efs.stype = chan->local_stype;
3226 efs.msdu = cpu_to_le16(chan->local_msdu);
3227 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003228 efs.acc_lat = __constant_cpu_to_le32(L2CAP_DEFAULT_ACC_LAT);
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03003229 efs.flush_to = __constant_cpu_to_le32(L2CAP_EFS_DEFAULT_FLUSH_TO);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003230 break;
3231
3232 case L2CAP_MODE_STREAMING:
3233 efs.id = 1;
3234 efs.stype = L2CAP_SERV_BESTEFFORT;
3235 efs.msdu = cpu_to_le16(chan->local_msdu);
3236 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
3237 efs.acc_lat = 0;
3238 efs.flush_to = 0;
3239 break;
3240
3241 default:
3242 return;
3243 }
3244
3245 l2cap_add_conf_opt(ptr, L2CAP_CONF_EFS, sizeof(efs),
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03003246 (unsigned long) &efs);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003247}
3248
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003249static void l2cap_ack_timeout(struct work_struct *work)
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003250{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003251 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau03625202012-05-17 20:53:51 -07003252 ack_timer.work);
3253 u16 frames_to_ack;
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003254
Gustavo F. Padovan2fb9b3d2011-12-22 16:56:05 -02003255 BT_DBG("chan %p", chan);
3256
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003257 l2cap_chan_lock(chan);
3258
Mat Martineau03625202012-05-17 20:53:51 -07003259 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
3260 chan->last_acked_seq);
3261
3262 if (frames_to_ack)
3263 l2cap_send_rr_or_rnr(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003264
3265 l2cap_chan_unlock(chan);
Szymon Janc09bfb2e2012-01-11 10:59:49 +01003266 l2cap_chan_put(chan);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003267}
3268
Andrei Emeltchenko466f8002012-05-29 13:59:01 +03003269int l2cap_ertm_init(struct l2cap_chan *chan)
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003270{
Mat Martineau3c588192012-04-11 10:48:42 -07003271 int err;
3272
Mat Martineau105bdf92012-04-27 16:50:48 -07003273 chan->next_tx_seq = 0;
3274 chan->expected_tx_seq = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03003275 chan->expected_ack_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03003276 chan->unacked_frames = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03003277 chan->buffer_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03003278 chan->frames_sent = 0;
Mat Martineau105bdf92012-04-27 16:50:48 -07003279 chan->last_acked_seq = 0;
3280 chan->sdu = NULL;
3281 chan->sdu_last_frag = NULL;
3282 chan->sdu_len = 0;
3283
Mat Martineaud34c34f2012-05-14 14:49:27 -07003284 skb_queue_head_init(&chan->tx_q);
3285
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003286 chan->local_amp_id = AMP_ID_BREDR;
3287 chan->move_id = AMP_ID_BREDR;
Mat Martineau08333282012-10-23 15:24:06 -07003288 chan->move_state = L2CAP_MOVE_STABLE;
3289 chan->move_role = L2CAP_MOVE_ROLE_NONE;
3290
Mat Martineau105bdf92012-04-27 16:50:48 -07003291 if (chan->mode != L2CAP_MODE_ERTM)
3292 return 0;
3293
3294 chan->rx_state = L2CAP_RX_STATE_RECV;
3295 chan->tx_state = L2CAP_TX_STATE_XMIT;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003296
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003297 INIT_DELAYED_WORK(&chan->retrans_timer, l2cap_retrans_timeout);
3298 INIT_DELAYED_WORK(&chan->monitor_timer, l2cap_monitor_timeout);
3299 INIT_DELAYED_WORK(&chan->ack_timer, l2cap_ack_timeout);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003300
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -03003301 skb_queue_head_init(&chan->srej_q);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003302
Mat Martineau3c588192012-04-11 10:48:42 -07003303 err = l2cap_seq_list_init(&chan->srej_list, chan->tx_win);
3304 if (err < 0)
3305 return err;
3306
Mat Martineau9dc9aff2012-05-17 16:20:14 -07003307 err = l2cap_seq_list_init(&chan->retrans_list, chan->remote_tx_win);
3308 if (err < 0)
3309 l2cap_seq_list_free(&chan->srej_list);
3310
3311 return err;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003312}
3313
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003314static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
3315{
3316 switch (mode) {
3317 case L2CAP_MODE_STREAMING:
3318 case L2CAP_MODE_ERTM:
3319 if (l2cap_mode_supported(mode, remote_feat_mask))
3320 return mode;
3321 /* fall through */
3322 default:
3323 return L2CAP_MODE_BASIC;
3324 }
3325}
3326
Marcel Holtmann848566b2013-10-01 22:59:22 -07003327static inline bool __l2cap_ews_supported(struct l2cap_conn *conn)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003328{
Marcel Holtmann848566b2013-10-01 22:59:22 -07003329 return conn->hs_enabled && conn->feat_mask & L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003330}
3331
Marcel Holtmann848566b2013-10-01 22:59:22 -07003332static inline bool __l2cap_efs_supported(struct l2cap_conn *conn)
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003333{
Marcel Holtmann848566b2013-10-01 22:59:22 -07003334 return conn->hs_enabled && conn->feat_mask & L2CAP_FEAT_EXT_FLOW;
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003335}
3336
Mat Martineau36c86c82012-10-23 15:24:20 -07003337static void __l2cap_set_ertm_timeouts(struct l2cap_chan *chan,
3338 struct l2cap_conf_rfc *rfc)
3339{
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003340 if (chan->local_amp_id != AMP_ID_BREDR && chan->hs_hcon) {
Mat Martineau36c86c82012-10-23 15:24:20 -07003341 u64 ertm_to = chan->hs_hcon->hdev->amp_be_flush_to;
3342
3343 /* Class 1 devices have must have ERTM timeouts
3344 * exceeding the Link Supervision Timeout. The
3345 * default Link Supervision Timeout for AMP
3346 * controllers is 10 seconds.
3347 *
3348 * Class 1 devices use 0xffffffff for their
3349 * best-effort flush timeout, so the clamping logic
3350 * will result in a timeout that meets the above
3351 * requirement. ERTM timeouts are 16-bit values, so
3352 * the maximum timeout is 65.535 seconds.
3353 */
3354
3355 /* Convert timeout to milliseconds and round */
3356 ertm_to = DIV_ROUND_UP_ULL(ertm_to, 1000);
3357
3358 /* This is the recommended formula for class 2 devices
3359 * that start ERTM timers when packets are sent to the
3360 * controller.
3361 */
3362 ertm_to = 3 * ertm_to + 500;
3363
3364 if (ertm_to > 0xffff)
3365 ertm_to = 0xffff;
3366
3367 rfc->retrans_timeout = cpu_to_le16((u16) ertm_to);
3368 rfc->monitor_timeout = rfc->retrans_timeout;
3369 } else {
3370 rfc->retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
3371 rfc->monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
3372 }
3373}
3374
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003375static inline void l2cap_txwin_setup(struct l2cap_chan *chan)
3376{
3377 if (chan->tx_win > L2CAP_DEFAULT_TX_WINDOW &&
Marcel Holtmann848566b2013-10-01 22:59:22 -07003378 __l2cap_ews_supported(chan->conn)) {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003379 /* use extended control field */
3380 set_bit(FLAG_EXT_CTRL, &chan->flags);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003381 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
3382 } else {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003383 chan->tx_win = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003384 L2CAP_DEFAULT_TX_WINDOW);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003385 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
3386 }
Mat Martineauc20f8e32012-07-10 05:47:07 -07003387 chan->ack_win = chan->tx_win;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003388}
3389
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003390static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003391{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003392 struct l2cap_conf_req *req = data;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003393 struct l2cap_conf_rfc rfc = { .mode = chan->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07003394 void *ptr = req->data;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003395 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003396
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03003397 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003398
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003399 if (chan->num_conf_req || chan->num_conf_rsp)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003400 goto done;
3401
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003402 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003403 case L2CAP_MODE_STREAMING:
3404 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003405 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state))
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003406 break;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003407
Marcel Holtmann848566b2013-10-01 22:59:22 -07003408 if (__l2cap_efs_supported(chan->conn))
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003409 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3410
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03003411 /* fall through */
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003412 default:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003413 chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003414 break;
3415 }
3416
3417done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003418 if (chan->imtu != L2CAP_DEFAULT_MTU)
3419 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovan7990681c2011-01-24 16:01:43 -02003420
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003421 switch (chan->mode) {
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003422 case L2CAP_MODE_BASIC:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003423 if (!(chan->conn->feat_mask & L2CAP_FEAT_ERTM) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003424 !(chan->conn->feat_mask & L2CAP_FEAT_STREAMING))
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003425 break;
3426
Gustavo F. Padovan62547752010-06-08 20:05:31 -03003427 rfc.mode = L2CAP_MODE_BASIC;
3428 rfc.txwin_size = 0;
3429 rfc.max_transmit = 0;
3430 rfc.retrans_timeout = 0;
3431 rfc.monitor_timeout = 0;
3432 rfc.max_pdu_size = 0;
3433
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003434 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003435 (unsigned long) &rfc);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003436 break;
3437
3438 case L2CAP_MODE_ERTM:
3439 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003440 rfc.max_transmit = chan->max_tx;
Mat Martineau36c86c82012-10-23 15:24:20 -07003441
3442 __l2cap_set_ertm_timeouts(chan, &rfc);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003443
3444 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003445 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3446 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003447 rfc.max_pdu_size = cpu_to_le16(size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003448
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003449 l2cap_txwin_setup(chan);
3450
3451 rfc.txwin_size = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003452 L2CAP_DEFAULT_TX_WINDOW);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003453
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003454 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003455 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003456
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003457 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3458 l2cap_add_opt_efs(&ptr, chan);
3459
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003460 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3461 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003462 chan->tx_win);
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003463
3464 if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
3465 if (chan->fcs == L2CAP_FCS_NONE ||
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003466 test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003467 chan->fcs = L2CAP_FCS_NONE;
3468 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
3469 chan->fcs);
3470 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003471 break;
3472
3473 case L2CAP_MODE_STREAMING:
Mat Martineau273759e2012-05-17 20:53:53 -07003474 l2cap_txwin_setup(chan);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003475 rfc.mode = L2CAP_MODE_STREAMING;
3476 rfc.txwin_size = 0;
3477 rfc.max_transmit = 0;
3478 rfc.retrans_timeout = 0;
3479 rfc.monitor_timeout = 0;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003480
3481 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003482 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3483 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003484 rfc.max_pdu_size = cpu_to_le16(size);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003485
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003486 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003487 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003488
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003489 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3490 l2cap_add_opt_efs(&ptr, chan);
3491
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003492 if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
3493 if (chan->fcs == L2CAP_FCS_NONE ||
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003494 test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003495 chan->fcs = L2CAP_FCS_NONE;
3496 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
3497 chan->fcs);
3498 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003499 break;
3500 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003501
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003502 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003503 req->flags = __constant_cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003504
3505 return ptr - data;
3506}
3507
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003508static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003509{
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003510 struct l2cap_conf_rsp *rsp = data;
3511 void *ptr = rsp->data;
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003512 void *req = chan->conf_req;
3513 int len = chan->conf_len;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003514 int type, hint, olen;
3515 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003516 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003517 struct l2cap_conf_efs efs;
3518 u8 remote_efs = 0;
Marcel Holtmann861d6882007-10-20 13:37:06 +02003519 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003520 u16 result = L2CAP_CONF_SUCCESS;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003521 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003522
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003523 BT_DBG("chan %p", chan);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01003524
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003525 while (len >= L2CAP_CONF_OPT_SIZE) {
3526 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003527
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03003528 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003529 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003530
3531 switch (type) {
3532 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02003533 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003534 break;
3535
3536 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003537 chan->flush_to = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003538 break;
3539
3540 case L2CAP_CONF_QOS:
3541 break;
3542
Marcel Holtmann6464f352007-10-20 13:39:51 +02003543 case L2CAP_CONF_RFC:
3544 if (olen == sizeof(rfc))
3545 memcpy(&rfc, (void *) val, olen);
3546 break;
3547
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003548 case L2CAP_CONF_FCS:
3549 if (val == L2CAP_FCS_NONE)
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003550 set_bit(CONF_RECV_NO_FCS, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003551 break;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003552
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003553 case L2CAP_CONF_EFS:
3554 remote_efs = 1;
3555 if (olen == sizeof(efs))
3556 memcpy(&efs, (void *) val, olen);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003557 break;
3558
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003559 case L2CAP_CONF_EWS:
Marcel Holtmann848566b2013-10-01 22:59:22 -07003560 if (!chan->conn->hs_enabled)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003561 return -ECONNREFUSED;
3562
3563 set_bit(FLAG_EXT_CTRL, &chan->flags);
3564 set_bit(CONF_EWS_RECV, &chan->conf_state);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003565 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003566 chan->remote_tx_win = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003567 break;
3568
3569 default:
3570 if (hint)
3571 break;
3572
3573 result = L2CAP_CONF_UNKNOWN;
3574 *((u8 *) ptr++) = type;
3575 break;
3576 }
3577 }
3578
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003579 if (chan->num_conf_rsp || chan->num_conf_req > 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003580 goto done;
3581
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003582 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003583 case L2CAP_MODE_STREAMING:
3584 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003585 if (!test_bit(CONF_STATE2_DEVICE, &chan->conf_state)) {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003586 chan->mode = l2cap_select_mode(rfc.mode,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003587 chan->conn->feat_mask);
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003588 break;
3589 }
3590
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003591 if (remote_efs) {
Marcel Holtmann848566b2013-10-01 22:59:22 -07003592 if (__l2cap_efs_supported(chan->conn))
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003593 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3594 else
3595 return -ECONNREFUSED;
3596 }
3597
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003598 if (chan->mode != rfc.mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003599 return -ECONNREFUSED;
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03003600
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003601 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003602 }
3603
3604done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003605 if (chan->mode != rfc.mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003606 result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003607 rfc.mode = chan->mode;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003608
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003609 if (chan->num_conf_rsp == 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003610 return -ECONNREFUSED;
3611
Gustavo Padovan2d792812012-10-06 10:07:01 +01003612 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3613 (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003614 }
3615
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003616 if (result == L2CAP_CONF_SUCCESS) {
3617 /* Configure output options and let the other side know
3618 * which ones we don't like. */
3619
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003620 if (mtu < L2CAP_DEFAULT_MIN_MTU)
3621 result = L2CAP_CONF_UNACCEPT;
3622 else {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003623 chan->omtu = mtu;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003624 set_bit(CONF_MTU_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003625 }
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003626 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003627
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003628 if (remote_efs) {
3629 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003630 efs.stype != L2CAP_SERV_NOTRAFIC &&
3631 efs.stype != chan->local_stype) {
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003632
3633 result = L2CAP_CONF_UNACCEPT;
3634
3635 if (chan->num_conf_req >= 1)
3636 return -ECONNREFUSED;
3637
3638 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003639 sizeof(efs),
3640 (unsigned long) &efs);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003641 } else {
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003642 /* Send PENDING Conf Rsp */
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003643 result = L2CAP_CONF_PENDING;
3644 set_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003645 }
3646 }
3647
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003648 switch (rfc.mode) {
3649 case L2CAP_MODE_BASIC:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003650 chan->fcs = L2CAP_FCS_NONE;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003651 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003652 break;
3653
3654 case L2CAP_MODE_ERTM:
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003655 if (!test_bit(CONF_EWS_RECV, &chan->conf_state))
3656 chan->remote_tx_win = rfc.txwin_size;
3657 else
3658 rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW;
3659
Gustavo F. Padovan2c03a7a2011-03-25 20:15:28 -03003660 chan->remote_max_tx = rfc.max_transmit;
Mat Martineau86b1b262010-08-05 15:54:22 -07003661
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003662 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003663 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3664 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003665 rfc.max_pdu_size = cpu_to_le16(size);
3666 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003667
Mat Martineau36c86c82012-10-23 15:24:20 -07003668 __l2cap_set_ertm_timeouts(chan, &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003669
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003670 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003671
3672 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003673 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003674
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003675 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3676 chan->remote_id = efs.id;
3677 chan->remote_stype = efs.stype;
3678 chan->remote_msdu = le16_to_cpu(efs.msdu);
3679 chan->remote_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003680 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003681 chan->remote_acc_lat =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003682 le32_to_cpu(efs.acc_lat);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003683 chan->remote_sdu_itime =
3684 le32_to_cpu(efs.sdu_itime);
3685 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003686 sizeof(efs),
3687 (unsigned long) &efs);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003688 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003689 break;
3690
3691 case L2CAP_MODE_STREAMING:
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003692 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003693 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3694 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003695 rfc.max_pdu_size = cpu_to_le16(size);
3696 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003697
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003698 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003699
Gustavo Padovan2d792812012-10-06 10:07:01 +01003700 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3701 (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003702
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003703 break;
3704
3705 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02003706 result = L2CAP_CONF_UNACCEPT;
3707
3708 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003709 rfc.mode = chan->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003710 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003711
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003712 if (result == L2CAP_CONF_SUCCESS)
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003713 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003714 }
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003715 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003716 rsp->result = cpu_to_le16(result);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003717 rsp->flags = __constant_cpu_to_le16(0);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003718
3719 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003720}
3721
Gustavo Padovan2d792812012-10-06 10:07:01 +01003722static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len,
3723 void *data, u16 *result)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003724{
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003725 struct l2cap_conf_req *req = data;
3726 void *ptr = req->data;
3727 int type, olen;
3728 unsigned long val;
Mat Martineau36e999a2011-12-08 17:23:21 -08003729 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003730 struct l2cap_conf_efs efs;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003731
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003732 BT_DBG("chan %p, rsp %p, len %d, req %p", chan, rsp, len, data);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003733
3734 while (len >= L2CAP_CONF_OPT_SIZE) {
3735 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3736
3737 switch (type) {
3738 case L2CAP_CONF_MTU:
3739 if (val < L2CAP_DEFAULT_MIN_MTU) {
3740 *result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003741 chan->imtu = L2CAP_DEFAULT_MIN_MTU;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003742 } else
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003743 chan->imtu = val;
3744 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003745 break;
3746
3747 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003748 chan->flush_to = val;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003749 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003750 2, chan->flush_to);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003751 break;
3752
3753 case L2CAP_CONF_RFC:
3754 if (olen == sizeof(rfc))
3755 memcpy(&rfc, (void *)val, olen);
3756
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003757 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003758 rfc.mode != chan->mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003759 return -ECONNREFUSED;
3760
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003761 chan->fcs = 0;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003762
3763 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003764 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003765 break;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003766
3767 case L2CAP_CONF_EWS:
Mat Martineauc20f8e32012-07-10 05:47:07 -07003768 chan->ack_win = min_t(u16, val, chan->ack_win);
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003769 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Mat Martineauc20f8e32012-07-10 05:47:07 -07003770 chan->tx_win);
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003771 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003772
3773 case L2CAP_CONF_EFS:
3774 if (olen == sizeof(efs))
3775 memcpy(&efs, (void *)val, olen);
3776
3777 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003778 efs.stype != L2CAP_SERV_NOTRAFIC &&
3779 efs.stype != chan->local_stype)
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003780 return -ECONNREFUSED;
3781
Gustavo Padovan2d792812012-10-06 10:07:01 +01003782 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs),
3783 (unsigned long) &efs);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003784 break;
Andrei Emeltchenkocbabee72012-11-29 17:46:07 +02003785
3786 case L2CAP_CONF_FCS:
3787 if (*result == L2CAP_CONF_PENDING)
3788 if (val == L2CAP_FCS_NONE)
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003789 set_bit(CONF_RECV_NO_FCS,
Andrei Emeltchenkocbabee72012-11-29 17:46:07 +02003790 &chan->conf_state);
3791 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003792 }
3793 }
3794
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003795 if (chan->mode == L2CAP_MODE_BASIC && chan->mode != rfc.mode)
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003796 return -ECONNREFUSED;
3797
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003798 chan->mode = rfc.mode;
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003799
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003800 if (*result == L2CAP_CONF_SUCCESS || *result == L2CAP_CONF_PENDING) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003801 switch (rfc.mode) {
3802 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003803 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3804 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
3805 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003806 if (!test_bit(FLAG_EXT_CTRL, &chan->flags))
3807 chan->ack_win = min_t(u16, chan->ack_win,
3808 rfc.txwin_size);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003809
3810 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3811 chan->local_msdu = le16_to_cpu(efs.msdu);
3812 chan->local_sdu_itime =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003813 le32_to_cpu(efs.sdu_itime);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003814 chan->local_acc_lat = le32_to_cpu(efs.acc_lat);
3815 chan->local_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003816 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003817 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003818 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003819
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003820 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003821 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003822 }
3823 }
3824
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003825 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003826 req->flags = __constant_cpu_to_le16(0);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003827
3828 return ptr - data;
3829}
3830
Gustavo Padovan2d792812012-10-06 10:07:01 +01003831static int l2cap_build_conf_rsp(struct l2cap_chan *chan, void *data,
3832 u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003833{
3834 struct l2cap_conf_rsp *rsp = data;
3835 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003836
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003837 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003838
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003839 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003840 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003841 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003842
3843 return ptr - data;
3844}
3845
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03003846void __l2cap_le_connect_rsp_defer(struct l2cap_chan *chan)
3847{
3848 struct l2cap_le_conn_rsp rsp;
3849 struct l2cap_conn *conn = chan->conn;
3850
3851 BT_DBG("chan %p", chan);
3852
3853 rsp.dcid = cpu_to_le16(chan->scid);
3854 rsp.mtu = cpu_to_le16(chan->imtu);
Johan Hedberg3916aed2013-10-07 15:35:26 +02003855 rsp.mps = cpu_to_le16(chan->mps);
Johan Hedberg0cd75f72013-05-17 13:09:05 +03003856 rsp.credits = cpu_to_le16(chan->rx_credits);
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03003857 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
3858
3859 l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CONN_RSP, sizeof(rsp),
3860 &rsp);
3861}
3862
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003863void __l2cap_connect_rsp_defer(struct l2cap_chan *chan)
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003864{
3865 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003866 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003867 u8 buf[128];
Andrei Emeltchenko439f34a2012-10-31 15:46:28 +02003868 u8 rsp_code;
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003869
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003870 rsp.scid = cpu_to_le16(chan->dcid);
3871 rsp.dcid = cpu_to_le16(chan->scid);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003872 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
3873 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Andrei Emeltchenko439f34a2012-10-31 15:46:28 +02003874
3875 if (chan->hs_hcon)
3876 rsp_code = L2CAP_CREATE_CHAN_RSP;
3877 else
3878 rsp_code = L2CAP_CONN_RSP;
3879
3880 BT_DBG("chan %p rsp_code %u", chan, rsp_code);
3881
3882 l2cap_send_cmd(conn, chan->ident, rsp_code, sizeof(rsp), &rsp);
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003883
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003884 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003885 return;
3886
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003887 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003888 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003889 chan->num_conf_req++;
3890}
3891
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003892static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003893{
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003894 int type, olen;
3895 unsigned long val;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003896 /* Use sane default values in case a misbehaving remote device
3897 * did not send an RFC or extended window size option.
3898 */
3899 u16 txwin_ext = chan->ack_win;
3900 struct l2cap_conf_rfc rfc = {
3901 .mode = chan->mode,
3902 .retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO),
3903 .monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO),
3904 .max_pdu_size = cpu_to_le16(chan->imtu),
3905 .txwin_size = min_t(u16, chan->ack_win, L2CAP_DEFAULT_TX_WINDOW),
3906 };
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003907
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003908 BT_DBG("chan %p, rsp %p, len %d", chan, rsp, len);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003909
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003910 if ((chan->mode != L2CAP_MODE_ERTM) && (chan->mode != L2CAP_MODE_STREAMING))
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003911 return;
3912
3913 while (len >= L2CAP_CONF_OPT_SIZE) {
3914 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3915
Mat Martineauc20f8e32012-07-10 05:47:07 -07003916 switch (type) {
3917 case L2CAP_CONF_RFC:
3918 if (olen == sizeof(rfc))
3919 memcpy(&rfc, (void *)val, olen);
Szymon Janc8f321f82012-06-08 11:33:33 +02003920 break;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003921 case L2CAP_CONF_EWS:
3922 txwin_ext = val;
3923 break;
3924 }
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003925 }
3926
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003927 switch (rfc.mode) {
3928 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003929 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3930 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003931 chan->mps = le16_to_cpu(rfc.max_pdu_size);
3932 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3933 chan->ack_win = min_t(u16, chan->ack_win, txwin_ext);
3934 else
3935 chan->ack_win = min_t(u16, chan->ack_win,
3936 rfc.txwin_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003937 break;
3938 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003939 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003940 }
3941}
3942
Gustavo Padovan2d792812012-10-06 10:07:01 +01003943static inline int l2cap_command_rej(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003944 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3945 u8 *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003946{
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003947 struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003948
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003949 if (cmd_len < sizeof(*rej))
3950 return -EPROTO;
3951
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003952 if (rej->reason != L2CAP_REJ_NOT_UNDERSTOOD)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003953 return 0;
3954
3955 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003956 cmd->ident == conn->info_ident) {
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02003957 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01003958
3959 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003960 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003961
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003962 l2cap_conn_start(conn);
3963 }
3964
3965 return 0;
3966}
3967
Mat Martineau17009152012-10-23 15:24:07 -07003968static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
3969 struct l2cap_cmd_hdr *cmd,
3970 u8 *data, u8 rsp_code, u8 amp_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003971{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003972 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
3973 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003974 struct l2cap_chan *chan = NULL, *pchan;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003975 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003976
3977 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003978 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003979
Andrei Emeltchenko097db762012-03-09 14:16:17 +02003980 BT_DBG("psm 0x%2.2x scid 0x%4.4x", __le16_to_cpu(psm), scid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003981
3982 /* Check if we have socket listening on psm */
Marcel Holtmann6f59b902013-10-13 05:24:01 -07003983 pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, &conn->hcon->src,
Johan Hedbergbf20fd42013-05-14 13:23:13 +03003984 &conn->hcon->dst, ACL_LINK);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003985 if (!pchan) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003986 result = L2CAP_CR_BAD_PSM;
3987 goto sendresp;
3988 }
3989
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003990 mutex_lock(&conn->chan_lock);
Gustavo Padovan8ffb9292013-10-21 14:21:41 -02003991 l2cap_chan_lock(pchan);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00003992
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003993 /* Check if the ACL is secure enough (if not SDP) */
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +03003994 if (psm != __constant_cpu_to_le16(L2CAP_PSM_SDP) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003995 !hci_conn_check_link_mode(conn->hcon)) {
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003996 conn->disc_reason = HCI_ERROR_AUTH_FAILURE;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003997 result = L2CAP_CR_SEC_BLOCK;
3998 goto response;
3999 }
4000
Linus Torvalds1da177e2005-04-16 15:20:36 -07004001 result = L2CAP_CR_NO_MEM;
4002
Gustavo Padovan2dfa1002012-05-27 22:27:58 -03004003 /* Check if we already have channel with that dcid */
4004 if (__l2cap_get_chan_by_dcid(conn, scid))
4005 goto response;
4006
Gustavo Padovan80b98022012-05-27 22:27:51 -03004007 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03004008 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004009 goto response;
4010
Syam Sidhardhan330b6c12013-08-06 01:59:12 +09004011 /* For certain devices (ex: HID mouse), support for authentication,
4012 * pairing and bonding is optional. For such devices, inorder to avoid
4013 * the ACL alive for too long after L2CAP disconnection, reset the ACL
4014 * disc_timeout back to HCI_DISCONN_TIMEOUT during L2CAP connect.
4015 */
4016 conn->hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
4017
Marcel Holtmann7eafc592013-10-13 08:12:47 -07004018 bacpy(&chan->src, &conn->hcon->src);
4019 bacpy(&chan->dst, &conn->hcon->dst);
Marcel Holtmann4f1654e2013-10-13 08:50:41 -07004020 chan->src_type = bdaddr_type(conn->hcon, conn->hcon->src_type);
4021 chan->dst_type = bdaddr_type(conn->hcon, conn->hcon->dst_type);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03004022 chan->psm = psm;
4023 chan->dcid = scid;
Mat Martineau17009152012-10-23 15:24:07 -07004024 chan->local_amp_id = amp_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004025
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004026 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004027
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03004028 dcid = chan->scid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004029
Gustavo Padovan8d836d72013-10-15 19:24:47 -03004030 __set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
Linus Torvalds1da177e2005-04-16 15:20:36 -07004031
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03004032 chan->ident = cmd->ident;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004033
Marcel Holtmann984947d2009-02-06 23:35:19 +01004034 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02004035 if (l2cap_chan_check_security(chan)) {
Marcel Holtmannbdc25782013-10-14 02:45:34 -07004036 if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02004037 l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01004038 result = L2CAP_CR_PEND;
4039 status = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08004040 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01004041 } else {
Mat Martineau17009152012-10-23 15:24:07 -07004042 /* Force pending result for AMP controllers.
4043 * The connection will succeed after the
4044 * physical link is up.
4045 */
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004046 if (amp_id == AMP_ID_BREDR) {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02004047 l2cap_state_change(chan, BT_CONFIG);
Mat Martineau17009152012-10-23 15:24:07 -07004048 result = L2CAP_CR_SUCCESS;
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004049 } else {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02004050 l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004051 result = L2CAP_CR_PEND;
Mat Martineau17009152012-10-23 15:24:07 -07004052 }
Marcel Holtmannf66dc812009-01-15 21:57:00 +01004053 status = L2CAP_CS_NO_INFO;
4054 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004055 } else {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02004056 l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004057 result = L2CAP_CR_PEND;
4058 status = L2CAP_CS_AUTHEN_PEND;
4059 }
4060 } else {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02004061 l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004062 result = L2CAP_CR_PEND;
4063 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004064 }
4065
Linus Torvalds1da177e2005-04-16 15:20:36 -07004066response:
Gustavo Padovan8ffb9292013-10-21 14:21:41 -02004067 l2cap_chan_unlock(pchan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004068 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004069
4070sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07004071 rsp.scid = cpu_to_le16(scid);
4072 rsp.dcid = cpu_to_le16(dcid);
4073 rsp.result = cpu_to_le16(result);
4074 rsp.status = cpu_to_le16(status);
Mat Martineau4c89b6a2012-10-11 17:48:22 +03004075 l2cap_send_cmd(conn, cmd->ident, rsp_code, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004076
4077 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
4078 struct l2cap_info_req info;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004079 info.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004080
4081 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
4082 conn->info_ident = l2cap_get_ident(conn);
4083
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08004084 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004085
Gustavo Padovan2d792812012-10-06 10:07:01 +01004086 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
4087 sizeof(info), &info);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004088 }
4089
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004090 if (chan && !test_bit(CONF_REQ_SENT, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01004091 result == L2CAP_CR_SUCCESS) {
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03004092 u8 buf[128];
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004093 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03004094 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004095 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004096 chan->num_conf_req++;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03004097 }
Mat Martineau17009152012-10-23 15:24:07 -07004098
4099 return chan;
Mat Martineau4c89b6a2012-10-11 17:48:22 +03004100}
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03004101
Mat Martineau4c89b6a2012-10-11 17:48:22 +03004102static int l2cap_connect_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004103 struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
Mat Martineau4c89b6a2012-10-11 17:48:22 +03004104{
Jaganath Kanakkassery7b064ed2013-01-10 10:28:35 +05304105 struct hci_dev *hdev = conn->hcon->hdev;
4106 struct hci_conn *hcon = conn->hcon;
4107
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004108 if (cmd_len < sizeof(struct l2cap_conn_req))
4109 return -EPROTO;
4110
Jaganath Kanakkassery7b064ed2013-01-10 10:28:35 +05304111 hci_dev_lock(hdev);
4112 if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
4113 !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &hcon->flags))
4114 mgmt_device_connected(hdev, &hcon->dst, hcon->type,
4115 hcon->dst_type, 0, NULL, 0,
4116 hcon->dev_class);
4117 hci_dev_unlock(hdev);
4118
Gustavo Padovan300229f2012-10-12 19:40:40 +08004119 l2cap_connect(conn, cmd, data, L2CAP_CONN_RSP, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004120 return 0;
4121}
4122
Mat Martineau5909cf32012-10-23 15:24:08 -07004123static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004124 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4125 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004126{
4127 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
4128 u16 scid, dcid, result, status;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004129 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004130 u8 req[128];
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004131 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004132
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004133 if (cmd_len < sizeof(*rsp))
4134 return -EPROTO;
4135
Linus Torvalds1da177e2005-04-16 15:20:36 -07004136 scid = __le16_to_cpu(rsp->scid);
4137 dcid = __le16_to_cpu(rsp->dcid);
4138 result = __le16_to_cpu(rsp->result);
4139 status = __le16_to_cpu(rsp->status);
4140
Andrei Emeltchenko1b009c92012-02-21 12:54:54 +02004141 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 +01004142 dcid, scid, result, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004143
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004144 mutex_lock(&conn->chan_lock);
4145
Linus Torvalds1da177e2005-04-16 15:20:36 -07004146 if (scid) {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004147 chan = __l2cap_get_chan_by_scid(conn, scid);
4148 if (!chan) {
Johan Hedberg21870b52013-09-16 13:05:14 +03004149 err = -EBADSLT;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004150 goto unlock;
4151 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004152 } else {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004153 chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
4154 if (!chan) {
Johan Hedberg21870b52013-09-16 13:05:14 +03004155 err = -EBADSLT;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004156 goto unlock;
4157 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004158 }
4159
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004160 err = 0;
4161
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004162 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004163
Linus Torvalds1da177e2005-04-16 15:20:36 -07004164 switch (result) {
4165 case L2CAP_CR_SUCCESS:
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03004166 l2cap_state_change(chan, BT_CONFIG);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03004167 chan->ident = 0;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03004168 chan->dcid = dcid;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004169 clear_bit(CONF_CONNECT_PEND, &chan->conf_state);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01004170
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004171 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03004172 break;
4173
Linus Torvalds1da177e2005-04-16 15:20:36 -07004174 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004175 l2cap_build_conf_req(chan, req), req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004176 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004177 break;
4178
4179 case L2CAP_CR_PEND:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004180 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004181 break;
4182
4183 default:
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004184 l2cap_chan_del(chan, ECONNREFUSED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004185 break;
4186 }
4187
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004188 l2cap_chan_unlock(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004189
4190unlock:
4191 mutex_unlock(&conn->chan_lock);
4192
4193 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004194}
4195
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004196static inline void set_default_fcs(struct l2cap_chan *chan)
Mat Martineau8c462b62010-08-24 15:35:42 -07004197{
4198 /* FCS is enabled only in ERTM or streaming mode, if one or both
4199 * sides request it.
4200 */
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03004201 if (chan->mode != L2CAP_MODE_ERTM && chan->mode != L2CAP_MODE_STREAMING)
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004202 chan->fcs = L2CAP_FCS_NONE;
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02004203 else if (!test_bit(CONF_RECV_NO_FCS, &chan->conf_state))
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004204 chan->fcs = L2CAP_FCS_CRC16;
Mat Martineau8c462b62010-08-24 15:35:42 -07004205}
4206
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03004207static void l2cap_send_efs_conf_rsp(struct l2cap_chan *chan, void *data,
4208 u8 ident, u16 flags)
4209{
4210 struct l2cap_conn *conn = chan->conn;
4211
4212 BT_DBG("conn %p chan %p ident %d flags 0x%4.4x", conn, chan, ident,
4213 flags);
4214
4215 clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
4216 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
4217
4218 l2cap_send_cmd(conn, ident, L2CAP_CONF_RSP,
4219 l2cap_build_conf_rsp(chan, data,
4220 L2CAP_CONF_SUCCESS, flags), data);
4221}
4222
Johan Hedberg662d6522013-10-16 11:20:47 +03004223static void cmd_reject_invalid_cid(struct l2cap_conn *conn, u8 ident,
4224 u16 scid, u16 dcid)
4225{
4226 struct l2cap_cmd_rej_cid rej;
4227
4228 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_INVALID_CID);
4229 rej.scid = __cpu_to_le16(scid);
4230 rej.dcid = __cpu_to_le16(dcid);
4231
4232 l2cap_send_cmd(conn, ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
4233}
4234
Gustavo Padovan2d792812012-10-06 10:07:01 +01004235static inline int l2cap_config_req(struct l2cap_conn *conn,
4236 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4237 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004238{
4239 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
4240 u16 dcid, flags;
4241 u8 rsp[64];
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004242 struct l2cap_chan *chan;
Mat Martineau3c588192012-04-11 10:48:42 -07004243 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004244
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004245 if (cmd_len < sizeof(*req))
4246 return -EPROTO;
4247
Linus Torvalds1da177e2005-04-16 15:20:36 -07004248 dcid = __le16_to_cpu(req->dcid);
4249 flags = __le16_to_cpu(req->flags);
4250
4251 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
4252
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03004253 chan = l2cap_get_chan_by_scid(conn, dcid);
Johan Hedberg662d6522013-10-16 11:20:47 +03004254 if (!chan) {
4255 cmd_reject_invalid_cid(conn, cmd->ident, dcid, 0);
4256 return 0;
4257 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004258
David S. Miller033b1142011-07-21 13:38:42 -07004259 if (chan->state != BT_CONFIG && chan->state != BT_CONNECT2) {
Johan Hedberg662d6522013-10-16 11:20:47 +03004260 cmd_reject_invalid_cid(conn, cmd->ident, chan->scid,
4261 chan->dcid);
Marcel Holtmann354f60a2006-11-18 22:15:20 +01004262 goto unlock;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03004263 }
Marcel Holtmann354f60a2006-11-18 22:15:20 +01004264
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004265 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07004266 len = cmd_len - sizeof(*req);
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004267 if (chan->conf_len + len > sizeof(chan->conf_req)) {
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004268 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004269 l2cap_build_conf_rsp(chan, rsp,
4270 L2CAP_CONF_REJECT, flags), rsp);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004271 goto unlock;
4272 }
4273
4274 /* Store config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004275 memcpy(chan->conf_req + chan->conf_len, req->data, len);
4276 chan->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004277
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03004278 if (flags & L2CAP_CONF_FLAG_CONTINUATION) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004279 /* Incomplete config. Send empty response. */
4280 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004281 l2cap_build_conf_rsp(chan, rsp,
4282 L2CAP_CONF_SUCCESS, flags), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004283 goto unlock;
4284 }
4285
4286 /* Complete config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004287 len = l2cap_parse_conf_req(chan, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004288 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004289 l2cap_send_disconn_req(chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004290 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004291 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004292
Mat Martineau1500109b2012-10-23 15:24:15 -07004293 chan->ident = cmd->ident;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004294 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004295 chan->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004296
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004297 /* Reset config buffer. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004298 chan->conf_len = 0;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004299
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004300 if (!test_bit(CONF_OUTPUT_DONE, &chan->conf_state))
Marcel Holtmann876d9482007-10-20 13:35:42 +02004301 goto unlock;
4302
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004303 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004304 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004305
Mat Martineau105bdf92012-04-27 16:50:48 -07004306 if (chan->mode == L2CAP_MODE_ERTM ||
4307 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07004308 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03004309
Mat Martineau3c588192012-04-11 10:48:42 -07004310 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004311 l2cap_send_disconn_req(chan, -err);
Mat Martineau3c588192012-04-11 10:48:42 -07004312 else
4313 l2cap_chan_ready(chan);
4314
Marcel Holtmann876d9482007-10-20 13:35:42 +02004315 goto unlock;
4316 }
4317
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004318 if (!test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004319 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004320 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004321 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004322 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004323 }
4324
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004325 /* Got Conf Rsp PENDING from remote side and asume we sent
4326 Conf Rsp PENDING in the code above */
4327 if (test_bit(CONF_REM_CONF_PEND, &chan->conf_state) &&
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03004328 test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004329
4330 /* check compatibility */
4331
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004332 /* Send rsp for BR/EDR channel */
Andrei Emeltchenkof351bc72012-10-31 15:46:35 +02004333 if (!chan->hs_hcon)
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004334 l2cap_send_efs_conf_rsp(chan, rsp, cmd->ident, flags);
4335 else
4336 chan->ident = cmd->ident;
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004337 }
4338
Linus Torvalds1da177e2005-04-16 15:20:36 -07004339unlock:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004340 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07004341 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004342}
4343
Gustavo Padovan2d792812012-10-06 10:07:01 +01004344static inline int l2cap_config_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004345 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4346 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004347{
4348 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
4349 u16 scid, flags, result;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004350 struct l2cap_chan *chan;
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004351 int len = cmd_len - sizeof(*rsp);
Mat Martineau3c588192012-04-11 10:48:42 -07004352 int err = 0;
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 flags = __le16_to_cpu(rsp->flags);
4359 result = __le16_to_cpu(rsp->result);
4360
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02004361 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x len %d", scid, flags,
4362 result, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004363
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03004364 chan = l2cap_get_chan_by_scid(conn, scid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004365 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004366 return 0;
4367
4368 switch (result) {
4369 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004370 l2cap_conf_rfc_get(chan, rsp->data, len);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004371 clear_bit(CONF_REM_CONF_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004372 break;
4373
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004374 case L2CAP_CONF_PENDING:
4375 set_bit(CONF_REM_CONF_PEND, &chan->conf_state);
4376
4377 if (test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
4378 char buf[64];
4379
4380 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004381 buf, &result);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004382 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004383 l2cap_send_disconn_req(chan, ECONNRESET);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004384 goto done;
4385 }
4386
Andrei Emeltchenkof351bc72012-10-31 15:46:35 +02004387 if (!chan->hs_hcon) {
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004388 l2cap_send_efs_conf_rsp(chan, buf, cmd->ident,
4389 0);
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +02004390 } else {
4391 if (l2cap_check_efs(chan)) {
4392 amp_create_logical_link(chan);
4393 chan->ident = cmd->ident;
4394 }
4395 }
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004396 }
4397 goto done;
4398
Linus Torvalds1da177e2005-04-16 15:20:36 -07004399 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004400 if (chan->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004401 char req[64];
4402
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02004403 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004404 l2cap_send_disconn_req(chan, ECONNRESET);
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02004405 goto done;
4406 }
4407
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004408 /* throw out any old stored conf requests */
4409 result = L2CAP_CONF_SUCCESS;
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03004410 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004411 req, &result);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004412 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004413 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004414 goto done;
4415 }
4416
4417 l2cap_send_cmd(conn, l2cap_get_ident(conn),
Gustavo Padovan2d792812012-10-06 10:07:01 +01004418 L2CAP_CONF_REQ, len, req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004419 chan->num_conf_req++;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004420 if (result != L2CAP_CONF_SUCCESS)
4421 goto done;
4422 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004423 }
4424
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09004425 default:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004426 l2cap_chan_set_err(chan, ECONNRESET);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02004427
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08004428 __set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004429 l2cap_send_disconn_req(chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004430 goto done;
4431 }
4432
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03004433 if (flags & L2CAP_CONF_FLAG_CONTINUATION)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004434 goto done;
4435
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004436 set_bit(CONF_INPUT_DONE, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004437
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004438 if (test_bit(CONF_OUTPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004439 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004440
Mat Martineau105bdf92012-04-27 16:50:48 -07004441 if (chan->mode == L2CAP_MODE_ERTM ||
4442 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07004443 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03004444
Mat Martineau3c588192012-04-11 10:48:42 -07004445 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004446 l2cap_send_disconn_req(chan, -err);
Mat Martineau3c588192012-04-11 10:48:42 -07004447 else
4448 l2cap_chan_ready(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004449 }
4450
4451done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004452 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07004453 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004454}
4455
Gustavo Padovan2d792812012-10-06 10:07:01 +01004456static inline int l2cap_disconnect_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004457 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4458 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004459{
4460 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
4461 struct l2cap_disconn_rsp rsp;
4462 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004463 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004464
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004465 if (cmd_len != sizeof(*req))
4466 return -EPROTO;
4467
Linus Torvalds1da177e2005-04-16 15:20:36 -07004468 scid = __le16_to_cpu(req->scid);
4469 dcid = __le16_to_cpu(req->dcid);
4470
4471 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
4472
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004473 mutex_lock(&conn->chan_lock);
4474
4475 chan = __l2cap_get_chan_by_scid(conn, dcid);
4476 if (!chan) {
4477 mutex_unlock(&conn->chan_lock);
Johan Hedberg662d6522013-10-16 11:20:47 +03004478 cmd_reject_invalid_cid(conn, cmd->ident, dcid, scid);
4479 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004480 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004481
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004482 l2cap_chan_lock(chan);
4483
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03004484 rsp.dcid = cpu_to_le16(chan->scid);
4485 rsp.scid = cpu_to_le16(chan->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004486 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
4487
Gustavo Padovan5ec1bbe2013-10-15 19:24:48 -03004488 chan->ops->set_shutdown(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004489
Mat Martineau61d6ef32012-04-27 16:50:50 -07004490 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004491 l2cap_chan_del(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004492
4493 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004494
Gustavo Padovan80b98022012-05-27 22:27:51 -03004495 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004496 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004497
4498 mutex_unlock(&conn->chan_lock);
4499
Linus Torvalds1da177e2005-04-16 15:20:36 -07004500 return 0;
4501}
4502
Gustavo Padovan2d792812012-10-06 10:07:01 +01004503static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004504 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4505 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004506{
4507 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
4508 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004509 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004510
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004511 if (cmd_len != sizeof(*rsp))
4512 return -EPROTO;
4513
Linus Torvalds1da177e2005-04-16 15:20:36 -07004514 scid = __le16_to_cpu(rsp->scid);
4515 dcid = __le16_to_cpu(rsp->dcid);
4516
4517 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
4518
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004519 mutex_lock(&conn->chan_lock);
4520
4521 chan = __l2cap_get_chan_by_scid(conn, scid);
4522 if (!chan) {
4523 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004524 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004525 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004526
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004527 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004528
Mat Martineau61d6ef32012-04-27 16:50:50 -07004529 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004530 l2cap_chan_del(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004531
4532 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004533
Gustavo Padovan80b98022012-05-27 22:27:51 -03004534 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004535 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004536
4537 mutex_unlock(&conn->chan_lock);
4538
Linus Torvalds1da177e2005-04-16 15:20:36 -07004539 return 0;
4540}
4541
Gustavo Padovan2d792812012-10-06 10:07:01 +01004542static inline int l2cap_information_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004543 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4544 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004545{
4546 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004547 u16 type;
4548
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004549 if (cmd_len != sizeof(*req))
4550 return -EPROTO;
4551
Linus Torvalds1da177e2005-04-16 15:20:36 -07004552 type = __le16_to_cpu(req->type);
4553
4554 BT_DBG("type 0x%4.4x", type);
4555
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004556 if (type == L2CAP_IT_FEAT_MASK) {
4557 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07004558 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004559 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004560 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
4561 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03004562 if (!disable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004563 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
Gustavo Padovan2d792812012-10-06 10:07:01 +01004564 | L2CAP_FEAT_FCS;
Marcel Holtmann848566b2013-10-01 22:59:22 -07004565 if (conn->hs_enabled)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03004566 feat_mask |= L2CAP_FEAT_EXT_FLOW
Gustavo Padovan2d792812012-10-06 10:07:01 +01004567 | L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03004568
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03004569 put_unaligned_le32(feat_mask, rsp->data);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004570 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4571 buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004572 } else if (type == L2CAP_IT_FIXED_CHAN) {
4573 u8 buf[12];
4574 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Mat Martineau50a147c2011-11-02 16:18:34 -07004575
Marcel Holtmann848566b2013-10-01 22:59:22 -07004576 if (conn->hs_enabled)
Mat Martineau50a147c2011-11-02 16:18:34 -07004577 l2cap_fixed_chan[0] |= L2CAP_FC_A2MP;
4578 else
4579 l2cap_fixed_chan[0] &= ~L2CAP_FC_A2MP;
4580
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004581 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
4582 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Andrei Emeltchenkoc6337ea2011-10-20 17:02:44 +03004583 memcpy(rsp->data, l2cap_fixed_chan, sizeof(l2cap_fixed_chan));
Gustavo Padovan2d792812012-10-06 10:07:01 +01004584 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4585 buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004586 } else {
4587 struct l2cap_info_rsp rsp;
4588 rsp.type = cpu_to_le16(type);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004589 rsp.result = __constant_cpu_to_le16(L2CAP_IR_NOTSUPP);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004590 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(rsp),
4591 &rsp);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004592 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004593
4594 return 0;
4595}
4596
Gustavo Padovan2d792812012-10-06 10:07:01 +01004597static inline int l2cap_information_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004598 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4599 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004600{
4601 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
4602 u16 type, result;
4603
Jaganath Kanakkassery3f6fa3d2013-06-21 19:55:11 +05304604 if (cmd_len < sizeof(*rsp))
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004605 return -EPROTO;
4606
Linus Torvalds1da177e2005-04-16 15:20:36 -07004607 type = __le16_to_cpu(rsp->type);
4608 result = __le16_to_cpu(rsp->result);
4609
4610 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
4611
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004612 /* L2CAP Info req/rsp are unbound to channels, add extra checks */
4613 if (cmd->ident != conn->info_ident ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01004614 conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004615 return 0;
4616
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02004617 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004618
Ville Tervoadb08ed2010-08-04 09:43:33 +03004619 if (result != L2CAP_IR_SUCCESS) {
4620 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4621 conn->info_ident = 0;
4622
4623 l2cap_conn_start(conn);
4624
4625 return 0;
4626 }
4627
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004628 switch (type) {
4629 case L2CAP_IT_FEAT_MASK:
Harvey Harrison83985312008-05-02 16:25:46 -07004630 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004631
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07004632 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004633 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004634 req.type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004635
4636 conn->info_ident = l2cap_get_ident(conn);
4637
4638 l2cap_send_cmd(conn, conn->info_ident,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004639 L2CAP_INFO_REQ, sizeof(req), &req);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004640 } else {
4641 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4642 conn->info_ident = 0;
4643
4644 l2cap_conn_start(conn);
4645 }
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004646 break;
4647
4648 case L2CAP_IT_FIXED_CHAN:
4649 conn->fixed_chan_mask = rsp->data[0];
Marcel Holtmann984947d2009-02-06 23:35:19 +01004650 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004651 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004652
4653 l2cap_conn_start(conn);
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004654 break;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004655 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004656
Linus Torvalds1da177e2005-04-16 15:20:36 -07004657 return 0;
4658}
4659
Mat Martineau17009152012-10-23 15:24:07 -07004660static int l2cap_create_channel_req(struct l2cap_conn *conn,
4661 struct l2cap_cmd_hdr *cmd,
4662 u16 cmd_len, void *data)
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004663{
4664 struct l2cap_create_chan_req *req = data;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004665 struct l2cap_create_chan_rsp rsp;
Mat Martineau17009152012-10-23 15:24:07 -07004666 struct l2cap_chan *chan;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004667 struct hci_dev *hdev;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004668 u16 psm, scid;
4669
4670 if (cmd_len != sizeof(*req))
4671 return -EPROTO;
4672
Marcel Holtmann848566b2013-10-01 22:59:22 -07004673 if (!conn->hs_enabled)
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004674 return -EINVAL;
4675
4676 psm = le16_to_cpu(req->psm);
4677 scid = le16_to_cpu(req->scid);
4678
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004679 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 -07004680
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004681 /* For controller id 0 make BR/EDR connection */
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004682 if (req->amp_id == AMP_ID_BREDR) {
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004683 l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4684 req->amp_id);
4685 return 0;
4686 }
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004687
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004688 /* Validate AMP controller id */
4689 hdev = hci_dev_get(req->amp_id);
4690 if (!hdev)
4691 goto error;
Mat Martineau17009152012-10-23 15:24:07 -07004692
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004693 if (hdev->dev_type != HCI_AMP || !test_bit(HCI_UP, &hdev->flags)) {
Mat Martineau17009152012-10-23 15:24:07 -07004694 hci_dev_put(hdev);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004695 goto error;
Mat Martineau17009152012-10-23 15:24:07 -07004696 }
4697
4698 chan = l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4699 req->amp_id);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004700 if (chan) {
4701 struct amp_mgr *mgr = conn->hcon->amp_mgr;
4702 struct hci_conn *hs_hcon;
4703
Marcel Holtmann98e0f7e2013-10-13 02:23:40 -07004704 hs_hcon = hci_conn_hash_lookup_ba(hdev, AMP_LINK,
4705 &conn->hcon->dst);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004706 if (!hs_hcon) {
4707 hci_dev_put(hdev);
Johan Hedberg662d6522013-10-16 11:20:47 +03004708 cmd_reject_invalid_cid(conn, cmd->ident, chan->scid,
4709 chan->dcid);
4710 return 0;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004711 }
4712
4713 BT_DBG("mgr %p bredr_chan %p hs_hcon %p", mgr, chan, hs_hcon);
4714
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004715 mgr->bredr_chan = chan;
4716 chan->hs_hcon = hs_hcon;
Andrei Emeltchenkofd45bf42012-11-20 17:16:22 +02004717 chan->fcs = L2CAP_FCS_NONE;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004718 conn->mtu = hdev->block_mtu;
4719 }
4720
4721 hci_dev_put(hdev);
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004722
4723 return 0;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004724
4725error:
4726 rsp.dcid = 0;
4727 rsp.scid = cpu_to_le16(scid);
4728 rsp.result = __constant_cpu_to_le16(L2CAP_CR_BAD_AMP);
4729 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
4730
4731 l2cap_send_cmd(conn, cmd->ident, L2CAP_CREATE_CHAN_RSP,
4732 sizeof(rsp), &rsp);
4733
Johan Hedbergdc280802013-09-16 13:05:13 +03004734 return 0;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004735}
4736
Mat Martineau8eb200b2012-10-23 15:24:17 -07004737static void l2cap_send_move_chan_req(struct l2cap_chan *chan, u8 dest_amp_id)
4738{
4739 struct l2cap_move_chan_req req;
4740 u8 ident;
4741
4742 BT_DBG("chan %p, dest_amp_id %d", chan, dest_amp_id);
4743
4744 ident = l2cap_get_ident(chan->conn);
4745 chan->ident = ident;
4746
4747 req.icid = cpu_to_le16(chan->scid);
4748 req.dest_amp_id = dest_amp_id;
4749
4750 l2cap_send_cmd(chan->conn, ident, L2CAP_MOVE_CHAN_REQ, sizeof(req),
4751 &req);
4752
4753 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4754}
4755
Mat Martineau1500109b2012-10-23 15:24:15 -07004756static void l2cap_send_move_chan_rsp(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004757{
4758 struct l2cap_move_chan_rsp rsp;
4759
Mat Martineau1500109b2012-10-23 15:24:15 -07004760 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004761
Mat Martineau1500109b2012-10-23 15:24:15 -07004762 rsp.icid = cpu_to_le16(chan->dcid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004763 rsp.result = cpu_to_le16(result);
4764
Mat Martineau1500109b2012-10-23 15:24:15 -07004765 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_RSP,
4766 sizeof(rsp), &rsp);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004767}
4768
Mat Martineau5b155ef2012-10-23 15:24:14 -07004769static void l2cap_send_move_chan_cfm(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004770{
4771 struct l2cap_move_chan_cfm cfm;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004772
Mat Martineau5b155ef2012-10-23 15:24:14 -07004773 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004774
Mat Martineau5b155ef2012-10-23 15:24:14 -07004775 chan->ident = l2cap_get_ident(chan->conn);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004776
Mat Martineau5b155ef2012-10-23 15:24:14 -07004777 cfm.icid = cpu_to_le16(chan->scid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004778 cfm.result = cpu_to_le16(result);
4779
Mat Martineau5b155ef2012-10-23 15:24:14 -07004780 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_CFM,
4781 sizeof(cfm), &cfm);
4782
4783 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4784}
4785
4786static void l2cap_send_move_chan_cfm_icid(struct l2cap_conn *conn, u16 icid)
4787{
4788 struct l2cap_move_chan_cfm cfm;
4789
4790 BT_DBG("conn %p, icid 0x%4.4x", conn, icid);
4791
4792 cfm.icid = cpu_to_le16(icid);
4793 cfm.result = __constant_cpu_to_le16(L2CAP_MC_UNCONFIRMED);
4794
4795 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_MOVE_CHAN_CFM,
4796 sizeof(cfm), &cfm);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004797}
4798
4799static void l2cap_send_move_chan_cfm_rsp(struct l2cap_conn *conn, u8 ident,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004800 u16 icid)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004801{
4802 struct l2cap_move_chan_cfm_rsp rsp;
4803
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004804 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004805
4806 rsp.icid = cpu_to_le16(icid);
4807 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM_RSP, sizeof(rsp), &rsp);
4808}
4809
Mat Martineau5f3847a2012-10-23 15:24:12 -07004810static void __release_logical_link(struct l2cap_chan *chan)
4811{
4812 chan->hs_hchan = NULL;
4813 chan->hs_hcon = NULL;
4814
4815 /* Placeholder - release the logical link */
4816}
4817
Mat Martineau1500109b2012-10-23 15:24:15 -07004818static void l2cap_logical_fail(struct l2cap_chan *chan)
4819{
4820 /* Logical link setup failed */
4821 if (chan->state != BT_CONNECTED) {
4822 /* Create channel failure, disconnect */
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004823 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineau1500109b2012-10-23 15:24:15 -07004824 return;
4825 }
4826
4827 switch (chan->move_role) {
4828 case L2CAP_MOVE_ROLE_RESPONDER:
4829 l2cap_move_done(chan);
4830 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_SUPP);
4831 break;
4832 case L2CAP_MOVE_ROLE_INITIATOR:
4833 if (chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_COMP ||
4834 chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_CFM) {
4835 /* Remote has only sent pending or
4836 * success responses, clean up
4837 */
4838 l2cap_move_done(chan);
4839 }
4840
4841 /* Other amp move states imply that the move
4842 * has already aborted
4843 */
4844 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4845 break;
4846 }
4847}
4848
4849static void l2cap_logical_finish_create(struct l2cap_chan *chan,
4850 struct hci_chan *hchan)
4851{
4852 struct l2cap_conf_rsp rsp;
Mat Martineau1500109b2012-10-23 15:24:15 -07004853
Andrei Emeltchenko336178a2012-10-31 15:46:27 +02004854 chan->hs_hchan = hchan;
Mat Martineau1500109b2012-10-23 15:24:15 -07004855 chan->hs_hcon->l2cap_data = chan->conn;
4856
Andrei Emeltchenko35ba9562012-10-25 15:20:43 +03004857 l2cap_send_efs_conf_rsp(chan, &rsp, chan->ident, 0);
Mat Martineau1500109b2012-10-23 15:24:15 -07004858
4859 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Andrei Emeltchenkofe79c6f2012-10-25 15:20:42 +03004860 int err;
Mat Martineau1500109b2012-10-23 15:24:15 -07004861
4862 set_default_fcs(chan);
4863
4864 err = l2cap_ertm_init(chan);
4865 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004866 l2cap_send_disconn_req(chan, -err);
Mat Martineau1500109b2012-10-23 15:24:15 -07004867 else
4868 l2cap_chan_ready(chan);
4869 }
4870}
4871
4872static void l2cap_logical_finish_move(struct l2cap_chan *chan,
4873 struct hci_chan *hchan)
4874{
4875 chan->hs_hcon = hchan->conn;
4876 chan->hs_hcon->l2cap_data = chan->conn;
4877
4878 BT_DBG("move_state %d", chan->move_state);
4879
4880 switch (chan->move_state) {
4881 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
4882 /* Move confirm will be sent after a success
4883 * response is received
4884 */
4885 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4886 break;
4887 case L2CAP_MOVE_WAIT_LOGICAL_CFM:
4888 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4889 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4890 } else if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
4891 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
4892 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4893 } else if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
4894 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4895 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
4896 }
4897 break;
4898 default:
4899 /* Move was not in expected state, free the channel */
4900 __release_logical_link(chan);
4901
4902 chan->move_state = L2CAP_MOVE_STABLE;
4903 }
4904}
4905
4906/* Call with chan locked */
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03004907void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan,
4908 u8 status)
Mat Martineau5b155ef2012-10-23 15:24:14 -07004909{
Mat Martineau1500109b2012-10-23 15:24:15 -07004910 BT_DBG("chan %p, hchan %p, status %d", chan, hchan, status);
4911
4912 if (status) {
4913 l2cap_logical_fail(chan);
4914 __release_logical_link(chan);
4915 return;
4916 }
4917
4918 if (chan->state != BT_CONNECTED) {
4919 /* Ignore logical link if channel is on BR/EDR */
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004920 if (chan->local_amp_id != AMP_ID_BREDR)
Mat Martineau1500109b2012-10-23 15:24:15 -07004921 l2cap_logical_finish_create(chan, hchan);
4922 } else {
4923 l2cap_logical_finish_move(chan, hchan);
4924 }
Mat Martineau5b155ef2012-10-23 15:24:14 -07004925}
4926
Mat Martineau3f7a56c2012-10-23 15:24:23 -07004927void l2cap_move_start(struct l2cap_chan *chan)
4928{
4929 BT_DBG("chan %p", chan);
4930
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004931 if (chan->local_amp_id == AMP_ID_BREDR) {
Mat Martineau3f7a56c2012-10-23 15:24:23 -07004932 if (chan->chan_policy != BT_CHANNEL_POLICY_AMP_PREFERRED)
4933 return;
4934 chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
4935 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
4936 /* Placeholder - start physical link setup */
4937 } else {
4938 chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
4939 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4940 chan->move_id = 0;
4941 l2cap_move_setup(chan);
4942 l2cap_send_move_chan_req(chan, 0);
4943 }
4944}
4945
Mat Martineau8eb200b2012-10-23 15:24:17 -07004946static void l2cap_do_create(struct l2cap_chan *chan, int result,
4947 u8 local_amp_id, u8 remote_amp_id)
4948{
Andrei Emeltchenko62748ca2012-11-20 17:16:19 +02004949 BT_DBG("chan %p state %s %u -> %u", chan, state_to_string(chan->state),
4950 local_amp_id, remote_amp_id);
4951
Andrei Emeltchenko12d6cc62012-11-14 17:39:31 +02004952 chan->fcs = L2CAP_FCS_NONE;
4953
Andrei Emeltchenko62748ca2012-11-20 17:16:19 +02004954 /* Outgoing channel on AMP */
4955 if (chan->state == BT_CONNECT) {
4956 if (result == L2CAP_CR_SUCCESS) {
4957 chan->local_amp_id = local_amp_id;
4958 l2cap_send_create_chan_req(chan, remote_amp_id);
4959 } else {
4960 /* Revert to BR/EDR connect */
4961 l2cap_send_conn_req(chan);
4962 }
4963
4964 return;
4965 }
4966
4967 /* Incoming channel on AMP */
4968 if (__l2cap_no_conn_pending(chan)) {
Mat Martineau8eb200b2012-10-23 15:24:17 -07004969 struct l2cap_conn_rsp rsp;
4970 char buf[128];
4971 rsp.scid = cpu_to_le16(chan->dcid);
4972 rsp.dcid = cpu_to_le16(chan->scid);
4973
Mat Martineau8eb200b2012-10-23 15:24:17 -07004974 if (result == L2CAP_CR_SUCCESS) {
4975 /* Send successful response */
Andrei Emeltchenko62cd50e2012-11-14 17:39:32 +02004976 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
4977 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004978 } else {
4979 /* Send negative response */
Andrei Emeltchenko62cd50e2012-11-14 17:39:32 +02004980 rsp.result = __constant_cpu_to_le16(L2CAP_CR_NO_MEM);
4981 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004982 }
4983
4984 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_RSP,
4985 sizeof(rsp), &rsp);
4986
4987 if (result == L2CAP_CR_SUCCESS) {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02004988 l2cap_state_change(chan, BT_CONFIG);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004989 set_bit(CONF_REQ_SENT, &chan->conf_state);
4990 l2cap_send_cmd(chan->conn, l2cap_get_ident(chan->conn),
4991 L2CAP_CONF_REQ,
4992 l2cap_build_conf_req(chan, buf), buf);
4993 chan->num_conf_req++;
4994 }
Mat Martineau8eb200b2012-10-23 15:24:17 -07004995 }
4996}
4997
4998static void l2cap_do_move_initiate(struct l2cap_chan *chan, u8 local_amp_id,
4999 u8 remote_amp_id)
5000{
5001 l2cap_move_setup(chan);
5002 chan->move_id = local_amp_id;
5003 chan->move_state = L2CAP_MOVE_WAIT_RSP;
5004
5005 l2cap_send_move_chan_req(chan, remote_amp_id);
5006}
5007
5008static void l2cap_do_move_respond(struct l2cap_chan *chan, int result)
5009{
5010 struct hci_chan *hchan = NULL;
5011
5012 /* Placeholder - get hci_chan for logical link */
5013
5014 if (hchan) {
5015 if (hchan->state == BT_CONNECTED) {
5016 /* Logical link is ready to go */
5017 chan->hs_hcon = hchan->conn;
5018 chan->hs_hcon->l2cap_data = chan->conn;
5019 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
5020 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
5021
5022 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
5023 } else {
5024 /* Wait for logical link to be ready */
5025 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
5026 }
5027 } else {
5028 /* Logical link not available */
5029 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_ALLOWED);
5030 }
5031}
5032
5033static void l2cap_do_move_cancel(struct l2cap_chan *chan, int result)
5034{
5035 if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
5036 u8 rsp_result;
5037 if (result == -EINVAL)
5038 rsp_result = L2CAP_MR_BAD_ID;
5039 else
5040 rsp_result = L2CAP_MR_NOT_ALLOWED;
5041
5042 l2cap_send_move_chan_rsp(chan, rsp_result);
5043 }
5044
5045 chan->move_role = L2CAP_MOVE_ROLE_NONE;
5046 chan->move_state = L2CAP_MOVE_STABLE;
5047
5048 /* Restart data transmission */
5049 l2cap_ertm_send(chan);
5050}
5051
Andrei Emeltchenkoa514b172012-11-14 17:39:30 +02005052/* Invoke with locked chan */
5053void __l2cap_physical_cfm(struct l2cap_chan *chan, int result)
Mat Martineau8eb200b2012-10-23 15:24:17 -07005054{
Andrei Emeltchenko770bfef2012-10-31 15:46:29 +02005055 u8 local_amp_id = chan->local_amp_id;
Andrei Emeltchenkofffadc02012-11-01 15:37:03 +02005056 u8 remote_amp_id = chan->remote_amp_id;
Andrei Emeltchenko770bfef2012-10-31 15:46:29 +02005057
Mat Martineau8eb200b2012-10-23 15:24:17 -07005058 BT_DBG("chan %p, result %d, local_amp_id %d, remote_amp_id %d",
5059 chan, result, local_amp_id, remote_amp_id);
5060
Mat Martineau8eb200b2012-10-23 15:24:17 -07005061 if (chan->state == BT_DISCONN || chan->state == BT_CLOSED) {
5062 l2cap_chan_unlock(chan);
5063 return;
5064 }
5065
5066 if (chan->state != BT_CONNECTED) {
5067 l2cap_do_create(chan, result, local_amp_id, remote_amp_id);
5068 } else if (result != L2CAP_MR_SUCCESS) {
5069 l2cap_do_move_cancel(chan, result);
5070 } else {
5071 switch (chan->move_role) {
5072 case L2CAP_MOVE_ROLE_INITIATOR:
5073 l2cap_do_move_initiate(chan, local_amp_id,
5074 remote_amp_id);
5075 break;
5076 case L2CAP_MOVE_ROLE_RESPONDER:
5077 l2cap_do_move_respond(chan, result);
5078 break;
5079 default:
5080 l2cap_do_move_cancel(chan, result);
5081 break;
5082 }
5083 }
Mat Martineau8eb200b2012-10-23 15:24:17 -07005084}
5085
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005086static inline int l2cap_move_channel_req(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005087 struct l2cap_cmd_hdr *cmd,
5088 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005089{
5090 struct l2cap_move_chan_req *req = data;
Mat Martineau1500109b2012-10-23 15:24:15 -07005091 struct l2cap_move_chan_rsp rsp;
Mat Martineau02b0fbb2012-10-23 15:24:10 -07005092 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005093 u16 icid = 0;
5094 u16 result = L2CAP_MR_NOT_ALLOWED;
5095
5096 if (cmd_len != sizeof(*req))
5097 return -EPROTO;
5098
5099 icid = le16_to_cpu(req->icid);
5100
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005101 BT_DBG("icid 0x%4.4x, dest_amp_id %d", icid, req->dest_amp_id);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005102
Marcel Holtmann848566b2013-10-01 22:59:22 -07005103 if (!conn->hs_enabled)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005104 return -EINVAL;
5105
Mat Martineau02b0fbb2012-10-23 15:24:10 -07005106 chan = l2cap_get_chan_by_dcid(conn, icid);
5107 if (!chan) {
Mat Martineau1500109b2012-10-23 15:24:15 -07005108 rsp.icid = cpu_to_le16(icid);
5109 rsp.result = __constant_cpu_to_le16(L2CAP_MR_NOT_ALLOWED);
5110 l2cap_send_cmd(conn, cmd->ident, L2CAP_MOVE_CHAN_RSP,
5111 sizeof(rsp), &rsp);
Mat Martineau02b0fbb2012-10-23 15:24:10 -07005112 return 0;
5113 }
5114
Mat Martineau1500109b2012-10-23 15:24:15 -07005115 chan->ident = cmd->ident;
5116
Mat Martineau02b0fbb2012-10-23 15:24:10 -07005117 if (chan->scid < L2CAP_CID_DYN_START ||
5118 chan->chan_policy == BT_CHANNEL_POLICY_BREDR_ONLY ||
5119 (chan->mode != L2CAP_MODE_ERTM &&
5120 chan->mode != L2CAP_MODE_STREAMING)) {
5121 result = L2CAP_MR_NOT_ALLOWED;
5122 goto send_move_response;
5123 }
5124
5125 if (chan->local_amp_id == req->dest_amp_id) {
5126 result = L2CAP_MR_SAME_ID;
5127 goto send_move_response;
5128 }
5129
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07005130 if (req->dest_amp_id != AMP_ID_BREDR) {
Mat Martineau02b0fbb2012-10-23 15:24:10 -07005131 struct hci_dev *hdev;
5132 hdev = hci_dev_get(req->dest_amp_id);
5133 if (!hdev || hdev->dev_type != HCI_AMP ||
5134 !test_bit(HCI_UP, &hdev->flags)) {
5135 if (hdev)
5136 hci_dev_put(hdev);
5137
5138 result = L2CAP_MR_BAD_ID;
5139 goto send_move_response;
5140 }
5141 hci_dev_put(hdev);
5142 }
5143
5144 /* Detect a move collision. Only send a collision response
5145 * if this side has "lost", otherwise proceed with the move.
5146 * The winner has the larger bd_addr.
5147 */
5148 if ((__chan_is_moving(chan) ||
5149 chan->move_role != L2CAP_MOVE_ROLE_NONE) &&
Marcel Holtmann6f59b902013-10-13 05:24:01 -07005150 bacmp(&conn->hcon->src, &conn->hcon->dst) > 0) {
Mat Martineau02b0fbb2012-10-23 15:24:10 -07005151 result = L2CAP_MR_COLLISION;
5152 goto send_move_response;
5153 }
5154
Mat Martineau02b0fbb2012-10-23 15:24:10 -07005155 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
5156 l2cap_move_setup(chan);
5157 chan->move_id = req->dest_amp_id;
5158 icid = chan->dcid;
5159
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07005160 if (req->dest_amp_id == AMP_ID_BREDR) {
Mat Martineau02b0fbb2012-10-23 15:24:10 -07005161 /* Moving to BR/EDR */
5162 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5163 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
5164 result = L2CAP_MR_PEND;
5165 } else {
5166 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
5167 result = L2CAP_MR_SUCCESS;
5168 }
5169 } else {
5170 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
5171 /* Placeholder - uncomment when amp functions are available */
5172 /*amp_accept_physical(chan, req->dest_amp_id);*/
5173 result = L2CAP_MR_PEND;
5174 }
5175
5176send_move_response:
Mat Martineau1500109b2012-10-23 15:24:15 -07005177 l2cap_send_move_chan_rsp(chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005178
Mat Martineau02b0fbb2012-10-23 15:24:10 -07005179 l2cap_chan_unlock(chan);
5180
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005181 return 0;
5182}
5183
Mat Martineau5b155ef2012-10-23 15:24:14 -07005184static void l2cap_move_continue(struct l2cap_conn *conn, u16 icid, u16 result)
5185{
5186 struct l2cap_chan *chan;
5187 struct hci_chan *hchan = NULL;
5188
5189 chan = l2cap_get_chan_by_scid(conn, icid);
5190 if (!chan) {
5191 l2cap_send_move_chan_cfm_icid(conn, icid);
5192 return;
5193 }
5194
5195 __clear_chan_timer(chan);
5196 if (result == L2CAP_MR_PEND)
5197 __set_chan_timer(chan, L2CAP_MOVE_ERTX_TIMEOUT);
5198
5199 switch (chan->move_state) {
5200 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
5201 /* Move confirm will be sent when logical link
5202 * is complete.
5203 */
5204 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
5205 break;
5206 case L2CAP_MOVE_WAIT_RSP_SUCCESS:
5207 if (result == L2CAP_MR_PEND) {
5208 break;
5209 } else if (test_bit(CONN_LOCAL_BUSY,
5210 &chan->conn_state)) {
5211 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
5212 } else {
5213 /* Logical link is up or moving to BR/EDR,
5214 * proceed with move
5215 */
5216 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
5217 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
5218 }
5219 break;
5220 case L2CAP_MOVE_WAIT_RSP:
5221 /* Moving to AMP */
5222 if (result == L2CAP_MR_SUCCESS) {
5223 /* Remote is ready, send confirm immediately
5224 * after logical link is ready
5225 */
5226 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
5227 } else {
5228 /* Both logical link and move success
5229 * are required to confirm
5230 */
5231 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_COMP;
5232 }
5233
5234 /* Placeholder - get hci_chan for logical link */
5235 if (!hchan) {
5236 /* Logical link not available */
5237 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
5238 break;
5239 }
5240
5241 /* If the logical link is not yet connected, do not
5242 * send confirmation.
5243 */
5244 if (hchan->state != BT_CONNECTED)
5245 break;
5246
5247 /* Logical link is already ready to go */
5248
5249 chan->hs_hcon = hchan->conn;
5250 chan->hs_hcon->l2cap_data = chan->conn;
5251
5252 if (result == L2CAP_MR_SUCCESS) {
5253 /* Can confirm now */
5254 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
5255 } else {
5256 /* Now only need move success
5257 * to confirm
5258 */
5259 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
5260 }
5261
5262 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
5263 break;
5264 default:
5265 /* Any other amp move state means the move failed. */
5266 chan->move_id = chan->local_amp_id;
5267 l2cap_move_done(chan);
5268 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
5269 }
5270
5271 l2cap_chan_unlock(chan);
5272}
5273
5274static void l2cap_move_fail(struct l2cap_conn *conn, u8 ident, u16 icid,
5275 u16 result)
5276{
5277 struct l2cap_chan *chan;
5278
5279 chan = l2cap_get_chan_by_ident(conn, ident);
5280 if (!chan) {
5281 /* Could not locate channel, icid is best guess */
5282 l2cap_send_move_chan_cfm_icid(conn, icid);
5283 return;
5284 }
5285
5286 __clear_chan_timer(chan);
5287
5288 if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
5289 if (result == L2CAP_MR_COLLISION) {
5290 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
5291 } else {
5292 /* Cleanup - cancel move */
5293 chan->move_id = chan->local_amp_id;
5294 l2cap_move_done(chan);
5295 }
5296 }
5297
5298 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
5299
5300 l2cap_chan_unlock(chan);
5301}
5302
5303static int l2cap_move_channel_rsp(struct l2cap_conn *conn,
5304 struct l2cap_cmd_hdr *cmd,
5305 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005306{
5307 struct l2cap_move_chan_rsp *rsp = data;
5308 u16 icid, result;
5309
5310 if (cmd_len != sizeof(*rsp))
5311 return -EPROTO;
5312
5313 icid = le16_to_cpu(rsp->icid);
5314 result = le16_to_cpu(rsp->result);
5315
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005316 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005317
Mat Martineau5b155ef2012-10-23 15:24:14 -07005318 if (result == L2CAP_MR_SUCCESS || result == L2CAP_MR_PEND)
5319 l2cap_move_continue(conn, icid, result);
5320 else
5321 l2cap_move_fail(conn, cmd->ident, icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005322
5323 return 0;
5324}
5325
Mat Martineau5f3847a2012-10-23 15:24:12 -07005326static int l2cap_move_channel_confirm(struct l2cap_conn *conn,
5327 struct l2cap_cmd_hdr *cmd,
5328 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005329{
5330 struct l2cap_move_chan_cfm *cfm = data;
Mat Martineau5f3847a2012-10-23 15:24:12 -07005331 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005332 u16 icid, result;
5333
5334 if (cmd_len != sizeof(*cfm))
5335 return -EPROTO;
5336
5337 icid = le16_to_cpu(cfm->icid);
5338 result = le16_to_cpu(cfm->result);
5339
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005340 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005341
Mat Martineau5f3847a2012-10-23 15:24:12 -07005342 chan = l2cap_get_chan_by_dcid(conn, icid);
5343 if (!chan) {
5344 /* Spec requires a response even if the icid was not found */
5345 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
5346 return 0;
5347 }
5348
5349 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM) {
5350 if (result == L2CAP_MC_CONFIRMED) {
5351 chan->local_amp_id = chan->move_id;
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07005352 if (chan->local_amp_id == AMP_ID_BREDR)
Mat Martineau5f3847a2012-10-23 15:24:12 -07005353 __release_logical_link(chan);
5354 } else {
5355 chan->move_id = chan->local_amp_id;
5356 }
5357
5358 l2cap_move_done(chan);
5359 }
5360
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005361 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
5362
Mat Martineau5f3847a2012-10-23 15:24:12 -07005363 l2cap_chan_unlock(chan);
5364
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005365 return 0;
5366}
5367
5368static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005369 struct l2cap_cmd_hdr *cmd,
5370 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005371{
5372 struct l2cap_move_chan_cfm_rsp *rsp = data;
Mat Martineau3fd71a02012-10-23 15:24:16 -07005373 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005374 u16 icid;
5375
5376 if (cmd_len != sizeof(*rsp))
5377 return -EPROTO;
5378
5379 icid = le16_to_cpu(rsp->icid);
5380
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005381 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005382
Mat Martineau3fd71a02012-10-23 15:24:16 -07005383 chan = l2cap_get_chan_by_scid(conn, icid);
5384 if (!chan)
5385 return 0;
5386
5387 __clear_chan_timer(chan);
5388
5389 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM_RSP) {
5390 chan->local_amp_id = chan->move_id;
5391
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07005392 if (chan->local_amp_id == AMP_ID_BREDR && chan->hs_hchan)
Mat Martineau3fd71a02012-10-23 15:24:16 -07005393 __release_logical_link(chan);
5394
5395 l2cap_move_done(chan);
5396 }
5397
5398 l2cap_chan_unlock(chan);
5399
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005400 return 0;
5401}
5402
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03005403static inline int l2cap_check_conn_param(u16 min, u16 max, u16 latency,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005404 u16 to_multiplier)
Claudio Takahaside731152011-02-11 19:28:55 -02005405{
5406 u16 max_latency;
5407
5408 if (min > max || min < 6 || max > 3200)
5409 return -EINVAL;
5410
5411 if (to_multiplier < 10 || to_multiplier > 3200)
5412 return -EINVAL;
5413
5414 if (max >= to_multiplier * 8)
5415 return -EINVAL;
5416
5417 max_latency = (to_multiplier * 8 / max) - 1;
5418 if (latency > 499 || latency > max_latency)
5419 return -EINVAL;
5420
5421 return 0;
5422}
5423
5424static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005425 struct l2cap_cmd_hdr *cmd,
Johan Hedberg203e6392013-05-15 10:07:15 +03005426 u16 cmd_len, u8 *data)
Claudio Takahaside731152011-02-11 19:28:55 -02005427{
5428 struct hci_conn *hcon = conn->hcon;
5429 struct l2cap_conn_param_update_req *req;
5430 struct l2cap_conn_param_update_rsp rsp;
Johan Hedberg203e6392013-05-15 10:07:15 +03005431 u16 min, max, latency, to_multiplier;
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005432 int err;
Claudio Takahaside731152011-02-11 19:28:55 -02005433
5434 if (!(hcon->link_mode & HCI_LM_MASTER))
5435 return -EINVAL;
5436
Claudio Takahaside731152011-02-11 19:28:55 -02005437 if (cmd_len != sizeof(struct l2cap_conn_param_update_req))
5438 return -EPROTO;
5439
5440 req = (struct l2cap_conn_param_update_req *) data;
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03005441 min = __le16_to_cpu(req->min);
5442 max = __le16_to_cpu(req->max);
Claudio Takahaside731152011-02-11 19:28:55 -02005443 latency = __le16_to_cpu(req->latency);
5444 to_multiplier = __le16_to_cpu(req->to_multiplier);
5445
5446 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 +01005447 min, max, latency, to_multiplier);
Claudio Takahaside731152011-02-11 19:28:55 -02005448
5449 memset(&rsp, 0, sizeof(rsp));
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005450
5451 err = l2cap_check_conn_param(min, max, latency, to_multiplier);
5452 if (err)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005453 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
Claudio Takahaside731152011-02-11 19:28:55 -02005454 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005455 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED);
Claudio Takahaside731152011-02-11 19:28:55 -02005456
5457 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005458 sizeof(rsp), &rsp);
Claudio Takahaside731152011-02-11 19:28:55 -02005459
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005460 if (!err)
5461 hci_le_conn_update(hcon, min, max, latency, to_multiplier);
5462
Claudio Takahaside731152011-02-11 19:28:55 -02005463 return 0;
5464}
5465
Johan Hedbergf1496de2013-05-13 14:15:56 +03005466static int l2cap_le_connect_rsp(struct l2cap_conn *conn,
5467 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5468 u8 *data)
5469{
5470 struct l2cap_le_conn_rsp *rsp = (struct l2cap_le_conn_rsp *) data;
5471 u16 dcid, mtu, mps, credits, result;
5472 struct l2cap_chan *chan;
5473 int err;
5474
5475 if (cmd_len < sizeof(*rsp))
5476 return -EPROTO;
5477
5478 dcid = __le16_to_cpu(rsp->dcid);
5479 mtu = __le16_to_cpu(rsp->mtu);
5480 mps = __le16_to_cpu(rsp->mps);
5481 credits = __le16_to_cpu(rsp->credits);
5482 result = __le16_to_cpu(rsp->result);
5483
5484 if (result == L2CAP_CR_SUCCESS && (mtu < 23 || mps < 23))
5485 return -EPROTO;
5486
5487 BT_DBG("dcid 0x%4.4x mtu %u mps %u credits %u result 0x%2.2x",
5488 dcid, mtu, mps, credits, result);
5489
5490 mutex_lock(&conn->chan_lock);
5491
5492 chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
5493 if (!chan) {
5494 err = -EBADSLT;
5495 goto unlock;
5496 }
5497
5498 err = 0;
5499
5500 l2cap_chan_lock(chan);
5501
5502 switch (result) {
5503 case L2CAP_CR_SUCCESS:
5504 chan->ident = 0;
5505 chan->dcid = dcid;
5506 chan->omtu = mtu;
5507 chan->remote_mps = mps;
Johan Hedberg0cd75f72013-05-17 13:09:05 +03005508 chan->tx_credits = credits;
Johan Hedbergf1496de2013-05-13 14:15:56 +03005509 l2cap_chan_ready(chan);
5510 break;
5511
5512 default:
5513 l2cap_chan_del(chan, ECONNREFUSED);
5514 break;
5515 }
5516
5517 l2cap_chan_unlock(chan);
5518
5519unlock:
5520 mutex_unlock(&conn->chan_lock);
5521
5522 return err;
5523}
5524
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005525static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005526 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5527 u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005528{
5529 int err = 0;
5530
5531 switch (cmd->code) {
5532 case L2CAP_COMMAND_REJ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005533 l2cap_command_rej(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005534 break;
5535
5536 case L2CAP_CONN_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005537 err = l2cap_connect_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005538 break;
5539
5540 case L2CAP_CONN_RSP:
Mat Martineauf5a25982012-10-11 17:48:21 +03005541 case L2CAP_CREATE_CHAN_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005542 l2cap_connect_create_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005543 break;
5544
5545 case L2CAP_CONF_REQ:
5546 err = l2cap_config_req(conn, cmd, cmd_len, data);
5547 break;
5548
5549 case L2CAP_CONF_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005550 l2cap_config_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005551 break;
5552
5553 case L2CAP_DISCONN_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005554 err = l2cap_disconnect_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005555 break;
5556
5557 case L2CAP_DISCONN_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005558 l2cap_disconnect_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005559 break;
5560
5561 case L2CAP_ECHO_REQ:
5562 l2cap_send_cmd(conn, cmd->ident, L2CAP_ECHO_RSP, cmd_len, data);
5563 break;
5564
5565 case L2CAP_ECHO_RSP:
5566 break;
5567
5568 case L2CAP_INFO_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005569 err = l2cap_information_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005570 break;
5571
5572 case L2CAP_INFO_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005573 l2cap_information_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005574 break;
5575
Mat Martineauf94ff6f2011-11-02 16:18:32 -07005576 case L2CAP_CREATE_CHAN_REQ:
5577 err = l2cap_create_channel_req(conn, cmd, cmd_len, data);
5578 break;
5579
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005580 case L2CAP_MOVE_CHAN_REQ:
5581 err = l2cap_move_channel_req(conn, cmd, cmd_len, data);
5582 break;
5583
5584 case L2CAP_MOVE_CHAN_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005585 l2cap_move_channel_rsp(conn, cmd, cmd_len, data);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005586 break;
5587
5588 case L2CAP_MOVE_CHAN_CFM:
5589 err = l2cap_move_channel_confirm(conn, cmd, cmd_len, data);
5590 break;
5591
5592 case L2CAP_MOVE_CHAN_CFM_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005593 l2cap_move_channel_confirm_rsp(conn, cmd, cmd_len, data);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005594 break;
5595
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005596 default:
5597 BT_ERR("Unknown BR/EDR signaling command 0x%2.2x", cmd->code);
5598 err = -EINVAL;
5599 break;
5600 }
5601
5602 return err;
5603}
5604
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005605static int l2cap_le_connect_req(struct l2cap_conn *conn,
5606 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5607 u8 *data)
5608{
5609 struct l2cap_le_conn_req *req = (struct l2cap_le_conn_req *) data;
5610 struct l2cap_le_conn_rsp rsp;
5611 struct l2cap_chan *chan, *pchan;
Johan Hedberg0cd75f72013-05-17 13:09:05 +03005612 u16 dcid, scid, credits, mtu, mps;
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005613 __le16 psm;
5614 u8 result;
5615
5616 if (cmd_len != sizeof(*req))
5617 return -EPROTO;
5618
5619 scid = __le16_to_cpu(req->scid);
5620 mtu = __le16_to_cpu(req->mtu);
5621 mps = __le16_to_cpu(req->mps);
5622 psm = req->psm;
5623 dcid = 0;
Johan Hedberg0cd75f72013-05-17 13:09:05 +03005624 credits = 0;
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005625
5626 if (mtu < 23 || mps < 23)
5627 return -EPROTO;
5628
5629 BT_DBG("psm 0x%2.2x scid 0x%4.4x mtu %u mps %u", __le16_to_cpu(psm),
5630 scid, mtu, mps);
5631
5632 /* Check if we have socket listening on psm */
5633 pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, &conn->hcon->src,
5634 &conn->hcon->dst, LE_LINK);
5635 if (!pchan) {
5636 result = L2CAP_CR_BAD_PSM;
5637 chan = NULL;
5638 goto response;
5639 }
5640
5641 mutex_lock(&conn->chan_lock);
5642 l2cap_chan_lock(pchan);
5643
5644 if (!smp_sufficient_security(conn->hcon, pchan->sec_level)) {
5645 result = L2CAP_CR_AUTHENTICATION;
5646 chan = NULL;
5647 goto response_unlock;
5648 }
5649
5650 /* Check if we already have channel with that dcid */
5651 if (__l2cap_get_chan_by_dcid(conn, scid)) {
5652 result = L2CAP_CR_NO_MEM;
5653 chan = NULL;
5654 goto response_unlock;
5655 }
5656
5657 chan = pchan->ops->new_connection(pchan);
5658 if (!chan) {
5659 result = L2CAP_CR_NO_MEM;
5660 goto response_unlock;
5661 }
5662
5663 bacpy(&chan->src, &conn->hcon->src);
5664 bacpy(&chan->dst, &conn->hcon->dst);
5665 chan->src_type = bdaddr_type(conn->hcon, conn->hcon->src_type);
5666 chan->dst_type = bdaddr_type(conn->hcon, conn->hcon->dst_type);
5667 chan->psm = psm;
5668 chan->dcid = scid;
5669 chan->omtu = mtu;
5670 chan->remote_mps = mps;
Johan Hedberg0cd75f72013-05-17 13:09:05 +03005671 chan->tx_credits = __le16_to_cpu(req->credits);
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005672
5673 __l2cap_chan_add(conn, chan);
5674 dcid = chan->scid;
Johan Hedberg0cd75f72013-05-17 13:09:05 +03005675 credits = chan->rx_credits;
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005676
5677 __set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
5678
5679 chan->ident = cmd->ident;
5680
5681 if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
5682 l2cap_state_change(chan, BT_CONNECT2);
5683 result = L2CAP_CR_PEND;
5684 chan->ops->defer(chan);
5685 } else {
5686 l2cap_chan_ready(chan);
5687 result = L2CAP_CR_SUCCESS;
5688 }
5689
5690response_unlock:
5691 l2cap_chan_unlock(pchan);
5692 mutex_unlock(&conn->chan_lock);
5693
5694 if (result == L2CAP_CR_PEND)
5695 return 0;
5696
5697response:
5698 if (chan) {
5699 rsp.mtu = cpu_to_le16(chan->imtu);
Johan Hedberg3916aed2013-10-07 15:35:26 +02005700 rsp.mps = cpu_to_le16(chan->mps);
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005701 } else {
5702 rsp.mtu = 0;
5703 rsp.mps = 0;
5704 }
5705
5706 rsp.dcid = cpu_to_le16(dcid);
Johan Hedberg0cd75f72013-05-17 13:09:05 +03005707 rsp.credits = cpu_to_le16(credits);
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005708 rsp.result = cpu_to_le16(result);
5709
5710 l2cap_send_cmd(conn, cmd->ident, L2CAP_LE_CONN_RSP, sizeof(rsp), &rsp);
5711
5712 return 0;
5713}
5714
Johan Hedbergfad5fc82013-12-05 09:45:01 +02005715static inline int l2cap_le_credits(struct l2cap_conn *conn,
5716 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5717 u8 *data)
5718{
5719 struct l2cap_le_credits *pkt;
5720 struct l2cap_chan *chan;
5721 u16 cid, credits;
5722
5723 if (cmd_len != sizeof(*pkt))
5724 return -EPROTO;
5725
5726 pkt = (struct l2cap_le_credits *) data;
5727 cid = __le16_to_cpu(pkt->cid);
5728 credits = __le16_to_cpu(pkt->credits);
5729
5730 BT_DBG("cid 0x%4.4x credits 0x%4.4x", cid, credits);
5731
5732 chan = l2cap_get_chan_by_dcid(conn, cid);
5733 if (!chan)
5734 return -EBADSLT;
5735
5736 chan->tx_credits += credits;
5737
5738 while (chan->tx_credits && !skb_queue_empty(&chan->tx_q)) {
5739 l2cap_do_send(chan, skb_dequeue(&chan->tx_q));
5740 chan->tx_credits--;
5741 }
5742
5743 if (chan->tx_credits)
5744 chan->ops->resume(chan);
5745
5746 l2cap_chan_unlock(chan);
5747
5748 return 0;
5749}
5750
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005751static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn,
Johan Hedberg203e6392013-05-15 10:07:15 +03005752 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5753 u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005754{
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005755 int err = 0;
5756
Johan Hedberg3af8ace2013-12-03 09:51:51 +02005757 if (!enable_lecoc) {
5758 switch (cmd->code) {
5759 case L2CAP_LE_CONN_REQ:
5760 case L2CAP_LE_CONN_RSP:
5761 case L2CAP_LE_CREDITS:
5762 case L2CAP_DISCONN_REQ:
5763 case L2CAP_DISCONN_RSP:
5764 return -EINVAL;
5765 }
5766 }
5767
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005768 switch (cmd->code) {
5769 case L2CAP_COMMAND_REJ:
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005770 break;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005771
5772 case L2CAP_CONN_PARAM_UPDATE_REQ:
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005773 err = l2cap_conn_param_update_req(conn, cmd, cmd_len, data);
5774 break;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005775
5776 case L2CAP_CONN_PARAM_UPDATE_RSP:
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005777 break;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005778
Johan Hedbergf1496de2013-05-13 14:15:56 +03005779 case L2CAP_LE_CONN_RSP:
5780 l2cap_le_connect_rsp(conn, cmd, cmd_len, data);
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005781 break;
Johan Hedbergf1496de2013-05-13 14:15:56 +03005782
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005783 case L2CAP_LE_CONN_REQ:
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005784 err = l2cap_le_connect_req(conn, cmd, cmd_len, data);
5785 break;
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005786
Johan Hedbergfad5fc82013-12-05 09:45:01 +02005787 case L2CAP_LE_CREDITS:
5788 err = l2cap_le_credits(conn, cmd, cmd_len, data);
5789 break;
5790
Johan Hedberg3defe012013-05-15 10:16:06 +03005791 case L2CAP_DISCONN_REQ:
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005792 err = l2cap_disconnect_req(conn, cmd, cmd_len, data);
5793 break;
Johan Hedberg3defe012013-05-15 10:16:06 +03005794
5795 case L2CAP_DISCONN_RSP:
5796 l2cap_disconnect_rsp(conn, cmd, cmd_len, data);
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005797 break;
Johan Hedberg3defe012013-05-15 10:16:06 +03005798
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005799 default:
5800 BT_ERR("Unknown LE signaling command 0x%2.2x", cmd->code);
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005801 err = -EINVAL;
5802 break;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005803 }
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005804
5805 return err;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005806}
5807
Johan Hedbergc5623552013-04-29 19:35:33 +03005808static inline void l2cap_le_sig_channel(struct l2cap_conn *conn,
5809 struct sk_buff *skb)
5810{
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005811 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005812 struct l2cap_cmd_hdr *cmd;
5813 u16 len;
Johan Hedbergc5623552013-04-29 19:35:33 +03005814 int err;
5815
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005816 if (hcon->type != LE_LINK)
Marcel Holtmann3b166292013-10-02 08:28:21 -07005817 goto drop;
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005818
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005819 if (skb->len < L2CAP_CMD_HDR_SIZE)
5820 goto drop;
Johan Hedbergc5623552013-04-29 19:35:33 +03005821
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005822 cmd = (void *) skb->data;
5823 skb_pull(skb, L2CAP_CMD_HDR_SIZE);
Johan Hedbergc5623552013-04-29 19:35:33 +03005824
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005825 len = le16_to_cpu(cmd->len);
Johan Hedbergc5623552013-04-29 19:35:33 +03005826
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005827 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd->code, len, cmd->ident);
Johan Hedbergc5623552013-04-29 19:35:33 +03005828
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005829 if (len != skb->len || !cmd->ident) {
5830 BT_DBG("corrupted command");
5831 goto drop;
5832 }
Johan Hedbergc5623552013-04-29 19:35:33 +03005833
Johan Hedberg203e6392013-05-15 10:07:15 +03005834 err = l2cap_le_sig_cmd(conn, cmd, len, skb->data);
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005835 if (err) {
5836 struct l2cap_cmd_rej_unk rej;
Johan Hedbergc5623552013-04-29 19:35:33 +03005837
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005838 BT_ERR("Wrong link type (%d)", err);
Johan Hedbergc5623552013-04-29 19:35:33 +03005839
Johan Hedberga5211492013-10-16 11:20:49 +03005840 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005841 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
5842 sizeof(rej), &rej);
Johan Hedbergc5623552013-04-29 19:35:33 +03005843 }
5844
Marcel Holtmann3b166292013-10-02 08:28:21 -07005845drop:
Johan Hedbergc5623552013-04-29 19:35:33 +03005846 kfree_skb(skb);
5847}
5848
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005849static inline void l2cap_sig_channel(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005850 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005851{
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005852 struct hci_conn *hcon = conn->hcon;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005853 u8 *data = skb->data;
5854 int len = skb->len;
5855 struct l2cap_cmd_hdr cmd;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005856 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005857
5858 l2cap_raw_recv(conn, skb);
5859
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005860 if (hcon->type != ACL_LINK)
Marcel Holtmann3b166292013-10-02 08:28:21 -07005861 goto drop;
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005862
Linus Torvalds1da177e2005-04-16 15:20:36 -07005863 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07005864 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005865 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
5866 data += L2CAP_CMD_HDR_SIZE;
5867 len -= L2CAP_CMD_HDR_SIZE;
5868
Al Viro88219a02007-07-29 00:17:25 -07005869 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005870
Gustavo Padovan2d792812012-10-06 10:07:01 +01005871 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len,
5872 cmd.ident);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005873
Al Viro88219a02007-07-29 00:17:25 -07005874 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005875 BT_DBG("corrupted command");
5876 break;
5877 }
5878
Johan Hedbergc5623552013-04-29 19:35:33 +03005879 err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005880 if (err) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03005881 struct l2cap_cmd_rej_unk rej;
Gustavo F. Padovan2c6d1a22011-03-23 14:38:32 -03005882
5883 BT_ERR("Wrong link type (%d)", err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005884
Johan Hedberga5211492013-10-16 11:20:49 +03005885 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
Gustavo Padovan2d792812012-10-06 10:07:01 +01005886 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ,
5887 sizeof(rej), &rej);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005888 }
5889
Al Viro88219a02007-07-29 00:17:25 -07005890 data += cmd_len;
5891 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005892 }
5893
Marcel Holtmann3b166292013-10-02 08:28:21 -07005894drop:
Linus Torvalds1da177e2005-04-16 15:20:36 -07005895 kfree_skb(skb);
5896}
5897
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005898static int l2cap_check_fcs(struct l2cap_chan *chan, struct sk_buff *skb)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005899{
5900 u16 our_fcs, rcv_fcs;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03005901 int hdr_size;
5902
5903 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
5904 hdr_size = L2CAP_EXT_HDR_SIZE;
5905 else
5906 hdr_size = L2CAP_ENH_HDR_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005907
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005908 if (chan->fcs == L2CAP_FCS_CRC16) {
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005909 skb_trim(skb, skb->len - L2CAP_FCS_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005910 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
5911 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
5912
5913 if (our_fcs != rcv_fcs)
João Paulo Rechi Vita7a560e52010-06-22 13:56:27 -03005914 return -EBADMSG;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005915 }
5916 return 0;
5917}
5918
Mat Martineau6ea00482012-05-17 20:53:52 -07005919static void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan)
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005920{
Mat Martineaue31f7632012-05-17 20:53:41 -07005921 struct l2cap_ctrl control;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005922
Mat Martineaue31f7632012-05-17 20:53:41 -07005923 BT_DBG("chan %p", chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005924
Mat Martineaue31f7632012-05-17 20:53:41 -07005925 memset(&control, 0, sizeof(control));
5926 control.sframe = 1;
5927 control.final = 1;
5928 control.reqseq = chan->buffer_seq;
5929 set_bit(CONN_SEND_FBIT, &chan->conn_state);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005930
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03005931 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
Mat Martineaue31f7632012-05-17 20:53:41 -07005932 control.super = L2CAP_SUPER_RNR;
5933 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005934 }
5935
Mat Martineaue31f7632012-05-17 20:53:41 -07005936 if (test_and_clear_bit(CONN_REMOTE_BUSY, &chan->conn_state) &&
5937 chan->unacked_frames > 0)
5938 __set_retrans_timer(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005939
Mat Martineaue31f7632012-05-17 20:53:41 -07005940 /* Send pending iframes */
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03005941 l2cap_ertm_send(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005942
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03005943 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
Mat Martineaue31f7632012-05-17 20:53:41 -07005944 test_bit(CONN_SEND_FBIT, &chan->conn_state)) {
5945 /* F-bit wasn't sent in an s-frame or i-frame yet, so
5946 * send it now.
5947 */
5948 control.super = L2CAP_SUPER_RR;
5949 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005950 }
5951}
5952
Gustavo Padovan2d792812012-10-06 10:07:01 +01005953static void append_skb_frag(struct sk_buff *skb, struct sk_buff *new_frag,
5954 struct sk_buff **last_frag)
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005955{
Mat Martineau84084a32011-07-22 14:54:00 -07005956 /* skb->len reflects data in skb as well as all fragments
5957 * skb->data_len reflects only data in fragments
5958 */
5959 if (!skb_has_frag_list(skb))
5960 skb_shinfo(skb)->frag_list = new_frag;
5961
5962 new_frag->next = NULL;
5963
5964 (*last_frag)->next = new_frag;
5965 *last_frag = new_frag;
5966
5967 skb->len += new_frag->len;
5968 skb->data_len += new_frag->len;
5969 skb->truesize += new_frag->truesize;
5970}
5971
Mat Martineau4b51dae92012-05-17 20:53:37 -07005972static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb,
5973 struct l2cap_ctrl *control)
Mat Martineau84084a32011-07-22 14:54:00 -07005974{
5975 int err = -EINVAL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005976
Mat Martineau4b51dae92012-05-17 20:53:37 -07005977 switch (control->sar) {
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005978 case L2CAP_SAR_UNSEGMENTED:
Mat Martineau84084a32011-07-22 14:54:00 -07005979 if (chan->sdu)
5980 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005981
Gustavo Padovan80b98022012-05-27 22:27:51 -03005982 err = chan->ops->recv(chan, skb);
Mat Martineau84084a32011-07-22 14:54:00 -07005983 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005984
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005985 case L2CAP_SAR_START:
Mat Martineau84084a32011-07-22 14:54:00 -07005986 if (chan->sdu)
5987 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005988
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005989 chan->sdu_len = get_unaligned_le16(skb->data);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005990 skb_pull(skb, L2CAP_SDULEN_SIZE);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005991
Mat Martineau84084a32011-07-22 14:54:00 -07005992 if (chan->sdu_len > chan->imtu) {
5993 err = -EMSGSIZE;
5994 break;
5995 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005996
Mat Martineau84084a32011-07-22 14:54:00 -07005997 if (skb->len >= chan->sdu_len)
5998 break;
5999
6000 chan->sdu = skb;
6001 chan->sdu_last_frag = skb;
6002
6003 skb = NULL;
6004 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03006005 break;
6006
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03006007 case L2CAP_SAR_CONTINUE:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03006008 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07006009 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03006010
Mat Martineau84084a32011-07-22 14:54:00 -07006011 append_skb_frag(chan->sdu, skb,
6012 &chan->sdu_last_frag);
6013 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03006014
Mat Martineau84084a32011-07-22 14:54:00 -07006015 if (chan->sdu->len >= chan->sdu_len)
6016 break;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03006017
Mat Martineau84084a32011-07-22 14:54:00 -07006018 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03006019 break;
6020
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03006021 case L2CAP_SAR_END:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03006022 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07006023 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03006024
Mat Martineau84084a32011-07-22 14:54:00 -07006025 append_skb_frag(chan->sdu, skb,
6026 &chan->sdu_last_frag);
6027 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03006028
Mat Martineau84084a32011-07-22 14:54:00 -07006029 if (chan->sdu->len != chan->sdu_len)
6030 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03006031
Gustavo Padovan80b98022012-05-27 22:27:51 -03006032 err = chan->ops->recv(chan, chan->sdu);
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03006033
Mat Martineau84084a32011-07-22 14:54:00 -07006034 if (!err) {
6035 /* Reassembly complete */
6036 chan->sdu = NULL;
6037 chan->sdu_last_frag = NULL;
6038 chan->sdu_len = 0;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03006039 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03006040 break;
6041 }
6042
Mat Martineau84084a32011-07-22 14:54:00 -07006043 if (err) {
6044 kfree_skb(skb);
6045 kfree_skb(chan->sdu);
6046 chan->sdu = NULL;
6047 chan->sdu_last_frag = NULL;
6048 chan->sdu_len = 0;
6049 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03006050
Mat Martineau84084a32011-07-22 14:54:00 -07006051 return err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03006052}
6053
Mat Martineau32b32732012-10-23 15:24:11 -07006054static int l2cap_resegment(struct l2cap_chan *chan)
6055{
6056 /* Placeholder */
6057 return 0;
6058}
6059
Mat Martineaue3281402011-07-07 09:39:02 -07006060void l2cap_chan_busy(struct l2cap_chan *chan, int busy)
Gustavo F. Padovan712132eb2010-06-21 19:39:50 -03006061{
Mat Martineau61aa4f52012-05-17 20:53:40 -07006062 u8 event;
6063
6064 if (chan->mode != L2CAP_MODE_ERTM)
6065 return;
6066
6067 event = busy ? L2CAP_EV_LOCAL_BUSY_DETECTED : L2CAP_EV_LOCAL_BUSY_CLEAR;
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03006068 l2cap_tx(chan, NULL, NULL, event);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03006069}
6070
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006071static int l2cap_rx_queued_iframes(struct l2cap_chan *chan)
6072{
Mat Martineau63838722012-05-17 20:53:45 -07006073 int err = 0;
6074 /* Pass sequential frames to l2cap_reassemble_sdu()
6075 * until a gap is encountered.
6076 */
6077
6078 BT_DBG("chan %p", chan);
6079
6080 while (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
6081 struct sk_buff *skb;
6082 BT_DBG("Searching for skb with txseq %d (queue len %d)",
6083 chan->buffer_seq, skb_queue_len(&chan->srej_q));
6084
6085 skb = l2cap_ertm_seq_in_queue(&chan->srej_q, chan->buffer_seq);
6086
6087 if (!skb)
6088 break;
6089
6090 skb_unlink(skb, &chan->srej_q);
6091 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
6092 err = l2cap_reassemble_sdu(chan, skb, &bt_cb(skb)->control);
6093 if (err)
6094 break;
6095 }
6096
6097 if (skb_queue_empty(&chan->srej_q)) {
6098 chan->rx_state = L2CAP_RX_STATE_RECV;
6099 l2cap_send_ack(chan);
6100 }
6101
6102 return err;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006103}
6104
6105static void l2cap_handle_srej(struct l2cap_chan *chan,
6106 struct l2cap_ctrl *control)
6107{
Mat Martineauf80842a2012-05-17 20:53:46 -07006108 struct sk_buff *skb;
6109
6110 BT_DBG("chan %p, control %p", chan, control);
6111
6112 if (control->reqseq == chan->next_tx_seq) {
6113 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006114 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineauf80842a2012-05-17 20:53:46 -07006115 return;
6116 }
6117
6118 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
6119
6120 if (skb == NULL) {
6121 BT_DBG("Seq %d not available for retransmission",
6122 control->reqseq);
6123 return;
6124 }
6125
6126 if (chan->max_tx != 0 && bt_cb(skb)->control.retries >= chan->max_tx) {
6127 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006128 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineauf80842a2012-05-17 20:53:46 -07006129 return;
6130 }
6131
6132 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6133
6134 if (control->poll) {
6135 l2cap_pass_to_tx(chan, control);
6136
6137 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6138 l2cap_retransmit(chan, control);
6139 l2cap_ertm_send(chan);
6140
6141 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
6142 set_bit(CONN_SREJ_ACT, &chan->conn_state);
6143 chan->srej_save_reqseq = control->reqseq;
6144 }
6145 } else {
6146 l2cap_pass_to_tx_fbit(chan, control);
6147
6148 if (control->final) {
6149 if (chan->srej_save_reqseq != control->reqseq ||
6150 !test_and_clear_bit(CONN_SREJ_ACT,
6151 &chan->conn_state))
6152 l2cap_retransmit(chan, control);
6153 } else {
6154 l2cap_retransmit(chan, control);
6155 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
6156 set_bit(CONN_SREJ_ACT, &chan->conn_state);
6157 chan->srej_save_reqseq = control->reqseq;
6158 }
6159 }
6160 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006161}
6162
6163static void l2cap_handle_rej(struct l2cap_chan *chan,
6164 struct l2cap_ctrl *control)
6165{
Mat Martineaufcd289d2012-05-17 20:53:47 -07006166 struct sk_buff *skb;
6167
6168 BT_DBG("chan %p, control %p", chan, control);
6169
6170 if (control->reqseq == chan->next_tx_seq) {
6171 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006172 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaufcd289d2012-05-17 20:53:47 -07006173 return;
6174 }
6175
6176 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
6177
6178 if (chan->max_tx && skb &&
6179 bt_cb(skb)->control.retries >= chan->max_tx) {
6180 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006181 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaufcd289d2012-05-17 20:53:47 -07006182 return;
6183 }
6184
6185 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6186
6187 l2cap_pass_to_tx(chan, control);
6188
6189 if (control->final) {
6190 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state))
6191 l2cap_retransmit_all(chan, control);
6192 } else {
6193 l2cap_retransmit_all(chan, control);
6194 l2cap_ertm_send(chan);
6195 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F)
6196 set_bit(CONN_REJ_ACT, &chan->conn_state);
6197 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006198}
6199
Mat Martineau4b51dae92012-05-17 20:53:37 -07006200static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq)
6201{
6202 BT_DBG("chan %p, txseq %d", chan, txseq);
6203
6204 BT_DBG("last_acked_seq %d, expected_tx_seq %d", chan->last_acked_seq,
6205 chan->expected_tx_seq);
6206
6207 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
6208 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
Gustavo Padovan2d792812012-10-06 10:07:01 +01006209 chan->tx_win) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07006210 /* See notes below regarding "double poll" and
6211 * invalid packets.
6212 */
6213 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
6214 BT_DBG("Invalid/Ignore - after SREJ");
6215 return L2CAP_TXSEQ_INVALID_IGNORE;
6216 } else {
6217 BT_DBG("Invalid - in window after SREJ sent");
6218 return L2CAP_TXSEQ_INVALID;
6219 }
6220 }
6221
6222 if (chan->srej_list.head == txseq) {
6223 BT_DBG("Expected SREJ");
6224 return L2CAP_TXSEQ_EXPECTED_SREJ;
6225 }
6226
6227 if (l2cap_ertm_seq_in_queue(&chan->srej_q, txseq)) {
6228 BT_DBG("Duplicate SREJ - txseq already stored");
6229 return L2CAP_TXSEQ_DUPLICATE_SREJ;
6230 }
6231
6232 if (l2cap_seq_list_contains(&chan->srej_list, txseq)) {
6233 BT_DBG("Unexpected SREJ - not requested");
6234 return L2CAP_TXSEQ_UNEXPECTED_SREJ;
6235 }
6236 }
6237
6238 if (chan->expected_tx_seq == txseq) {
6239 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
6240 chan->tx_win) {
6241 BT_DBG("Invalid - txseq outside tx window");
6242 return L2CAP_TXSEQ_INVALID;
6243 } else {
6244 BT_DBG("Expected");
6245 return L2CAP_TXSEQ_EXPECTED;
6246 }
6247 }
6248
6249 if (__seq_offset(chan, txseq, chan->last_acked_seq) <
Gustavo Padovan2d792812012-10-06 10:07:01 +01006250 __seq_offset(chan, chan->expected_tx_seq, chan->last_acked_seq)) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07006251 BT_DBG("Duplicate - expected_tx_seq later than txseq");
6252 return L2CAP_TXSEQ_DUPLICATE;
6253 }
6254
6255 if (__seq_offset(chan, txseq, chan->last_acked_seq) >= chan->tx_win) {
6256 /* A source of invalid packets is a "double poll" condition,
6257 * where delays cause us to send multiple poll packets. If
6258 * the remote stack receives and processes both polls,
6259 * sequence numbers can wrap around in such a way that a
6260 * resent frame has a sequence number that looks like new data
6261 * with a sequence gap. This would trigger an erroneous SREJ
6262 * request.
6263 *
6264 * Fortunately, this is impossible with a tx window that's
6265 * less than half of the maximum sequence number, which allows
6266 * invalid frames to be safely ignored.
6267 *
6268 * With tx window sizes greater than half of the tx window
6269 * maximum, the frame is invalid and cannot be ignored. This
6270 * causes a disconnect.
6271 */
6272
6273 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
6274 BT_DBG("Invalid/Ignore - txseq outside tx window");
6275 return L2CAP_TXSEQ_INVALID_IGNORE;
6276 } else {
6277 BT_DBG("Invalid - txseq outside tx window");
6278 return L2CAP_TXSEQ_INVALID;
6279 }
6280 } else {
6281 BT_DBG("Unexpected - txseq indicates missing frames");
6282 return L2CAP_TXSEQ_UNEXPECTED;
6283 }
6284}
6285
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006286static int l2cap_rx_state_recv(struct l2cap_chan *chan,
6287 struct l2cap_ctrl *control,
6288 struct sk_buff *skb, u8 event)
6289{
6290 int err = 0;
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006291 bool skb_in_use = false;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006292
6293 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
6294 event);
6295
6296 switch (event) {
6297 case L2CAP_EV_RECV_IFRAME:
6298 switch (l2cap_classify_txseq(chan, control->txseq)) {
6299 case L2CAP_TXSEQ_EXPECTED:
6300 l2cap_pass_to_tx(chan, control);
6301
6302 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
6303 BT_DBG("Busy, discarding expected seq %d",
6304 control->txseq);
6305 break;
6306 }
6307
6308 chan->expected_tx_seq = __next_seq(chan,
6309 control->txseq);
6310
6311 chan->buffer_seq = chan->expected_tx_seq;
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006312 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006313
6314 err = l2cap_reassemble_sdu(chan, skb, control);
6315 if (err)
6316 break;
6317
6318 if (control->final) {
6319 if (!test_and_clear_bit(CONN_REJ_ACT,
6320 &chan->conn_state)) {
6321 control->final = 0;
6322 l2cap_retransmit_all(chan, control);
6323 l2cap_ertm_send(chan);
6324 }
6325 }
6326
6327 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
6328 l2cap_send_ack(chan);
6329 break;
6330 case L2CAP_TXSEQ_UNEXPECTED:
6331 l2cap_pass_to_tx(chan, control);
6332
6333 /* Can't issue SREJ frames in the local busy state.
6334 * Drop this frame, it will be seen as missing
6335 * when local busy is exited.
6336 */
6337 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
6338 BT_DBG("Busy, discarding unexpected seq %d",
6339 control->txseq);
6340 break;
6341 }
6342
6343 /* There was a gap in the sequence, so an SREJ
6344 * must be sent for each missing frame. The
6345 * current frame is stored for later use.
6346 */
6347 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006348 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006349 BT_DBG("Queued %p (queue len %d)", skb,
6350 skb_queue_len(&chan->srej_q));
6351
6352 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
6353 l2cap_seq_list_clear(&chan->srej_list);
6354 l2cap_send_srej(chan, control->txseq);
6355
6356 chan->rx_state = L2CAP_RX_STATE_SREJ_SENT;
6357 break;
6358 case L2CAP_TXSEQ_DUPLICATE:
6359 l2cap_pass_to_tx(chan, control);
6360 break;
6361 case L2CAP_TXSEQ_INVALID_IGNORE:
6362 break;
6363 case L2CAP_TXSEQ_INVALID:
6364 default:
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006365 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006366 break;
6367 }
6368 break;
6369 case L2CAP_EV_RECV_RR:
6370 l2cap_pass_to_tx(chan, control);
6371 if (control->final) {
6372 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6373
Mat Martineaue6a3ee62012-10-23 15:24:22 -07006374 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state) &&
6375 !__chan_is_moving(chan)) {
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006376 control->final = 0;
6377 l2cap_retransmit_all(chan, control);
6378 }
6379
6380 l2cap_ertm_send(chan);
6381 } else if (control->poll) {
6382 l2cap_send_i_or_rr_or_rnr(chan);
6383 } else {
6384 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6385 &chan->conn_state) &&
6386 chan->unacked_frames)
6387 __set_retrans_timer(chan);
6388
6389 l2cap_ertm_send(chan);
6390 }
6391 break;
6392 case L2CAP_EV_RECV_RNR:
6393 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6394 l2cap_pass_to_tx(chan, control);
6395 if (control && control->poll) {
6396 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6397 l2cap_send_rr_or_rnr(chan, 0);
6398 }
6399 __clear_retrans_timer(chan);
6400 l2cap_seq_list_clear(&chan->retrans_list);
6401 break;
6402 case L2CAP_EV_RECV_REJ:
6403 l2cap_handle_rej(chan, control);
6404 break;
6405 case L2CAP_EV_RECV_SREJ:
6406 l2cap_handle_srej(chan, control);
6407 break;
6408 default:
6409 break;
6410 }
6411
6412 if (skb && !skb_in_use) {
6413 BT_DBG("Freeing %p", skb);
6414 kfree_skb(skb);
6415 }
6416
6417 return err;
6418}
6419
6420static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan,
6421 struct l2cap_ctrl *control,
6422 struct sk_buff *skb, u8 event)
6423{
6424 int err = 0;
6425 u16 txseq = control->txseq;
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006426 bool skb_in_use = false;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006427
6428 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
6429 event);
6430
6431 switch (event) {
6432 case L2CAP_EV_RECV_IFRAME:
6433 switch (l2cap_classify_txseq(chan, txseq)) {
6434 case L2CAP_TXSEQ_EXPECTED:
6435 /* Keep frame for reassembly later */
6436 l2cap_pass_to_tx(chan, control);
6437 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006438 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006439 BT_DBG("Queued %p (queue len %d)", skb,
6440 skb_queue_len(&chan->srej_q));
6441
6442 chan->expected_tx_seq = __next_seq(chan, txseq);
6443 break;
6444 case L2CAP_TXSEQ_EXPECTED_SREJ:
6445 l2cap_seq_list_pop(&chan->srej_list);
6446
6447 l2cap_pass_to_tx(chan, control);
6448 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006449 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006450 BT_DBG("Queued %p (queue len %d)", skb,
6451 skb_queue_len(&chan->srej_q));
6452
6453 err = l2cap_rx_queued_iframes(chan);
6454 if (err)
6455 break;
6456
6457 break;
6458 case L2CAP_TXSEQ_UNEXPECTED:
6459 /* Got a frame that can't be reassembled yet.
6460 * Save it for later, and send SREJs to cover
6461 * the missing frames.
6462 */
6463 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006464 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006465 BT_DBG("Queued %p (queue len %d)", skb,
6466 skb_queue_len(&chan->srej_q));
6467
6468 l2cap_pass_to_tx(chan, control);
6469 l2cap_send_srej(chan, control->txseq);
6470 break;
6471 case L2CAP_TXSEQ_UNEXPECTED_SREJ:
6472 /* This frame was requested with an SREJ, but
6473 * some expected retransmitted frames are
6474 * missing. Request retransmission of missing
6475 * SREJ'd frames.
6476 */
6477 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006478 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006479 BT_DBG("Queued %p (queue len %d)", skb,
6480 skb_queue_len(&chan->srej_q));
6481
6482 l2cap_pass_to_tx(chan, control);
6483 l2cap_send_srej_list(chan, control->txseq);
6484 break;
6485 case L2CAP_TXSEQ_DUPLICATE_SREJ:
6486 /* We've already queued this frame. Drop this copy. */
6487 l2cap_pass_to_tx(chan, control);
6488 break;
6489 case L2CAP_TXSEQ_DUPLICATE:
6490 /* Expecting a later sequence number, so this frame
6491 * was already received. Ignore it completely.
6492 */
6493 break;
6494 case L2CAP_TXSEQ_INVALID_IGNORE:
6495 break;
6496 case L2CAP_TXSEQ_INVALID:
6497 default:
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006498 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006499 break;
6500 }
6501 break;
6502 case L2CAP_EV_RECV_RR:
6503 l2cap_pass_to_tx(chan, control);
6504 if (control->final) {
6505 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6506
6507 if (!test_and_clear_bit(CONN_REJ_ACT,
6508 &chan->conn_state)) {
6509 control->final = 0;
6510 l2cap_retransmit_all(chan, control);
6511 }
6512
6513 l2cap_ertm_send(chan);
6514 } else if (control->poll) {
6515 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6516 &chan->conn_state) &&
6517 chan->unacked_frames) {
6518 __set_retrans_timer(chan);
6519 }
6520
6521 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6522 l2cap_send_srej_tail(chan);
6523 } else {
6524 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6525 &chan->conn_state) &&
6526 chan->unacked_frames)
6527 __set_retrans_timer(chan);
6528
6529 l2cap_send_ack(chan);
6530 }
6531 break;
6532 case L2CAP_EV_RECV_RNR:
6533 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6534 l2cap_pass_to_tx(chan, control);
6535 if (control->poll) {
6536 l2cap_send_srej_tail(chan);
6537 } else {
6538 struct l2cap_ctrl rr_control;
6539 memset(&rr_control, 0, sizeof(rr_control));
6540 rr_control.sframe = 1;
6541 rr_control.super = L2CAP_SUPER_RR;
6542 rr_control.reqseq = chan->buffer_seq;
6543 l2cap_send_sframe(chan, &rr_control);
6544 }
6545
6546 break;
6547 case L2CAP_EV_RECV_REJ:
6548 l2cap_handle_rej(chan, control);
6549 break;
6550 case L2CAP_EV_RECV_SREJ:
6551 l2cap_handle_srej(chan, control);
6552 break;
6553 }
6554
6555 if (skb && !skb_in_use) {
6556 BT_DBG("Freeing %p", skb);
6557 kfree_skb(skb);
6558 }
6559
6560 return err;
6561}
6562
Mat Martineau32b32732012-10-23 15:24:11 -07006563static int l2cap_finish_move(struct l2cap_chan *chan)
6564{
6565 BT_DBG("chan %p", chan);
6566
6567 chan->rx_state = L2CAP_RX_STATE_RECV;
6568
6569 if (chan->hs_hcon)
6570 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
6571 else
6572 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
6573
6574 return l2cap_resegment(chan);
6575}
6576
6577static int l2cap_rx_state_wait_p(struct l2cap_chan *chan,
6578 struct l2cap_ctrl *control,
6579 struct sk_buff *skb, u8 event)
6580{
6581 int err;
6582
6583 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
6584 event);
6585
6586 if (!control->poll)
6587 return -EPROTO;
6588
6589 l2cap_process_reqseq(chan, control->reqseq);
6590
6591 if (!skb_queue_empty(&chan->tx_q))
6592 chan->tx_send_head = skb_peek(&chan->tx_q);
6593 else
6594 chan->tx_send_head = NULL;
6595
6596 /* Rewind next_tx_seq to the point expected
6597 * by the receiver.
6598 */
6599 chan->next_tx_seq = control->reqseq;
6600 chan->unacked_frames = 0;
6601
6602 err = l2cap_finish_move(chan);
6603 if (err)
6604 return err;
6605
6606 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6607 l2cap_send_i_or_rr_or_rnr(chan);
6608
6609 if (event == L2CAP_EV_RECV_IFRAME)
6610 return -EPROTO;
6611
6612 return l2cap_rx_state_recv(chan, control, NULL, event);
6613}
6614
6615static int l2cap_rx_state_wait_f(struct l2cap_chan *chan,
6616 struct l2cap_ctrl *control,
6617 struct sk_buff *skb, u8 event)
6618{
6619 int err;
6620
6621 if (!control->final)
6622 return -EPROTO;
6623
6624 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6625
6626 chan->rx_state = L2CAP_RX_STATE_RECV;
6627 l2cap_process_reqseq(chan, control->reqseq);
6628
6629 if (!skb_queue_empty(&chan->tx_q))
6630 chan->tx_send_head = skb_peek(&chan->tx_q);
6631 else
6632 chan->tx_send_head = NULL;
6633
6634 /* Rewind next_tx_seq to the point expected
6635 * by the receiver.
6636 */
6637 chan->next_tx_seq = control->reqseq;
6638 chan->unacked_frames = 0;
6639
6640 if (chan->hs_hcon)
6641 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
6642 else
6643 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
6644
6645 err = l2cap_resegment(chan);
6646
6647 if (!err)
6648 err = l2cap_rx_state_recv(chan, control, skb, event);
6649
6650 return err;
6651}
6652
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006653static bool __valid_reqseq(struct l2cap_chan *chan, u16 reqseq)
6654{
6655 /* Make sure reqseq is for a packet that has been sent but not acked */
6656 u16 unacked;
6657
6658 unacked = __seq_offset(chan, chan->next_tx_seq, chan->expected_ack_seq);
6659 return __seq_offset(chan, chan->next_tx_seq, reqseq) <= unacked;
6660}
6661
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006662static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
6663 struct sk_buff *skb, u8 event)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006664{
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006665 int err = 0;
6666
6667 BT_DBG("chan %p, control %p, skb %p, event %d, state %d", chan,
6668 control, skb, event, chan->rx_state);
6669
6670 if (__valid_reqseq(chan, control->reqseq)) {
6671 switch (chan->rx_state) {
6672 case L2CAP_RX_STATE_RECV:
6673 err = l2cap_rx_state_recv(chan, control, skb, event);
6674 break;
6675 case L2CAP_RX_STATE_SREJ_SENT:
6676 err = l2cap_rx_state_srej_sent(chan, control, skb,
6677 event);
6678 break;
Mat Martineau32b32732012-10-23 15:24:11 -07006679 case L2CAP_RX_STATE_WAIT_P:
6680 err = l2cap_rx_state_wait_p(chan, control, skb, event);
6681 break;
6682 case L2CAP_RX_STATE_WAIT_F:
6683 err = l2cap_rx_state_wait_f(chan, control, skb, event);
6684 break;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006685 default:
6686 /* shut it down */
6687 break;
6688 }
6689 } else {
6690 BT_DBG("Invalid reqseq %d (next_tx_seq %d, expected_ack_seq %d",
6691 control->reqseq, chan->next_tx_seq,
6692 chan->expected_ack_seq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006693 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006694 }
6695
6696 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006697}
6698
6699static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
6700 struct sk_buff *skb)
6701{
Mat Martineau4b51dae92012-05-17 20:53:37 -07006702 int err = 0;
6703
6704 BT_DBG("chan %p, control %p, skb %p, state %d", chan, control, skb,
6705 chan->rx_state);
6706
6707 if (l2cap_classify_txseq(chan, control->txseq) ==
6708 L2CAP_TXSEQ_EXPECTED) {
6709 l2cap_pass_to_tx(chan, control);
6710
6711 BT_DBG("buffer_seq %d->%d", chan->buffer_seq,
6712 __next_seq(chan, chan->buffer_seq));
6713
6714 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
6715
6716 l2cap_reassemble_sdu(chan, skb, control);
6717 } else {
6718 if (chan->sdu) {
6719 kfree_skb(chan->sdu);
6720 chan->sdu = NULL;
6721 }
6722 chan->sdu_last_frag = NULL;
6723 chan->sdu_len = 0;
6724
6725 if (skb) {
6726 BT_DBG("Freeing %p", skb);
6727 kfree_skb(skb);
6728 }
6729 }
6730
6731 chan->last_acked_seq = control->txseq;
6732 chan->expected_tx_seq = __next_seq(chan, control->txseq);
6733
6734 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006735}
6736
6737static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
6738{
6739 struct l2cap_ctrl *control = &bt_cb(skb)->control;
6740 u16 len;
6741 u8 event;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006742
Mat Martineaub76bbd62012-04-11 10:48:43 -07006743 __unpack_control(chan, skb);
6744
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006745 len = skb->len;
6746
6747 /*
6748 * We can just drop the corrupted I-frame here.
6749 * Receiver will miss it and start proper recovery
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006750 * procedures and ask for retransmission.
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006751 */
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006752 if (l2cap_check_fcs(chan, skb))
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006753 goto drop;
6754
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006755 if (!control->sframe && control->sar == L2CAP_SAR_START)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03006756 len -= L2CAP_SDULEN_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006757
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006758 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03006759 len -= L2CAP_FCS_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006760
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006761 if (len > chan->mps) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006762 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006763 goto drop;
6764 }
6765
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006766 if (!control->sframe) {
6767 int err;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006768
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006769 BT_DBG("iframe sar %d, reqseq %d, final %d, txseq %d",
6770 control->sar, control->reqseq, control->final,
6771 control->txseq);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03006772
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006773 /* Validate F-bit - F=0 always valid, F=1 only
6774 * valid in TX WAIT_F
6775 */
6776 if (control->final && chan->tx_state != L2CAP_TX_STATE_WAIT_F)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006777 goto drop;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006778
6779 if (chan->mode != L2CAP_MODE_STREAMING) {
6780 event = L2CAP_EV_RECV_IFRAME;
6781 err = l2cap_rx(chan, control, skb, event);
6782 } else {
6783 err = l2cap_stream_rx(chan, control, skb);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006784 }
6785
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006786 if (err)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006787 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006788 } else {
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006789 const u8 rx_func_to_event[4] = {
6790 L2CAP_EV_RECV_RR, L2CAP_EV_RECV_REJ,
6791 L2CAP_EV_RECV_RNR, L2CAP_EV_RECV_SREJ
6792 };
6793
6794 /* Only I-frames are expected in streaming mode */
6795 if (chan->mode == L2CAP_MODE_STREAMING)
6796 goto drop;
6797
6798 BT_DBG("sframe reqseq %d, final %d, poll %d, super %d",
6799 control->reqseq, control->final, control->poll,
6800 control->super);
6801
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006802 if (len != 0) {
Andrei Emeltchenko1bb166e2012-11-20 17:16:21 +02006803 BT_ERR("Trailing bytes: %d in sframe", len);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006804 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006805 goto drop;
6806 }
6807
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006808 /* Validate F and P bits */
6809 if (control->final && (control->poll ||
6810 chan->tx_state != L2CAP_TX_STATE_WAIT_F))
6811 goto drop;
6812
6813 event = rx_func_to_event[control->super];
6814 if (l2cap_rx(chan, control, skb, event))
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006815 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006816 }
6817
6818 return 0;
6819
6820drop:
6821 kfree_skb(skb);
6822 return 0;
6823}
6824
Johan Hedbergb1c325c2013-12-05 09:43:34 +02006825static void l2cap_chan_le_send_credits(struct l2cap_chan *chan)
6826{
6827 struct l2cap_conn *conn = chan->conn;
6828 struct l2cap_le_credits pkt;
6829 u16 return_credits;
6830
6831 /* We return more credits to the sender only after the amount of
6832 * credits falls below half of the initial amount.
6833 */
6834 if (chan->rx_credits >= (L2CAP_LE_MAX_CREDITS + 1) / 2)
6835 return;
6836
6837 return_credits = L2CAP_LE_MAX_CREDITS - chan->rx_credits;
6838
6839 BT_DBG("chan %p returning %u credits to sender", chan, return_credits);
6840
6841 chan->rx_credits += return_credits;
6842
6843 pkt.cid = cpu_to_le16(chan->scid);
6844 pkt.credits = cpu_to_le16(return_credits);
6845
6846 chan->ident = l2cap_get_ident(conn);
6847
6848 l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CREDITS, sizeof(pkt), &pkt);
6849}
6850
Johan Hedbergfad5fc82013-12-05 09:45:01 +02006851static int l2cap_le_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
6852{
Johan Hedbergaac23bf2013-06-01 10:14:57 +03006853 int err;
Johan Hedbergfad5fc82013-12-05 09:45:01 +02006854
Johan Hedbergaac23bf2013-06-01 10:14:57 +03006855 if (!chan->rx_credits) {
6856 BT_ERR("No credits to receive LE L2CAP data");
Johan Hedbergfad5fc82013-12-05 09:45:01 +02006857 return -ENOBUFS;
Johan Hedbergaac23bf2013-06-01 10:14:57 +03006858 }
6859
6860 if (chan->imtu < skb->len) {
6861 BT_ERR("Too big LE L2CAP PDU");
6862 return -ENOBUFS;
6863 }
Johan Hedbergfad5fc82013-12-05 09:45:01 +02006864
6865 chan->rx_credits--;
6866 BT_DBG("rx_credits %u -> %u", chan->rx_credits + 1, chan->rx_credits);
6867
6868 l2cap_chan_le_send_credits(chan);
6869
Johan Hedbergaac23bf2013-06-01 10:14:57 +03006870 err = 0;
6871
6872 if (!chan->sdu) {
6873 u16 sdu_len;
6874
6875 sdu_len = get_unaligned_le16(skb->data);
6876 skb_pull(skb, L2CAP_SDULEN_SIZE);
6877
6878 BT_DBG("Start of new SDU. sdu_len %u skb->len %u imtu %u",
6879 sdu_len, skb->len, chan->imtu);
6880
6881 if (sdu_len > chan->imtu) {
6882 BT_ERR("Too big LE L2CAP SDU length received");
6883 err = -EMSGSIZE;
6884 goto failed;
6885 }
6886
6887 if (skb->len > sdu_len) {
6888 BT_ERR("Too much LE L2CAP data received");
6889 err = -EINVAL;
6890 goto failed;
6891 }
6892
6893 if (skb->len == sdu_len)
6894 return chan->ops->recv(chan, skb);
6895
6896 chan->sdu = skb;
6897 chan->sdu_len = sdu_len;
6898 chan->sdu_last_frag = skb;
6899
6900 return 0;
6901 }
6902
6903 BT_DBG("SDU fragment. chan->sdu->len %u skb->len %u chan->sdu_len %u",
6904 chan->sdu->len, skb->len, chan->sdu_len);
6905
6906 if (chan->sdu->len + skb->len > chan->sdu_len) {
6907 BT_ERR("Too much LE L2CAP data received");
6908 err = -EINVAL;
6909 goto failed;
6910 }
6911
6912 append_skb_frag(chan->sdu, skb, &chan->sdu_last_frag);
6913 skb = NULL;
6914
6915 if (chan->sdu->len == chan->sdu_len) {
6916 err = chan->ops->recv(chan, chan->sdu);
6917 if (!err) {
6918 chan->sdu = NULL;
6919 chan->sdu_last_frag = NULL;
6920 chan->sdu_len = 0;
6921 }
6922 }
6923
6924failed:
6925 if (err) {
6926 kfree_skb(skb);
6927 kfree_skb(chan->sdu);
6928 chan->sdu = NULL;
6929 chan->sdu_last_frag = NULL;
6930 chan->sdu_len = 0;
6931 }
6932
6933 /* We can't return an error here since we took care of the skb
6934 * freeing internally. An error return would cause the caller to
6935 * do a double-free of the skb.
6936 */
6937 return 0;
Johan Hedbergfad5fc82013-12-05 09:45:01 +02006938}
6939
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006940static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid,
6941 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006942{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006943 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006944
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03006945 chan = l2cap_get_chan_by_scid(conn, cid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006946 if (!chan) {
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006947 if (cid == L2CAP_CID_A2MP) {
6948 chan = a2mp_channel_create(conn, skb);
6949 if (!chan) {
6950 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006951 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006952 }
6953
6954 l2cap_chan_lock(chan);
6955 } else {
6956 BT_DBG("unknown cid 0x%4.4x", cid);
6957 /* Drop packet and return */
6958 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006959 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006960 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006961 }
6962
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03006963 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006964
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03006965 if (chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006966 goto drop;
6967
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006968 switch (chan->mode) {
Johan Hedberg38319712013-05-17 12:49:23 +03006969 case L2CAP_MODE_LE_FLOWCTL:
Johan Hedbergfad5fc82013-12-05 09:45:01 +02006970 if (l2cap_le_data_rcv(chan, skb) < 0)
6971 goto drop;
6972
6973 goto done;
6974
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006975 case L2CAP_MODE_BASIC:
6976 /* If socket recv buffers overflows we drop data here
6977 * which is *bad* because L2CAP has to be reliable.
6978 * But we don't have any other choice. L2CAP doesn't
6979 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006980
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006981 if (chan->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006982 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006983
Gustavo Padovan80b98022012-05-27 22:27:51 -03006984 if (!chan->ops->recv(chan, skb))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006985 goto done;
6986 break;
6987
6988 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03006989 case L2CAP_MODE_STREAMING:
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006990 l2cap_data_rcv(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03006991 goto done;
6992
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006993 default:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006994 BT_DBG("chan %p: bad mode 0x%2.2x", chan, chan->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006995 break;
6996 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006997
6998drop:
6999 kfree_skb(skb);
7000
7001done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02007002 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007003}
7004
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03007005static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm,
7006 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007007{
Marcel Holtmannae4fd2d2013-10-03 00:03:39 -07007008 struct hci_conn *hcon = conn->hcon;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007009 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007010
Marcel Holtmannae4fd2d2013-10-03 00:03:39 -07007011 if (hcon->type != ACL_LINK)
7012 goto drop;
7013
Johan Hedbergbf20fd42013-05-14 13:23:13 +03007014 chan = l2cap_global_chan_by_psm(0, psm, &hcon->src, &hcon->dst,
7015 ACL_LINK);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007016 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007017 goto drop;
7018
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02007019 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007020
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03007021 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007022 goto drop;
7023
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03007024 if (chan->imtu < skb->len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007025 goto drop;
7026
Marcel Holtmann2edf8702013-10-13 12:55:29 -07007027 /* Store remote BD_ADDR and PSM for msg_name */
Marcel Holtmann06ae3312013-10-18 03:43:00 -07007028 bacpy(&bt_cb(skb)->bdaddr, &hcon->dst);
Marcel Holtmann2edf8702013-10-13 12:55:29 -07007029 bt_cb(skb)->psm = psm;
7030
Gustavo Padovan80b98022012-05-27 22:27:51 -03007031 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03007032 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007033
7034drop:
7035 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007036}
7037
Marcel Holtmann72f78352013-04-23 00:59:00 -07007038static void l2cap_att_channel(struct l2cap_conn *conn,
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03007039 struct sk_buff *skb)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03007040{
Marcel Holtmannb99707d2013-10-03 02:54:11 -07007041 struct hci_conn *hcon = conn->hcon;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007042 struct l2cap_chan *chan;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03007043
Marcel Holtmannb99707d2013-10-03 02:54:11 -07007044 if (hcon->type != LE_LINK)
7045 goto drop;
7046
Johan Hedbergaf1c0132013-04-29 19:35:42 +03007047 chan = l2cap_global_chan_by_scid(BT_CONNECTED, L2CAP_CID_ATT,
Marcel Holtmann06ae3312013-10-18 03:43:00 -07007048 &hcon->src, &hcon->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007049 if (!chan)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03007050 goto drop;
7051
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02007052 BT_DBG("chan %p, len %d", chan, skb->len);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03007053
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07007054 if (hci_blacklist_lookup(hcon->hdev, &hcon->dst, hcon->dst_type))
7055 goto drop;
7056
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03007057 if (chan->imtu < skb->len)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03007058 goto drop;
7059
Gustavo Padovan80b98022012-05-27 22:27:51 -03007060 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03007061 return;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03007062
7063drop:
7064 kfree_skb(skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03007065}
7066
Linus Torvalds1da177e2005-04-16 15:20:36 -07007067static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
7068{
7069 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07007070 u16 cid, len;
7071 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007072
7073 skb_pull(skb, L2CAP_HDR_SIZE);
7074 cid = __le16_to_cpu(lh->cid);
7075 len = __le16_to_cpu(lh->len);
7076
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03007077 if (len != skb->len) {
7078 kfree_skb(skb);
7079 return;
7080 }
7081
Linus Torvalds1da177e2005-04-16 15:20:36 -07007082 BT_DBG("len %d, cid 0x%4.4x", len, cid);
7083
7084 switch (cid) {
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03007085 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07007086 l2cap_sig_channel(conn, skb);
7087 break;
7088
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03007089 case L2CAP_CID_CONN_LESS:
Andrei Emeltchenko097db762012-03-09 14:16:17 +02007090 psm = get_unaligned((__le16 *) skb->data);
Andrei Emeltchenko0181a702012-05-29 10:04:05 +03007091 skb_pull(skb, L2CAP_PSMLEN_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007092 l2cap_conless_channel(conn, psm, skb);
7093 break;
7094
Johan Hedberg073d1cf2013-04-29 19:35:35 +03007095 case L2CAP_CID_ATT:
Marcel Holtmann72f78352013-04-23 00:59:00 -07007096 l2cap_att_channel(conn, skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03007097 break;
7098
Marcel Holtmanna2877622013-10-02 23:46:54 -07007099 case L2CAP_CID_LE_SIGNALING:
7100 l2cap_le_sig_channel(conn, skb);
7101 break;
7102
Anderson Brigliab501d6a2011-06-07 18:46:31 -03007103 case L2CAP_CID_SMP:
7104 if (smp_sig_channel(conn, skb))
7105 l2cap_conn_del(conn->hcon, EACCES);
7106 break;
7107
Linus Torvalds1da177e2005-04-16 15:20:36 -07007108 default:
7109 l2cap_data_channel(conn, cid, skb);
7110 break;
7111 }
7112}
7113
7114/* ---- L2CAP interface with lower layer (HCI) ---- */
7115
Ulisses Furquim686ebf22011-12-21 10:11:33 -02007116int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007117{
7118 int exact = 0, lm1 = 0, lm2 = 0;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007119 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007120
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03007121 BT_DBG("hdev %s, bdaddr %pMR", hdev->name, bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007122
7123 /* Find listening sockets and check their link_mode */
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007124 read_lock(&chan_list_lock);
7125 list_for_each_entry(c, &chan_list, global_l) {
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03007126 if (c->state != BT_LISTEN)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007127 continue;
7128
Marcel Holtmann7eafc592013-10-13 08:12:47 -07007129 if (!bacmp(&c->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01007130 lm1 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03007131 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01007132 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007133 exact++;
Marcel Holtmann7eafc592013-10-13 08:12:47 -07007134 } else if (!bacmp(&c->src, BDADDR_ANY)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01007135 lm2 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03007136 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01007137 lm2 |= HCI_LM_MASTER;
7138 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07007139 }
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007140 read_unlock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007141
7142 return exact ? lm1 : lm2;
7143}
7144
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03007145void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007146{
Marcel Holtmann01394182006-07-03 10:02:46 +02007147 struct l2cap_conn *conn;
7148
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03007149 BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007150
Linus Torvalds1da177e2005-04-16 15:20:36 -07007151 if (!status) {
Claudio Takahasibaf43252013-04-11 13:55:50 -03007152 conn = l2cap_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007153 if (conn)
7154 l2cap_conn_ready(conn);
Andrei Emeltchenkoba6fc312012-10-31 15:46:26 +02007155 } else {
Joe Perchese1750722011-06-29 18:18:29 -07007156 l2cap_conn_del(hcon, bt_to_errno(status));
Andrei Emeltchenkoba6fc312012-10-31 15:46:26 +02007157 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07007158}
7159
Ulisses Furquim686ebf22011-12-21 10:11:33 -02007160int l2cap_disconn_ind(struct hci_conn *hcon)
Marcel Holtmann2950f212009-02-12 14:02:50 +01007161{
7162 struct l2cap_conn *conn = hcon->l2cap_data;
7163
7164 BT_DBG("hcon %p", hcon);
7165
Ulisses Furquim686ebf22011-12-21 10:11:33 -02007166 if (!conn)
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02007167 return HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01007168 return conn->disc_reason;
7169}
7170
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03007171void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007172{
7173 BT_DBG("hcon %p reason %d", hcon, reason);
7174
Joe Perchese1750722011-06-29 18:18:29 -07007175 l2cap_conn_del(hcon, bt_to_errno(reason));
Linus Torvalds1da177e2005-04-16 15:20:36 -07007176}
7177
Gustavo F. Padovan43434782011-04-12 18:31:57 -03007178static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
Marcel Holtmannf62e4322009-01-15 21:58:44 +01007179{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03007180 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED)
Marcel Holtmann255c7602009-02-04 21:07:19 +01007181 return;
7182
Marcel Holtmannf62e4322009-01-15 21:58:44 +01007183 if (encrypt == 0x00) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03007184 if (chan->sec_level == BT_SECURITY_MEDIUM) {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08007185 __set_chan_timer(chan, L2CAP_ENC_TIMEOUT);
Gustavo F. Padovan43434782011-04-12 18:31:57 -03007186 } else if (chan->sec_level == BT_SECURITY_HIGH)
Gustavo F. Padovan0f852722011-05-04 19:42:50 -03007187 l2cap_chan_close(chan, ECONNREFUSED);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01007188 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03007189 if (chan->sec_level == BT_SECURITY_MEDIUM)
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03007190 __clear_chan_timer(chan);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01007191 }
7192}
7193
Ulisses Furquim686ebf22011-12-21 10:11:33 -02007194int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007195{
Marcel Holtmann40be4922008-07-14 20:13:50 +02007196 struct l2cap_conn *conn = hcon->l2cap_data;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03007197 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007198
Marcel Holtmann01394182006-07-03 10:02:46 +02007199 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007200 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02007201
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03007202 BT_DBG("conn %p status 0x%2.2x encrypt %u", conn, status, encrypt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007203
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03007204 if (hcon->type == LE_LINK) {
Hemant Gupta35d4adcc2012-04-18 14:46:26 +05307205 if (!status && encrypt)
7206 smp_distribute_keys(conn, 0);
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02007207 cancel_delayed_work(&conn->security_timer);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03007208 }
7209
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02007210 mutex_lock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007211
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02007212 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02007213 l2cap_chan_lock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007214
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03007215 BT_DBG("chan %p scid 0x%4.4x state %s", chan, chan->scid,
7216 state_to_string(chan->state));
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03007217
Andrei Emeltchenko78eb2f92012-07-19 17:03:47 +03007218 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
7219 l2cap_chan_unlock(chan);
7220 continue;
7221 }
7222
Johan Hedberg073d1cf2013-04-29 19:35:35 +03007223 if (chan->scid == L2CAP_CID_ATT) {
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03007224 if (!status && encrypt) {
7225 chan->sec_level = hcon->sec_level;
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02007226 l2cap_chan_ready(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03007227 }
7228
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02007229 l2cap_chan_unlock(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03007230 continue;
7231 }
7232
Andrei Emeltchenko96eff462012-11-15 18:14:53 +02007233 if (!__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02007234 l2cap_chan_unlock(chan);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01007235 continue;
7236 }
7237
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03007238 if (!status && (chan->state == BT_CONNECTED ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01007239 chan->state == BT_CONFIG)) {
Marcel Holtmannd97c8992013-10-14 02:53:54 -07007240 chan->ops->resume(chan);
Gustavo F. Padovan43434782011-04-12 18:31:57 -03007241 l2cap_check_encryption(chan, encrypt);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02007242 l2cap_chan_unlock(chan);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02007243 continue;
7244 }
7245
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03007246 if (chan->state == BT_CONNECT) {
Johan Hedberg6d3c15d2013-12-02 22:13:24 +02007247 if (!status)
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03007248 l2cap_start_connection(chan);
Johan Hedberg6d3c15d2013-12-02 22:13:24 +02007249 else
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08007250 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03007251 } else if (chan->state == BT_CONNECT2) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +02007252 struct l2cap_conn_rsp rsp;
Johan Hedbergdf3c3932011-06-14 12:48:19 +03007253 __u16 res, stat;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02007254
7255 if (!status) {
Marcel Holtmannbdc25782013-10-14 02:45:34 -07007256 if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
Johan Hedbergdf3c3932011-06-14 12:48:19 +03007257 res = L2CAP_CR_PEND;
7258 stat = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08007259 chan->ops->defer(chan);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03007260 } else {
Gustavo Padovanacdcabf2013-10-21 14:21:39 -02007261 l2cap_state_change(chan, BT_CONFIG);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03007262 res = L2CAP_CR_SUCCESS;
7263 stat = L2CAP_CS_NO_INFO;
7264 }
Marcel Holtmannb1235d72008-07-14 20:13:54 +02007265 } else {
Gustavo Padovanacdcabf2013-10-21 14:21:39 -02007266 l2cap_state_change(chan, BT_DISCONN);
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08007267 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03007268 res = L2CAP_CR_SEC_BLOCK;
7269 stat = L2CAP_CS_NO_INFO;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02007270 }
7271
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03007272 rsp.scid = cpu_to_le16(chan->dcid);
7273 rsp.dcid = cpu_to_le16(chan->scid);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03007274 rsp.result = cpu_to_le16(res);
7275 rsp.status = cpu_to_le16(stat);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03007276 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01007277 sizeof(rsp), &rsp);
Mat Martineau2d369352012-05-23 14:59:30 -07007278
7279 if (!test_bit(CONF_REQ_SENT, &chan->conf_state) &&
7280 res == L2CAP_CR_SUCCESS) {
7281 char buf[128];
7282 set_bit(CONF_REQ_SENT, &chan->conf_state);
7283 l2cap_send_cmd(conn, l2cap_get_ident(conn),
7284 L2CAP_CONF_REQ,
7285 l2cap_build_conf_req(chan, buf),
7286 buf);
7287 chan->num_conf_req++;
7288 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07007289 }
7290
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02007291 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007292 }
7293
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02007294 mutex_unlock(&conn->chan_lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02007295
Linus Torvalds1da177e2005-04-16 15:20:36 -07007296 return 0;
7297}
7298
Ulisses Furquim686ebf22011-12-21 10:11:33 -02007299int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007300{
7301 struct l2cap_conn *conn = hcon->l2cap_data;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03007302 struct l2cap_hdr *hdr;
7303 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007304
Andrei Emeltchenko1d13a252012-10-15 11:58:41 +03007305 /* For AMP controller do not create l2cap conn */
7306 if (!conn && hcon->hdev->dev_type != HCI_BREDR)
7307 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007308
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02007309 if (!conn)
Claudio Takahasibaf43252013-04-11 13:55:50 -03007310 conn = l2cap_conn_add(hcon);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02007311
7312 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007313 goto drop;
7314
7315 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
7316
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03007317 switch (flags) {
7318 case ACL_START:
7319 case ACL_START_NO_FLUSH:
7320 case ACL_COMPLETE:
Linus Torvalds1da177e2005-04-16 15:20:36 -07007321 if (conn->rx_len) {
7322 BT_ERR("Unexpected start frame (len %d)", skb->len);
7323 kfree_skb(conn->rx_skb);
7324 conn->rx_skb = NULL;
7325 conn->rx_len = 0;
7326 l2cap_conn_unreliable(conn, ECOMM);
7327 }
7328
Andrei Emeltchenkoaae7fe22010-09-15 14:28:43 +03007329 /* Start fragment always begin with Basic L2CAP header */
7330 if (skb->len < L2CAP_HDR_SIZE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07007331 BT_ERR("Frame is too short (len %d)", skb->len);
7332 l2cap_conn_unreliable(conn, ECOMM);
7333 goto drop;
7334 }
7335
7336 hdr = (struct l2cap_hdr *) skb->data;
7337 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
7338
7339 if (len == skb->len) {
7340 /* Complete frame received */
7341 l2cap_recv_frame(conn, skb);
7342 return 0;
7343 }
7344
7345 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
7346
7347 if (skb->len > len) {
7348 BT_ERR("Frame is too long (len %d, expected len %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01007349 skb->len, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007350 l2cap_conn_unreliable(conn, ECOMM);
7351 goto drop;
7352 }
7353
7354 /* Allocate skb for the complete frame (with header) */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03007355 conn->rx_skb = bt_skb_alloc(len, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03007356 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007357 goto drop;
7358
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03007359 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01007360 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007361 conn->rx_len = len - skb->len;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03007362 break;
7363
7364 case ACL_CONT:
Linus Torvalds1da177e2005-04-16 15:20:36 -07007365 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
7366
7367 if (!conn->rx_len) {
7368 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
7369 l2cap_conn_unreliable(conn, ECOMM);
7370 goto drop;
7371 }
7372
7373 if (skb->len > conn->rx_len) {
7374 BT_ERR("Fragment is too long (len %d, expected %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01007375 skb->len, conn->rx_len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007376 kfree_skb(conn->rx_skb);
7377 conn->rx_skb = NULL;
7378 conn->rx_len = 0;
7379 l2cap_conn_unreliable(conn, ECOMM);
7380 goto drop;
7381 }
7382
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03007383 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01007384 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007385 conn->rx_len -= skb->len;
7386
7387 if (!conn->rx_len) {
Johan Hedbergc4e5baf2013-10-10 13:33:37 +02007388 /* Complete frame received. l2cap_recv_frame
7389 * takes ownership of the skb so set the global
7390 * rx_skb pointer to NULL first.
7391 */
7392 struct sk_buff *rx_skb = conn->rx_skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007393 conn->rx_skb = NULL;
Johan Hedbergc4e5baf2013-10-10 13:33:37 +02007394 l2cap_recv_frame(conn, rx_skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007395 }
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03007396 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007397 }
7398
7399drop:
7400 kfree_skb(skb);
7401 return 0;
7402}
7403
Marcel Holtmannaef7d972010-03-21 05:27:45 +01007404static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007405{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007406 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007407
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02007408 read_lock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007409
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007410 list_for_each_entry(c, &chan_list, global_l) {
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +03007411 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 -07007412 &c->src, &c->dst,
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +03007413 c->state, __le16_to_cpu(c->psm),
7414 c->scid, c->dcid, c->imtu, c->omtu,
7415 c->sec_level, c->mode);
Andrei Emeltchenko61e1b4b2012-01-19 11:19:50 +02007416 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07007417
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02007418 read_unlock(&chan_list_lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08007419
Marcel Holtmannaef7d972010-03-21 05:27:45 +01007420 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007421}
7422
Marcel Holtmannaef7d972010-03-21 05:27:45 +01007423static int l2cap_debugfs_open(struct inode *inode, struct file *file)
7424{
7425 return single_open(file, l2cap_debugfs_show, inode->i_private);
7426}
7427
7428static const struct file_operations l2cap_debugfs_fops = {
7429 .open = l2cap_debugfs_open,
7430 .read = seq_read,
7431 .llseek = seq_lseek,
7432 .release = single_release,
7433};
7434
7435static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007436
Gustavo F. Padovan64274512011-02-07 20:08:52 -02007437int __init l2cap_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007438{
7439 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08007440
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02007441 err = l2cap_init_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07007442 if (err < 0)
7443 return err;
7444
Marcel Holtmann1120e4b2013-10-17 17:24:16 -07007445 if (IS_ERR_OR_NULL(bt_debugfs))
7446 return 0;
7447
7448 l2cap_debugfs = debugfs_create_file("l2cap", 0444, bt_debugfs,
7449 NULL, &l2cap_debugfs_fops);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007450
Linus Torvalds1da177e2005-04-16 15:20:36 -07007451 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007452}
7453
Gustavo F. Padovan64274512011-02-07 20:08:52 -02007454void l2cap_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007455{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01007456 debugfs_remove(l2cap_debugfs);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02007457 l2cap_cleanup_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07007458}
7459
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03007460module_param(disable_ertm, bool, 0644);
7461MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode");