blob: a0a910eb897bc12ded3a8ef3cad3f54f1184d646 [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
Johan Hedberg0f1bfe42014-01-27 15:11:35 -080044#define LE_FLOWCTL_MAX_CREDITS 65535
45
Mat Martineaud1de6d42012-05-17 20:53:55 -070046bool disable_ertm;
Marcel Holtmannf0709e02007-10-20 13:38:51 +020047
Marcel Holtmann547d1032013-10-12 08:18:19 -070048static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN | L2CAP_FEAT_UCD;
Marcel Holtmanna6801ca2014-07-11 06:03:08 +020049static u8 l2cap_fixed_chan[8] = { L2CAP_FC_SIG_BREDR | L2CAP_FC_CONNLESS, };
Linus Torvalds1da177e2005-04-16 15:20:36 -070050
Johannes Bergb5ad8b72011-06-01 08:54:45 +020051static LIST_HEAD(chan_list);
52static DEFINE_RWLOCK(chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -070053
Johan Hedbergf15b8ec2013-12-03 15:08:25 +020054static u16 le_max_credits = L2CAP_LE_MAX_CREDITS;
55static u16 le_default_mps = L2CAP_LE_DEFAULT_MPS;
56
Linus Torvalds1da177e2005-04-16 15:20:36 -070057static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +010058 u8 code, u8 ident, u16 dlen, void *data);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -030059static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
Gustavo Padovan2d792812012-10-06 10:07:01 +010060 void *data);
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -030061static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +020062static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err);
Linus Torvalds1da177e2005-04-16 15:20:36 -070063
Gustavo Padovand6603662012-05-21 13:58:22 -030064static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
Gustavo Padovan2d792812012-10-06 10:07:01 +010065 struct sk_buff_head *skbs, u8 event);
Mat Martineau608bcc62012-05-17 20:53:32 -070066
Marcel Holtmann4f1654e2013-10-13 08:50:41 -070067static inline __u8 bdaddr_type(struct hci_conn *hcon, __u8 type)
68{
69 if (hcon->type == LE_LINK) {
70 if (type == ADDR_LE_DEV_PUBLIC)
71 return BDADDR_LE_PUBLIC;
72 else
73 return BDADDR_LE_RANDOM;
74 }
75
76 return BDADDR_BREDR;
77}
78
Marcel Holtmann01394182006-07-03 10:02:46 +020079/* ---- L2CAP channels ---- */
Gustavo F. Padovan71ba0e52011-05-17 14:34:52 -030080
Gustavo Padovan2d792812012-10-06 10:07:01 +010081static struct l2cap_chan *__l2cap_get_chan_by_dcid(struct l2cap_conn *conn,
82 u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +020083{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020084 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030085
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020086 list_for_each_entry(c, &conn->chan_l, list) {
87 if (c->dcid == cid)
88 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +020089 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020090 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +020091}
92
Gustavo Padovan2d792812012-10-06 10:07:01 +010093static struct l2cap_chan *__l2cap_get_chan_by_scid(struct l2cap_conn *conn,
94 u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +020095{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020096 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030097
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020098 list_for_each_entry(c, &conn->chan_l, list) {
99 if (c->scid == cid)
100 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +0200101 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200102 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200103}
104
105/* Find channel with given SCID.
Mat Martineauef191ad2012-05-02 09:42:00 -0700106 * Returns locked channel. */
Gustavo Padovan2d792812012-10-06 10:07:01 +0100107static struct l2cap_chan *l2cap_get_chan_by_scid(struct l2cap_conn *conn,
108 u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +0200109{
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300110 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300111
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200112 mutex_lock(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300113 c = __l2cap_get_chan_by_scid(conn, cid);
Mat Martineauef191ad2012-05-02 09:42:00 -0700114 if (c)
115 l2cap_chan_lock(c);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200116 mutex_unlock(&conn->chan_lock);
117
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300118 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +0200119}
120
Mat Martineaub1a130b2012-10-23 15:24:09 -0700121/* Find channel with given DCID.
122 * Returns locked channel.
123 */
124static struct l2cap_chan *l2cap_get_chan_by_dcid(struct l2cap_conn *conn,
125 u16 cid)
126{
127 struct l2cap_chan *c;
128
129 mutex_lock(&conn->chan_lock);
130 c = __l2cap_get_chan_by_dcid(conn, cid);
131 if (c)
132 l2cap_chan_lock(c);
133 mutex_unlock(&conn->chan_lock);
134
135 return c;
136}
137
Gustavo Padovan2d792812012-10-06 10:07:01 +0100138static struct l2cap_chan *__l2cap_get_chan_by_ident(struct l2cap_conn *conn,
139 u8 ident)
Marcel Holtmann01394182006-07-03 10:02:46 +0200140{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200141 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300142
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200143 list_for_each_entry(c, &conn->chan_l, list) {
144 if (c->ident == ident)
145 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +0200146 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200147 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200148}
149
Mat Martineau5b155ef2012-10-23 15:24:14 -0700150static struct l2cap_chan *l2cap_get_chan_by_ident(struct l2cap_conn *conn,
151 u8 ident)
152{
153 struct l2cap_chan *c;
154
155 mutex_lock(&conn->chan_lock);
156 c = __l2cap_get_chan_by_ident(conn, ident);
157 if (c)
158 l2cap_chan_lock(c);
159 mutex_unlock(&conn->chan_lock);
160
161 return c;
162}
163
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300164static struct l2cap_chan *__l2cap_global_chan_by_addr(__le16 psm, bdaddr_t *src)
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300165{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300166 struct l2cap_chan *c;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300167
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300168 list_for_each_entry(c, &chan_list, global_l) {
Marcel Holtmann7eafc592013-10-13 08:12:47 -0700169 if (c->sport == psm && !bacmp(&c->src, src))
Szymon Janc250938c2011-11-16 09:32:22 +0100170 return c;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300171 }
Szymon Janc250938c2011-11-16 09:32:22 +0100172 return NULL;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300173}
174
175int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm)
176{
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300177 int err;
178
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200179 write_lock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300180
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300181 if (psm && __l2cap_global_chan_by_addr(psm, src)) {
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300182 err = -EADDRINUSE;
183 goto done;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300184 }
185
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300186 if (psm) {
187 chan->psm = psm;
188 chan->sport = psm;
189 err = 0;
190 } else {
191 u16 p;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300192
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300193 err = -EINVAL;
194 for (p = 0x1001; p < 0x1100; p += 2)
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300195 if (!__l2cap_global_chan_by_addr(cpu_to_le16(p), src)) {
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300196 chan->psm = cpu_to_le16(p);
197 chan->sport = cpu_to_le16(p);
198 err = 0;
199 break;
200 }
201 }
202
203done:
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200204 write_unlock(&chan_list_lock);
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300205 return err;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300206}
Jukka Rissanen6b8d4a62014-06-18 16:37:08 +0300207EXPORT_SYMBOL_GPL(l2cap_add_psm);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300208
209int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid)
210{
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200211 write_lock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300212
213 chan->scid = scid;
214
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200215 write_unlock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300216
217 return 0;
218}
219
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300220static u16 l2cap_alloc_cid(struct l2cap_conn *conn)
Marcel Holtmann01394182006-07-03 10:02:46 +0200221{
Johan Hedberge77af752013-10-08 10:31:00 +0200222 u16 cid, dyn_end;
Marcel Holtmann01394182006-07-03 10:02:46 +0200223
Johan Hedberge77af752013-10-08 10:31:00 +0200224 if (conn->hcon->type == LE_LINK)
225 dyn_end = L2CAP_CID_LE_DYN_END;
226 else
227 dyn_end = L2CAP_CID_DYN_END;
228
229 for (cid = L2CAP_CID_DYN_START; cid < dyn_end; cid++) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300230 if (!__l2cap_get_chan_by_scid(conn, cid))
Marcel Holtmann01394182006-07-03 10:02:46 +0200231 return cid;
232 }
233
234 return 0;
235}
236
Gustavo Padovanf93fa272013-10-21 14:21:40 -0200237static void l2cap_state_change(struct l2cap_chan *chan, int state)
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300238{
Andrei Emeltchenko42d2d872012-02-17 11:40:57 +0200239 BT_DBG("chan %p %s -> %s", chan, state_to_string(chan->state),
Gustavo Padovan2d792812012-10-06 10:07:01 +0100240 state_to_string(state));
Gustavo F. Padovanbadaaa02011-11-23 20:11:46 -0200241
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300242 chan->state = state;
Gustavo Padovan53f52122013-10-15 19:24:45 -0300243 chan->ops->state_change(chan, state, 0);
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300244}
245
Gustavo Padovanf8e73012013-10-15 19:24:46 -0300246static inline void l2cap_state_change_and_error(struct l2cap_chan *chan,
247 int state, int err)
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +0200248{
Gustavo Padovanf8e73012013-10-15 19:24:46 -0300249 chan->state = state;
Gustavo Padovan53f52122013-10-15 19:24:45 -0300250 chan->ops->state_change(chan, chan->state, err);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +0200251}
252
253static inline void l2cap_chan_set_err(struct l2cap_chan *chan, int err)
254{
Gustavo Padovanf8e73012013-10-15 19:24:46 -0300255 chan->ops->state_change(chan, chan->state, err);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +0200256}
257
Mat Martineau4239d162012-05-17 20:53:49 -0700258static void __set_retrans_timer(struct l2cap_chan *chan)
259{
260 if (!delayed_work_pending(&chan->monitor_timer) &&
261 chan->retrans_timeout) {
262 l2cap_set_timer(chan, &chan->retrans_timer,
263 msecs_to_jiffies(chan->retrans_timeout));
264 }
265}
266
267static void __set_monitor_timer(struct l2cap_chan *chan)
268{
269 __clear_retrans_timer(chan);
270 if (chan->monitor_timeout) {
271 l2cap_set_timer(chan, &chan->monitor_timer,
272 msecs_to_jiffies(chan->monitor_timeout));
273 }
274}
275
Mat Martineau608bcc62012-05-17 20:53:32 -0700276static struct sk_buff *l2cap_ertm_seq_in_queue(struct sk_buff_head *head,
277 u16 seq)
278{
279 struct sk_buff *skb;
280
281 skb_queue_walk(head, skb) {
282 if (bt_cb(skb)->control.txseq == seq)
283 return skb;
284 }
285
286 return NULL;
287}
288
Mat Martineau3c588192012-04-11 10:48:42 -0700289/* ---- L2CAP sequence number lists ---- */
290
291/* For ERTM, ordered lists of sequence numbers must be tracked for
292 * SREJ requests that are received and for frames that are to be
293 * retransmitted. These seq_list functions implement a singly-linked
294 * list in an array, where membership in the list can also be checked
295 * in constant time. Items can also be added to the tail of the list
296 * and removed from the head in constant time, without further memory
297 * allocs or frees.
298 */
299
300static int l2cap_seq_list_init(struct l2cap_seq_list *seq_list, u16 size)
301{
302 size_t alloc_size, i;
303
304 /* Allocated size is a power of 2 to map sequence numbers
305 * (which may be up to 14 bits) in to a smaller array that is
306 * sized for the negotiated ERTM transmit windows.
307 */
308 alloc_size = roundup_pow_of_two(size);
309
310 seq_list->list = kmalloc(sizeof(u16) * alloc_size, GFP_KERNEL);
311 if (!seq_list->list)
312 return -ENOMEM;
313
314 seq_list->mask = alloc_size - 1;
315 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
316 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
317 for (i = 0; i < alloc_size; i++)
318 seq_list->list[i] = L2CAP_SEQ_LIST_CLEAR;
319
320 return 0;
321}
322
323static inline void l2cap_seq_list_free(struct l2cap_seq_list *seq_list)
324{
325 kfree(seq_list->list);
326}
327
328static inline bool l2cap_seq_list_contains(struct l2cap_seq_list *seq_list,
329 u16 seq)
330{
331 /* Constant-time check for list membership */
332 return seq_list->list[seq & seq_list->mask] != L2CAP_SEQ_LIST_CLEAR;
333}
334
Mat Martineau3c588192012-04-11 10:48:42 -0700335static inline u16 l2cap_seq_list_pop(struct l2cap_seq_list *seq_list)
336{
Johan Hedberg03a0c5d2014-01-18 21:32:59 +0200337 u16 seq = seq_list->head;
338 u16 mask = seq_list->mask;
339
340 seq_list->head = seq_list->list[seq & mask];
341 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_CLEAR;
342
343 if (seq_list->head == L2CAP_SEQ_LIST_TAIL) {
344 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
345 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
346 }
347
348 return seq;
Mat Martineau3c588192012-04-11 10:48:42 -0700349}
350
351static void l2cap_seq_list_clear(struct l2cap_seq_list *seq_list)
352{
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300353 u16 i;
Mat Martineau3c588192012-04-11 10:48:42 -0700354
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300355 if (seq_list->head == L2CAP_SEQ_LIST_CLEAR)
356 return;
357
358 for (i = 0; i <= seq_list->mask; i++)
359 seq_list->list[i] = L2CAP_SEQ_LIST_CLEAR;
360
361 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
362 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
Mat Martineau3c588192012-04-11 10:48:42 -0700363}
364
365static void l2cap_seq_list_append(struct l2cap_seq_list *seq_list, u16 seq)
366{
367 u16 mask = seq_list->mask;
368
369 /* All appends happen in constant time */
370
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300371 if (seq_list->list[seq & mask] != L2CAP_SEQ_LIST_CLEAR)
372 return;
Mat Martineau3c588192012-04-11 10:48:42 -0700373
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300374 if (seq_list->tail == L2CAP_SEQ_LIST_CLEAR)
375 seq_list->head = seq;
376 else
377 seq_list->list[seq_list->tail & mask] = seq;
378
379 seq_list->tail = seq;
380 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_TAIL;
Mat Martineau3c588192012-04-11 10:48:42 -0700381}
382
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300383static void l2cap_chan_timeout(struct work_struct *work)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300384{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300385 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100386 chan_timer.work);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200387 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300388 int reason;
389
Andrei Emeltchenkoe05dcc32012-02-17 11:40:56 +0200390 BT_DBG("chan %p state %s", chan, state_to_string(chan->state));
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300391
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200392 mutex_lock(&conn->chan_lock);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200393 l2cap_chan_lock(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300394
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300395 if (chan->state == BT_CONNECTED || chan->state == BT_CONFIG)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300396 reason = ECONNREFUSED;
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300397 else if (chan->state == BT_CONNECT &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100398 chan->sec_level != BT_SECURITY_SDP)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300399 reason = ECONNREFUSED;
400 else
401 reason = ETIMEDOUT;
402
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300403 l2cap_chan_close(chan, reason);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300404
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200405 l2cap_chan_unlock(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300406
Gustavo Padovan80b98022012-05-27 22:27:51 -0300407 chan->ops->close(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200408 mutex_unlock(&conn->chan_lock);
409
Ulisses Furquim371fd832011-12-21 20:02:36 -0200410 l2cap_chan_put(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300411}
412
Gustavo Padovaneef1d9b2012-03-25 13:59:16 -0300413struct l2cap_chan *l2cap_chan_create(void)
Marcel Holtmann01394182006-07-03 10:02:46 +0200414{
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300415 struct l2cap_chan *chan;
Marcel Holtmann01394182006-07-03 10:02:46 +0200416
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300417 chan = kzalloc(sizeof(*chan), GFP_ATOMIC);
418 if (!chan)
419 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200420
Andrei Emeltchenkoc03b3552012-02-21 12:54:56 +0200421 mutex_init(&chan->lock);
422
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200423 write_lock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300424 list_add(&chan->global_l, &chan_list);
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200425 write_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300426
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300427 INIT_DELAYED_WORK(&chan->chan_timer, l2cap_chan_timeout);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300428
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300429 chan->state = BT_OPEN;
430
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530431 kref_init(&chan->kref);
Gustavo F. Padovan71ba0e52011-05-17 14:34:52 -0300432
Mat Martineau28270112012-05-17 21:14:09 -0700433 /* This flag is cleared in l2cap_chan_ready() */
434 set_bit(CONF_NOT_COMPLETE, &chan->conf_state);
435
Gustavo Padovaneef1d9b2012-03-25 13:59:16 -0300436 BT_DBG("chan %p", chan);
Szymon Jancabc545b2011-11-03 16:05:44 +0100437
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300438 return chan;
Marcel Holtmann01394182006-07-03 10:02:46 +0200439}
Jukka Rissanen6b8d4a62014-06-18 16:37:08 +0300440EXPORT_SYMBOL_GPL(l2cap_chan_create);
Marcel Holtmann01394182006-07-03 10:02:46 +0200441
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530442static void l2cap_chan_destroy(struct kref *kref)
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300443{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530444 struct l2cap_chan *chan = container_of(kref, struct l2cap_chan, kref);
445
Jaganath Kanakkassery4af66c62012-07-13 18:17:55 +0530446 BT_DBG("chan %p", chan);
447
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200448 write_lock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300449 list_del(&chan->global_l);
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200450 write_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300451
Jaganath Kanakkassery4af66c62012-07-13 18:17:55 +0530452 kfree(chan);
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300453}
454
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530455void l2cap_chan_hold(struct l2cap_chan *c)
456{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530457 BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->kref.refcount));
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530458
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530459 kref_get(&c->kref);
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530460}
461
462void l2cap_chan_put(struct l2cap_chan *c)
463{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530464 BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->kref.refcount));
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530465
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530466 kref_put(&c->kref, l2cap_chan_destroy);
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530467}
Jukka Rissanen6b8d4a62014-06-18 16:37:08 +0300468EXPORT_SYMBOL_GPL(l2cap_chan_put);
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530469
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +0300470void l2cap_chan_set_defaults(struct l2cap_chan *chan)
471{
472 chan->fcs = L2CAP_FCS_CRC16;
473 chan->max_tx = L2CAP_DEFAULT_MAX_TX;
474 chan->tx_win = L2CAP_DEFAULT_TX_WINDOW;
475 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
Jukka Rissanen6a5e8162014-05-28 14:43:04 +0300476 chan->remote_max_tx = chan->max_tx;
477 chan->remote_tx_win = chan->tx_win;
Mat Martineauc20f8e32012-07-10 05:47:07 -0700478 chan->ack_win = L2CAP_DEFAULT_TX_WINDOW;
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +0300479 chan->sec_level = BT_SECURITY_LOW;
Jukka Rissanen6a5e8162014-05-28 14:43:04 +0300480 chan->flush_to = L2CAP_DEFAULT_FLUSH_TO;
481 chan->retrans_timeout = L2CAP_DEFAULT_RETRANS_TO;
482 chan->monitor_timeout = L2CAP_DEFAULT_MONITOR_TO;
483 chan->conf_state = 0;
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +0300484
485 set_bit(FLAG_FORCE_ACTIVE, &chan->flags);
486}
Jukka Rissanen6b8d4a62014-06-18 16:37:08 +0300487EXPORT_SYMBOL_GPL(l2cap_chan_set_defaults);
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +0300488
Johan Hedberg0ce43ce2013-12-05 14:55:33 +0200489static void l2cap_le_flowctl_init(struct l2cap_chan *chan)
Johan Hedberg38319712013-05-17 12:49:23 +0300490{
Johan Hedberg0ce43ce2013-12-05 14:55:33 +0200491 chan->sdu = NULL;
492 chan->sdu_last_frag = NULL;
493 chan->sdu_len = 0;
Johan Hedberg0cd75f72013-05-17 13:09:05 +0300494 chan->tx_credits = 0;
Johan Hedbergf15b8ec2013-12-03 15:08:25 +0200495 chan->rx_credits = le_max_credits;
Johan Hedbergd1d79412014-01-27 15:11:33 -0800496 chan->mps = min_t(u16, chan->imtu, le_default_mps);
Johan Hedberg0ce43ce2013-12-05 14:55:33 +0200497
498 skb_queue_head_init(&chan->tx_q);
Johan Hedberg38319712013-05-17 12:49:23 +0300499}
500
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +0300501void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Marcel Holtmann01394182006-07-03 10:02:46 +0200502{
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300503 BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
Andrei Emeltchenko097db762012-03-09 14:16:17 +0200504 __le16_to_cpu(chan->psm), chan->dcid);
Marcel Holtmann01394182006-07-03 10:02:46 +0200505
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +0200506 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +0100507
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300508 chan->conn = conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200509
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200510 switch (chan->chan_type) {
511 case L2CAP_CHAN_CONN_ORIENTED:
Johan Hedberg21626e62014-01-24 10:35:41 +0200512 /* Alloc CID for connection-oriented socket */
513 chan->scid = l2cap_alloc_cid(conn);
514 if (conn->hcon->type == ACL_LINK)
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300515 chan->omtu = L2CAP_DEFAULT_MTU;
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200516 break;
517
518 case L2CAP_CHAN_CONN_LESS:
Marcel Holtmann01394182006-07-03 10:02:46 +0200519 /* Connectionless socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300520 chan->scid = L2CAP_CID_CONN_LESS;
521 chan->dcid = L2CAP_CID_CONN_LESS;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300522 chan->omtu = L2CAP_DEFAULT_MTU;
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200523 break;
524
Johan Hedberg2338a7e2014-01-24 10:35:40 +0200525 case L2CAP_CHAN_FIXED:
526 /* Caller will set CID and CID specific MTU values */
Andrei Emeltchenko416fa752012-05-29 13:59:16 +0300527 break;
528
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200529 default:
Marcel Holtmann01394182006-07-03 10:02:46 +0200530 /* Raw socket can send/recv signalling messages only */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300531 chan->scid = L2CAP_CID_SIGNALING;
532 chan->dcid = L2CAP_CID_SIGNALING;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300533 chan->omtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann01394182006-07-03 10:02:46 +0200534 }
535
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300536 chan->local_id = L2CAP_BESTEFFORT_ID;
537 chan->local_stype = L2CAP_SERV_BESTEFFORT;
538 chan->local_msdu = L2CAP_DEFAULT_MAX_SDU_SIZE;
539 chan->local_sdu_itime = L2CAP_DEFAULT_SDU_ITIME;
540 chan->local_acc_lat = L2CAP_DEFAULT_ACC_LAT;
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +0300541 chan->local_flush_to = L2CAP_EFS_DEFAULT_FLUSH_TO;
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300542
Ulisses Furquim371fd832011-12-21 20:02:36 -0200543 l2cap_chan_hold(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300544
Johan Hedberg5ee98912013-04-29 19:35:43 +0300545 hci_conn_hold(conn->hcon);
546
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200547 list_add(&chan->list, &conn->chan_l);
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200548}
549
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300550void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200551{
552 mutex_lock(&conn->chan_lock);
553 __l2cap_chan_add(conn, chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200554 mutex_unlock(&conn->chan_lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200555}
556
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300557void l2cap_chan_del(struct l2cap_chan *chan, int err)
Marcel Holtmann01394182006-07-03 10:02:46 +0200558{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300559 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200560
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300561 __clear_chan_timer(chan);
Marcel Holtmann01394182006-07-03 10:02:46 +0200562
Gustavo F. Padovan49208c92011-04-04 15:59:54 -0300563 BT_DBG("chan %p, conn %p, err %d", chan, conn, err);
Marcel Holtmann01394182006-07-03 10:02:46 +0200564
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900565 if (conn) {
Andrei Emeltchenko56f60982012-10-15 11:58:44 +0300566 struct amp_mgr *mgr = conn->hcon->amp_mgr;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300567 /* Delete from channel list */
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200568 list_del(&chan->list);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -0200569
Ulisses Furquim371fd832011-12-21 20:02:36 -0200570 l2cap_chan_put(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300571
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300572 chan->conn = NULL;
Andrei Emeltchenko3cabbfd2012-05-31 11:01:37 +0300573
Johan Hedberg2338a7e2014-01-24 10:35:40 +0200574 if (chan->scid != L2CAP_CID_A2MP)
David Herrmann76a68ba2013-04-06 20:28:37 +0200575 hci_conn_drop(conn->hcon);
Andrei Emeltchenko56f60982012-10-15 11:58:44 +0300576
577 if (mgr && mgr->bredr_chan == chan)
578 mgr->bredr_chan = NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200579 }
580
Andrei Emeltchenko419e08c2012-10-31 15:46:34 +0200581 if (chan->hs_hchan) {
582 struct hci_chan *hs_hchan = chan->hs_hchan;
583
584 BT_DBG("chan %p disconnect hs_hchan %p", chan, hs_hchan);
585 amp_disconnect_logical_link(hs_hchan);
586 }
587
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100588 chan->ops->teardown(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200589
Mat Martineau28270112012-05-17 21:14:09 -0700590 if (test_bit(CONF_NOT_COMPLETE, &chan->conf_state))
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300591 return;
Gustavo F. Padovan2ead70b2011-04-01 15:13:36 -0300592
Gustavo Padovanee556f62012-05-18 20:22:38 -0300593 switch(chan->mode) {
594 case L2CAP_MODE_BASIC:
595 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300596
Johan Hedberg38319712013-05-17 12:49:23 +0300597 case L2CAP_MODE_LE_FLOWCTL:
Johan Hedberg177f8f22013-05-31 17:54:51 +0300598 skb_queue_purge(&chan->tx_q);
Johan Hedberg38319712013-05-17 12:49:23 +0300599 break;
600
Gustavo Padovanee556f62012-05-18 20:22:38 -0300601 case L2CAP_MODE_ERTM:
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -0300602 __clear_retrans_timer(chan);
603 __clear_monitor_timer(chan);
604 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300605
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -0300606 skb_queue_purge(&chan->srej_q);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300607
Mat Martineau3c588192012-04-11 10:48:42 -0700608 l2cap_seq_list_free(&chan->srej_list);
609 l2cap_seq_list_free(&chan->retrans_list);
Gustavo Padovanee556f62012-05-18 20:22:38 -0300610
611 /* fall through */
612
613 case L2CAP_MODE_STREAMING:
614 skb_queue_purge(&chan->tx_q);
615 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300616 }
Gustavo Padovanee556f62012-05-18 20:22:38 -0300617
618 return;
Marcel Holtmann01394182006-07-03 10:02:46 +0200619}
Jukka Rissanen6b8d4a62014-06-18 16:37:08 +0300620EXPORT_SYMBOL_GPL(l2cap_chan_del);
Marcel Holtmann01394182006-07-03 10:02:46 +0200621
Johan Hedberg387a33e2014-02-18 21:41:33 +0200622void l2cap_conn_update_id_addr(struct hci_conn *hcon)
623{
624 struct l2cap_conn *conn = hcon->l2cap_data;
625 struct l2cap_chan *chan;
626
627 mutex_lock(&conn->chan_lock);
628
629 list_for_each_entry(chan, &conn->chan_l, list) {
630 l2cap_chan_lock(chan);
631 bacpy(&chan->dst, &hcon->dst);
632 chan->dst_type = bdaddr_type(hcon, hcon->dst_type);
633 l2cap_chan_unlock(chan);
634 }
635
636 mutex_unlock(&conn->chan_lock);
637}
638
Johan Hedberg27e2d4c2013-05-14 13:27:21 +0300639static void l2cap_chan_le_connect_reject(struct l2cap_chan *chan)
640{
641 struct l2cap_conn *conn = chan->conn;
642 struct l2cap_le_conn_rsp rsp;
643 u16 result;
644
645 if (test_bit(FLAG_DEFER_SETUP, &chan->flags))
646 result = L2CAP_CR_AUTHORIZATION;
647 else
648 result = L2CAP_CR_BAD_PSM;
649
650 l2cap_state_change(chan, BT_DISCONN);
651
652 rsp.dcid = cpu_to_le16(chan->scid);
653 rsp.mtu = cpu_to_le16(chan->imtu);
Johan Hedberg3916aed2013-10-07 15:35:26 +0200654 rsp.mps = cpu_to_le16(chan->mps);
Johan Hedberg0cd75f72013-05-17 13:09:05 +0300655 rsp.credits = cpu_to_le16(chan->rx_credits);
Johan Hedberg27e2d4c2013-05-14 13:27:21 +0300656 rsp.result = cpu_to_le16(result);
657
658 l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CONN_RSP, sizeof(rsp),
659 &rsp);
660}
661
Johan Hedberg791d60f2013-05-14 22:24:44 +0300662static void l2cap_chan_connect_reject(struct l2cap_chan *chan)
663{
664 struct l2cap_conn *conn = chan->conn;
665 struct l2cap_conn_rsp rsp;
666 u16 result;
667
668 if (test_bit(FLAG_DEFER_SETUP, &chan->flags))
669 result = L2CAP_CR_SEC_BLOCK;
670 else
671 result = L2CAP_CR_BAD_PSM;
672
673 l2cap_state_change(chan, BT_DISCONN);
674
675 rsp.scid = cpu_to_le16(chan->dcid);
676 rsp.dcid = cpu_to_le16(chan->scid);
677 rsp.result = cpu_to_le16(result);
Joe Perchesdcf4adb2014-03-12 10:52:35 -0700678 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
Johan Hedberg791d60f2013-05-14 22:24:44 +0300679
680 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
681}
682
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300683void l2cap_chan_close(struct l2cap_chan *chan, int reason)
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300684{
685 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300686
Marcel Holtmann7eafc592013-10-13 08:12:47 -0700687 BT_DBG("chan %p state %s", chan, state_to_string(chan->state));
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300688
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300689 switch (chan->state) {
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300690 case BT_LISTEN:
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100691 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300692 break;
693
694 case BT_CONNECTED:
695 case BT_CONFIG:
Johan Hedberg7b25c9b2014-01-28 15:28:04 -0800696 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED) {
Gustavo Padovan8d836d72013-10-15 19:24:47 -0300697 __set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +0200698 l2cap_send_disconn_req(chan, reason);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300699 } else
700 l2cap_chan_del(chan, reason);
701 break;
702
703 case BT_CONNECT2:
Johan Hedberg791d60f2013-05-14 22:24:44 +0300704 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED) {
705 if (conn->hcon->type == ACL_LINK)
706 l2cap_chan_connect_reject(chan);
Johan Hedberg27e2d4c2013-05-14 13:27:21 +0300707 else if (conn->hcon->type == LE_LINK)
708 l2cap_chan_le_connect_reject(chan);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300709 }
710
711 l2cap_chan_del(chan, reason);
712 break;
713
714 case BT_CONNECT:
715 case BT_DISCONN:
716 l2cap_chan_del(chan, reason);
717 break;
718
719 default:
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100720 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300721 break;
722 }
723}
Jukka Rissanen6b8d4a62014-06-18 16:37:08 +0300724EXPORT_SYMBOL(l2cap_chan_close);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300725
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300726static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530727{
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700728 switch (chan->chan_type) {
729 case L2CAP_CHAN_RAW:
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300730 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530731 case BT_SECURITY_HIGH:
Marcel Holtmann7d513e92014-01-15 22:37:40 -0800732 case BT_SECURITY_FIPS:
Johan Hedberg8556edd32011-01-19 12:06:50 +0530733 return HCI_AT_DEDICATED_BONDING_MITM;
734 case BT_SECURITY_MEDIUM:
735 return HCI_AT_DEDICATED_BONDING;
736 default:
737 return HCI_AT_NO_BONDING;
738 }
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700739 break;
Marcel Holtmann3124b842013-10-12 07:19:32 -0700740 case L2CAP_CHAN_CONN_LESS:
Joe Perchesdcf4adb2014-03-12 10:52:35 -0700741 if (chan->psm == cpu_to_le16(L2CAP_PSM_3DSP)) {
Marcel Holtmann3124b842013-10-12 07:19:32 -0700742 if (chan->sec_level == BT_SECURITY_LOW)
743 chan->sec_level = BT_SECURITY_SDP;
744 }
Marcel Holtmann7d513e92014-01-15 22:37:40 -0800745 if (chan->sec_level == BT_SECURITY_HIGH ||
746 chan->sec_level == BT_SECURITY_FIPS)
Marcel Holtmann3124b842013-10-12 07:19:32 -0700747 return HCI_AT_NO_BONDING_MITM;
748 else
749 return HCI_AT_NO_BONDING;
750 break;
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700751 case L2CAP_CHAN_CONN_ORIENTED:
Joe Perchesdcf4adb2014-03-12 10:52:35 -0700752 if (chan->psm == cpu_to_le16(L2CAP_PSM_SDP)) {
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700753 if (chan->sec_level == BT_SECURITY_LOW)
754 chan->sec_level = BT_SECURITY_SDP;
Johan Hedberg8556edd32011-01-19 12:06:50 +0530755
Marcel Holtmann7d513e92014-01-15 22:37:40 -0800756 if (chan->sec_level == BT_SECURITY_HIGH ||
757 chan->sec_level == BT_SECURITY_FIPS)
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700758 return HCI_AT_NO_BONDING_MITM;
759 else
760 return HCI_AT_NO_BONDING;
761 }
762 /* fall through */
763 default:
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300764 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530765 case BT_SECURITY_HIGH:
Marcel Holtmann7d513e92014-01-15 22:37:40 -0800766 case BT_SECURITY_FIPS:
Johan Hedberg8556edd32011-01-19 12:06:50 +0530767 return HCI_AT_GENERAL_BONDING_MITM;
768 case BT_SECURITY_MEDIUM:
769 return HCI_AT_GENERAL_BONDING;
770 default:
771 return HCI_AT_NO_BONDING;
772 }
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700773 break;
Johan Hedberg8556edd32011-01-19 12:06:50 +0530774 }
775}
776
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200777/* Service level security */
Johan Hedberge7cafc42014-07-17 15:35:38 +0300778int l2cap_chan_check_security(struct l2cap_chan *chan, bool initiator)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200779{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300780 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100781 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200782
Johan Hedberga17de2f2013-05-14 13:25:37 +0300783 if (conn->hcon->type == LE_LINK)
784 return smp_conn_security(conn->hcon, chan->sec_level);
785
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300786 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100787
Johan Hedberge7cafc42014-07-17 15:35:38 +0300788 return hci_conn_security(conn->hcon, chan->sec_level, auth_type,
789 initiator);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200790}
791
Johannes Bergb5ad8b72011-06-01 08:54:45 +0200792static u8 l2cap_get_ident(struct l2cap_conn *conn)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200793{
794 u8 id;
795
796 /* Get next available identificator.
797 * 1 - 128 are used by kernel.
798 * 129 - 199 are reserved.
799 * 200 - 254 are used by utilities like l2ping, etc.
800 */
801
Marcel Holtmann5a54e7c2014-07-13 20:50:15 +0200802 mutex_lock(&conn->ident_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200803
804 if (++conn->tx_ident > 128)
805 conn->tx_ident = 1;
806
807 id = conn->tx_ident;
808
Marcel Holtmann5a54e7c2014-07-13 20:50:15 +0200809 mutex_unlock(&conn->ident_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200810
811 return id;
812}
813
Gustavo Padovan2d792812012-10-06 10:07:01 +0100814static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
815 void *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200816{
817 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200818 u8 flags;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200819
820 BT_DBG("code 0x%2.2x", code);
821
822 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300823 return;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200824
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200825 if (lmp_no_flush_capable(conn->hcon->hdev))
826 flags = ACL_START_NO_FLUSH;
827 else
828 flags = ACL_START;
829
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700830 bt_cb(skb)->force_active = BT_POWER_FORCE_ACTIVE_ON;
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +0200831 skb->priority = HCI_PRIO_MAX;
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700832
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200833 hci_send_acl(conn->hchan, skb, flags);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200834}
835
Mat Martineau02b0fbb2012-10-23 15:24:10 -0700836static bool __chan_is_moving(struct l2cap_chan *chan)
837{
838 return chan->move_state != L2CAP_MOVE_STABLE &&
839 chan->move_state != L2CAP_MOVE_WAIT_PREPARE;
840}
841
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200842static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb)
843{
844 struct hci_conn *hcon = chan->conn->hcon;
845 u16 flags;
846
847 BT_DBG("chan %p, skb %p len %d priority %u", chan, skb, skb->len,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100848 skb->priority);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200849
Mat Martineaud5f8a752012-10-23 15:24:18 -0700850 if (chan->hs_hcon && !__chan_is_moving(chan)) {
851 if (chan->hs_hchan)
852 hci_send_acl(chan->hs_hchan, skb, ACL_COMPLETE);
853 else
854 kfree_skb(skb);
855
856 return;
857 }
858
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200859 if (!test_bit(FLAG_FLUSHABLE, &chan->flags) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100860 lmp_no_flush_capable(hcon->hdev))
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200861 flags = ACL_START_NO_FLUSH;
862 else
863 flags = ACL_START;
864
865 bt_cb(skb)->force_active = test_bit(FLAG_FORCE_ACTIVE, &chan->flags);
866 hci_send_acl(chan->conn->hchan, skb, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700867}
868
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700869static void __unpack_enhanced_control(u16 enh, struct l2cap_ctrl *control)
870{
871 control->reqseq = (enh & L2CAP_CTRL_REQSEQ) >> L2CAP_CTRL_REQSEQ_SHIFT;
872 control->final = (enh & L2CAP_CTRL_FINAL) >> L2CAP_CTRL_FINAL_SHIFT;
873
874 if (enh & L2CAP_CTRL_FRAME_TYPE) {
875 /* S-Frame */
876 control->sframe = 1;
877 control->poll = (enh & L2CAP_CTRL_POLL) >> L2CAP_CTRL_POLL_SHIFT;
878 control->super = (enh & L2CAP_CTRL_SUPERVISE) >> L2CAP_CTRL_SUPER_SHIFT;
879
880 control->sar = 0;
881 control->txseq = 0;
882 } else {
883 /* I-Frame */
884 control->sframe = 0;
885 control->sar = (enh & L2CAP_CTRL_SAR) >> L2CAP_CTRL_SAR_SHIFT;
886 control->txseq = (enh & L2CAP_CTRL_TXSEQ) >> L2CAP_CTRL_TXSEQ_SHIFT;
887
888 control->poll = 0;
889 control->super = 0;
890 }
891}
892
893static void __unpack_extended_control(u32 ext, struct l2cap_ctrl *control)
894{
895 control->reqseq = (ext & L2CAP_EXT_CTRL_REQSEQ) >> L2CAP_EXT_CTRL_REQSEQ_SHIFT;
896 control->final = (ext & L2CAP_EXT_CTRL_FINAL) >> L2CAP_EXT_CTRL_FINAL_SHIFT;
897
898 if (ext & L2CAP_EXT_CTRL_FRAME_TYPE) {
899 /* S-Frame */
900 control->sframe = 1;
901 control->poll = (ext & L2CAP_EXT_CTRL_POLL) >> L2CAP_EXT_CTRL_POLL_SHIFT;
902 control->super = (ext & L2CAP_EXT_CTRL_SUPERVISE) >> L2CAP_EXT_CTRL_SUPER_SHIFT;
903
904 control->sar = 0;
905 control->txseq = 0;
906 } else {
907 /* I-Frame */
908 control->sframe = 0;
909 control->sar = (ext & L2CAP_EXT_CTRL_SAR) >> L2CAP_EXT_CTRL_SAR_SHIFT;
910 control->txseq = (ext & L2CAP_EXT_CTRL_TXSEQ) >> L2CAP_EXT_CTRL_TXSEQ_SHIFT;
911
912 control->poll = 0;
913 control->super = 0;
914 }
915}
916
917static inline void __unpack_control(struct l2cap_chan *chan,
918 struct sk_buff *skb)
919{
920 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
921 __unpack_extended_control(get_unaligned_le32(skb->data),
922 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700923 skb_pull(skb, L2CAP_EXT_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700924 } else {
925 __unpack_enhanced_control(get_unaligned_le16(skb->data),
926 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700927 skb_pull(skb, L2CAP_ENH_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700928 }
929}
930
931static u32 __pack_extended_control(struct l2cap_ctrl *control)
932{
933 u32 packed;
934
935 packed = control->reqseq << L2CAP_EXT_CTRL_REQSEQ_SHIFT;
936 packed |= control->final << L2CAP_EXT_CTRL_FINAL_SHIFT;
937
938 if (control->sframe) {
939 packed |= control->poll << L2CAP_EXT_CTRL_POLL_SHIFT;
940 packed |= control->super << L2CAP_EXT_CTRL_SUPER_SHIFT;
941 packed |= L2CAP_EXT_CTRL_FRAME_TYPE;
942 } else {
943 packed |= control->sar << L2CAP_EXT_CTRL_SAR_SHIFT;
944 packed |= control->txseq << L2CAP_EXT_CTRL_TXSEQ_SHIFT;
945 }
946
947 return packed;
948}
949
950static u16 __pack_enhanced_control(struct l2cap_ctrl *control)
951{
952 u16 packed;
953
954 packed = control->reqseq << L2CAP_CTRL_REQSEQ_SHIFT;
955 packed |= control->final << L2CAP_CTRL_FINAL_SHIFT;
956
957 if (control->sframe) {
958 packed |= control->poll << L2CAP_CTRL_POLL_SHIFT;
959 packed |= control->super << L2CAP_CTRL_SUPER_SHIFT;
960 packed |= L2CAP_CTRL_FRAME_TYPE;
961 } else {
962 packed |= control->sar << L2CAP_CTRL_SAR_SHIFT;
963 packed |= control->txseq << L2CAP_CTRL_TXSEQ_SHIFT;
964 }
965
966 return packed;
967}
968
969static inline void __pack_control(struct l2cap_chan *chan,
970 struct l2cap_ctrl *control,
971 struct sk_buff *skb)
972{
973 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
974 put_unaligned_le32(__pack_extended_control(control),
975 skb->data + L2CAP_HDR_SIZE);
976 } else {
977 put_unaligned_le16(__pack_enhanced_control(control),
978 skb->data + L2CAP_HDR_SIZE);
979 }
980}
981
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300982static inline unsigned int __ertm_hdr_size(struct l2cap_chan *chan)
983{
984 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
985 return L2CAP_EXT_HDR_SIZE;
986 else
987 return L2CAP_ENH_HDR_SIZE;
988}
989
Mat Martineaua67d7f62012-05-17 20:53:35 -0700990static struct sk_buff *l2cap_create_sframe_pdu(struct l2cap_chan *chan,
991 u32 control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300992{
993 struct sk_buff *skb;
994 struct l2cap_hdr *lh;
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300995 int hlen = __ertm_hdr_size(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300996
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300997 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300998 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300999
Mat Martineaua67d7f62012-05-17 20:53:35 -07001000 skb = bt_skb_alloc(hlen, GFP_KERNEL);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001001
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001002 if (!skb)
Mat Martineaua67d7f62012-05-17 20:53:35 -07001003 return ERR_PTR(-ENOMEM);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001004
1005 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001006 lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001007 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03001008
Mat Martineaua67d7f62012-05-17 20:53:35 -07001009 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
1010 put_unaligned_le32(control, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
1011 else
1012 put_unaligned_le16(control, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001013
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001014 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineaua67d7f62012-05-17 20:53:35 -07001015 u16 fcs = crc16(0, (u8 *)skb->data, skb->len);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03001016 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001017 }
1018
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001019 skb->priority = HCI_PRIO_MAX;
Mat Martineaua67d7f62012-05-17 20:53:35 -07001020 return skb;
1021}
1022
1023static void l2cap_send_sframe(struct l2cap_chan *chan,
1024 struct l2cap_ctrl *control)
1025{
1026 struct sk_buff *skb;
1027 u32 control_field;
1028
1029 BT_DBG("chan %p, control %p", chan, control);
1030
1031 if (!control->sframe)
1032 return;
1033
Mat Martineaub99e13a2012-10-23 15:24:19 -07001034 if (__chan_is_moving(chan))
1035 return;
1036
Mat Martineaua67d7f62012-05-17 20:53:35 -07001037 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state) &&
1038 !control->poll)
1039 control->final = 1;
1040
1041 if (control->super == L2CAP_SUPER_RR)
1042 clear_bit(CONN_RNR_SENT, &chan->conn_state);
1043 else if (control->super == L2CAP_SUPER_RNR)
1044 set_bit(CONN_RNR_SENT, &chan->conn_state);
1045
1046 if (control->super != L2CAP_SUPER_SREJ) {
1047 chan->last_acked_seq = control->reqseq;
1048 __clear_ack_timer(chan);
1049 }
1050
1051 BT_DBG("reqseq %d, final %d, poll %d, super %d", control->reqseq,
1052 control->final, control->poll, control->super);
1053
1054 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
1055 control_field = __pack_extended_control(control);
1056 else
1057 control_field = __pack_enhanced_control(control);
1058
1059 skb = l2cap_create_sframe_pdu(chan, control_field);
1060 if (!IS_ERR(skb))
1061 l2cap_do_send(chan, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001062}
1063
Mat Martineauc9e3d5e2012-05-17 20:53:48 -07001064static void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, bool poll)
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001065{
Mat Martineauc9e3d5e2012-05-17 20:53:48 -07001066 struct l2cap_ctrl control;
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001067
Mat Martineauc9e3d5e2012-05-17 20:53:48 -07001068 BT_DBG("chan %p, poll %d", chan, poll);
1069
1070 memset(&control, 0, sizeof(control));
1071 control.sframe = 1;
1072 control.poll = poll;
1073
1074 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
1075 control.super = L2CAP_SUPER_RNR;
1076 else
1077 control.super = L2CAP_SUPER_RR;
1078
1079 control.reqseq = chan->buffer_seq;
1080 l2cap_send_sframe(chan, &control);
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001081}
1082
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03001083static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan)
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03001084{
Johan Hedberg5ff6f342014-08-07 22:56:43 +03001085 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED)
1086 return true;
1087
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001088 return !test_bit(CONF_CONNECT_PEND, &chan->conf_state);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03001089}
1090
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001091static bool __amp_capable(struct l2cap_chan *chan)
1092{
1093 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann1df7b172013-10-05 11:47:49 -07001094 struct hci_dev *hdev;
1095 bool amp_available = false;
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001096
Marcel Holtmann1df7b172013-10-05 11:47:49 -07001097 if (!conn->hs_enabled)
1098 return false;
1099
1100 if (!(conn->fixed_chan_mask & L2CAP_FC_A2MP))
1101 return false;
1102
1103 read_lock(&hci_dev_list_lock);
1104 list_for_each_entry(hdev, &hci_dev_list, list) {
1105 if (hdev->amp_type != AMP_TYPE_BREDR &&
1106 test_bit(HCI_UP, &hdev->flags)) {
1107 amp_available = true;
1108 break;
1109 }
1110 }
1111 read_unlock(&hci_dev_list_lock);
1112
1113 if (chan->chan_policy == BT_CHANNEL_POLICY_AMP_PREFERRED)
1114 return amp_available;
Marcel Holtmann848566b2013-10-01 22:59:22 -07001115
1116 return false;
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001117}
1118
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +02001119static bool l2cap_check_efs(struct l2cap_chan *chan)
1120{
1121 /* Check EFS parameters */
1122 return true;
1123}
1124
Andrei Emeltchenko2766be42012-09-27 17:26:21 +03001125void l2cap_send_conn_req(struct l2cap_chan *chan)
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +02001126{
1127 struct l2cap_conn *conn = chan->conn;
1128 struct l2cap_conn_req req;
1129
1130 req.scid = cpu_to_le16(chan->scid);
1131 req.psm = chan->psm;
1132
1133 chan->ident = l2cap_get_ident(conn);
1134
1135 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
1136
1137 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, sizeof(req), &req);
1138}
1139
Mat Martineau8eb200b2012-10-23 15:24:17 -07001140static void l2cap_send_create_chan_req(struct l2cap_chan *chan, u8 amp_id)
1141{
1142 struct l2cap_create_chan_req req;
1143 req.scid = cpu_to_le16(chan->scid);
1144 req.psm = chan->psm;
1145 req.amp_id = amp_id;
1146
1147 chan->ident = l2cap_get_ident(chan->conn);
1148
1149 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_REQ,
1150 sizeof(req), &req);
1151}
1152
Mat Martineau02b0fbb2012-10-23 15:24:10 -07001153static void l2cap_move_setup(struct l2cap_chan *chan)
1154{
1155 struct sk_buff *skb;
1156
1157 BT_DBG("chan %p", chan);
1158
1159 if (chan->mode != L2CAP_MODE_ERTM)
1160 return;
1161
1162 __clear_retrans_timer(chan);
1163 __clear_monitor_timer(chan);
1164 __clear_ack_timer(chan);
1165
1166 chan->retry_count = 0;
1167 skb_queue_walk(&chan->tx_q, skb) {
1168 if (bt_cb(skb)->control.retries)
1169 bt_cb(skb)->control.retries = 1;
1170 else
1171 break;
1172 }
1173
1174 chan->expected_tx_seq = chan->buffer_seq;
1175
1176 clear_bit(CONN_REJ_ACT, &chan->conn_state);
1177 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
1178 l2cap_seq_list_clear(&chan->retrans_list);
1179 l2cap_seq_list_clear(&chan->srej_list);
1180 skb_queue_purge(&chan->srej_q);
1181
1182 chan->tx_state = L2CAP_TX_STATE_XMIT;
1183 chan->rx_state = L2CAP_RX_STATE_MOVE;
1184
1185 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
1186}
1187
Mat Martineau5f3847a2012-10-23 15:24:12 -07001188static void l2cap_move_done(struct l2cap_chan *chan)
1189{
1190 u8 move_role = chan->move_role;
1191 BT_DBG("chan %p", chan);
1192
1193 chan->move_state = L2CAP_MOVE_STABLE;
1194 chan->move_role = L2CAP_MOVE_ROLE_NONE;
1195
1196 if (chan->mode != L2CAP_MODE_ERTM)
1197 return;
1198
1199 switch (move_role) {
1200 case L2CAP_MOVE_ROLE_INITIATOR:
1201 l2cap_tx(chan, NULL, NULL, L2CAP_EV_EXPLICIT_POLL);
1202 chan->rx_state = L2CAP_RX_STATE_WAIT_F;
1203 break;
1204 case L2CAP_MOVE_ROLE_RESPONDER:
1205 chan->rx_state = L2CAP_RX_STATE_WAIT_P;
1206 break;
1207 }
1208}
1209
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001210static void l2cap_chan_ready(struct l2cap_chan *chan)
1211{
Mat Martineau28270112012-05-17 21:14:09 -07001212 /* This clears all conf flags, including CONF_NOT_COMPLETE */
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001213 chan->conf_state = 0;
1214 __clear_chan_timer(chan);
1215
Johan Hedberg0ce43ce2013-12-05 14:55:33 +02001216 if (chan->mode == L2CAP_MODE_LE_FLOWCTL && !chan->tx_credits)
1217 chan->ops->suspend(chan);
Johan Hedberg177f8f22013-05-31 17:54:51 +03001218
Andrei Emeltchenko54a59aa2012-05-27 22:27:53 -03001219 chan->state = BT_CONNECTED;
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001220
Andrei Emeltchenkofd83e2c2012-05-30 09:55:32 +03001221 chan->ops->ready(chan);
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001222}
1223
Johan Hedbergf1496de2013-05-13 14:15:56 +03001224static void l2cap_le_connect(struct l2cap_chan *chan)
1225{
1226 struct l2cap_conn *conn = chan->conn;
1227 struct l2cap_le_conn_req req;
1228
Johan Hedberg595177f2013-12-02 22:12:22 +02001229 if (test_and_set_bit(FLAG_LE_CONN_REQ_SENT, &chan->flags))
1230 return;
1231
Johan Hedbergf1496de2013-05-13 14:15:56 +03001232 req.psm = chan->psm;
1233 req.scid = cpu_to_le16(chan->scid);
1234 req.mtu = cpu_to_le16(chan->imtu);
Johan Hedberg3916aed2013-10-07 15:35:26 +02001235 req.mps = cpu_to_le16(chan->mps);
Johan Hedberg0cd75f72013-05-17 13:09:05 +03001236 req.credits = cpu_to_le16(chan->rx_credits);
Johan Hedbergf1496de2013-05-13 14:15:56 +03001237
1238 chan->ident = l2cap_get_ident(conn);
1239
1240 l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CONN_REQ,
1241 sizeof(req), &req);
1242}
1243
1244static void l2cap_le_start(struct l2cap_chan *chan)
1245{
1246 struct l2cap_conn *conn = chan->conn;
1247
1248 if (!smp_conn_security(conn->hcon, chan->sec_level))
1249 return;
1250
1251 if (!chan->psm) {
1252 l2cap_chan_ready(chan);
1253 return;
1254 }
1255
1256 if (chan->state == BT_CONNECT)
1257 l2cap_le_connect(chan);
1258}
1259
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001260static void l2cap_start_connection(struct l2cap_chan *chan)
1261{
1262 if (__amp_capable(chan)) {
1263 BT_DBG("chan %p AMP capable: discover AMPs", chan);
1264 a2mp_discover_amp(chan);
Johan Hedbergf1496de2013-05-13 14:15:56 +03001265 } else if (chan->conn->hcon->type == LE_LINK) {
1266 l2cap_le_start(chan);
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001267 } else {
1268 l2cap_send_conn_req(chan);
1269 }
1270}
1271
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001272static void l2cap_do_start(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001273{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001274 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001275
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001276 if (conn->hcon->type == LE_LINK) {
Johan Hedberg96ac34f2013-05-13 11:15:07 +03001277 l2cap_le_start(chan);
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001278 return;
1279 }
1280
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001281 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01001282 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
1283 return;
1284
Johan Hedberge7cafc42014-07-17 15:35:38 +03001285 if (l2cap_chan_check_security(chan, true) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01001286 __l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001287 l2cap_start_connection(chan);
1288 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001289 } else {
1290 struct l2cap_info_req req;
Joe Perchesdcf4adb2014-03-12 10:52:35 -07001291 req.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001292
1293 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
1294 conn->info_ident = l2cap_get_ident(conn);
1295
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08001296 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001297
Gustavo Padovan2d792812012-10-06 10:07:01 +01001298 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
1299 sizeof(req), &req);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001300 }
1301}
1302
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001303static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
1304{
1305 u32 local_feat_mask = l2cap_feat_mask;
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03001306 if (!disable_ertm)
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001307 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
1308
1309 switch (mode) {
1310 case L2CAP_MODE_ERTM:
1311 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
1312 case L2CAP_MODE_STREAMING:
1313 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
1314 default:
1315 return 0x00;
1316 }
1317}
1318
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02001319static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err)
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001320{
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02001321 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001322 struct l2cap_disconn_req req;
1323
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001324 if (!conn)
1325 return;
1326
Andrei Emeltchenkoaad3d0e2012-09-06 15:05:42 +03001327 if (chan->mode == L2CAP_MODE_ERTM && chan->state == BT_CONNECTED) {
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03001328 __clear_retrans_timer(chan);
1329 __clear_monitor_timer(chan);
1330 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001331 }
1332
Johan Hedberg2338a7e2014-01-24 10:35:40 +02001333 if (chan->scid == L2CAP_CID_A2MP) {
Gustavo Padovand1177732012-10-06 11:47:38 +01001334 l2cap_state_change(chan, BT_DISCONN);
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001335 return;
1336 }
1337
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001338 req.dcid = cpu_to_le16(chan->dcid);
1339 req.scid = cpu_to_le16(chan->scid);
Gustavo Padovan2d792812012-10-06 10:07:01 +01001340 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_DISCONN_REQ,
1341 sizeof(req), &req);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001342
Gustavo Padovanf8e73012013-10-15 19:24:46 -03001343 l2cap_state_change_and_error(chan, BT_DISCONN, err);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001344}
1345
Linus Torvalds1da177e2005-04-16 15:20:36 -07001346/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001347static void l2cap_conn_start(struct l2cap_conn *conn)
1348{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001349 struct l2cap_chan *chan, *tmp;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001350
1351 BT_DBG("conn %p", conn);
1352
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001353 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001354
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001355 list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001356 l2cap_chan_lock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001357
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001358 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001359 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001360 continue;
1361 }
1362
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001363 if (chan->state == BT_CONNECT) {
Johan Hedberge7cafc42014-07-17 15:35:38 +03001364 if (!l2cap_chan_check_security(chan, true) ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001365 !__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001366 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001367 continue;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02001368 }
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001369
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001370 if (!l2cap_mode_supported(chan->mode, conn->feat_mask)
Gustavo Padovan2d792812012-10-06 10:07:01 +01001371 && test_bit(CONF_STATE2_DEVICE,
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001372 &chan->conf_state)) {
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001373 l2cap_chan_close(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001374 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001375 continue;
1376 }
1377
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001378 l2cap_start_connection(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001379
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001380 } else if (chan->state == BT_CONNECT2) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001381 struct l2cap_conn_rsp rsp;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001382 char buf[128];
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001383 rsp.scid = cpu_to_le16(chan->dcid);
1384 rsp.dcid = cpu_to_le16(chan->scid);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001385
Johan Hedberge7cafc42014-07-17 15:35:38 +03001386 if (l2cap_chan_check_security(chan, false)) {
Marcel Holtmannbdc25782013-10-14 02:45:34 -07001387 if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
Joe Perchesdcf4adb2014-03-12 10:52:35 -07001388 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
1389 rsp.status = cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08001390 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001391
1392 } else {
Gustavo Padovanacdcabf2013-10-21 14:21:39 -02001393 l2cap_state_change(chan, BT_CONFIG);
Joe Perchesdcf4adb2014-03-12 10:52:35 -07001394 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
1395 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001396 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001397 } else {
Joe Perchesdcf4adb2014-03-12 10:52:35 -07001398 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
1399 rsp.status = cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001400 }
1401
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001402 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001403 sizeof(rsp), &rsp);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001404
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001405 if (test_bit(CONF_REQ_SENT, &chan->conf_state) ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001406 rsp.result != L2CAP_CR_SUCCESS) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001407 l2cap_chan_unlock(chan);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001408 continue;
1409 }
1410
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001411 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001412 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001413 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03001414 chan->num_conf_req++;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001415 }
1416
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001417 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001418 }
1419
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001420 mutex_unlock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001421}
1422
Ido Yarivc2287682012-04-20 15:46:07 -03001423/* Find socket with cid and source/destination bdaddr.
Ville Tervob62f3282011-02-10 22:38:50 -03001424 * Returns closest match, locked.
1425 */
Andrei Emeltchenkod9b88702012-03-12 12:13:08 +02001426static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid,
Ido Yarivc2287682012-04-20 15:46:07 -03001427 bdaddr_t *src,
1428 bdaddr_t *dst)
Ville Tervob62f3282011-02-10 22:38:50 -03001429{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001430 struct l2cap_chan *c, *c1 = NULL;
Ville Tervob62f3282011-02-10 22:38:50 -03001431
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001432 read_lock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001433
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001434 list_for_each_entry(c, &chan_list, global_l) {
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001435 if (state && c->state != state)
Ville Tervob62f3282011-02-10 22:38:50 -03001436 continue;
1437
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001438 if (c->scid == cid) {
Ido Yarivc2287682012-04-20 15:46:07 -03001439 int src_match, dst_match;
1440 int src_any, dst_any;
1441
Ville Tervob62f3282011-02-10 22:38:50 -03001442 /* Exact match. */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001443 src_match = !bacmp(&c->src, src);
1444 dst_match = !bacmp(&c->dst, dst);
Ido Yarivc2287682012-04-20 15:46:07 -03001445 if (src_match && dst_match) {
Johan Hedberga24cce12014-08-07 22:56:42 +03001446 l2cap_chan_hold(c);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001447 read_unlock(&chan_list_lock);
1448 return c;
1449 }
Ville Tervob62f3282011-02-10 22:38:50 -03001450
1451 /* Closest match */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001452 src_any = !bacmp(&c->src, BDADDR_ANY);
1453 dst_any = !bacmp(&c->dst, BDADDR_ANY);
Ido Yarivc2287682012-04-20 15:46:07 -03001454 if ((src_match && dst_any) || (src_any && dst_match) ||
1455 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001456 c1 = c;
Ville Tervob62f3282011-02-10 22:38:50 -03001457 }
1458 }
Gustavo F. Padovan280f2942011-04-13 19:01:22 -03001459
Johan Hedberga24cce12014-08-07 22:56:42 +03001460 if (c1)
1461 l2cap_chan_hold(c1);
1462
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001463 read_unlock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001464
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001465 return c1;
Ville Tervob62f3282011-02-10 22:38:50 -03001466}
1467
1468static void l2cap_le_conn_ready(struct l2cap_conn *conn)
1469{
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001470 struct hci_conn *hcon = conn->hcon;
Johan Hedbergdcc36c12014-07-09 12:59:13 +03001471 struct hci_dev *hdev = hcon->hdev;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001472 struct l2cap_chan *chan, *pchan;
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001473 u8 dst_type;
Ville Tervob62f3282011-02-10 22:38:50 -03001474
1475 BT_DBG("");
1476
1477 /* Check if we have socket listening on cid */
Johan Hedberg073d1cf2013-04-29 19:35:35 +03001478 pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_ATT,
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001479 &hcon->src, &hcon->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001480 if (!pchan)
Ville Tervob62f3282011-02-10 22:38:50 -03001481 return;
1482
Johan Hedberg44f3b0f2013-04-29 19:35:45 +03001483 /* Client ATT sockets should override the server one */
1484 if (__l2cap_get_chan_by_dcid(conn, L2CAP_CID_ATT))
Johan Hedberga24cce12014-08-07 22:56:42 +03001485 goto put;
Johan Hedberg44f3b0f2013-04-29 19:35:45 +03001486
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001487 dst_type = bdaddr_type(hcon, hcon->dst_type);
1488
1489 /* If device is blocked, do not create a channel for it */
Johan Hedbergdcc36c12014-07-09 12:59:13 +03001490 if (hci_bdaddr_list_lookup(&hdev->blacklist, &hcon->dst, dst_type))
Johan Hedberga24cce12014-08-07 22:56:42 +03001491 goto put;
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001492
Marcel Holtmann80afeb62014-06-23 12:18:51 +02001493 /* For LE slave connections, make sure the connection interval
1494 * is in the range of the minium and maximum interval that has
1495 * been configured for this connection. If not, then trigger
1496 * the connection update procedure.
1497 */
Johan Hedberg40bef302014-07-16 11:42:27 +03001498 if (hcon->role == HCI_ROLE_SLAVE &&
Marcel Holtmann80afeb62014-06-23 12:18:51 +02001499 (hcon->le_conn_interval < hcon->le_conn_min_interval ||
1500 hcon->le_conn_interval > hcon->le_conn_max_interval)) {
1501 struct l2cap_conn_param_update_req req;
1502
1503 req.min = cpu_to_le16(hcon->le_conn_min_interval);
1504 req.max = cpu_to_le16(hcon->le_conn_max_interval);
1505 req.latency = cpu_to_le16(hcon->le_conn_latency);
1506 req.to_multiplier = cpu_to_le16(hcon->le_supv_timeout);
1507
1508 l2cap_send_cmd(conn, l2cap_get_ident(conn),
1509 L2CAP_CONN_PARAM_UPDATE_REQ, sizeof(req), &req);
1510 }
1511
Gustavo Padovan8ffb9292013-10-21 14:21:41 -02001512 l2cap_chan_lock(pchan);
Gustavo F. Padovan62f3a2c2011-04-14 18:34:34 -03001513
Gustavo Padovan80b98022012-05-27 22:27:51 -03001514 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001515 if (!chan)
Ville Tervob62f3282011-02-10 22:38:50 -03001516 goto clean;
1517
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001518 bacpy(&chan->src, &hcon->src);
1519 bacpy(&chan->dst, &hcon->dst);
1520 chan->src_type = bdaddr_type(hcon, hcon->src_type);
1521 chan->dst_type = dst_type;
Ville Tervob62f3282011-02-10 22:38:50 -03001522
Johan Hedberg44f3b0f2013-04-29 19:35:45 +03001523 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001524
Ville Tervob62f3282011-02-10 22:38:50 -03001525clean:
Gustavo Padovan8ffb9292013-10-21 14:21:41 -02001526 l2cap_chan_unlock(pchan);
Johan Hedberga24cce12014-08-07 22:56:42 +03001527put:
1528 l2cap_chan_put(pchan);
Ville Tervob62f3282011-02-10 22:38:50 -03001529}
1530
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001531static void l2cap_conn_ready(struct l2cap_conn *conn)
1532{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001533 struct l2cap_chan *chan;
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001534 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001535
1536 BT_DBG("conn %p", conn);
1537
Johan Hedbergd8729922013-04-29 19:35:39 +03001538 /* For outgoing pairing which doesn't necessarily have an
1539 * associated socket (e.g. mgmt_pair_device).
1540 */
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001541 if (hcon->out && hcon->type == LE_LINK)
1542 smp_conn_security(hcon, hcon->pending_sec_level);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03001543
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001544 mutex_lock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001545
Johan Hedberg44f3b0f2013-04-29 19:35:45 +03001546 if (hcon->type == LE_LINK)
1547 l2cap_le_conn_ready(conn);
1548
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001549 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001550
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001551 l2cap_chan_lock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001552
Johan Hedberg2338a7e2014-01-24 10:35:40 +02001553 if (chan->scid == L2CAP_CID_A2MP) {
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001554 l2cap_chan_unlock(chan);
1555 continue;
1556 }
1557
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001558 if (hcon->type == LE_LINK) {
Johan Hedbergf1496de2013-05-13 14:15:56 +03001559 l2cap_le_start(chan);
Vinicius Costa Gomes63128452011-06-17 22:46:26 -03001560 } else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Gustavo Padovan74e75742013-10-15 19:24:51 -03001561 l2cap_chan_ready(chan);
Anderson Brigliab501d6a2011-06-07 18:46:31 -03001562
Gustavo Padovan1c244f72012-12-07 03:29:10 -02001563 } else if (chan->state == BT_CONNECT) {
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001564 l2cap_do_start(chan);
Gustavo Padovan1c244f72012-12-07 03:29:10 -02001565 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001566
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001567 l2cap_chan_unlock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001568 }
1569
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001570 mutex_unlock(&conn->chan_lock);
Johan Hedberg61a939c2014-01-17 20:45:11 +02001571
1572 queue_work(hcon->hdev->workqueue, &conn->pending_rx_work);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001573}
1574
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001575/* Notify sockets that we cannot guaranty reliability anymore */
1576static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
1577{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001578 struct l2cap_chan *chan;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001579
1580 BT_DBG("conn %p", conn);
1581
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001582 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001583
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001584 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenkoecf61bd2011-10-11 14:04:32 +03001585 if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags))
Gustavo Padovan1d8b1fd2012-10-06 11:34:52 +01001586 l2cap_chan_set_err(chan, err);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001587 }
1588
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001589 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001590}
1591
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001592static void l2cap_info_timeout(struct work_struct *work)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001593{
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001594 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001595 info_timer.work);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001596
Marcel Holtmann984947d2009-02-06 23:35:19 +01001597 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01001598 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01001599
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001600 l2cap_conn_start(conn);
1601}
1602
David Herrmann2c8e1412013-04-06 20:28:45 +02001603/*
1604 * l2cap_user
1605 * External modules can register l2cap_user objects on l2cap_conn. The ->probe
1606 * callback is called during registration. The ->remove callback is called
1607 * during unregistration.
1608 * An l2cap_user object can either be explicitly unregistered or when the
1609 * underlying l2cap_conn object is deleted. This guarantees that l2cap->hcon,
1610 * l2cap->hchan, .. are valid as long as the remove callback hasn't been called.
1611 * External modules must own a reference to the l2cap_conn object if they intend
1612 * to call l2cap_unregister_user(). The l2cap_conn object might get destroyed at
1613 * any time if they don't.
1614 */
1615
1616int l2cap_register_user(struct l2cap_conn *conn, struct l2cap_user *user)
1617{
1618 struct hci_dev *hdev = conn->hcon->hdev;
1619 int ret;
1620
1621 /* We need to check whether l2cap_conn is registered. If it is not, we
1622 * must not register the l2cap_user. l2cap_conn_del() is unregisters
1623 * l2cap_conn objects, but doesn't provide its own locking. Instead, it
1624 * relies on the parent hci_conn object to be locked. This itself relies
1625 * on the hci_dev object to be locked. So we must lock the hci device
1626 * here, too. */
1627
1628 hci_dev_lock(hdev);
1629
1630 if (user->list.next || user->list.prev) {
1631 ret = -EINVAL;
1632 goto out_unlock;
1633 }
1634
1635 /* conn->hchan is NULL after l2cap_conn_del() was called */
1636 if (!conn->hchan) {
1637 ret = -ENODEV;
1638 goto out_unlock;
1639 }
1640
1641 ret = user->probe(conn, user);
1642 if (ret)
1643 goto out_unlock;
1644
1645 list_add(&user->list, &conn->users);
1646 ret = 0;
1647
1648out_unlock:
1649 hci_dev_unlock(hdev);
1650 return ret;
1651}
1652EXPORT_SYMBOL(l2cap_register_user);
1653
1654void l2cap_unregister_user(struct l2cap_conn *conn, struct l2cap_user *user)
1655{
1656 struct hci_dev *hdev = conn->hcon->hdev;
1657
1658 hci_dev_lock(hdev);
1659
1660 if (!user->list.next || !user->list.prev)
1661 goto out_unlock;
1662
1663 list_del(&user->list);
1664 user->list.next = NULL;
1665 user->list.prev = NULL;
1666 user->remove(conn, user);
1667
1668out_unlock:
1669 hci_dev_unlock(hdev);
1670}
1671EXPORT_SYMBOL(l2cap_unregister_user);
1672
1673static void l2cap_unregister_all_users(struct l2cap_conn *conn)
1674{
1675 struct l2cap_user *user;
1676
1677 while (!list_empty(&conn->users)) {
1678 user = list_first_entry(&conn->users, struct l2cap_user, list);
1679 list_del(&user->list);
1680 user->list.next = NULL;
1681 user->list.prev = NULL;
1682 user->remove(conn, user);
1683 }
1684}
1685
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001686static void l2cap_conn_del(struct hci_conn *hcon, int err)
1687{
1688 struct l2cap_conn *conn = hcon->l2cap_data;
1689 struct l2cap_chan *chan, *l;
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001690
1691 if (!conn)
1692 return;
1693
1694 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
1695
1696 kfree_skb(conn->rx_skb);
1697
Johan Hedberg61a939c2014-01-17 20:45:11 +02001698 skb_queue_purge(&conn->pending_rx);
Jukka Taimisto7ab56c32014-06-12 10:15:13 +00001699
1700 /* We can not call flush_work(&conn->pending_rx_work) here since we
1701 * might block if we are running on a worker from the same workqueue
1702 * pending_rx_work is waiting on.
1703 */
1704 if (work_pending(&conn->pending_rx_work))
1705 cancel_work_sync(&conn->pending_rx_work);
Johan Hedberg61a939c2014-01-17 20:45:11 +02001706
David Herrmann2c8e1412013-04-06 20:28:45 +02001707 l2cap_unregister_all_users(conn);
1708
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001709 mutex_lock(&conn->chan_lock);
1710
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001711 /* Kill channels */
1712 list_for_each_entry_safe(chan, l, &conn->chan_l, list) {
Mat Martineau61d6ef32012-04-27 16:50:50 -07001713 l2cap_chan_hold(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001714 l2cap_chan_lock(chan);
1715
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001716 l2cap_chan_del(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001717
1718 l2cap_chan_unlock(chan);
1719
Gustavo Padovan80b98022012-05-27 22:27:51 -03001720 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07001721 l2cap_chan_put(chan);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001722 }
1723
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001724 mutex_unlock(&conn->chan_lock);
1725
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001726 hci_chan_del(conn->hchan);
1727
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001728 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
Ulisses Furquim127074b2012-01-30 18:26:29 -02001729 cancel_delayed_work_sync(&conn->info_timer);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001730
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001731 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) {
Ulisses Furquim127074b2012-01-30 18:26:29 -02001732 cancel_delayed_work_sync(&conn->security_timer);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -03001733 smp_chan_destroy(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001734 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001735
1736 hcon->l2cap_data = NULL;
David Herrmann9c903e32013-04-06 20:28:44 +02001737 conn->hchan = NULL;
1738 l2cap_conn_put(conn);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001739}
1740
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001741static void security_timeout(struct work_struct *work)
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001742{
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001743 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001744 security_timer.work);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001745
Johan Hedbergd06cc412012-06-06 18:44:11 +08001746 BT_DBG("conn %p", conn);
1747
1748 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) {
1749 smp_chan_destroy(conn);
1750 l2cap_conn_del(conn->hcon, ETIMEDOUT);
1751 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001752}
1753
David Herrmann9c903e32013-04-06 20:28:44 +02001754static void l2cap_conn_free(struct kref *ref)
1755{
1756 struct l2cap_conn *conn = container_of(ref, struct l2cap_conn, ref);
1757
1758 hci_conn_put(conn->hcon);
1759 kfree(conn);
1760}
1761
1762void l2cap_conn_get(struct l2cap_conn *conn)
1763{
1764 kref_get(&conn->ref);
1765}
1766EXPORT_SYMBOL(l2cap_conn_get);
1767
1768void l2cap_conn_put(struct l2cap_conn *conn)
1769{
1770 kref_put(&conn->ref, l2cap_conn_free);
1771}
1772EXPORT_SYMBOL(l2cap_conn_put);
1773
Linus Torvalds1da177e2005-04-16 15:20:36 -07001774/* ---- Socket interface ---- */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001775
Ido Yarivc2287682012-04-20 15:46:07 -03001776/* Find socket with psm and source / destination bdaddr.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001777 * Returns closest match.
1778 */
Ido Yarivc2287682012-04-20 15:46:07 -03001779static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
1780 bdaddr_t *src,
Johan Hedbergbf20fd42013-05-14 13:23:13 +03001781 bdaddr_t *dst,
1782 u8 link_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001783{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001784 struct l2cap_chan *c, *c1 = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001785
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001786 read_lock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001787
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001788 list_for_each_entry(c, &chan_list, global_l) {
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001789 if (state && c->state != state)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001790 continue;
1791
Johan Hedbergbf20fd42013-05-14 13:23:13 +03001792 if (link_type == ACL_LINK && c->src_type != BDADDR_BREDR)
1793 continue;
1794
1795 if (link_type == LE_LINK && c->src_type == BDADDR_BREDR)
1796 continue;
1797
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001798 if (c->psm == psm) {
Ido Yarivc2287682012-04-20 15:46:07 -03001799 int src_match, dst_match;
1800 int src_any, dst_any;
1801
Linus Torvalds1da177e2005-04-16 15:20:36 -07001802 /* Exact match. */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001803 src_match = !bacmp(&c->src, src);
1804 dst_match = !bacmp(&c->dst, dst);
Ido Yarivc2287682012-04-20 15:46:07 -03001805 if (src_match && dst_match) {
Johan Hedberga24cce12014-08-07 22:56:42 +03001806 l2cap_chan_hold(c);
Johannes Berga7567b22011-06-01 08:29:54 +02001807 read_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001808 return c;
1809 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001810
1811 /* Closest match */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001812 src_any = !bacmp(&c->src, BDADDR_ANY);
1813 dst_any = !bacmp(&c->dst, BDADDR_ANY);
Ido Yarivc2287682012-04-20 15:46:07 -03001814 if ((src_match && dst_any) || (src_any && dst_match) ||
1815 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001816 c1 = c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001817 }
1818 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001819
Johan Hedberga24cce12014-08-07 22:56:42 +03001820 if (c1)
1821 l2cap_chan_hold(c1);
1822
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001823 read_unlock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001824
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001825 return c1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001826}
1827
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001828static void l2cap_monitor_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001829{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001830 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001831 monitor_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001832
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03001833 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001834
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001835 l2cap_chan_lock(chan);
1836
Mat Martineau80909e02012-05-17 20:53:50 -07001837 if (!chan->conn) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001838 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001839 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001840 return;
1841 }
1842
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001843 l2cap_tx(chan, NULL, NULL, L2CAP_EV_MONITOR_TO);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001844
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001845 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001846 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001847}
1848
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001849static void l2cap_retrans_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001850{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001851 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001852 retrans_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001853
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03001854 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001855
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001856 l2cap_chan_lock(chan);
1857
Mat Martineau80909e02012-05-17 20:53:50 -07001858 if (!chan->conn) {
1859 l2cap_chan_unlock(chan);
1860 l2cap_chan_put(chan);
1861 return;
1862 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001863
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001864 l2cap_tx(chan, NULL, NULL, L2CAP_EV_RETRANS_TO);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001865 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001866 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001867}
1868
Gustavo Padovand6603662012-05-21 13:58:22 -03001869static void l2cap_streaming_send(struct l2cap_chan *chan,
1870 struct sk_buff_head *skbs)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001871{
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001872 struct sk_buff *skb;
Mat Martineau37339372012-05-17 20:53:33 -07001873 struct l2cap_ctrl *control;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001874
Mat Martineau37339372012-05-17 20:53:33 -07001875 BT_DBG("chan %p, skbs %p", chan, skbs);
1876
Mat Martineaub99e13a2012-10-23 15:24:19 -07001877 if (__chan_is_moving(chan))
1878 return;
1879
Mat Martineau37339372012-05-17 20:53:33 -07001880 skb_queue_splice_tail_init(skbs, &chan->tx_q);
1881
1882 while (!skb_queue_empty(&chan->tx_q)) {
1883
1884 skb = skb_dequeue(&chan->tx_q);
1885
1886 bt_cb(skb)->control.retries = 1;
1887 control = &bt_cb(skb)->control;
1888
1889 control->reqseq = 0;
1890 control->txseq = chan->next_tx_seq;
1891
1892 __pack_control(chan, control, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001893
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001894 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau37339372012-05-17 20:53:33 -07001895 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
1896 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001897 }
1898
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001899 l2cap_do_send(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001900
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001901 BT_DBG("Sent txseq %u", control->txseq);
Mat Martineau37339372012-05-17 20:53:33 -07001902
Andrei Emeltchenko836be932011-10-17 12:19:57 +03001903 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau37339372012-05-17 20:53:33 -07001904 chan->frames_sent++;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001905 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001906}
1907
Szymon Janc67c9e842011-07-28 16:24:33 +02001908static int l2cap_ertm_send(struct l2cap_chan *chan)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001909{
1910 struct sk_buff *skb, *tx_skb;
Mat Martineau18a48e72012-05-17 20:53:34 -07001911 struct l2cap_ctrl *control;
1912 int sent = 0;
1913
1914 BT_DBG("chan %p", chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001915
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001916 if (chan->state != BT_CONNECTED)
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001917 return -ENOTCONN;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001918
Mat Martineau94122bb2012-05-02 09:42:02 -07001919 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1920 return 0;
1921
Mat Martineaub99e13a2012-10-23 15:24:19 -07001922 if (__chan_is_moving(chan))
1923 return 0;
1924
Mat Martineau18a48e72012-05-17 20:53:34 -07001925 while (chan->tx_send_head &&
1926 chan->unacked_frames < chan->remote_tx_win &&
1927 chan->tx_state == L2CAP_TX_STATE_XMIT) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001928
Mat Martineau18a48e72012-05-17 20:53:34 -07001929 skb = chan->tx_send_head;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001930
Mat Martineau18a48e72012-05-17 20:53:34 -07001931 bt_cb(skb)->control.retries = 1;
1932 control = &bt_cb(skb)->control;
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03001933
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03001934 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
Mat Martineau18a48e72012-05-17 20:53:34 -07001935 control->final = 1;
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03001936
Mat Martineau18a48e72012-05-17 20:53:34 -07001937 control->reqseq = chan->buffer_seq;
1938 chan->last_acked_seq = chan->buffer_seq;
1939 control->txseq = chan->next_tx_seq;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001940
Mat Martineau18a48e72012-05-17 20:53:34 -07001941 __pack_control(chan, control, skb);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001942
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001943 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau18a48e72012-05-17 20:53:34 -07001944 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
1945 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001946 }
1947
Mat Martineau18a48e72012-05-17 20:53:34 -07001948 /* Clone after data has been modified. Data is assumed to be
1949 read-only (for locking purposes) on cloned sk_buffs.
1950 */
1951 tx_skb = skb_clone(skb, GFP_KERNEL);
1952
1953 if (!tx_skb)
1954 break;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001955
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03001956 __set_retrans_timer(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001957
Andrei Emeltchenko836be932011-10-17 12:19:57 +03001958 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau18a48e72012-05-17 20:53:34 -07001959 chan->unacked_frames++;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03001960 chan->frames_sent++;
Mat Martineau18a48e72012-05-17 20:53:34 -07001961 sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001962
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03001963 if (skb_queue_is_last(&chan->tx_q, skb))
1964 chan->tx_send_head = NULL;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001965 else
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03001966 chan->tx_send_head = skb_queue_next(&chan->tx_q, skb);
Mat Martineau18a48e72012-05-17 20:53:34 -07001967
1968 l2cap_do_send(chan, tx_skb);
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001969 BT_DBG("Sent txseq %u", control->txseq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001970 }
1971
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001972 BT_DBG("Sent %d, %u unacked, %u in ERTM queue", sent,
1973 chan->unacked_frames, skb_queue_len(&chan->tx_q));
Mat Martineau18a48e72012-05-17 20:53:34 -07001974
1975 return sent;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001976}
1977
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001978static void l2cap_ertm_resend(struct l2cap_chan *chan)
1979{
1980 struct l2cap_ctrl control;
1981 struct sk_buff *skb;
1982 struct sk_buff *tx_skb;
1983 u16 seq;
1984
1985 BT_DBG("chan %p", chan);
1986
1987 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1988 return;
1989
Mat Martineaub99e13a2012-10-23 15:24:19 -07001990 if (__chan_is_moving(chan))
1991 return;
1992
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001993 while (chan->retrans_list.head != L2CAP_SEQ_LIST_CLEAR) {
1994 seq = l2cap_seq_list_pop(&chan->retrans_list);
1995
1996 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, seq);
1997 if (!skb) {
1998 BT_DBG("Error: Can't retransmit seq %d, frame missing",
Gustavo Padovan2d792812012-10-06 10:07:01 +01001999 seq);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002000 continue;
2001 }
2002
2003 bt_cb(skb)->control.retries++;
2004 control = bt_cb(skb)->control;
2005
2006 if (chan->max_tx != 0 &&
2007 bt_cb(skb)->control.retries > chan->max_tx) {
2008 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02002009 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002010 l2cap_seq_list_clear(&chan->retrans_list);
2011 break;
2012 }
2013
2014 control.reqseq = chan->buffer_seq;
2015 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
2016 control.final = 1;
2017 else
2018 control.final = 0;
2019
2020 if (skb_cloned(skb)) {
2021 /* Cloned sk_buffs are read-only, so we need a
2022 * writeable copy
2023 */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002024 tx_skb = skb_copy(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002025 } else {
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002026 tx_skb = skb_clone(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002027 }
2028
2029 if (!tx_skb) {
2030 l2cap_seq_list_clear(&chan->retrans_list);
2031 break;
2032 }
2033
2034 /* Update skb contents */
2035 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
2036 put_unaligned_le32(__pack_extended_control(&control),
2037 tx_skb->data + L2CAP_HDR_SIZE);
2038 } else {
2039 put_unaligned_le16(__pack_enhanced_control(&control),
2040 tx_skb->data + L2CAP_HDR_SIZE);
2041 }
2042
2043 if (chan->fcs == L2CAP_FCS_CRC16) {
2044 u16 fcs = crc16(0, (u8 *) tx_skb->data, tx_skb->len);
2045 put_unaligned_le16(fcs, skb_put(tx_skb,
2046 L2CAP_FCS_SIZE));
2047 }
2048
2049 l2cap_do_send(chan, tx_skb);
2050
2051 BT_DBG("Resent txseq %d", control.txseq);
2052
2053 chan->last_acked_seq = chan->buffer_seq;
2054 }
2055}
2056
Mat Martineauf80842a2012-05-17 20:53:46 -07002057static void l2cap_retransmit(struct l2cap_chan *chan,
2058 struct l2cap_ctrl *control)
2059{
2060 BT_DBG("chan %p, control %p", chan, control);
2061
2062 l2cap_seq_list_append(&chan->retrans_list, control->reqseq);
2063 l2cap_ertm_resend(chan);
2064}
2065
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002066static void l2cap_retransmit_all(struct l2cap_chan *chan,
2067 struct l2cap_ctrl *control)
2068{
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002069 struct sk_buff *skb;
2070
2071 BT_DBG("chan %p, control %p", chan, control);
2072
2073 if (control->poll)
2074 set_bit(CONN_SEND_FBIT, &chan->conn_state);
2075
2076 l2cap_seq_list_clear(&chan->retrans_list);
2077
2078 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2079 return;
2080
2081 if (chan->unacked_frames) {
2082 skb_queue_walk(&chan->tx_q, skb) {
2083 if (bt_cb(skb)->control.txseq == control->reqseq ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01002084 skb == chan->tx_send_head)
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002085 break;
2086 }
2087
2088 skb_queue_walk_from(&chan->tx_q, skb) {
2089 if (skb == chan->tx_send_head)
2090 break;
2091
2092 l2cap_seq_list_append(&chan->retrans_list,
2093 bt_cb(skb)->control.txseq);
2094 }
2095
2096 l2cap_ertm_resend(chan);
2097 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002098}
2099
Szymon Jancb17e73b2012-01-11 10:59:47 +01002100static void l2cap_send_ack(struct l2cap_chan *chan)
2101{
Mat Martineau0a0aba42012-05-17 20:53:39 -07002102 struct l2cap_ctrl control;
2103 u16 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
2104 chan->last_acked_seq);
2105 int threshold;
2106
2107 BT_DBG("chan %p last_acked_seq %d buffer_seq %d",
2108 chan, chan->last_acked_seq, chan->buffer_seq);
2109
2110 memset(&control, 0, sizeof(control));
2111 control.sframe = 1;
2112
2113 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
2114 chan->rx_state == L2CAP_RX_STATE_RECV) {
2115 __clear_ack_timer(chan);
2116 control.super = L2CAP_SUPER_RNR;
2117 control.reqseq = chan->buffer_seq;
2118 l2cap_send_sframe(chan, &control);
2119 } else {
2120 if (!test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) {
2121 l2cap_ertm_send(chan);
2122 /* If any i-frames were sent, they included an ack */
2123 if (chan->buffer_seq == chan->last_acked_seq)
2124 frames_to_ack = 0;
2125 }
2126
Mat Martineauc20f8e32012-07-10 05:47:07 -07002127 /* Ack now if the window is 3/4ths full.
Mat Martineau0a0aba42012-05-17 20:53:39 -07002128 * Calculate without mul or div
2129 */
Mat Martineauc20f8e32012-07-10 05:47:07 -07002130 threshold = chan->ack_win;
Mat Martineau0a0aba42012-05-17 20:53:39 -07002131 threshold += threshold << 1;
2132 threshold >>= 2;
2133
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002134 BT_DBG("frames_to_ack %u, threshold %d", frames_to_ack,
Mat Martineau0a0aba42012-05-17 20:53:39 -07002135 threshold);
2136
2137 if (frames_to_ack >= threshold) {
2138 __clear_ack_timer(chan);
2139 control.super = L2CAP_SUPER_RR;
2140 control.reqseq = chan->buffer_seq;
2141 l2cap_send_sframe(chan, &control);
2142 frames_to_ack = 0;
2143 }
2144
2145 if (frames_to_ack)
2146 __set_ack_timer(chan);
2147 }
Szymon Jancb17e73b2012-01-11 10:59:47 +01002148}
2149
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002150static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
2151 struct msghdr *msg, int len,
2152 int count, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002153{
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002154 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002155 struct sk_buff **frag;
Gustavo Padovan90338942012-04-06 20:15:47 -03002156 int sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002157
Jukka Rissanen04988782014-06-18 16:37:07 +03002158 if (chan->ops->memcpy_fromiovec(chan, skb_put(skb, count),
2159 msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002160 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002161
2162 sent += count;
2163 len -= count;
2164
2165 /* Continuation fragments (no L2CAP header) */
2166 frag = &skb_shinfo(skb)->frag_list;
2167 while (len) {
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002168 struct sk_buff *tmp;
2169
Linus Torvalds1da177e2005-04-16 15:20:36 -07002170 count = min_t(unsigned int, conn->mtu, len);
2171
Marcel Holtmannd9fbd022014-06-08 11:22:28 +02002172 tmp = chan->ops->alloc_skb(chan, 0, count,
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002173 msg->msg_flags & MSG_DONTWAIT);
2174 if (IS_ERR(tmp))
2175 return PTR_ERR(tmp);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002176
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002177 *frag = tmp;
2178
Jukka Rissanen04988782014-06-18 16:37:07 +03002179 if (chan->ops->memcpy_fromiovec(chan, skb_put(*frag, count),
2180 msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002181 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002182
2183 sent += count;
2184 len -= count;
2185
Gustavo Padovan2d0ed3d2012-05-11 13:16:12 -03002186 skb->len += (*frag)->len;
2187 skb->data_len += (*frag)->len;
2188
Linus Torvalds1da177e2005-04-16 15:20:36 -07002189 frag = &(*frag)->next;
2190 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002191
2192 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002193}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002194
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002195static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan,
Marcel Holtmann8d463212014-06-05 15:22:51 +02002196 struct msghdr *msg, size_t len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002197{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002198 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002199 struct sk_buff *skb;
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002200 int err, count, hlen = L2CAP_HDR_SIZE + L2CAP_PSMLEN_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002201 struct l2cap_hdr *lh;
2202
Marcel Holtmann8d463212014-06-05 15:22:51 +02002203 BT_DBG("chan %p psm 0x%2.2x len %zu", chan,
2204 __le16_to_cpu(chan->psm), len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002205
2206 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002207
Marcel Holtmannd9fbd022014-06-08 11:22:28 +02002208 skb = chan->ops->alloc_skb(chan, hlen, count,
Gustavo Padovan90338942012-04-06 20:15:47 -03002209 msg->msg_flags & MSG_DONTWAIT);
2210 if (IS_ERR(skb))
2211 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002212
2213 /* Create L2CAP header */
2214 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002215 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenkodaf6a78c2012-05-03 10:55:52 +03002216 lh->len = cpu_to_le16(len + L2CAP_PSMLEN_SIZE);
Marcel Holtmann43b1b8d2013-10-12 06:01:26 -07002217 put_unaligned(chan->psm, (__le16 *) skb_put(skb, L2CAP_PSMLEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002218
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002219 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002220 if (unlikely(err < 0)) {
2221 kfree_skb(skb);
2222 return ERR_PTR(err);
2223 }
2224 return skb;
2225}
2226
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002227static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan,
Marcel Holtmann8d463212014-06-05 15:22:51 +02002228 struct msghdr *msg, size_t len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002229{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002230 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002231 struct sk_buff *skb;
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002232 int err, count;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002233 struct l2cap_hdr *lh;
2234
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002235 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002236
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002237 count = min_t(unsigned int, (conn->mtu - L2CAP_HDR_SIZE), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002238
Marcel Holtmannd9fbd022014-06-08 11:22:28 +02002239 skb = chan->ops->alloc_skb(chan, L2CAP_HDR_SIZE, count,
Gustavo Padovan90338942012-04-06 20:15:47 -03002240 msg->msg_flags & MSG_DONTWAIT);
2241 if (IS_ERR(skb))
2242 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002243
2244 /* Create L2CAP header */
2245 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002246 lh->cid = cpu_to_le16(chan->dcid);
Gustavo Padovan6ff9b5e2012-05-02 11:56:17 -03002247 lh->len = cpu_to_le16(len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002248
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002249 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002250 if (unlikely(err < 0)) {
2251 kfree_skb(skb);
2252 return ERR_PTR(err);
2253 }
2254 return skb;
2255}
2256
Luiz Augusto von Dentzab0ff762011-09-12 20:00:50 +03002257static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002258 struct msghdr *msg, size_t len,
2259 u16 sdulen)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002260{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002261 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002262 struct sk_buff *skb;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002263 int err, count, hlen;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002264 struct l2cap_hdr *lh;
2265
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002266 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002267
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03002268 if (!conn)
2269 return ERR_PTR(-ENOTCONN);
2270
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002271 hlen = __ertm_hdr_size(chan);
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002272
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002273 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002274 hlen += L2CAP_SDULEN_SIZE;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002275
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002276 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002277 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002278
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002279 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002280
Marcel Holtmannd9fbd022014-06-08 11:22:28 +02002281 skb = chan->ops->alloc_skb(chan, hlen, count,
Gustavo Padovan90338942012-04-06 20:15:47 -03002282 msg->msg_flags & MSG_DONTWAIT);
2283 if (IS_ERR(skb))
2284 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002285
2286 /* Create L2CAP header */
2287 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002288 lh->cid = cpu_to_le16(chan->dcid);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002289 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002290
Mat Martineau18a48e72012-05-17 20:53:34 -07002291 /* Control header is populated later */
2292 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
2293 put_unaligned_le32(0, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
2294 else
2295 put_unaligned_le16(0, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002296
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002297 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002298 put_unaligned_le16(sdulen, skb_put(skb, L2CAP_SDULEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002299
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002300 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002301 if (unlikely(err < 0)) {
2302 kfree_skb(skb);
2303 return ERR_PTR(err);
2304 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002305
Mat Martineau18a48e72012-05-17 20:53:34 -07002306 bt_cb(skb)->control.fcs = chan->fcs;
Mat Martineau3ce35142012-04-25 16:36:14 -07002307 bt_cb(skb)->control.retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002308 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002309}
2310
Mat Martineau94122bb2012-05-02 09:42:02 -07002311static int l2cap_segment_sdu(struct l2cap_chan *chan,
2312 struct sk_buff_head *seg_queue,
2313 struct msghdr *msg, size_t len)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002314{
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002315 struct sk_buff *skb;
Mat Martineau94122bb2012-05-02 09:42:02 -07002316 u16 sdu_len;
2317 size_t pdu_len;
Mat Martineau94122bb2012-05-02 09:42:02 -07002318 u8 sar;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002319
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002320 BT_DBG("chan %p, msg %p, len %zu", chan, msg, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002321
Mat Martineau94122bb2012-05-02 09:42:02 -07002322 /* It is critical that ERTM PDUs fit in a single HCI fragment,
2323 * so fragmented skbs are not used. The HCI layer's handling
2324 * of fragmented skbs is not compatible with ERTM's queueing.
2325 */
2326
2327 /* PDU size is derived from the HCI MTU */
2328 pdu_len = chan->conn->mtu;
2329
Mat Martineaua5495742012-10-23 15:24:21 -07002330 /* Constrain PDU size for BR/EDR connections */
2331 if (!chan->hs_hcon)
2332 pdu_len = min_t(size_t, pdu_len, L2CAP_BREDR_MAX_PAYLOAD);
Mat Martineau94122bb2012-05-02 09:42:02 -07002333
2334 /* Adjust for largest possible L2CAP overhead. */
Gustavo Padovan35d401d2012-05-25 18:57:05 -03002335 if (chan->fcs)
2336 pdu_len -= L2CAP_FCS_SIZE;
2337
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002338 pdu_len -= __ertm_hdr_size(chan);
Mat Martineau94122bb2012-05-02 09:42:02 -07002339
2340 /* Remote device may have requested smaller PDUs */
2341 pdu_len = min_t(size_t, pdu_len, chan->remote_mps);
2342
2343 if (len <= pdu_len) {
2344 sar = L2CAP_SAR_UNSEGMENTED;
2345 sdu_len = 0;
2346 pdu_len = len;
2347 } else {
2348 sar = L2CAP_SAR_START;
2349 sdu_len = len;
2350 pdu_len -= L2CAP_SDULEN_SIZE;
2351 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002352
2353 while (len > 0) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002354 skb = l2cap_create_iframe_pdu(chan, msg, pdu_len, sdu_len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002355
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002356 if (IS_ERR(skb)) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002357 __skb_queue_purge(seg_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002358 return PTR_ERR(skb);
2359 }
2360
Mat Martineau94122bb2012-05-02 09:42:02 -07002361 bt_cb(skb)->control.sar = sar;
2362 __skb_queue_tail(seg_queue, skb);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002363
Mat Martineau94122bb2012-05-02 09:42:02 -07002364 len -= pdu_len;
2365 if (sdu_len) {
2366 sdu_len = 0;
2367 pdu_len += L2CAP_SDULEN_SIZE;
2368 }
2369
2370 if (len <= pdu_len) {
2371 sar = L2CAP_SAR_END;
2372 pdu_len = len;
2373 } else {
2374 sar = L2CAP_SAR_CONTINUE;
2375 }
2376 }
2377
Gustavo Padovanf0f62792012-05-29 13:29:17 -03002378 return 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002379}
2380
Johan Hedberg177f8f22013-05-31 17:54:51 +03002381static struct sk_buff *l2cap_create_le_flowctl_pdu(struct l2cap_chan *chan,
2382 struct msghdr *msg,
2383 size_t len, u16 sdulen)
2384{
2385 struct l2cap_conn *conn = chan->conn;
2386 struct sk_buff *skb;
2387 int err, count, hlen;
2388 struct l2cap_hdr *lh;
2389
2390 BT_DBG("chan %p len %zu", chan, len);
2391
2392 if (!conn)
2393 return ERR_PTR(-ENOTCONN);
2394
2395 hlen = L2CAP_HDR_SIZE;
2396
2397 if (sdulen)
2398 hlen += L2CAP_SDULEN_SIZE;
2399
2400 count = min_t(unsigned int, (conn->mtu - hlen), len);
2401
Marcel Holtmannd9fbd022014-06-08 11:22:28 +02002402 skb = chan->ops->alloc_skb(chan, hlen, count,
Johan Hedberg177f8f22013-05-31 17:54:51 +03002403 msg->msg_flags & MSG_DONTWAIT);
2404 if (IS_ERR(skb))
2405 return skb;
2406
2407 /* Create L2CAP header */
2408 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
2409 lh->cid = cpu_to_le16(chan->dcid);
2410 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
2411
2412 if (sdulen)
2413 put_unaligned_le16(sdulen, skb_put(skb, L2CAP_SDULEN_SIZE));
2414
2415 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
2416 if (unlikely(err < 0)) {
2417 kfree_skb(skb);
2418 return ERR_PTR(err);
2419 }
2420
2421 return skb;
2422}
2423
2424static int l2cap_segment_le_sdu(struct l2cap_chan *chan,
2425 struct sk_buff_head *seg_queue,
2426 struct msghdr *msg, size_t len)
2427{
2428 struct sk_buff *skb;
2429 size_t pdu_len;
2430 u16 sdu_len;
2431
2432 BT_DBG("chan %p, msg %p, len %zu", chan, msg, len);
2433
2434 pdu_len = chan->conn->mtu - L2CAP_HDR_SIZE;
2435
2436 pdu_len = min_t(size_t, pdu_len, chan->remote_mps);
2437
2438 sdu_len = len;
2439 pdu_len -= L2CAP_SDULEN_SIZE;
2440
2441 while (len > 0) {
2442 if (len <= pdu_len)
2443 pdu_len = len;
2444
2445 skb = l2cap_create_le_flowctl_pdu(chan, msg, pdu_len, sdu_len);
2446 if (IS_ERR(skb)) {
2447 __skb_queue_purge(seg_queue);
2448 return PTR_ERR(skb);
2449 }
2450
2451 __skb_queue_tail(seg_queue, skb);
2452
2453 len -= pdu_len;
2454
2455 if (sdu_len) {
2456 sdu_len = 0;
2457 pdu_len += L2CAP_SDULEN_SIZE;
2458 }
2459 }
2460
2461 return 0;
2462}
2463
Marcel Holtmann8d463212014-06-05 15:22:51 +02002464int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len)
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002465{
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002466 struct sk_buff *skb;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002467 int err;
Mat Martineau94122bb2012-05-02 09:42:02 -07002468 struct sk_buff_head seg_queue;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002469
Seung-Woo Kim31e8ce82013-11-05 18:46:33 +09002470 if (!chan->conn)
2471 return -ENOTCONN;
2472
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002473 /* Connectionless channel */
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002474 if (chan->chan_type == L2CAP_CHAN_CONN_LESS) {
Marcel Holtmann8d463212014-06-05 15:22:51 +02002475 skb = l2cap_create_connless_pdu(chan, msg, len);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002476 if (IS_ERR(skb))
2477 return PTR_ERR(skb);
2478
Andrzej Kaczmarekede81a22014-02-25 17:16:22 +01002479 /* Channel lock is released before requesting new skb and then
2480 * reacquired thus we need to recheck channel state.
2481 */
2482 if (chan->state != BT_CONNECTED) {
2483 kfree_skb(skb);
2484 return -ENOTCONN;
2485 }
2486
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002487 l2cap_do_send(chan, skb);
2488 return len;
2489 }
2490
2491 switch (chan->mode) {
Johan Hedberg38319712013-05-17 12:49:23 +03002492 case L2CAP_MODE_LE_FLOWCTL:
Johan Hedberg177f8f22013-05-31 17:54:51 +03002493 /* Check outgoing MTU */
2494 if (len > chan->omtu)
2495 return -EMSGSIZE;
2496
Johan Hedbergfad5fc892013-12-05 09:45:01 +02002497 if (!chan->tx_credits)
2498 return -EAGAIN;
2499
Johan Hedberg177f8f22013-05-31 17:54:51 +03002500 __skb_queue_head_init(&seg_queue);
2501
2502 err = l2cap_segment_le_sdu(chan, &seg_queue, msg, len);
2503
2504 if (chan->state != BT_CONNECTED) {
2505 __skb_queue_purge(&seg_queue);
2506 err = -ENOTCONN;
2507 }
2508
2509 if (err)
2510 return err;
2511
2512 skb_queue_splice_tail_init(&seg_queue, &chan->tx_q);
2513
2514 while (chan->tx_credits && !skb_queue_empty(&chan->tx_q)) {
2515 l2cap_do_send(chan, skb_dequeue(&chan->tx_q));
2516 chan->tx_credits--;
2517 }
2518
2519 if (!chan->tx_credits)
2520 chan->ops->suspend(chan);
2521
2522 err = len;
2523
2524 break;
2525
Johan Hedbergfad5fc892013-12-05 09:45:01 +02002526 case L2CAP_MODE_BASIC:
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002527 /* Check outgoing MTU */
2528 if (len > chan->omtu)
2529 return -EMSGSIZE;
2530
2531 /* Create a basic PDU */
Marcel Holtmann8d463212014-06-05 15:22:51 +02002532 skb = l2cap_create_basic_pdu(chan, msg, len);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002533 if (IS_ERR(skb))
2534 return PTR_ERR(skb);
2535
Andrzej Kaczmarekede81a22014-02-25 17:16:22 +01002536 /* Channel lock is released before requesting new skb and then
2537 * reacquired thus we need to recheck channel state.
2538 */
2539 if (chan->state != BT_CONNECTED) {
2540 kfree_skb(skb);
2541 return -ENOTCONN;
2542 }
2543
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002544 l2cap_do_send(chan, skb);
2545 err = len;
2546 break;
2547
2548 case L2CAP_MODE_ERTM:
2549 case L2CAP_MODE_STREAMING:
Mat Martineau94122bb2012-05-02 09:42:02 -07002550 /* Check outgoing MTU */
2551 if (len > chan->omtu) {
2552 err = -EMSGSIZE;
2553 break;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002554 }
2555
Mat Martineau94122bb2012-05-02 09:42:02 -07002556 __skb_queue_head_init(&seg_queue);
2557
2558 /* Do segmentation before calling in to the state machine,
2559 * since it's possible to block while waiting for memory
2560 * allocation.
2561 */
2562 err = l2cap_segment_sdu(chan, &seg_queue, msg, len);
2563
2564 /* The channel could have been closed while segmenting,
2565 * check that it is still connected.
2566 */
2567 if (chan->state != BT_CONNECTED) {
2568 __skb_queue_purge(&seg_queue);
2569 err = -ENOTCONN;
2570 }
2571
2572 if (err)
2573 break;
2574
Mat Martineau37339372012-05-17 20:53:33 -07002575 if (chan->mode == L2CAP_MODE_ERTM)
Gustavo Padovand6603662012-05-21 13:58:22 -03002576 l2cap_tx(chan, NULL, &seg_queue, L2CAP_EV_DATA_REQUEST);
Mat Martineau37339372012-05-17 20:53:33 -07002577 else
Gustavo Padovand6603662012-05-21 13:58:22 -03002578 l2cap_streaming_send(chan, &seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002579
Gustavo Padovand6603662012-05-21 13:58:22 -03002580 err = len;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002581
Mat Martineau94122bb2012-05-02 09:42:02 -07002582 /* If the skbs were not queued for sending, they'll still be in
2583 * seg_queue and need to be purged.
2584 */
2585 __skb_queue_purge(&seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002586 break;
2587
2588 default:
2589 BT_DBG("bad state %1.1x", chan->mode);
2590 err = -EBADFD;
2591 }
2592
2593 return err;
2594}
Jukka Rissanen6b8d4a62014-06-18 16:37:08 +03002595EXPORT_SYMBOL_GPL(l2cap_chan_send);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002596
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002597static void l2cap_send_srej(struct l2cap_chan *chan, u16 txseq)
2598{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002599 struct l2cap_ctrl control;
2600 u16 seq;
2601
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002602 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002603
2604 memset(&control, 0, sizeof(control));
2605 control.sframe = 1;
2606 control.super = L2CAP_SUPER_SREJ;
2607
2608 for (seq = chan->expected_tx_seq; seq != txseq;
2609 seq = __next_seq(chan, seq)) {
2610 if (!l2cap_ertm_seq_in_queue(&chan->srej_q, seq)) {
2611 control.reqseq = seq;
2612 l2cap_send_sframe(chan, &control);
2613 l2cap_seq_list_append(&chan->srej_list, seq);
2614 }
2615 }
2616
2617 chan->expected_tx_seq = __next_seq(chan, txseq);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002618}
2619
2620static void l2cap_send_srej_tail(struct l2cap_chan *chan)
2621{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002622 struct l2cap_ctrl control;
2623
2624 BT_DBG("chan %p", chan);
2625
2626 if (chan->srej_list.tail == L2CAP_SEQ_LIST_CLEAR)
2627 return;
2628
2629 memset(&control, 0, sizeof(control));
2630 control.sframe = 1;
2631 control.super = L2CAP_SUPER_SREJ;
2632 control.reqseq = chan->srej_list.tail;
2633 l2cap_send_sframe(chan, &control);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002634}
2635
2636static void l2cap_send_srej_list(struct l2cap_chan *chan, u16 txseq)
2637{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002638 struct l2cap_ctrl control;
2639 u16 initial_head;
2640 u16 seq;
2641
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002642 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002643
2644 memset(&control, 0, sizeof(control));
2645 control.sframe = 1;
2646 control.super = L2CAP_SUPER_SREJ;
2647
2648 /* Capture initial list head to allow only one pass through the list. */
2649 initial_head = chan->srej_list.head;
2650
2651 do {
2652 seq = l2cap_seq_list_pop(&chan->srej_list);
2653 if (seq == txseq || seq == L2CAP_SEQ_LIST_CLEAR)
2654 break;
2655
2656 control.reqseq = seq;
2657 l2cap_send_sframe(chan, &control);
2658 l2cap_seq_list_append(&chan->srej_list, seq);
2659 } while (chan->srej_list.head != initial_head);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002660}
2661
Mat Martineau608bcc62012-05-17 20:53:32 -07002662static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq)
2663{
2664 struct sk_buff *acked_skb;
2665 u16 ackseq;
2666
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002667 BT_DBG("chan %p, reqseq %u", chan, reqseq);
Mat Martineau608bcc62012-05-17 20:53:32 -07002668
2669 if (chan->unacked_frames == 0 || reqseq == chan->expected_ack_seq)
2670 return;
2671
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002672 BT_DBG("expected_ack_seq %u, unacked_frames %u",
Mat Martineau608bcc62012-05-17 20:53:32 -07002673 chan->expected_ack_seq, chan->unacked_frames);
2674
2675 for (ackseq = chan->expected_ack_seq; ackseq != reqseq;
2676 ackseq = __next_seq(chan, ackseq)) {
2677
2678 acked_skb = l2cap_ertm_seq_in_queue(&chan->tx_q, ackseq);
2679 if (acked_skb) {
2680 skb_unlink(acked_skb, &chan->tx_q);
2681 kfree_skb(acked_skb);
2682 chan->unacked_frames--;
2683 }
2684 }
2685
2686 chan->expected_ack_seq = reqseq;
2687
2688 if (chan->unacked_frames == 0)
2689 __clear_retrans_timer(chan);
2690
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002691 BT_DBG("unacked_frames %u", chan->unacked_frames);
Mat Martineau608bcc62012-05-17 20:53:32 -07002692}
2693
2694static void l2cap_abort_rx_srej_sent(struct l2cap_chan *chan)
2695{
2696 BT_DBG("chan %p", chan);
2697
2698 chan->expected_tx_seq = chan->buffer_seq;
2699 l2cap_seq_list_clear(&chan->srej_list);
2700 skb_queue_purge(&chan->srej_q);
2701 chan->rx_state = L2CAP_RX_STATE_RECV;
2702}
2703
Gustavo Padovand6603662012-05-21 13:58:22 -03002704static void l2cap_tx_state_xmit(struct l2cap_chan *chan,
2705 struct l2cap_ctrl *control,
2706 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002707{
Mat Martineau608bcc62012-05-17 20:53:32 -07002708 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2709 event);
2710
2711 switch (event) {
2712 case L2CAP_EV_DATA_REQUEST:
2713 if (chan->tx_send_head == NULL)
2714 chan->tx_send_head = skb_peek(skbs);
2715
2716 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2717 l2cap_ertm_send(chan);
2718 break;
2719 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2720 BT_DBG("Enter LOCAL_BUSY");
2721 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2722
2723 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2724 /* The SREJ_SENT state must be aborted if we are to
2725 * enter the LOCAL_BUSY state.
2726 */
2727 l2cap_abort_rx_srej_sent(chan);
2728 }
2729
2730 l2cap_send_ack(chan);
2731
2732 break;
2733 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2734 BT_DBG("Exit LOCAL_BUSY");
2735 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2736
2737 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2738 struct l2cap_ctrl local_control;
2739
2740 memset(&local_control, 0, sizeof(local_control));
2741 local_control.sframe = 1;
2742 local_control.super = L2CAP_SUPER_RR;
2743 local_control.poll = 1;
2744 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002745 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002746
2747 chan->retry_count = 1;
2748 __set_monitor_timer(chan);
2749 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2750 }
2751 break;
2752 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2753 l2cap_process_reqseq(chan, control->reqseq);
2754 break;
2755 case L2CAP_EV_EXPLICIT_POLL:
2756 l2cap_send_rr_or_rnr(chan, 1);
2757 chan->retry_count = 1;
2758 __set_monitor_timer(chan);
2759 __clear_ack_timer(chan);
2760 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2761 break;
2762 case L2CAP_EV_RETRANS_TO:
2763 l2cap_send_rr_or_rnr(chan, 1);
2764 chan->retry_count = 1;
2765 __set_monitor_timer(chan);
2766 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2767 break;
2768 case L2CAP_EV_RECV_FBIT:
2769 /* Nothing to process */
2770 break;
2771 default:
2772 break;
2773 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002774}
2775
Gustavo Padovand6603662012-05-21 13:58:22 -03002776static void l2cap_tx_state_wait_f(struct l2cap_chan *chan,
2777 struct l2cap_ctrl *control,
2778 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002779{
Mat Martineau608bcc62012-05-17 20:53:32 -07002780 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2781 event);
2782
2783 switch (event) {
2784 case L2CAP_EV_DATA_REQUEST:
2785 if (chan->tx_send_head == NULL)
2786 chan->tx_send_head = skb_peek(skbs);
2787 /* Queue data, but don't send. */
2788 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2789 break;
2790 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2791 BT_DBG("Enter LOCAL_BUSY");
2792 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2793
2794 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2795 /* The SREJ_SENT state must be aborted if we are to
2796 * enter the LOCAL_BUSY state.
2797 */
2798 l2cap_abort_rx_srej_sent(chan);
2799 }
2800
2801 l2cap_send_ack(chan);
2802
2803 break;
2804 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2805 BT_DBG("Exit LOCAL_BUSY");
2806 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2807
2808 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2809 struct l2cap_ctrl local_control;
2810 memset(&local_control, 0, sizeof(local_control));
2811 local_control.sframe = 1;
2812 local_control.super = L2CAP_SUPER_RR;
2813 local_control.poll = 1;
2814 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002815 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002816
2817 chan->retry_count = 1;
2818 __set_monitor_timer(chan);
2819 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2820 }
2821 break;
2822 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2823 l2cap_process_reqseq(chan, control->reqseq);
2824
2825 /* Fall through */
2826
2827 case L2CAP_EV_RECV_FBIT:
2828 if (control && control->final) {
2829 __clear_monitor_timer(chan);
2830 if (chan->unacked_frames > 0)
2831 __set_retrans_timer(chan);
2832 chan->retry_count = 0;
2833 chan->tx_state = L2CAP_TX_STATE_XMIT;
2834 BT_DBG("recv fbit tx_state 0x2.2%x", chan->tx_state);
2835 }
2836 break;
2837 case L2CAP_EV_EXPLICIT_POLL:
2838 /* Ignore */
2839 break;
2840 case L2CAP_EV_MONITOR_TO:
2841 if (chan->max_tx == 0 || chan->retry_count < chan->max_tx) {
2842 l2cap_send_rr_or_rnr(chan, 1);
2843 __set_monitor_timer(chan);
2844 chan->retry_count++;
2845 } else {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02002846 l2cap_send_disconn_req(chan, ECONNABORTED);
Mat Martineau608bcc62012-05-17 20:53:32 -07002847 }
2848 break;
2849 default:
2850 break;
2851 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002852}
2853
Gustavo Padovand6603662012-05-21 13:58:22 -03002854static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
2855 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002856{
Mat Martineau608bcc62012-05-17 20:53:32 -07002857 BT_DBG("chan %p, control %p, skbs %p, event %d, state %d",
2858 chan, control, skbs, event, chan->tx_state);
2859
2860 switch (chan->tx_state) {
2861 case L2CAP_TX_STATE_XMIT:
Gustavo Padovand6603662012-05-21 13:58:22 -03002862 l2cap_tx_state_xmit(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002863 break;
2864 case L2CAP_TX_STATE_WAIT_F:
Gustavo Padovand6603662012-05-21 13:58:22 -03002865 l2cap_tx_state_wait_f(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002866 break;
2867 default:
2868 /* Ignore event */
2869 break;
2870 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002871}
2872
Mat Martineau4b51dae92012-05-17 20:53:37 -07002873static void l2cap_pass_to_tx(struct l2cap_chan *chan,
2874 struct l2cap_ctrl *control)
2875{
2876 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002877 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_REQSEQ_AND_FBIT);
Mat Martineau4b51dae92012-05-17 20:53:37 -07002878}
2879
Mat Martineauf80842a2012-05-17 20:53:46 -07002880static void l2cap_pass_to_tx_fbit(struct l2cap_chan *chan,
2881 struct l2cap_ctrl *control)
2882{
2883 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002884 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_FBIT);
Mat Martineauf80842a2012-05-17 20:53:46 -07002885}
2886
Linus Torvalds1da177e2005-04-16 15:20:36 -07002887/* Copy frame to all raw sockets on that connection */
2888static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2889{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002890 struct sk_buff *nskb;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002891 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002892
2893 BT_DBG("conn %p", conn);
2894
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002895 mutex_lock(&conn->chan_lock);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002896
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002897 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002898 if (chan->chan_type != L2CAP_CHAN_RAW)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002899 continue;
2900
Gustavo Padovan7f5396a2013-10-21 18:22:25 -02002901 /* Don't send frame to the channel it came from */
2902 if (bt_cb(skb)->chan == chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002903 continue;
Gustavo Padovan7f5396a2013-10-21 18:22:25 -02002904
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002905 nskb = skb_clone(skb, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002906 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002907 continue;
Gustavo Padovan80b98022012-05-27 22:27:51 -03002908 if (chan->ops->recv(chan, nskb))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002909 kfree_skb(nskb);
2910 }
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002911
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002912 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002913}
2914
2915/* ---- L2CAP signalling commands ---- */
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002916static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code,
2917 u8 ident, u16 dlen, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002918{
2919 struct sk_buff *skb, **frag;
2920 struct l2cap_cmd_hdr *cmd;
2921 struct l2cap_hdr *lh;
2922 int len, count;
2923
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002924 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %u",
2925 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002926
Anderson Lizardo300b9622013-06-02 16:30:40 -04002927 if (conn->mtu < L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE)
2928 return NULL;
2929
Linus Torvalds1da177e2005-04-16 15:20:36 -07002930 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2931 count = min_t(unsigned int, conn->mtu, len);
2932
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002933 skb = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002934 if (!skb)
2935 return NULL;
2936
2937 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002938 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002939
2940 if (conn->hcon->type == LE_LINK)
Joe Perchesdcf4adb2014-03-12 10:52:35 -07002941 lh->cid = cpu_to_le16(L2CAP_CID_LE_SIGNALING);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002942 else
Joe Perchesdcf4adb2014-03-12 10:52:35 -07002943 lh->cid = cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002944
2945 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2946 cmd->code = code;
2947 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002948 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002949
2950 if (dlen) {
2951 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2952 memcpy(skb_put(skb, count), data, count);
2953 data += count;
2954 }
2955
2956 len -= skb->len;
2957
2958 /* Continuation fragments (no L2CAP header) */
2959 frag = &skb_shinfo(skb)->frag_list;
2960 while (len) {
2961 count = min_t(unsigned int, conn->mtu, len);
2962
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002963 *frag = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002964 if (!*frag)
2965 goto fail;
2966
2967 memcpy(skb_put(*frag, count), data, count);
2968
2969 len -= count;
2970 data += count;
2971
2972 frag = &(*frag)->next;
2973 }
2974
2975 return skb;
2976
2977fail:
2978 kfree_skb(skb);
2979 return NULL;
2980}
2981
Gustavo Padovan2d792812012-10-06 10:07:01 +01002982static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen,
2983 unsigned long *val)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002984{
2985 struct l2cap_conf_opt *opt = *ptr;
2986 int len;
2987
2988 len = L2CAP_CONF_OPT_SIZE + opt->len;
2989 *ptr += len;
2990
2991 *type = opt->type;
2992 *olen = opt->len;
2993
2994 switch (opt->len) {
2995 case 1:
2996 *val = *((u8 *) opt->val);
2997 break;
2998
2999 case 2:
steven miaobfaaeb32010-10-16 18:29:47 -04003000 *val = get_unaligned_le16(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003001 break;
3002
3003 case 4:
steven miaobfaaeb32010-10-16 18:29:47 -04003004 *val = get_unaligned_le32(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003005 break;
3006
3007 default:
3008 *val = (unsigned long) opt->val;
3009 break;
3010 }
3011
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03003012 BT_DBG("type 0x%2.2x len %u val 0x%lx", *type, opt->len, *val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003013 return len;
3014}
3015
Linus Torvalds1da177e2005-04-16 15:20:36 -07003016static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
3017{
3018 struct l2cap_conf_opt *opt = *ptr;
3019
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03003020 BT_DBG("type 0x%2.2x len %u val 0x%lx", type, len, val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003021
3022 opt->type = type;
3023 opt->len = len;
3024
3025 switch (len) {
3026 case 1:
3027 *((u8 *) opt->val) = val;
3028 break;
3029
3030 case 2:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02003031 put_unaligned_le16(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003032 break;
3033
3034 case 4:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02003035 put_unaligned_le32(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003036 break;
3037
3038 default:
3039 memcpy(opt->val, (void *) val, len);
3040 break;
3041 }
3042
3043 *ptr += L2CAP_CONF_OPT_SIZE + len;
3044}
3045
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003046static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan)
3047{
3048 struct l2cap_conf_efs efs;
3049
Szymon Janc1ec918c2011-11-16 09:32:21 +01003050 switch (chan->mode) {
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003051 case L2CAP_MODE_ERTM:
3052 efs.id = chan->local_id;
3053 efs.stype = chan->local_stype;
3054 efs.msdu = cpu_to_le16(chan->local_msdu);
3055 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
Joe Perchesdcf4adb2014-03-12 10:52:35 -07003056 efs.acc_lat = cpu_to_le32(L2CAP_DEFAULT_ACC_LAT);
3057 efs.flush_to = cpu_to_le32(L2CAP_EFS_DEFAULT_FLUSH_TO);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003058 break;
3059
3060 case L2CAP_MODE_STREAMING:
3061 efs.id = 1;
3062 efs.stype = L2CAP_SERV_BESTEFFORT;
3063 efs.msdu = cpu_to_le16(chan->local_msdu);
3064 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
3065 efs.acc_lat = 0;
3066 efs.flush_to = 0;
3067 break;
3068
3069 default:
3070 return;
3071 }
3072
3073 l2cap_add_conf_opt(ptr, L2CAP_CONF_EFS, sizeof(efs),
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03003074 (unsigned long) &efs);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003075}
3076
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003077static void l2cap_ack_timeout(struct work_struct *work)
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003078{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003079 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau03625202012-05-17 20:53:51 -07003080 ack_timer.work);
3081 u16 frames_to_ack;
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003082
Gustavo F. Padovan2fb9b3d2011-12-22 16:56:05 -02003083 BT_DBG("chan %p", chan);
3084
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003085 l2cap_chan_lock(chan);
3086
Mat Martineau03625202012-05-17 20:53:51 -07003087 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
3088 chan->last_acked_seq);
3089
3090 if (frames_to_ack)
3091 l2cap_send_rr_or_rnr(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003092
3093 l2cap_chan_unlock(chan);
Szymon Janc09bfb2e2012-01-11 10:59:49 +01003094 l2cap_chan_put(chan);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003095}
3096
Andrei Emeltchenko466f8002012-05-29 13:59:01 +03003097int l2cap_ertm_init(struct l2cap_chan *chan)
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003098{
Mat Martineau3c588192012-04-11 10:48:42 -07003099 int err;
3100
Mat Martineau105bdf92012-04-27 16:50:48 -07003101 chan->next_tx_seq = 0;
3102 chan->expected_tx_seq = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03003103 chan->expected_ack_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03003104 chan->unacked_frames = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03003105 chan->buffer_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03003106 chan->frames_sent = 0;
Mat Martineau105bdf92012-04-27 16:50:48 -07003107 chan->last_acked_seq = 0;
3108 chan->sdu = NULL;
3109 chan->sdu_last_frag = NULL;
3110 chan->sdu_len = 0;
3111
Mat Martineaud34c34f2012-05-14 14:49:27 -07003112 skb_queue_head_init(&chan->tx_q);
3113
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003114 chan->local_amp_id = AMP_ID_BREDR;
3115 chan->move_id = AMP_ID_BREDR;
Mat Martineau08333282012-10-23 15:24:06 -07003116 chan->move_state = L2CAP_MOVE_STABLE;
3117 chan->move_role = L2CAP_MOVE_ROLE_NONE;
3118
Mat Martineau105bdf92012-04-27 16:50:48 -07003119 if (chan->mode != L2CAP_MODE_ERTM)
3120 return 0;
3121
3122 chan->rx_state = L2CAP_RX_STATE_RECV;
3123 chan->tx_state = L2CAP_TX_STATE_XMIT;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003124
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003125 INIT_DELAYED_WORK(&chan->retrans_timer, l2cap_retrans_timeout);
3126 INIT_DELAYED_WORK(&chan->monitor_timer, l2cap_monitor_timeout);
3127 INIT_DELAYED_WORK(&chan->ack_timer, l2cap_ack_timeout);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003128
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -03003129 skb_queue_head_init(&chan->srej_q);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003130
Mat Martineau3c588192012-04-11 10:48:42 -07003131 err = l2cap_seq_list_init(&chan->srej_list, chan->tx_win);
3132 if (err < 0)
3133 return err;
3134
Mat Martineau9dc9aff2012-05-17 16:20:14 -07003135 err = l2cap_seq_list_init(&chan->retrans_list, chan->remote_tx_win);
3136 if (err < 0)
3137 l2cap_seq_list_free(&chan->srej_list);
3138
3139 return err;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003140}
3141
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003142static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
3143{
3144 switch (mode) {
3145 case L2CAP_MODE_STREAMING:
3146 case L2CAP_MODE_ERTM:
3147 if (l2cap_mode_supported(mode, remote_feat_mask))
3148 return mode;
3149 /* fall through */
3150 default:
3151 return L2CAP_MODE_BASIC;
3152 }
3153}
3154
Marcel Holtmann848566b2013-10-01 22:59:22 -07003155static inline bool __l2cap_ews_supported(struct l2cap_conn *conn)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003156{
Marcel Holtmann848566b2013-10-01 22:59:22 -07003157 return conn->hs_enabled && conn->feat_mask & L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003158}
3159
Marcel Holtmann848566b2013-10-01 22:59:22 -07003160static inline bool __l2cap_efs_supported(struct l2cap_conn *conn)
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003161{
Marcel Holtmann848566b2013-10-01 22:59:22 -07003162 return conn->hs_enabled && conn->feat_mask & L2CAP_FEAT_EXT_FLOW;
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003163}
3164
Mat Martineau36c86c82012-10-23 15:24:20 -07003165static void __l2cap_set_ertm_timeouts(struct l2cap_chan *chan,
3166 struct l2cap_conf_rfc *rfc)
3167{
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003168 if (chan->local_amp_id != AMP_ID_BREDR && chan->hs_hcon) {
Mat Martineau36c86c82012-10-23 15:24:20 -07003169 u64 ertm_to = chan->hs_hcon->hdev->amp_be_flush_to;
3170
3171 /* Class 1 devices have must have ERTM timeouts
3172 * exceeding the Link Supervision Timeout. The
3173 * default Link Supervision Timeout for AMP
3174 * controllers is 10 seconds.
3175 *
3176 * Class 1 devices use 0xffffffff for their
3177 * best-effort flush timeout, so the clamping logic
3178 * will result in a timeout that meets the above
3179 * requirement. ERTM timeouts are 16-bit values, so
3180 * the maximum timeout is 65.535 seconds.
3181 */
3182
3183 /* Convert timeout to milliseconds and round */
3184 ertm_to = DIV_ROUND_UP_ULL(ertm_to, 1000);
3185
3186 /* This is the recommended formula for class 2 devices
3187 * that start ERTM timers when packets are sent to the
3188 * controller.
3189 */
3190 ertm_to = 3 * ertm_to + 500;
3191
3192 if (ertm_to > 0xffff)
3193 ertm_to = 0xffff;
3194
3195 rfc->retrans_timeout = cpu_to_le16((u16) ertm_to);
3196 rfc->monitor_timeout = rfc->retrans_timeout;
3197 } else {
Joe Perchesdcf4adb2014-03-12 10:52:35 -07003198 rfc->retrans_timeout = cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
3199 rfc->monitor_timeout = cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
Mat Martineau36c86c82012-10-23 15:24:20 -07003200 }
3201}
3202
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003203static inline void l2cap_txwin_setup(struct l2cap_chan *chan)
3204{
3205 if (chan->tx_win > L2CAP_DEFAULT_TX_WINDOW &&
Marcel Holtmann848566b2013-10-01 22:59:22 -07003206 __l2cap_ews_supported(chan->conn)) {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003207 /* use extended control field */
3208 set_bit(FLAG_EXT_CTRL, &chan->flags);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003209 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
3210 } else {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003211 chan->tx_win = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003212 L2CAP_DEFAULT_TX_WINDOW);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003213 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
3214 }
Mat Martineauc20f8e32012-07-10 05:47:07 -07003215 chan->ack_win = chan->tx_win;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003216}
3217
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003218static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003219{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003220 struct l2cap_conf_req *req = data;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003221 struct l2cap_conf_rfc rfc = { .mode = chan->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07003222 void *ptr = req->data;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003223 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003224
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03003225 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003226
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003227 if (chan->num_conf_req || chan->num_conf_rsp)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003228 goto done;
3229
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003230 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003231 case L2CAP_MODE_STREAMING:
3232 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003233 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state))
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003234 break;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003235
Marcel Holtmann848566b2013-10-01 22:59:22 -07003236 if (__l2cap_efs_supported(chan->conn))
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003237 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3238
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03003239 /* fall through */
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003240 default:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003241 chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003242 break;
3243 }
3244
3245done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003246 if (chan->imtu != L2CAP_DEFAULT_MTU)
3247 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovan7990681c2011-01-24 16:01:43 -02003248
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003249 switch (chan->mode) {
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003250 case L2CAP_MODE_BASIC:
Marcel Holtmann6fea7ad2014-07-09 11:53:35 +02003251 if (disable_ertm)
3252 break;
3253
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003254 if (!(chan->conn->feat_mask & L2CAP_FEAT_ERTM) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003255 !(chan->conn->feat_mask & L2CAP_FEAT_STREAMING))
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003256 break;
3257
Gustavo F. Padovan62547752010-06-08 20:05:31 -03003258 rfc.mode = L2CAP_MODE_BASIC;
3259 rfc.txwin_size = 0;
3260 rfc.max_transmit = 0;
3261 rfc.retrans_timeout = 0;
3262 rfc.monitor_timeout = 0;
3263 rfc.max_pdu_size = 0;
3264
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003265 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003266 (unsigned long) &rfc);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003267 break;
3268
3269 case L2CAP_MODE_ERTM:
3270 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003271 rfc.max_transmit = chan->max_tx;
Mat Martineau36c86c82012-10-23 15:24:20 -07003272
3273 __l2cap_set_ertm_timeouts(chan, &rfc);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003274
3275 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003276 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3277 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003278 rfc.max_pdu_size = cpu_to_le16(size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003279
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003280 l2cap_txwin_setup(chan);
3281
3282 rfc.txwin_size = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003283 L2CAP_DEFAULT_TX_WINDOW);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003284
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003285 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003286 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003287
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003288 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3289 l2cap_add_opt_efs(&ptr, chan);
3290
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003291 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3292 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003293 chan->tx_win);
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003294
3295 if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
3296 if (chan->fcs == L2CAP_FCS_NONE ||
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003297 test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003298 chan->fcs = L2CAP_FCS_NONE;
3299 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
3300 chan->fcs);
3301 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003302 break;
3303
3304 case L2CAP_MODE_STREAMING:
Mat Martineau273759e2012-05-17 20:53:53 -07003305 l2cap_txwin_setup(chan);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003306 rfc.mode = L2CAP_MODE_STREAMING;
3307 rfc.txwin_size = 0;
3308 rfc.max_transmit = 0;
3309 rfc.retrans_timeout = 0;
3310 rfc.monitor_timeout = 0;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003311
3312 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003313 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3314 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003315 rfc.max_pdu_size = cpu_to_le16(size);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003316
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003317 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003318 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003319
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003320 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3321 l2cap_add_opt_efs(&ptr, chan);
3322
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003323 if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
3324 if (chan->fcs == L2CAP_FCS_NONE ||
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003325 test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003326 chan->fcs = L2CAP_FCS_NONE;
3327 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
3328 chan->fcs);
3329 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003330 break;
3331 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003332
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003333 req->dcid = cpu_to_le16(chan->dcid);
Joe Perchesdcf4adb2014-03-12 10:52:35 -07003334 req->flags = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003335
3336 return ptr - data;
3337}
3338
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003339static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003340{
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003341 struct l2cap_conf_rsp *rsp = data;
3342 void *ptr = rsp->data;
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003343 void *req = chan->conf_req;
3344 int len = chan->conf_len;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003345 int type, hint, olen;
3346 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003347 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003348 struct l2cap_conf_efs efs;
3349 u8 remote_efs = 0;
Marcel Holtmann861d6882007-10-20 13:37:06 +02003350 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003351 u16 result = L2CAP_CONF_SUCCESS;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003352 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003353
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003354 BT_DBG("chan %p", chan);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01003355
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003356 while (len >= L2CAP_CONF_OPT_SIZE) {
3357 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003358
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03003359 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003360 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003361
3362 switch (type) {
3363 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02003364 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003365 break;
3366
3367 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003368 chan->flush_to = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003369 break;
3370
3371 case L2CAP_CONF_QOS:
3372 break;
3373
Marcel Holtmann6464f352007-10-20 13:39:51 +02003374 case L2CAP_CONF_RFC:
3375 if (olen == sizeof(rfc))
3376 memcpy(&rfc, (void *) val, olen);
3377 break;
3378
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003379 case L2CAP_CONF_FCS:
3380 if (val == L2CAP_FCS_NONE)
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003381 set_bit(CONF_RECV_NO_FCS, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003382 break;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003383
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003384 case L2CAP_CONF_EFS:
3385 remote_efs = 1;
3386 if (olen == sizeof(efs))
3387 memcpy(&efs, (void *) val, olen);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003388 break;
3389
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003390 case L2CAP_CONF_EWS:
Marcel Holtmann848566b2013-10-01 22:59:22 -07003391 if (!chan->conn->hs_enabled)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003392 return -ECONNREFUSED;
3393
3394 set_bit(FLAG_EXT_CTRL, &chan->flags);
3395 set_bit(CONF_EWS_RECV, &chan->conf_state);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003396 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003397 chan->remote_tx_win = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003398 break;
3399
3400 default:
3401 if (hint)
3402 break;
3403
3404 result = L2CAP_CONF_UNKNOWN;
3405 *((u8 *) ptr++) = type;
3406 break;
3407 }
3408 }
3409
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003410 if (chan->num_conf_rsp || chan->num_conf_req > 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003411 goto done;
3412
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003413 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003414 case L2CAP_MODE_STREAMING:
3415 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003416 if (!test_bit(CONF_STATE2_DEVICE, &chan->conf_state)) {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003417 chan->mode = l2cap_select_mode(rfc.mode,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003418 chan->conn->feat_mask);
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003419 break;
3420 }
3421
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003422 if (remote_efs) {
Marcel Holtmann848566b2013-10-01 22:59:22 -07003423 if (__l2cap_efs_supported(chan->conn))
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003424 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3425 else
3426 return -ECONNREFUSED;
3427 }
3428
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003429 if (chan->mode != rfc.mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003430 return -ECONNREFUSED;
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03003431
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003432 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003433 }
3434
3435done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003436 if (chan->mode != rfc.mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003437 result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003438 rfc.mode = chan->mode;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003439
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003440 if (chan->num_conf_rsp == 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003441 return -ECONNREFUSED;
3442
Gustavo Padovan2d792812012-10-06 10:07:01 +01003443 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3444 (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003445 }
3446
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003447 if (result == L2CAP_CONF_SUCCESS) {
3448 /* Configure output options and let the other side know
3449 * which ones we don't like. */
3450
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003451 if (mtu < L2CAP_DEFAULT_MIN_MTU)
3452 result = L2CAP_CONF_UNACCEPT;
3453 else {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003454 chan->omtu = mtu;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003455 set_bit(CONF_MTU_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003456 }
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003457 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003458
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003459 if (remote_efs) {
3460 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003461 efs.stype != L2CAP_SERV_NOTRAFIC &&
3462 efs.stype != chan->local_stype) {
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003463
3464 result = L2CAP_CONF_UNACCEPT;
3465
3466 if (chan->num_conf_req >= 1)
3467 return -ECONNREFUSED;
3468
3469 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003470 sizeof(efs),
3471 (unsigned long) &efs);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003472 } else {
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003473 /* Send PENDING Conf Rsp */
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003474 result = L2CAP_CONF_PENDING;
3475 set_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003476 }
3477 }
3478
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003479 switch (rfc.mode) {
3480 case L2CAP_MODE_BASIC:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003481 chan->fcs = L2CAP_FCS_NONE;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003482 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003483 break;
3484
3485 case L2CAP_MODE_ERTM:
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003486 if (!test_bit(CONF_EWS_RECV, &chan->conf_state))
3487 chan->remote_tx_win = rfc.txwin_size;
3488 else
3489 rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW;
3490
Gustavo F. Padovan2c03a7a2011-03-25 20:15:28 -03003491 chan->remote_max_tx = rfc.max_transmit;
Mat Martineau86b1b262010-08-05 15:54:22 -07003492
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003493 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003494 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3495 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003496 rfc.max_pdu_size = cpu_to_le16(size);
3497 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003498
Mat Martineau36c86c82012-10-23 15:24:20 -07003499 __l2cap_set_ertm_timeouts(chan, &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003500
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003501 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003502
3503 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003504 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003505
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003506 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3507 chan->remote_id = efs.id;
3508 chan->remote_stype = efs.stype;
3509 chan->remote_msdu = le16_to_cpu(efs.msdu);
3510 chan->remote_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003511 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003512 chan->remote_acc_lat =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003513 le32_to_cpu(efs.acc_lat);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003514 chan->remote_sdu_itime =
3515 le32_to_cpu(efs.sdu_itime);
3516 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003517 sizeof(efs),
3518 (unsigned long) &efs);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003519 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003520 break;
3521
3522 case L2CAP_MODE_STREAMING:
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003523 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003524 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3525 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003526 rfc.max_pdu_size = cpu_to_le16(size);
3527 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003528
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003529 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003530
Gustavo Padovan2d792812012-10-06 10:07:01 +01003531 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3532 (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003533
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003534 break;
3535
3536 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02003537 result = L2CAP_CONF_UNACCEPT;
3538
3539 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003540 rfc.mode = chan->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003541 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003542
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003543 if (result == L2CAP_CONF_SUCCESS)
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003544 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003545 }
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003546 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003547 rsp->result = cpu_to_le16(result);
Joe Perchesdcf4adb2014-03-12 10:52:35 -07003548 rsp->flags = cpu_to_le16(0);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003549
3550 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003551}
3552
Gustavo Padovan2d792812012-10-06 10:07:01 +01003553static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len,
3554 void *data, u16 *result)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003555{
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003556 struct l2cap_conf_req *req = data;
3557 void *ptr = req->data;
3558 int type, olen;
3559 unsigned long val;
Mat Martineau36e999a2011-12-08 17:23:21 -08003560 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003561 struct l2cap_conf_efs efs;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003562
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003563 BT_DBG("chan %p, rsp %p, len %d, req %p", chan, rsp, len, data);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003564
3565 while (len >= L2CAP_CONF_OPT_SIZE) {
3566 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3567
3568 switch (type) {
3569 case L2CAP_CONF_MTU:
3570 if (val < L2CAP_DEFAULT_MIN_MTU) {
3571 *result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003572 chan->imtu = L2CAP_DEFAULT_MIN_MTU;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003573 } else
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003574 chan->imtu = val;
3575 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003576 break;
3577
3578 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003579 chan->flush_to = val;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003580 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003581 2, chan->flush_to);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003582 break;
3583
3584 case L2CAP_CONF_RFC:
3585 if (olen == sizeof(rfc))
3586 memcpy(&rfc, (void *)val, olen);
3587
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003588 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003589 rfc.mode != chan->mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003590 return -ECONNREFUSED;
3591
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003592 chan->fcs = 0;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003593
3594 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003595 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003596 break;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003597
3598 case L2CAP_CONF_EWS:
Mat Martineauc20f8e32012-07-10 05:47:07 -07003599 chan->ack_win = min_t(u16, val, chan->ack_win);
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003600 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Mat Martineauc20f8e32012-07-10 05:47:07 -07003601 chan->tx_win);
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003602 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003603
3604 case L2CAP_CONF_EFS:
3605 if (olen == sizeof(efs))
3606 memcpy(&efs, (void *)val, olen);
3607
3608 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003609 efs.stype != L2CAP_SERV_NOTRAFIC &&
3610 efs.stype != chan->local_stype)
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003611 return -ECONNREFUSED;
3612
Gustavo Padovan2d792812012-10-06 10:07:01 +01003613 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs),
3614 (unsigned long) &efs);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003615 break;
Andrei Emeltchenkocbabee72012-11-29 17:46:07 +02003616
3617 case L2CAP_CONF_FCS:
3618 if (*result == L2CAP_CONF_PENDING)
3619 if (val == L2CAP_FCS_NONE)
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003620 set_bit(CONF_RECV_NO_FCS,
Andrei Emeltchenkocbabee72012-11-29 17:46:07 +02003621 &chan->conf_state);
3622 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003623 }
3624 }
3625
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003626 if (chan->mode == L2CAP_MODE_BASIC && chan->mode != rfc.mode)
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003627 return -ECONNREFUSED;
3628
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003629 chan->mode = rfc.mode;
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003630
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003631 if (*result == L2CAP_CONF_SUCCESS || *result == L2CAP_CONF_PENDING) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003632 switch (rfc.mode) {
3633 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003634 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3635 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
3636 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003637 if (!test_bit(FLAG_EXT_CTRL, &chan->flags))
3638 chan->ack_win = min_t(u16, chan->ack_win,
3639 rfc.txwin_size);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003640
3641 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3642 chan->local_msdu = le16_to_cpu(efs.msdu);
3643 chan->local_sdu_itime =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003644 le32_to_cpu(efs.sdu_itime);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003645 chan->local_acc_lat = le32_to_cpu(efs.acc_lat);
3646 chan->local_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003647 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003648 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003649 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003650
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003651 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003652 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003653 }
3654 }
3655
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003656 req->dcid = cpu_to_le16(chan->dcid);
Joe Perchesdcf4adb2014-03-12 10:52:35 -07003657 req->flags = cpu_to_le16(0);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003658
3659 return ptr - data;
3660}
3661
Gustavo Padovan2d792812012-10-06 10:07:01 +01003662static int l2cap_build_conf_rsp(struct l2cap_chan *chan, void *data,
3663 u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003664{
3665 struct l2cap_conf_rsp *rsp = data;
3666 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003667
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003668 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003669
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003670 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003671 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003672 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003673
3674 return ptr - data;
3675}
3676
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03003677void __l2cap_le_connect_rsp_defer(struct l2cap_chan *chan)
3678{
3679 struct l2cap_le_conn_rsp rsp;
3680 struct l2cap_conn *conn = chan->conn;
3681
3682 BT_DBG("chan %p", chan);
3683
3684 rsp.dcid = cpu_to_le16(chan->scid);
3685 rsp.mtu = cpu_to_le16(chan->imtu);
Johan Hedberg3916aed2013-10-07 15:35:26 +02003686 rsp.mps = cpu_to_le16(chan->mps);
Johan Hedberg0cd75f72013-05-17 13:09:05 +03003687 rsp.credits = cpu_to_le16(chan->rx_credits);
Joe Perchesdcf4adb2014-03-12 10:52:35 -07003688 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03003689
3690 l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CONN_RSP, sizeof(rsp),
3691 &rsp);
3692}
3693
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003694void __l2cap_connect_rsp_defer(struct l2cap_chan *chan)
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003695{
3696 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003697 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003698 u8 buf[128];
Andrei Emeltchenko439f34a2012-10-31 15:46:28 +02003699 u8 rsp_code;
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003700
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003701 rsp.scid = cpu_to_le16(chan->dcid);
3702 rsp.dcid = cpu_to_le16(chan->scid);
Joe Perchesdcf4adb2014-03-12 10:52:35 -07003703 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
3704 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
Andrei Emeltchenko439f34a2012-10-31 15:46:28 +02003705
3706 if (chan->hs_hcon)
3707 rsp_code = L2CAP_CREATE_CHAN_RSP;
3708 else
3709 rsp_code = L2CAP_CONN_RSP;
3710
3711 BT_DBG("chan %p rsp_code %u", chan, rsp_code);
3712
3713 l2cap_send_cmd(conn, chan->ident, rsp_code, sizeof(rsp), &rsp);
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003714
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003715 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003716 return;
3717
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003718 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003719 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003720 chan->num_conf_req++;
3721}
3722
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003723static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003724{
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003725 int type, olen;
3726 unsigned long val;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003727 /* Use sane default values in case a misbehaving remote device
3728 * did not send an RFC or extended window size option.
3729 */
3730 u16 txwin_ext = chan->ack_win;
3731 struct l2cap_conf_rfc rfc = {
3732 .mode = chan->mode,
Joe Perchesdcf4adb2014-03-12 10:52:35 -07003733 .retrans_timeout = cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO),
3734 .monitor_timeout = cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO),
Mat Martineauc20f8e32012-07-10 05:47:07 -07003735 .max_pdu_size = cpu_to_le16(chan->imtu),
3736 .txwin_size = min_t(u16, chan->ack_win, L2CAP_DEFAULT_TX_WINDOW),
3737 };
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003738
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003739 BT_DBG("chan %p, rsp %p, len %d", chan, rsp, len);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003740
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003741 if ((chan->mode != L2CAP_MODE_ERTM) && (chan->mode != L2CAP_MODE_STREAMING))
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003742 return;
3743
3744 while (len >= L2CAP_CONF_OPT_SIZE) {
3745 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3746
Mat Martineauc20f8e32012-07-10 05:47:07 -07003747 switch (type) {
3748 case L2CAP_CONF_RFC:
3749 if (olen == sizeof(rfc))
3750 memcpy(&rfc, (void *)val, olen);
Szymon Janc8f321f82012-06-08 11:33:33 +02003751 break;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003752 case L2CAP_CONF_EWS:
3753 txwin_ext = val;
3754 break;
3755 }
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003756 }
3757
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003758 switch (rfc.mode) {
3759 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003760 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3761 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003762 chan->mps = le16_to_cpu(rfc.max_pdu_size);
3763 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3764 chan->ack_win = min_t(u16, chan->ack_win, txwin_ext);
3765 else
3766 chan->ack_win = min_t(u16, chan->ack_win,
3767 rfc.txwin_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003768 break;
3769 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003770 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003771 }
3772}
3773
Gustavo Padovan2d792812012-10-06 10:07:01 +01003774static inline int l2cap_command_rej(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003775 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3776 u8 *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003777{
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003778 struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003779
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003780 if (cmd_len < sizeof(*rej))
3781 return -EPROTO;
3782
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003783 if (rej->reason != L2CAP_REJ_NOT_UNDERSTOOD)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003784 return 0;
3785
3786 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003787 cmd->ident == conn->info_ident) {
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02003788 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01003789
3790 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003791 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003792
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003793 l2cap_conn_start(conn);
3794 }
3795
3796 return 0;
3797}
3798
Mat Martineau17009152012-10-23 15:24:07 -07003799static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
3800 struct l2cap_cmd_hdr *cmd,
3801 u8 *data, u8 rsp_code, u8 amp_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003802{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003803 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
3804 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003805 struct l2cap_chan *chan = NULL, *pchan;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003806 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003807
3808 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003809 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003810
Andrei Emeltchenko097db762012-03-09 14:16:17 +02003811 BT_DBG("psm 0x%2.2x scid 0x%4.4x", __le16_to_cpu(psm), scid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003812
3813 /* Check if we have socket listening on psm */
Marcel Holtmann6f59b902013-10-13 05:24:01 -07003814 pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, &conn->hcon->src,
Johan Hedbergbf20fd42013-05-14 13:23:13 +03003815 &conn->hcon->dst, ACL_LINK);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003816 if (!pchan) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003817 result = L2CAP_CR_BAD_PSM;
3818 goto sendresp;
3819 }
3820
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003821 mutex_lock(&conn->chan_lock);
Gustavo Padovan8ffb9292013-10-21 14:21:41 -02003822 l2cap_chan_lock(pchan);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00003823
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003824 /* Check if the ACL is secure enough (if not SDP) */
Joe Perchesdcf4adb2014-03-12 10:52:35 -07003825 if (psm != cpu_to_le16(L2CAP_PSM_SDP) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003826 !hci_conn_check_link_mode(conn->hcon)) {
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003827 conn->disc_reason = HCI_ERROR_AUTH_FAILURE;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003828 result = L2CAP_CR_SEC_BLOCK;
3829 goto response;
3830 }
3831
Linus Torvalds1da177e2005-04-16 15:20:36 -07003832 result = L2CAP_CR_NO_MEM;
3833
Gustavo Padovan2dfa1002012-05-27 22:27:58 -03003834 /* Check if we already have channel with that dcid */
3835 if (__l2cap_get_chan_by_dcid(conn, scid))
3836 goto response;
3837
Gustavo Padovan80b98022012-05-27 22:27:51 -03003838 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003839 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003840 goto response;
3841
Syam Sidhardhan330b6c12013-08-06 01:59:12 +09003842 /* For certain devices (ex: HID mouse), support for authentication,
3843 * pairing and bonding is optional. For such devices, inorder to avoid
3844 * the ACL alive for too long after L2CAP disconnection, reset the ACL
3845 * disc_timeout back to HCI_DISCONN_TIMEOUT during L2CAP connect.
3846 */
3847 conn->hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
3848
Marcel Holtmann7eafc592013-10-13 08:12:47 -07003849 bacpy(&chan->src, &conn->hcon->src);
3850 bacpy(&chan->dst, &conn->hcon->dst);
Marcel Holtmann4f1654e2013-10-13 08:50:41 -07003851 chan->src_type = bdaddr_type(conn->hcon, conn->hcon->src_type);
3852 chan->dst_type = bdaddr_type(conn->hcon, conn->hcon->dst_type);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003853 chan->psm = psm;
3854 chan->dcid = scid;
Mat Martineau17009152012-10-23 15:24:07 -07003855 chan->local_amp_id = amp_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003856
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003857 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003858
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003859 dcid = chan->scid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003860
Gustavo Padovan8d836d72013-10-15 19:24:47 -03003861 __set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003862
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003863 chan->ident = cmd->ident;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003864
Marcel Holtmann984947d2009-02-06 23:35:19 +01003865 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Johan Hedberge7cafc42014-07-17 15:35:38 +03003866 if (l2cap_chan_check_security(chan, false)) {
Marcel Holtmannbdc25782013-10-14 02:45:34 -07003867 if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02003868 l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003869 result = L2CAP_CR_PEND;
3870 status = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08003871 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003872 } else {
Mat Martineau17009152012-10-23 15:24:07 -07003873 /* Force pending result for AMP controllers.
3874 * The connection will succeed after the
3875 * physical link is up.
3876 */
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003877 if (amp_id == AMP_ID_BREDR) {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02003878 l2cap_state_change(chan, BT_CONFIG);
Mat Martineau17009152012-10-23 15:24:07 -07003879 result = L2CAP_CR_SUCCESS;
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003880 } else {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02003881 l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003882 result = L2CAP_CR_PEND;
Mat Martineau17009152012-10-23 15:24:07 -07003883 }
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003884 status = L2CAP_CS_NO_INFO;
3885 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003886 } else {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02003887 l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003888 result = L2CAP_CR_PEND;
3889 status = L2CAP_CS_AUTHEN_PEND;
3890 }
3891 } else {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02003892 l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003893 result = L2CAP_CR_PEND;
3894 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003895 }
3896
Linus Torvalds1da177e2005-04-16 15:20:36 -07003897response:
Gustavo Padovan8ffb9292013-10-21 14:21:41 -02003898 l2cap_chan_unlock(pchan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003899 mutex_unlock(&conn->chan_lock);
Johan Hedberga24cce12014-08-07 22:56:42 +03003900 l2cap_chan_put(pchan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003901
3902sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003903 rsp.scid = cpu_to_le16(scid);
3904 rsp.dcid = cpu_to_le16(dcid);
3905 rsp.result = cpu_to_le16(result);
3906 rsp.status = cpu_to_le16(status);
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003907 l2cap_send_cmd(conn, cmd->ident, rsp_code, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003908
3909 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
3910 struct l2cap_info_req info;
Joe Perchesdcf4adb2014-03-12 10:52:35 -07003911 info.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003912
3913 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
3914 conn->info_ident = l2cap_get_ident(conn);
3915
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08003916 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003917
Gustavo Padovan2d792812012-10-06 10:07:01 +01003918 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
3919 sizeof(info), &info);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003920 }
3921
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003922 if (chan && !test_bit(CONF_REQ_SENT, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003923 result == L2CAP_CR_SUCCESS) {
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003924 u8 buf[128];
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003925 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003926 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003927 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003928 chan->num_conf_req++;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003929 }
Mat Martineau17009152012-10-23 15:24:07 -07003930
3931 return chan;
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003932}
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003933
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003934static int l2cap_connect_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003935 struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003936{
Jaganath Kanakkassery7b064ed2013-01-10 10:28:35 +05303937 struct hci_dev *hdev = conn->hcon->hdev;
3938 struct hci_conn *hcon = conn->hcon;
3939
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003940 if (cmd_len < sizeof(struct l2cap_conn_req))
3941 return -EPROTO;
3942
Jaganath Kanakkassery7b064ed2013-01-10 10:28:35 +05303943 hci_dev_lock(hdev);
3944 if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
3945 !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &hcon->flags))
3946 mgmt_device_connected(hdev, &hcon->dst, hcon->type,
3947 hcon->dst_type, 0, NULL, 0,
3948 hcon->dev_class);
3949 hci_dev_unlock(hdev);
3950
Gustavo Padovan300229f2012-10-12 19:40:40 +08003951 l2cap_connect(conn, cmd, data, L2CAP_CONN_RSP, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003952 return 0;
3953}
3954
Mat Martineau5909cf32012-10-23 15:24:08 -07003955static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003956 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3957 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003958{
3959 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
3960 u16 scid, dcid, result, status;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003961 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003962 u8 req[128];
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003963 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003964
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003965 if (cmd_len < sizeof(*rsp))
3966 return -EPROTO;
3967
Linus Torvalds1da177e2005-04-16 15:20:36 -07003968 scid = __le16_to_cpu(rsp->scid);
3969 dcid = __le16_to_cpu(rsp->dcid);
3970 result = __le16_to_cpu(rsp->result);
3971 status = __le16_to_cpu(rsp->status);
3972
Andrei Emeltchenko1b009c92012-02-21 12:54:54 +02003973 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 +01003974 dcid, scid, result, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003975
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003976 mutex_lock(&conn->chan_lock);
3977
Linus Torvalds1da177e2005-04-16 15:20:36 -07003978 if (scid) {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003979 chan = __l2cap_get_chan_by_scid(conn, scid);
3980 if (!chan) {
Johan Hedberg21870b52013-09-16 13:05:14 +03003981 err = -EBADSLT;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003982 goto unlock;
3983 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003984 } else {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003985 chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
3986 if (!chan) {
Johan Hedberg21870b52013-09-16 13:05:14 +03003987 err = -EBADSLT;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003988 goto unlock;
3989 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003990 }
3991
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003992 err = 0;
3993
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003994 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003995
Linus Torvalds1da177e2005-04-16 15:20:36 -07003996 switch (result) {
3997 case L2CAP_CR_SUCCESS:
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03003998 l2cap_state_change(chan, BT_CONFIG);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003999 chan->ident = 0;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03004000 chan->dcid = dcid;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004001 clear_bit(CONF_CONNECT_PEND, &chan->conf_state);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01004002
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004003 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03004004 break;
4005
Linus Torvalds1da177e2005-04-16 15:20:36 -07004006 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004007 l2cap_build_conf_req(chan, req), req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004008 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004009 break;
4010
4011 case L2CAP_CR_PEND:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004012 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004013 break;
4014
4015 default:
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004016 l2cap_chan_del(chan, ECONNREFUSED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004017 break;
4018 }
4019
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004020 l2cap_chan_unlock(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004021
4022unlock:
4023 mutex_unlock(&conn->chan_lock);
4024
4025 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004026}
4027
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004028static inline void set_default_fcs(struct l2cap_chan *chan)
Mat Martineau8c462b62010-08-24 15:35:42 -07004029{
4030 /* FCS is enabled only in ERTM or streaming mode, if one or both
4031 * sides request it.
4032 */
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03004033 if (chan->mode != L2CAP_MODE_ERTM && chan->mode != L2CAP_MODE_STREAMING)
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004034 chan->fcs = L2CAP_FCS_NONE;
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02004035 else if (!test_bit(CONF_RECV_NO_FCS, &chan->conf_state))
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004036 chan->fcs = L2CAP_FCS_CRC16;
Mat Martineau8c462b62010-08-24 15:35:42 -07004037}
4038
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03004039static void l2cap_send_efs_conf_rsp(struct l2cap_chan *chan, void *data,
4040 u8 ident, u16 flags)
4041{
4042 struct l2cap_conn *conn = chan->conn;
4043
4044 BT_DBG("conn %p chan %p ident %d flags 0x%4.4x", conn, chan, ident,
4045 flags);
4046
4047 clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
4048 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
4049
4050 l2cap_send_cmd(conn, ident, L2CAP_CONF_RSP,
4051 l2cap_build_conf_rsp(chan, data,
4052 L2CAP_CONF_SUCCESS, flags), data);
4053}
4054
Johan Hedberg662d6522013-10-16 11:20:47 +03004055static void cmd_reject_invalid_cid(struct l2cap_conn *conn, u8 ident,
4056 u16 scid, u16 dcid)
4057{
4058 struct l2cap_cmd_rej_cid rej;
4059
Joe Perchesdcf4adb2014-03-12 10:52:35 -07004060 rej.reason = cpu_to_le16(L2CAP_REJ_INVALID_CID);
Johan Hedberg662d6522013-10-16 11:20:47 +03004061 rej.scid = __cpu_to_le16(scid);
4062 rej.dcid = __cpu_to_le16(dcid);
4063
4064 l2cap_send_cmd(conn, ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
4065}
4066
Gustavo Padovan2d792812012-10-06 10:07:01 +01004067static inline int l2cap_config_req(struct l2cap_conn *conn,
4068 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4069 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004070{
4071 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
4072 u16 dcid, flags;
4073 u8 rsp[64];
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004074 struct l2cap_chan *chan;
Mat Martineau3c588192012-04-11 10:48:42 -07004075 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004076
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004077 if (cmd_len < sizeof(*req))
4078 return -EPROTO;
4079
Linus Torvalds1da177e2005-04-16 15:20:36 -07004080 dcid = __le16_to_cpu(req->dcid);
4081 flags = __le16_to_cpu(req->flags);
4082
4083 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
4084
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03004085 chan = l2cap_get_chan_by_scid(conn, dcid);
Johan Hedberg662d6522013-10-16 11:20:47 +03004086 if (!chan) {
4087 cmd_reject_invalid_cid(conn, cmd->ident, dcid, 0);
4088 return 0;
4089 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004090
David S. Miller033b1142011-07-21 13:38:42 -07004091 if (chan->state != BT_CONFIG && chan->state != BT_CONNECT2) {
Johan Hedberg662d6522013-10-16 11:20:47 +03004092 cmd_reject_invalid_cid(conn, cmd->ident, chan->scid,
4093 chan->dcid);
Marcel Holtmann354f60a2006-11-18 22:15:20 +01004094 goto unlock;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03004095 }
Marcel Holtmann354f60a2006-11-18 22:15:20 +01004096
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004097 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07004098 len = cmd_len - sizeof(*req);
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004099 if (chan->conf_len + len > sizeof(chan->conf_req)) {
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004100 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004101 l2cap_build_conf_rsp(chan, rsp,
4102 L2CAP_CONF_REJECT, flags), rsp);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004103 goto unlock;
4104 }
4105
4106 /* Store config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004107 memcpy(chan->conf_req + chan->conf_len, req->data, len);
4108 chan->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004109
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03004110 if (flags & L2CAP_CONF_FLAG_CONTINUATION) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004111 /* Incomplete config. Send empty response. */
4112 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004113 l2cap_build_conf_rsp(chan, rsp,
4114 L2CAP_CONF_SUCCESS, flags), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004115 goto unlock;
4116 }
4117
4118 /* Complete config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004119 len = l2cap_parse_conf_req(chan, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004120 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004121 l2cap_send_disconn_req(chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004122 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004123 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004124
Mat Martineau1500109b2012-10-23 15:24:15 -07004125 chan->ident = cmd->ident;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004126 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004127 chan->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004128
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004129 /* Reset config buffer. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004130 chan->conf_len = 0;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004131
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004132 if (!test_bit(CONF_OUTPUT_DONE, &chan->conf_state))
Marcel Holtmann876d9482007-10-20 13:35:42 +02004133 goto unlock;
4134
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004135 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004136 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004137
Mat Martineau105bdf92012-04-27 16:50:48 -07004138 if (chan->mode == L2CAP_MODE_ERTM ||
4139 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07004140 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03004141
Mat Martineau3c588192012-04-11 10:48:42 -07004142 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004143 l2cap_send_disconn_req(chan, -err);
Mat Martineau3c588192012-04-11 10:48:42 -07004144 else
4145 l2cap_chan_ready(chan);
4146
Marcel Holtmann876d9482007-10-20 13:35:42 +02004147 goto unlock;
4148 }
4149
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004150 if (!test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004151 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004152 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004153 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004154 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004155 }
4156
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004157 /* Got Conf Rsp PENDING from remote side and asume we sent
4158 Conf Rsp PENDING in the code above */
4159 if (test_bit(CONF_REM_CONF_PEND, &chan->conf_state) &&
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03004160 test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004161
4162 /* check compatibility */
4163
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004164 /* Send rsp for BR/EDR channel */
Andrei Emeltchenkof351bc72012-10-31 15:46:35 +02004165 if (!chan->hs_hcon)
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004166 l2cap_send_efs_conf_rsp(chan, rsp, cmd->ident, flags);
4167 else
4168 chan->ident = cmd->ident;
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004169 }
4170
Linus Torvalds1da177e2005-04-16 15:20:36 -07004171unlock:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004172 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07004173 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004174}
4175
Gustavo Padovan2d792812012-10-06 10:07:01 +01004176static inline int l2cap_config_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004177 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4178 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004179{
4180 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
4181 u16 scid, flags, result;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004182 struct l2cap_chan *chan;
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004183 int len = cmd_len - sizeof(*rsp);
Mat Martineau3c588192012-04-11 10:48:42 -07004184 int err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004185
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004186 if (cmd_len < sizeof(*rsp))
4187 return -EPROTO;
4188
Linus Torvalds1da177e2005-04-16 15:20:36 -07004189 scid = __le16_to_cpu(rsp->scid);
4190 flags = __le16_to_cpu(rsp->flags);
4191 result = __le16_to_cpu(rsp->result);
4192
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02004193 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x len %d", scid, flags,
4194 result, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004195
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03004196 chan = l2cap_get_chan_by_scid(conn, scid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004197 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004198 return 0;
4199
4200 switch (result) {
4201 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004202 l2cap_conf_rfc_get(chan, rsp->data, len);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004203 clear_bit(CONF_REM_CONF_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004204 break;
4205
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004206 case L2CAP_CONF_PENDING:
4207 set_bit(CONF_REM_CONF_PEND, &chan->conf_state);
4208
4209 if (test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
4210 char buf[64];
4211
4212 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004213 buf, &result);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004214 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004215 l2cap_send_disconn_req(chan, ECONNRESET);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004216 goto done;
4217 }
4218
Andrei Emeltchenkof351bc72012-10-31 15:46:35 +02004219 if (!chan->hs_hcon) {
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004220 l2cap_send_efs_conf_rsp(chan, buf, cmd->ident,
4221 0);
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +02004222 } else {
4223 if (l2cap_check_efs(chan)) {
4224 amp_create_logical_link(chan);
4225 chan->ident = cmd->ident;
4226 }
4227 }
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004228 }
4229 goto done;
4230
Linus Torvalds1da177e2005-04-16 15:20:36 -07004231 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004232 if (chan->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004233 char req[64];
4234
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02004235 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004236 l2cap_send_disconn_req(chan, ECONNRESET);
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02004237 goto done;
4238 }
4239
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004240 /* throw out any old stored conf requests */
4241 result = L2CAP_CONF_SUCCESS;
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03004242 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004243 req, &result);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004244 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004245 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004246 goto done;
4247 }
4248
4249 l2cap_send_cmd(conn, l2cap_get_ident(conn),
Gustavo Padovan2d792812012-10-06 10:07:01 +01004250 L2CAP_CONF_REQ, len, req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004251 chan->num_conf_req++;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004252 if (result != L2CAP_CONF_SUCCESS)
4253 goto done;
4254 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004255 }
4256
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09004257 default:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004258 l2cap_chan_set_err(chan, ECONNRESET);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02004259
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08004260 __set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004261 l2cap_send_disconn_req(chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004262 goto done;
4263 }
4264
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03004265 if (flags & L2CAP_CONF_FLAG_CONTINUATION)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004266 goto done;
4267
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004268 set_bit(CONF_INPUT_DONE, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004269
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004270 if (test_bit(CONF_OUTPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004271 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004272
Mat Martineau105bdf92012-04-27 16:50:48 -07004273 if (chan->mode == L2CAP_MODE_ERTM ||
4274 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07004275 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03004276
Mat Martineau3c588192012-04-11 10:48:42 -07004277 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004278 l2cap_send_disconn_req(chan, -err);
Mat Martineau3c588192012-04-11 10:48:42 -07004279 else
4280 l2cap_chan_ready(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004281 }
4282
4283done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004284 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07004285 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004286}
4287
Gustavo Padovan2d792812012-10-06 10:07:01 +01004288static inline int l2cap_disconnect_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004289 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4290 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004291{
4292 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
4293 struct l2cap_disconn_rsp rsp;
4294 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004295 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004296
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004297 if (cmd_len != sizeof(*req))
4298 return -EPROTO;
4299
Linus Torvalds1da177e2005-04-16 15:20:36 -07004300 scid = __le16_to_cpu(req->scid);
4301 dcid = __le16_to_cpu(req->dcid);
4302
4303 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
4304
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004305 mutex_lock(&conn->chan_lock);
4306
4307 chan = __l2cap_get_chan_by_scid(conn, dcid);
4308 if (!chan) {
4309 mutex_unlock(&conn->chan_lock);
Johan Hedberg662d6522013-10-16 11:20:47 +03004310 cmd_reject_invalid_cid(conn, cmd->ident, dcid, scid);
4311 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004312 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004313
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004314 l2cap_chan_lock(chan);
4315
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03004316 rsp.dcid = cpu_to_le16(chan->scid);
4317 rsp.scid = cpu_to_le16(chan->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004318 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
4319
Gustavo Padovan5ec1bbe2013-10-15 19:24:48 -03004320 chan->ops->set_shutdown(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004321
Mat Martineau61d6ef32012-04-27 16:50:50 -07004322 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004323 l2cap_chan_del(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004324
4325 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004326
Gustavo Padovan80b98022012-05-27 22:27:51 -03004327 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004328 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004329
4330 mutex_unlock(&conn->chan_lock);
4331
Linus Torvalds1da177e2005-04-16 15:20:36 -07004332 return 0;
4333}
4334
Gustavo Padovan2d792812012-10-06 10:07:01 +01004335static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004336 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4337 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004338{
4339 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
4340 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004341 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004342
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004343 if (cmd_len != sizeof(*rsp))
4344 return -EPROTO;
4345
Linus Torvalds1da177e2005-04-16 15:20:36 -07004346 scid = __le16_to_cpu(rsp->scid);
4347 dcid = __le16_to_cpu(rsp->dcid);
4348
4349 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
4350
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004351 mutex_lock(&conn->chan_lock);
4352
4353 chan = __l2cap_get_chan_by_scid(conn, scid);
4354 if (!chan) {
4355 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004356 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004357 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004358
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004359 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004360
Mat Martineau61d6ef32012-04-27 16:50:50 -07004361 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004362 l2cap_chan_del(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004363
4364 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004365
Gustavo Padovan80b98022012-05-27 22:27:51 -03004366 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004367 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004368
4369 mutex_unlock(&conn->chan_lock);
4370
Linus Torvalds1da177e2005-04-16 15:20:36 -07004371 return 0;
4372}
4373
Gustavo Padovan2d792812012-10-06 10:07:01 +01004374static inline int l2cap_information_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004375 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4376 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004377{
4378 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004379 u16 type;
4380
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004381 if (cmd_len != sizeof(*req))
4382 return -EPROTO;
4383
Linus Torvalds1da177e2005-04-16 15:20:36 -07004384 type = __le16_to_cpu(req->type);
4385
4386 BT_DBG("type 0x%4.4x", type);
4387
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004388 if (type == L2CAP_IT_FEAT_MASK) {
4389 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07004390 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004391 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Joe Perchesdcf4adb2014-03-12 10:52:35 -07004392 rsp->type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
4393 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03004394 if (!disable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004395 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
Gustavo Padovan2d792812012-10-06 10:07:01 +01004396 | L2CAP_FEAT_FCS;
Marcel Holtmann848566b2013-10-01 22:59:22 -07004397 if (conn->hs_enabled)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03004398 feat_mask |= L2CAP_FEAT_EXT_FLOW
Gustavo Padovan2d792812012-10-06 10:07:01 +01004399 | L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03004400
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03004401 put_unaligned_le32(feat_mask, rsp->data);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004402 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4403 buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004404 } else if (type == L2CAP_IT_FIXED_CHAN) {
4405 u8 buf[12];
4406 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Mat Martineau50a147c2011-11-02 16:18:34 -07004407
Marcel Holtmann848566b2013-10-01 22:59:22 -07004408 if (conn->hs_enabled)
Mat Martineau50a147c2011-11-02 16:18:34 -07004409 l2cap_fixed_chan[0] |= L2CAP_FC_A2MP;
4410 else
4411 l2cap_fixed_chan[0] &= ~L2CAP_FC_A2MP;
4412
Joe Perchesdcf4adb2014-03-12 10:52:35 -07004413 rsp->type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
4414 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
Andrei Emeltchenkoc6337ea2011-10-20 17:02:44 +03004415 memcpy(rsp->data, l2cap_fixed_chan, sizeof(l2cap_fixed_chan));
Gustavo Padovan2d792812012-10-06 10:07:01 +01004416 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4417 buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004418 } else {
4419 struct l2cap_info_rsp rsp;
4420 rsp.type = cpu_to_le16(type);
Joe Perchesdcf4adb2014-03-12 10:52:35 -07004421 rsp.result = cpu_to_le16(L2CAP_IR_NOTSUPP);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004422 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(rsp),
4423 &rsp);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004424 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004425
4426 return 0;
4427}
4428
Gustavo Padovan2d792812012-10-06 10:07:01 +01004429static inline int l2cap_information_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004430 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4431 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004432{
4433 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
4434 u16 type, result;
4435
Jaganath Kanakkassery3f6fa3d2013-06-21 19:55:11 +05304436 if (cmd_len < sizeof(*rsp))
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004437 return -EPROTO;
4438
Linus Torvalds1da177e2005-04-16 15:20:36 -07004439 type = __le16_to_cpu(rsp->type);
4440 result = __le16_to_cpu(rsp->result);
4441
4442 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
4443
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004444 /* L2CAP Info req/rsp are unbound to channels, add extra checks */
4445 if (cmd->ident != conn->info_ident ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01004446 conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004447 return 0;
4448
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02004449 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004450
Ville Tervoadb08ed2010-08-04 09:43:33 +03004451 if (result != L2CAP_IR_SUCCESS) {
4452 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4453 conn->info_ident = 0;
4454
4455 l2cap_conn_start(conn);
4456
4457 return 0;
4458 }
4459
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004460 switch (type) {
4461 case L2CAP_IT_FEAT_MASK:
Harvey Harrison83985312008-05-02 16:25:46 -07004462 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004463
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07004464 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004465 struct l2cap_info_req req;
Joe Perchesdcf4adb2014-03-12 10:52:35 -07004466 req.type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004467
4468 conn->info_ident = l2cap_get_ident(conn);
4469
4470 l2cap_send_cmd(conn, conn->info_ident,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004471 L2CAP_INFO_REQ, sizeof(req), &req);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004472 } else {
4473 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4474 conn->info_ident = 0;
4475
4476 l2cap_conn_start(conn);
4477 }
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004478 break;
4479
4480 case L2CAP_IT_FIXED_CHAN:
4481 conn->fixed_chan_mask = rsp->data[0];
Marcel Holtmann984947d2009-02-06 23:35:19 +01004482 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004483 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004484
4485 l2cap_conn_start(conn);
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004486 break;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004487 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004488
Linus Torvalds1da177e2005-04-16 15:20:36 -07004489 return 0;
4490}
4491
Mat Martineau17009152012-10-23 15:24:07 -07004492static int l2cap_create_channel_req(struct l2cap_conn *conn,
4493 struct l2cap_cmd_hdr *cmd,
4494 u16 cmd_len, void *data)
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004495{
4496 struct l2cap_create_chan_req *req = data;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004497 struct l2cap_create_chan_rsp rsp;
Mat Martineau17009152012-10-23 15:24:07 -07004498 struct l2cap_chan *chan;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004499 struct hci_dev *hdev;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004500 u16 psm, scid;
4501
4502 if (cmd_len != sizeof(*req))
4503 return -EPROTO;
4504
Marcel Holtmann848566b2013-10-01 22:59:22 -07004505 if (!conn->hs_enabled)
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004506 return -EINVAL;
4507
4508 psm = le16_to_cpu(req->psm);
4509 scid = le16_to_cpu(req->scid);
4510
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004511 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 -07004512
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004513 /* For controller id 0 make BR/EDR connection */
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004514 if (req->amp_id == AMP_ID_BREDR) {
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004515 l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4516 req->amp_id);
4517 return 0;
4518 }
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004519
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004520 /* Validate AMP controller id */
4521 hdev = hci_dev_get(req->amp_id);
4522 if (!hdev)
4523 goto error;
Mat Martineau17009152012-10-23 15:24:07 -07004524
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004525 if (hdev->dev_type != HCI_AMP || !test_bit(HCI_UP, &hdev->flags)) {
Mat Martineau17009152012-10-23 15:24:07 -07004526 hci_dev_put(hdev);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004527 goto error;
Mat Martineau17009152012-10-23 15:24:07 -07004528 }
4529
4530 chan = l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4531 req->amp_id);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004532 if (chan) {
4533 struct amp_mgr *mgr = conn->hcon->amp_mgr;
4534 struct hci_conn *hs_hcon;
4535
Marcel Holtmann98e0f7e2013-10-13 02:23:40 -07004536 hs_hcon = hci_conn_hash_lookup_ba(hdev, AMP_LINK,
4537 &conn->hcon->dst);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004538 if (!hs_hcon) {
4539 hci_dev_put(hdev);
Johan Hedberg662d6522013-10-16 11:20:47 +03004540 cmd_reject_invalid_cid(conn, cmd->ident, chan->scid,
4541 chan->dcid);
4542 return 0;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004543 }
4544
4545 BT_DBG("mgr %p bredr_chan %p hs_hcon %p", mgr, chan, hs_hcon);
4546
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004547 mgr->bredr_chan = chan;
4548 chan->hs_hcon = hs_hcon;
Andrei Emeltchenkofd45bf42012-11-20 17:16:22 +02004549 chan->fcs = L2CAP_FCS_NONE;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004550 conn->mtu = hdev->block_mtu;
4551 }
4552
4553 hci_dev_put(hdev);
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004554
4555 return 0;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004556
4557error:
4558 rsp.dcid = 0;
4559 rsp.scid = cpu_to_le16(scid);
Joe Perchesdcf4adb2014-03-12 10:52:35 -07004560 rsp.result = cpu_to_le16(L2CAP_CR_BAD_AMP);
4561 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004562
4563 l2cap_send_cmd(conn, cmd->ident, L2CAP_CREATE_CHAN_RSP,
4564 sizeof(rsp), &rsp);
4565
Johan Hedbergdc280802013-09-16 13:05:13 +03004566 return 0;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004567}
4568
Mat Martineau8eb200b2012-10-23 15:24:17 -07004569static void l2cap_send_move_chan_req(struct l2cap_chan *chan, u8 dest_amp_id)
4570{
4571 struct l2cap_move_chan_req req;
4572 u8 ident;
4573
4574 BT_DBG("chan %p, dest_amp_id %d", chan, dest_amp_id);
4575
4576 ident = l2cap_get_ident(chan->conn);
4577 chan->ident = ident;
4578
4579 req.icid = cpu_to_le16(chan->scid);
4580 req.dest_amp_id = dest_amp_id;
4581
4582 l2cap_send_cmd(chan->conn, ident, L2CAP_MOVE_CHAN_REQ, sizeof(req),
4583 &req);
4584
4585 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4586}
4587
Mat Martineau1500109b2012-10-23 15:24:15 -07004588static void l2cap_send_move_chan_rsp(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004589{
4590 struct l2cap_move_chan_rsp rsp;
4591
Mat Martineau1500109b2012-10-23 15:24:15 -07004592 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004593
Mat Martineau1500109b2012-10-23 15:24:15 -07004594 rsp.icid = cpu_to_le16(chan->dcid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004595 rsp.result = cpu_to_le16(result);
4596
Mat Martineau1500109b2012-10-23 15:24:15 -07004597 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_RSP,
4598 sizeof(rsp), &rsp);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004599}
4600
Mat Martineau5b155ef2012-10-23 15:24:14 -07004601static void l2cap_send_move_chan_cfm(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004602{
4603 struct l2cap_move_chan_cfm cfm;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004604
Mat Martineau5b155ef2012-10-23 15:24:14 -07004605 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004606
Mat Martineau5b155ef2012-10-23 15:24:14 -07004607 chan->ident = l2cap_get_ident(chan->conn);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004608
Mat Martineau5b155ef2012-10-23 15:24:14 -07004609 cfm.icid = cpu_to_le16(chan->scid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004610 cfm.result = cpu_to_le16(result);
4611
Mat Martineau5b155ef2012-10-23 15:24:14 -07004612 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_CFM,
4613 sizeof(cfm), &cfm);
4614
4615 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4616}
4617
4618static void l2cap_send_move_chan_cfm_icid(struct l2cap_conn *conn, u16 icid)
4619{
4620 struct l2cap_move_chan_cfm cfm;
4621
4622 BT_DBG("conn %p, icid 0x%4.4x", conn, icid);
4623
4624 cfm.icid = cpu_to_le16(icid);
Joe Perchesdcf4adb2014-03-12 10:52:35 -07004625 cfm.result = cpu_to_le16(L2CAP_MC_UNCONFIRMED);
Mat Martineau5b155ef2012-10-23 15:24:14 -07004626
4627 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_MOVE_CHAN_CFM,
4628 sizeof(cfm), &cfm);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004629}
4630
4631static void l2cap_send_move_chan_cfm_rsp(struct l2cap_conn *conn, u8 ident,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004632 u16 icid)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004633{
4634 struct l2cap_move_chan_cfm_rsp rsp;
4635
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004636 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004637
4638 rsp.icid = cpu_to_le16(icid);
4639 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM_RSP, sizeof(rsp), &rsp);
4640}
4641
Mat Martineau5f3847a2012-10-23 15:24:12 -07004642static void __release_logical_link(struct l2cap_chan *chan)
4643{
4644 chan->hs_hchan = NULL;
4645 chan->hs_hcon = NULL;
4646
4647 /* Placeholder - release the logical link */
4648}
4649
Mat Martineau1500109b2012-10-23 15:24:15 -07004650static void l2cap_logical_fail(struct l2cap_chan *chan)
4651{
4652 /* Logical link setup failed */
4653 if (chan->state != BT_CONNECTED) {
4654 /* Create channel failure, disconnect */
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004655 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineau1500109b2012-10-23 15:24:15 -07004656 return;
4657 }
4658
4659 switch (chan->move_role) {
4660 case L2CAP_MOVE_ROLE_RESPONDER:
4661 l2cap_move_done(chan);
4662 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_SUPP);
4663 break;
4664 case L2CAP_MOVE_ROLE_INITIATOR:
4665 if (chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_COMP ||
4666 chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_CFM) {
4667 /* Remote has only sent pending or
4668 * success responses, clean up
4669 */
4670 l2cap_move_done(chan);
4671 }
4672
4673 /* Other amp move states imply that the move
4674 * has already aborted
4675 */
4676 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4677 break;
4678 }
4679}
4680
4681static void l2cap_logical_finish_create(struct l2cap_chan *chan,
4682 struct hci_chan *hchan)
4683{
4684 struct l2cap_conf_rsp rsp;
Mat Martineau1500109b2012-10-23 15:24:15 -07004685
Andrei Emeltchenko336178a2012-10-31 15:46:27 +02004686 chan->hs_hchan = hchan;
Mat Martineau1500109b2012-10-23 15:24:15 -07004687 chan->hs_hcon->l2cap_data = chan->conn;
4688
Andrei Emeltchenko35ba9562012-10-25 15:20:43 +03004689 l2cap_send_efs_conf_rsp(chan, &rsp, chan->ident, 0);
Mat Martineau1500109b2012-10-23 15:24:15 -07004690
4691 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Andrei Emeltchenkofe79c6f2012-10-25 15:20:42 +03004692 int err;
Mat Martineau1500109b2012-10-23 15:24:15 -07004693
4694 set_default_fcs(chan);
4695
4696 err = l2cap_ertm_init(chan);
4697 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004698 l2cap_send_disconn_req(chan, -err);
Mat Martineau1500109b2012-10-23 15:24:15 -07004699 else
4700 l2cap_chan_ready(chan);
4701 }
4702}
4703
4704static void l2cap_logical_finish_move(struct l2cap_chan *chan,
4705 struct hci_chan *hchan)
4706{
4707 chan->hs_hcon = hchan->conn;
4708 chan->hs_hcon->l2cap_data = chan->conn;
4709
4710 BT_DBG("move_state %d", chan->move_state);
4711
4712 switch (chan->move_state) {
4713 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
4714 /* Move confirm will be sent after a success
4715 * response is received
4716 */
4717 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4718 break;
4719 case L2CAP_MOVE_WAIT_LOGICAL_CFM:
4720 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4721 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4722 } else if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
4723 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
4724 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4725 } else if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
4726 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4727 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
4728 }
4729 break;
4730 default:
4731 /* Move was not in expected state, free the channel */
4732 __release_logical_link(chan);
4733
4734 chan->move_state = L2CAP_MOVE_STABLE;
4735 }
4736}
4737
4738/* Call with chan locked */
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03004739void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan,
4740 u8 status)
Mat Martineau5b155ef2012-10-23 15:24:14 -07004741{
Mat Martineau1500109b2012-10-23 15:24:15 -07004742 BT_DBG("chan %p, hchan %p, status %d", chan, hchan, status);
4743
4744 if (status) {
4745 l2cap_logical_fail(chan);
4746 __release_logical_link(chan);
4747 return;
4748 }
4749
4750 if (chan->state != BT_CONNECTED) {
4751 /* Ignore logical link if channel is on BR/EDR */
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004752 if (chan->local_amp_id != AMP_ID_BREDR)
Mat Martineau1500109b2012-10-23 15:24:15 -07004753 l2cap_logical_finish_create(chan, hchan);
4754 } else {
4755 l2cap_logical_finish_move(chan, hchan);
4756 }
Mat Martineau5b155ef2012-10-23 15:24:14 -07004757}
4758
Mat Martineau3f7a56c2012-10-23 15:24:23 -07004759void l2cap_move_start(struct l2cap_chan *chan)
4760{
4761 BT_DBG("chan %p", chan);
4762
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004763 if (chan->local_amp_id == AMP_ID_BREDR) {
Mat Martineau3f7a56c2012-10-23 15:24:23 -07004764 if (chan->chan_policy != BT_CHANNEL_POLICY_AMP_PREFERRED)
4765 return;
4766 chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
4767 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
4768 /* Placeholder - start physical link setup */
4769 } else {
4770 chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
4771 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4772 chan->move_id = 0;
4773 l2cap_move_setup(chan);
4774 l2cap_send_move_chan_req(chan, 0);
4775 }
4776}
4777
Mat Martineau8eb200b2012-10-23 15:24:17 -07004778static void l2cap_do_create(struct l2cap_chan *chan, int result,
4779 u8 local_amp_id, u8 remote_amp_id)
4780{
Andrei Emeltchenko62748ca2012-11-20 17:16:19 +02004781 BT_DBG("chan %p state %s %u -> %u", chan, state_to_string(chan->state),
4782 local_amp_id, remote_amp_id);
4783
Andrei Emeltchenko12d6cc62012-11-14 17:39:31 +02004784 chan->fcs = L2CAP_FCS_NONE;
4785
Andrei Emeltchenko62748ca2012-11-20 17:16:19 +02004786 /* Outgoing channel on AMP */
4787 if (chan->state == BT_CONNECT) {
4788 if (result == L2CAP_CR_SUCCESS) {
4789 chan->local_amp_id = local_amp_id;
4790 l2cap_send_create_chan_req(chan, remote_amp_id);
4791 } else {
4792 /* Revert to BR/EDR connect */
4793 l2cap_send_conn_req(chan);
4794 }
4795
4796 return;
4797 }
4798
4799 /* Incoming channel on AMP */
4800 if (__l2cap_no_conn_pending(chan)) {
Mat Martineau8eb200b2012-10-23 15:24:17 -07004801 struct l2cap_conn_rsp rsp;
4802 char buf[128];
4803 rsp.scid = cpu_to_le16(chan->dcid);
4804 rsp.dcid = cpu_to_le16(chan->scid);
4805
Mat Martineau8eb200b2012-10-23 15:24:17 -07004806 if (result == L2CAP_CR_SUCCESS) {
4807 /* Send successful response */
Joe Perchesdcf4adb2014-03-12 10:52:35 -07004808 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
4809 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004810 } else {
4811 /* Send negative response */
Joe Perchesdcf4adb2014-03-12 10:52:35 -07004812 rsp.result = cpu_to_le16(L2CAP_CR_NO_MEM);
4813 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004814 }
4815
4816 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_RSP,
4817 sizeof(rsp), &rsp);
4818
4819 if (result == L2CAP_CR_SUCCESS) {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02004820 l2cap_state_change(chan, BT_CONFIG);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004821 set_bit(CONF_REQ_SENT, &chan->conf_state);
4822 l2cap_send_cmd(chan->conn, l2cap_get_ident(chan->conn),
4823 L2CAP_CONF_REQ,
4824 l2cap_build_conf_req(chan, buf), buf);
4825 chan->num_conf_req++;
4826 }
Mat Martineau8eb200b2012-10-23 15:24:17 -07004827 }
4828}
4829
4830static void l2cap_do_move_initiate(struct l2cap_chan *chan, u8 local_amp_id,
4831 u8 remote_amp_id)
4832{
4833 l2cap_move_setup(chan);
4834 chan->move_id = local_amp_id;
4835 chan->move_state = L2CAP_MOVE_WAIT_RSP;
4836
4837 l2cap_send_move_chan_req(chan, remote_amp_id);
4838}
4839
4840static void l2cap_do_move_respond(struct l2cap_chan *chan, int result)
4841{
4842 struct hci_chan *hchan = NULL;
4843
4844 /* Placeholder - get hci_chan for logical link */
4845
4846 if (hchan) {
4847 if (hchan->state == BT_CONNECTED) {
4848 /* Logical link is ready to go */
4849 chan->hs_hcon = hchan->conn;
4850 chan->hs_hcon->l2cap_data = chan->conn;
4851 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4852 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
4853
4854 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
4855 } else {
4856 /* Wait for logical link to be ready */
4857 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4858 }
4859 } else {
4860 /* Logical link not available */
4861 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_ALLOWED);
4862 }
4863}
4864
4865static void l2cap_do_move_cancel(struct l2cap_chan *chan, int result)
4866{
4867 if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
4868 u8 rsp_result;
4869 if (result == -EINVAL)
4870 rsp_result = L2CAP_MR_BAD_ID;
4871 else
4872 rsp_result = L2CAP_MR_NOT_ALLOWED;
4873
4874 l2cap_send_move_chan_rsp(chan, rsp_result);
4875 }
4876
4877 chan->move_role = L2CAP_MOVE_ROLE_NONE;
4878 chan->move_state = L2CAP_MOVE_STABLE;
4879
4880 /* Restart data transmission */
4881 l2cap_ertm_send(chan);
4882}
4883
Andrei Emeltchenkoa514b172012-11-14 17:39:30 +02004884/* Invoke with locked chan */
4885void __l2cap_physical_cfm(struct l2cap_chan *chan, int result)
Mat Martineau8eb200b2012-10-23 15:24:17 -07004886{
Andrei Emeltchenko770bfef2012-10-31 15:46:29 +02004887 u8 local_amp_id = chan->local_amp_id;
Andrei Emeltchenkofffadc02012-11-01 15:37:03 +02004888 u8 remote_amp_id = chan->remote_amp_id;
Andrei Emeltchenko770bfef2012-10-31 15:46:29 +02004889
Mat Martineau8eb200b2012-10-23 15:24:17 -07004890 BT_DBG("chan %p, result %d, local_amp_id %d, remote_amp_id %d",
4891 chan, result, local_amp_id, remote_amp_id);
4892
Mat Martineau8eb200b2012-10-23 15:24:17 -07004893 if (chan->state == BT_DISCONN || chan->state == BT_CLOSED) {
4894 l2cap_chan_unlock(chan);
4895 return;
4896 }
4897
4898 if (chan->state != BT_CONNECTED) {
4899 l2cap_do_create(chan, result, local_amp_id, remote_amp_id);
4900 } else if (result != L2CAP_MR_SUCCESS) {
4901 l2cap_do_move_cancel(chan, result);
4902 } else {
4903 switch (chan->move_role) {
4904 case L2CAP_MOVE_ROLE_INITIATOR:
4905 l2cap_do_move_initiate(chan, local_amp_id,
4906 remote_amp_id);
4907 break;
4908 case L2CAP_MOVE_ROLE_RESPONDER:
4909 l2cap_do_move_respond(chan, result);
4910 break;
4911 default:
4912 l2cap_do_move_cancel(chan, result);
4913 break;
4914 }
4915 }
Mat Martineau8eb200b2012-10-23 15:24:17 -07004916}
4917
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004918static inline int l2cap_move_channel_req(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004919 struct l2cap_cmd_hdr *cmd,
4920 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004921{
4922 struct l2cap_move_chan_req *req = data;
Mat Martineau1500109b2012-10-23 15:24:15 -07004923 struct l2cap_move_chan_rsp rsp;
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004924 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004925 u16 icid = 0;
4926 u16 result = L2CAP_MR_NOT_ALLOWED;
4927
4928 if (cmd_len != sizeof(*req))
4929 return -EPROTO;
4930
4931 icid = le16_to_cpu(req->icid);
4932
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004933 BT_DBG("icid 0x%4.4x, dest_amp_id %d", icid, req->dest_amp_id);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004934
Marcel Holtmann848566b2013-10-01 22:59:22 -07004935 if (!conn->hs_enabled)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004936 return -EINVAL;
4937
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004938 chan = l2cap_get_chan_by_dcid(conn, icid);
4939 if (!chan) {
Mat Martineau1500109b2012-10-23 15:24:15 -07004940 rsp.icid = cpu_to_le16(icid);
Joe Perchesdcf4adb2014-03-12 10:52:35 -07004941 rsp.result = cpu_to_le16(L2CAP_MR_NOT_ALLOWED);
Mat Martineau1500109b2012-10-23 15:24:15 -07004942 l2cap_send_cmd(conn, cmd->ident, L2CAP_MOVE_CHAN_RSP,
4943 sizeof(rsp), &rsp);
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004944 return 0;
4945 }
4946
Mat Martineau1500109b2012-10-23 15:24:15 -07004947 chan->ident = cmd->ident;
4948
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004949 if (chan->scid < L2CAP_CID_DYN_START ||
4950 chan->chan_policy == BT_CHANNEL_POLICY_BREDR_ONLY ||
4951 (chan->mode != L2CAP_MODE_ERTM &&
4952 chan->mode != L2CAP_MODE_STREAMING)) {
4953 result = L2CAP_MR_NOT_ALLOWED;
4954 goto send_move_response;
4955 }
4956
4957 if (chan->local_amp_id == req->dest_amp_id) {
4958 result = L2CAP_MR_SAME_ID;
4959 goto send_move_response;
4960 }
4961
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004962 if (req->dest_amp_id != AMP_ID_BREDR) {
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004963 struct hci_dev *hdev;
4964 hdev = hci_dev_get(req->dest_amp_id);
4965 if (!hdev || hdev->dev_type != HCI_AMP ||
4966 !test_bit(HCI_UP, &hdev->flags)) {
4967 if (hdev)
4968 hci_dev_put(hdev);
4969
4970 result = L2CAP_MR_BAD_ID;
4971 goto send_move_response;
4972 }
4973 hci_dev_put(hdev);
4974 }
4975
4976 /* Detect a move collision. Only send a collision response
4977 * if this side has "lost", otherwise proceed with the move.
4978 * The winner has the larger bd_addr.
4979 */
4980 if ((__chan_is_moving(chan) ||
4981 chan->move_role != L2CAP_MOVE_ROLE_NONE) &&
Marcel Holtmann6f59b902013-10-13 05:24:01 -07004982 bacmp(&conn->hcon->src, &conn->hcon->dst) > 0) {
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004983 result = L2CAP_MR_COLLISION;
4984 goto send_move_response;
4985 }
4986
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004987 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
4988 l2cap_move_setup(chan);
4989 chan->move_id = req->dest_amp_id;
4990 icid = chan->dcid;
4991
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004992 if (req->dest_amp_id == AMP_ID_BREDR) {
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004993 /* Moving to BR/EDR */
4994 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4995 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4996 result = L2CAP_MR_PEND;
4997 } else {
4998 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4999 result = L2CAP_MR_SUCCESS;
5000 }
5001 } else {
5002 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
5003 /* Placeholder - uncomment when amp functions are available */
5004 /*amp_accept_physical(chan, req->dest_amp_id);*/
5005 result = L2CAP_MR_PEND;
5006 }
5007
5008send_move_response:
Mat Martineau1500109b2012-10-23 15:24:15 -07005009 l2cap_send_move_chan_rsp(chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005010
Mat Martineau02b0fbb2012-10-23 15:24:10 -07005011 l2cap_chan_unlock(chan);
5012
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005013 return 0;
5014}
5015
Mat Martineau5b155ef2012-10-23 15:24:14 -07005016static void l2cap_move_continue(struct l2cap_conn *conn, u16 icid, u16 result)
5017{
5018 struct l2cap_chan *chan;
5019 struct hci_chan *hchan = NULL;
5020
5021 chan = l2cap_get_chan_by_scid(conn, icid);
5022 if (!chan) {
5023 l2cap_send_move_chan_cfm_icid(conn, icid);
5024 return;
5025 }
5026
5027 __clear_chan_timer(chan);
5028 if (result == L2CAP_MR_PEND)
5029 __set_chan_timer(chan, L2CAP_MOVE_ERTX_TIMEOUT);
5030
5031 switch (chan->move_state) {
5032 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
5033 /* Move confirm will be sent when logical link
5034 * is complete.
5035 */
5036 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
5037 break;
5038 case L2CAP_MOVE_WAIT_RSP_SUCCESS:
5039 if (result == L2CAP_MR_PEND) {
5040 break;
5041 } else if (test_bit(CONN_LOCAL_BUSY,
5042 &chan->conn_state)) {
5043 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
5044 } else {
5045 /* Logical link is up or moving to BR/EDR,
5046 * proceed with move
5047 */
5048 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
5049 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
5050 }
5051 break;
5052 case L2CAP_MOVE_WAIT_RSP:
5053 /* Moving to AMP */
5054 if (result == L2CAP_MR_SUCCESS) {
5055 /* Remote is ready, send confirm immediately
5056 * after logical link is ready
5057 */
5058 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
5059 } else {
5060 /* Both logical link and move success
5061 * are required to confirm
5062 */
5063 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_COMP;
5064 }
5065
5066 /* Placeholder - get hci_chan for logical link */
5067 if (!hchan) {
5068 /* Logical link not available */
5069 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
5070 break;
5071 }
5072
5073 /* If the logical link is not yet connected, do not
5074 * send confirmation.
5075 */
5076 if (hchan->state != BT_CONNECTED)
5077 break;
5078
5079 /* Logical link is already ready to go */
5080
5081 chan->hs_hcon = hchan->conn;
5082 chan->hs_hcon->l2cap_data = chan->conn;
5083
5084 if (result == L2CAP_MR_SUCCESS) {
5085 /* Can confirm now */
5086 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
5087 } else {
5088 /* Now only need move success
5089 * to confirm
5090 */
5091 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
5092 }
5093
5094 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
5095 break;
5096 default:
5097 /* Any other amp move state means the move failed. */
5098 chan->move_id = chan->local_amp_id;
5099 l2cap_move_done(chan);
5100 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
5101 }
5102
5103 l2cap_chan_unlock(chan);
5104}
5105
5106static void l2cap_move_fail(struct l2cap_conn *conn, u8 ident, u16 icid,
5107 u16 result)
5108{
5109 struct l2cap_chan *chan;
5110
5111 chan = l2cap_get_chan_by_ident(conn, ident);
5112 if (!chan) {
5113 /* Could not locate channel, icid is best guess */
5114 l2cap_send_move_chan_cfm_icid(conn, icid);
5115 return;
5116 }
5117
5118 __clear_chan_timer(chan);
5119
5120 if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
5121 if (result == L2CAP_MR_COLLISION) {
5122 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
5123 } else {
5124 /* Cleanup - cancel move */
5125 chan->move_id = chan->local_amp_id;
5126 l2cap_move_done(chan);
5127 }
5128 }
5129
5130 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
5131
5132 l2cap_chan_unlock(chan);
5133}
5134
5135static int l2cap_move_channel_rsp(struct l2cap_conn *conn,
5136 struct l2cap_cmd_hdr *cmd,
5137 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005138{
5139 struct l2cap_move_chan_rsp *rsp = data;
5140 u16 icid, result;
5141
5142 if (cmd_len != sizeof(*rsp))
5143 return -EPROTO;
5144
5145 icid = le16_to_cpu(rsp->icid);
5146 result = le16_to_cpu(rsp->result);
5147
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005148 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005149
Mat Martineau5b155ef2012-10-23 15:24:14 -07005150 if (result == L2CAP_MR_SUCCESS || result == L2CAP_MR_PEND)
5151 l2cap_move_continue(conn, icid, result);
5152 else
5153 l2cap_move_fail(conn, cmd->ident, icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005154
5155 return 0;
5156}
5157
Mat Martineau5f3847a2012-10-23 15:24:12 -07005158static int l2cap_move_channel_confirm(struct l2cap_conn *conn,
5159 struct l2cap_cmd_hdr *cmd,
5160 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005161{
5162 struct l2cap_move_chan_cfm *cfm = data;
Mat Martineau5f3847a2012-10-23 15:24:12 -07005163 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005164 u16 icid, result;
5165
5166 if (cmd_len != sizeof(*cfm))
5167 return -EPROTO;
5168
5169 icid = le16_to_cpu(cfm->icid);
5170 result = le16_to_cpu(cfm->result);
5171
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005172 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005173
Mat Martineau5f3847a2012-10-23 15:24:12 -07005174 chan = l2cap_get_chan_by_dcid(conn, icid);
5175 if (!chan) {
5176 /* Spec requires a response even if the icid was not found */
5177 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
5178 return 0;
5179 }
5180
5181 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM) {
5182 if (result == L2CAP_MC_CONFIRMED) {
5183 chan->local_amp_id = chan->move_id;
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07005184 if (chan->local_amp_id == AMP_ID_BREDR)
Mat Martineau5f3847a2012-10-23 15:24:12 -07005185 __release_logical_link(chan);
5186 } else {
5187 chan->move_id = chan->local_amp_id;
5188 }
5189
5190 l2cap_move_done(chan);
5191 }
5192
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005193 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
5194
Mat Martineau5f3847a2012-10-23 15:24:12 -07005195 l2cap_chan_unlock(chan);
5196
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005197 return 0;
5198}
5199
5200static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005201 struct l2cap_cmd_hdr *cmd,
5202 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005203{
5204 struct l2cap_move_chan_cfm_rsp *rsp = data;
Mat Martineau3fd71a02012-10-23 15:24:16 -07005205 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005206 u16 icid;
5207
5208 if (cmd_len != sizeof(*rsp))
5209 return -EPROTO;
5210
5211 icid = le16_to_cpu(rsp->icid);
5212
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005213 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005214
Mat Martineau3fd71a02012-10-23 15:24:16 -07005215 chan = l2cap_get_chan_by_scid(conn, icid);
5216 if (!chan)
5217 return 0;
5218
5219 __clear_chan_timer(chan);
5220
5221 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM_RSP) {
5222 chan->local_amp_id = chan->move_id;
5223
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07005224 if (chan->local_amp_id == AMP_ID_BREDR && chan->hs_hchan)
Mat Martineau3fd71a02012-10-23 15:24:16 -07005225 __release_logical_link(chan);
5226
5227 l2cap_move_done(chan);
5228 }
5229
5230 l2cap_chan_unlock(chan);
5231
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005232 return 0;
5233}
5234
Claudio Takahaside731152011-02-11 19:28:55 -02005235static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005236 struct l2cap_cmd_hdr *cmd,
Johan Hedberg203e6392013-05-15 10:07:15 +03005237 u16 cmd_len, u8 *data)
Claudio Takahaside731152011-02-11 19:28:55 -02005238{
5239 struct hci_conn *hcon = conn->hcon;
5240 struct l2cap_conn_param_update_req *req;
5241 struct l2cap_conn_param_update_rsp rsp;
Johan Hedberg203e6392013-05-15 10:07:15 +03005242 u16 min, max, latency, to_multiplier;
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005243 int err;
Claudio Takahaside731152011-02-11 19:28:55 -02005244
Johan Hedberg40bef302014-07-16 11:42:27 +03005245 if (hcon->role != HCI_ROLE_MASTER)
Claudio Takahaside731152011-02-11 19:28:55 -02005246 return -EINVAL;
5247
Claudio Takahaside731152011-02-11 19:28:55 -02005248 if (cmd_len != sizeof(struct l2cap_conn_param_update_req))
5249 return -EPROTO;
5250
5251 req = (struct l2cap_conn_param_update_req *) data;
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03005252 min = __le16_to_cpu(req->min);
5253 max = __le16_to_cpu(req->max);
Claudio Takahaside731152011-02-11 19:28:55 -02005254 latency = __le16_to_cpu(req->latency);
5255 to_multiplier = __le16_to_cpu(req->to_multiplier);
5256
5257 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 +01005258 min, max, latency, to_multiplier);
Claudio Takahaside731152011-02-11 19:28:55 -02005259
5260 memset(&rsp, 0, sizeof(rsp));
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005261
Andre Guedesd4905f22014-06-25 21:52:52 -03005262 err = hci_check_conn_params(min, max, latency, to_multiplier);
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005263 if (err)
Joe Perchesdcf4adb2014-03-12 10:52:35 -07005264 rsp.result = cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
Claudio Takahaside731152011-02-11 19:28:55 -02005265 else
Joe Perchesdcf4adb2014-03-12 10:52:35 -07005266 rsp.result = cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED);
Claudio Takahaside731152011-02-11 19:28:55 -02005267
5268 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005269 sizeof(rsp), &rsp);
Claudio Takahaside731152011-02-11 19:28:55 -02005270
Andre Guedesffb5a8272014-07-01 18:10:11 -03005271 if (!err) {
Johan Hedbergf4869e22014-07-02 17:37:32 +03005272 u8 store_hint;
Andre Guedesffb5a8272014-07-01 18:10:11 -03005273
Johan Hedbergf4869e22014-07-02 17:37:32 +03005274 store_hint = hci_le_conn_update(hcon, min, max, latency,
5275 to_multiplier);
5276 mgmt_new_conn_param(hcon->hdev, &hcon->dst, hcon->dst_type,
5277 store_hint, min, max, latency,
5278 to_multiplier);
5279
Andre Guedesffb5a8272014-07-01 18:10:11 -03005280 }
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005281
Claudio Takahaside731152011-02-11 19:28:55 -02005282 return 0;
5283}
5284
Johan Hedbergf1496de2013-05-13 14:15:56 +03005285static int l2cap_le_connect_rsp(struct l2cap_conn *conn,
5286 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5287 u8 *data)
5288{
5289 struct l2cap_le_conn_rsp *rsp = (struct l2cap_le_conn_rsp *) data;
5290 u16 dcid, mtu, mps, credits, result;
5291 struct l2cap_chan *chan;
5292 int err;
5293
5294 if (cmd_len < sizeof(*rsp))
5295 return -EPROTO;
5296
5297 dcid = __le16_to_cpu(rsp->dcid);
5298 mtu = __le16_to_cpu(rsp->mtu);
5299 mps = __le16_to_cpu(rsp->mps);
5300 credits = __le16_to_cpu(rsp->credits);
5301 result = __le16_to_cpu(rsp->result);
5302
5303 if (result == L2CAP_CR_SUCCESS && (mtu < 23 || mps < 23))
5304 return -EPROTO;
5305
5306 BT_DBG("dcid 0x%4.4x mtu %u mps %u credits %u result 0x%2.2x",
5307 dcid, mtu, mps, credits, result);
5308
5309 mutex_lock(&conn->chan_lock);
5310
5311 chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
5312 if (!chan) {
5313 err = -EBADSLT;
5314 goto unlock;
5315 }
5316
5317 err = 0;
5318
5319 l2cap_chan_lock(chan);
5320
5321 switch (result) {
5322 case L2CAP_CR_SUCCESS:
5323 chan->ident = 0;
5324 chan->dcid = dcid;
5325 chan->omtu = mtu;
5326 chan->remote_mps = mps;
Johan Hedberg0cd75f72013-05-17 13:09:05 +03005327 chan->tx_credits = credits;
Johan Hedbergf1496de2013-05-13 14:15:56 +03005328 l2cap_chan_ready(chan);
5329 break;
5330
5331 default:
5332 l2cap_chan_del(chan, ECONNREFUSED);
5333 break;
5334 }
5335
5336 l2cap_chan_unlock(chan);
5337
5338unlock:
5339 mutex_unlock(&conn->chan_lock);
5340
5341 return err;
5342}
5343
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005344static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005345 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5346 u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005347{
5348 int err = 0;
5349
5350 switch (cmd->code) {
5351 case L2CAP_COMMAND_REJ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005352 l2cap_command_rej(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005353 break;
5354
5355 case L2CAP_CONN_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005356 err = l2cap_connect_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005357 break;
5358
5359 case L2CAP_CONN_RSP:
Mat Martineauf5a25982012-10-11 17:48:21 +03005360 case L2CAP_CREATE_CHAN_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005361 l2cap_connect_create_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005362 break;
5363
5364 case L2CAP_CONF_REQ:
5365 err = l2cap_config_req(conn, cmd, cmd_len, data);
5366 break;
5367
5368 case L2CAP_CONF_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005369 l2cap_config_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005370 break;
5371
5372 case L2CAP_DISCONN_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005373 err = l2cap_disconnect_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005374 break;
5375
5376 case L2CAP_DISCONN_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005377 l2cap_disconnect_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005378 break;
5379
5380 case L2CAP_ECHO_REQ:
5381 l2cap_send_cmd(conn, cmd->ident, L2CAP_ECHO_RSP, cmd_len, data);
5382 break;
5383
5384 case L2CAP_ECHO_RSP:
5385 break;
5386
5387 case L2CAP_INFO_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005388 err = l2cap_information_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005389 break;
5390
5391 case L2CAP_INFO_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005392 l2cap_information_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005393 break;
5394
Mat Martineauf94ff6f2011-11-02 16:18:32 -07005395 case L2CAP_CREATE_CHAN_REQ:
5396 err = l2cap_create_channel_req(conn, cmd, cmd_len, data);
5397 break;
5398
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005399 case L2CAP_MOVE_CHAN_REQ:
5400 err = l2cap_move_channel_req(conn, cmd, cmd_len, data);
5401 break;
5402
5403 case L2CAP_MOVE_CHAN_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005404 l2cap_move_channel_rsp(conn, cmd, cmd_len, data);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005405 break;
5406
5407 case L2CAP_MOVE_CHAN_CFM:
5408 err = l2cap_move_channel_confirm(conn, cmd, cmd_len, data);
5409 break;
5410
5411 case L2CAP_MOVE_CHAN_CFM_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005412 l2cap_move_channel_confirm_rsp(conn, cmd, cmd_len, data);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005413 break;
5414
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005415 default:
5416 BT_ERR("Unknown BR/EDR signaling command 0x%2.2x", cmd->code);
5417 err = -EINVAL;
5418 break;
5419 }
5420
5421 return err;
5422}
5423
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005424static int l2cap_le_connect_req(struct l2cap_conn *conn,
5425 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5426 u8 *data)
5427{
5428 struct l2cap_le_conn_req *req = (struct l2cap_le_conn_req *) data;
5429 struct l2cap_le_conn_rsp rsp;
5430 struct l2cap_chan *chan, *pchan;
Johan Hedberg0cd75f72013-05-17 13:09:05 +03005431 u16 dcid, scid, credits, mtu, mps;
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005432 __le16 psm;
5433 u8 result;
5434
5435 if (cmd_len != sizeof(*req))
5436 return -EPROTO;
5437
5438 scid = __le16_to_cpu(req->scid);
5439 mtu = __le16_to_cpu(req->mtu);
5440 mps = __le16_to_cpu(req->mps);
5441 psm = req->psm;
5442 dcid = 0;
Johan Hedberg0cd75f72013-05-17 13:09:05 +03005443 credits = 0;
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005444
5445 if (mtu < 23 || mps < 23)
5446 return -EPROTO;
5447
5448 BT_DBG("psm 0x%2.2x scid 0x%4.4x mtu %u mps %u", __le16_to_cpu(psm),
5449 scid, mtu, mps);
5450
5451 /* Check if we have socket listening on psm */
5452 pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, &conn->hcon->src,
5453 &conn->hcon->dst, LE_LINK);
5454 if (!pchan) {
5455 result = L2CAP_CR_BAD_PSM;
5456 chan = NULL;
5457 goto response;
5458 }
5459
5460 mutex_lock(&conn->chan_lock);
5461 l2cap_chan_lock(pchan);
5462
5463 if (!smp_sufficient_security(conn->hcon, pchan->sec_level)) {
5464 result = L2CAP_CR_AUTHENTICATION;
5465 chan = NULL;
5466 goto response_unlock;
5467 }
5468
5469 /* Check if we already have channel with that dcid */
5470 if (__l2cap_get_chan_by_dcid(conn, scid)) {
5471 result = L2CAP_CR_NO_MEM;
5472 chan = NULL;
5473 goto response_unlock;
5474 }
5475
5476 chan = pchan->ops->new_connection(pchan);
5477 if (!chan) {
5478 result = L2CAP_CR_NO_MEM;
5479 goto response_unlock;
5480 }
5481
Johan Hedberg0ce43ce2013-12-05 14:55:33 +02005482 l2cap_le_flowctl_init(chan);
5483
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005484 bacpy(&chan->src, &conn->hcon->src);
5485 bacpy(&chan->dst, &conn->hcon->dst);
5486 chan->src_type = bdaddr_type(conn->hcon, conn->hcon->src_type);
5487 chan->dst_type = bdaddr_type(conn->hcon, conn->hcon->dst_type);
5488 chan->psm = psm;
5489 chan->dcid = scid;
5490 chan->omtu = mtu;
5491 chan->remote_mps = mps;
Johan Hedberg0cd75f72013-05-17 13:09:05 +03005492 chan->tx_credits = __le16_to_cpu(req->credits);
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005493
5494 __l2cap_chan_add(conn, chan);
5495 dcid = chan->scid;
Johan Hedberg0cd75f72013-05-17 13:09:05 +03005496 credits = chan->rx_credits;
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005497
5498 __set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
5499
5500 chan->ident = cmd->ident;
5501
5502 if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
5503 l2cap_state_change(chan, BT_CONNECT2);
5504 result = L2CAP_CR_PEND;
5505 chan->ops->defer(chan);
5506 } else {
5507 l2cap_chan_ready(chan);
5508 result = L2CAP_CR_SUCCESS;
5509 }
5510
5511response_unlock:
5512 l2cap_chan_unlock(pchan);
5513 mutex_unlock(&conn->chan_lock);
Johan Hedberga24cce12014-08-07 22:56:42 +03005514 l2cap_chan_put(pchan);
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005515
5516 if (result == L2CAP_CR_PEND)
5517 return 0;
5518
5519response:
5520 if (chan) {
5521 rsp.mtu = cpu_to_le16(chan->imtu);
Johan Hedberg3916aed2013-10-07 15:35:26 +02005522 rsp.mps = cpu_to_le16(chan->mps);
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005523 } else {
5524 rsp.mtu = 0;
5525 rsp.mps = 0;
5526 }
5527
5528 rsp.dcid = cpu_to_le16(dcid);
Johan Hedberg0cd75f72013-05-17 13:09:05 +03005529 rsp.credits = cpu_to_le16(credits);
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005530 rsp.result = cpu_to_le16(result);
5531
5532 l2cap_send_cmd(conn, cmd->ident, L2CAP_LE_CONN_RSP, sizeof(rsp), &rsp);
5533
5534 return 0;
5535}
5536
Johan Hedbergfad5fc892013-12-05 09:45:01 +02005537static inline int l2cap_le_credits(struct l2cap_conn *conn,
5538 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5539 u8 *data)
5540{
5541 struct l2cap_le_credits *pkt;
5542 struct l2cap_chan *chan;
Johan Hedberg0f1bfe42014-01-27 15:11:35 -08005543 u16 cid, credits, max_credits;
Johan Hedbergfad5fc892013-12-05 09:45:01 +02005544
5545 if (cmd_len != sizeof(*pkt))
5546 return -EPROTO;
5547
5548 pkt = (struct l2cap_le_credits *) data;
5549 cid = __le16_to_cpu(pkt->cid);
5550 credits = __le16_to_cpu(pkt->credits);
5551
5552 BT_DBG("cid 0x%4.4x credits 0x%4.4x", cid, credits);
5553
5554 chan = l2cap_get_chan_by_dcid(conn, cid);
5555 if (!chan)
5556 return -EBADSLT;
5557
Johan Hedberg0f1bfe42014-01-27 15:11:35 -08005558 max_credits = LE_FLOWCTL_MAX_CREDITS - chan->tx_credits;
5559 if (credits > max_credits) {
5560 BT_ERR("LE credits overflow");
5561 l2cap_send_disconn_req(chan, ECONNRESET);
5562
5563 /* Return 0 so that we don't trigger an unnecessary
5564 * command reject packet.
5565 */
5566 return 0;
5567 }
5568
Johan Hedbergfad5fc892013-12-05 09:45:01 +02005569 chan->tx_credits += credits;
5570
5571 while (chan->tx_credits && !skb_queue_empty(&chan->tx_q)) {
5572 l2cap_do_send(chan, skb_dequeue(&chan->tx_q));
5573 chan->tx_credits--;
5574 }
5575
5576 if (chan->tx_credits)
5577 chan->ops->resume(chan);
5578
5579 l2cap_chan_unlock(chan);
5580
5581 return 0;
5582}
5583
Johan Hedberg71fb4192013-12-10 10:52:48 +02005584static inline int l2cap_le_command_rej(struct l2cap_conn *conn,
5585 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5586 u8 *data)
5587{
5588 struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data;
5589 struct l2cap_chan *chan;
5590
5591 if (cmd_len < sizeof(*rej))
5592 return -EPROTO;
5593
5594 mutex_lock(&conn->chan_lock);
5595
5596 chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
5597 if (!chan)
5598 goto done;
5599
5600 l2cap_chan_lock(chan);
5601 l2cap_chan_del(chan, ECONNREFUSED);
5602 l2cap_chan_unlock(chan);
5603
5604done:
5605 mutex_unlock(&conn->chan_lock);
5606 return 0;
5607}
5608
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005609static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn,
Johan Hedberg203e6392013-05-15 10:07:15 +03005610 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5611 u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005612{
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005613 int err = 0;
5614
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005615 switch (cmd->code) {
5616 case L2CAP_COMMAND_REJ:
Johan Hedberg71fb4192013-12-10 10:52:48 +02005617 l2cap_le_command_rej(conn, cmd, cmd_len, data);
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005618 break;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005619
5620 case L2CAP_CONN_PARAM_UPDATE_REQ:
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005621 err = l2cap_conn_param_update_req(conn, cmd, cmd_len, data);
5622 break;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005623
5624 case L2CAP_CONN_PARAM_UPDATE_RSP:
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005625 break;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005626
Johan Hedbergf1496de2013-05-13 14:15:56 +03005627 case L2CAP_LE_CONN_RSP:
5628 l2cap_le_connect_rsp(conn, cmd, cmd_len, data);
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005629 break;
Johan Hedbergf1496de2013-05-13 14:15:56 +03005630
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005631 case L2CAP_LE_CONN_REQ:
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005632 err = l2cap_le_connect_req(conn, cmd, cmd_len, data);
5633 break;
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005634
Johan Hedbergfad5fc892013-12-05 09:45:01 +02005635 case L2CAP_LE_CREDITS:
5636 err = l2cap_le_credits(conn, cmd, cmd_len, data);
5637 break;
5638
Johan Hedberg3defe012013-05-15 10:16:06 +03005639 case L2CAP_DISCONN_REQ:
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005640 err = l2cap_disconnect_req(conn, cmd, cmd_len, data);
5641 break;
Johan Hedberg3defe012013-05-15 10:16:06 +03005642
5643 case L2CAP_DISCONN_RSP:
5644 l2cap_disconnect_rsp(conn, cmd, cmd_len, data);
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005645 break;
Johan Hedberg3defe012013-05-15 10:16:06 +03005646
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005647 default:
5648 BT_ERR("Unknown LE signaling command 0x%2.2x", cmd->code);
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005649 err = -EINVAL;
5650 break;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005651 }
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005652
5653 return err;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005654}
5655
Johan Hedbergc5623552013-04-29 19:35:33 +03005656static inline void l2cap_le_sig_channel(struct l2cap_conn *conn,
5657 struct sk_buff *skb)
5658{
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005659 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005660 struct l2cap_cmd_hdr *cmd;
5661 u16 len;
Johan Hedbergc5623552013-04-29 19:35:33 +03005662 int err;
5663
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005664 if (hcon->type != LE_LINK)
Marcel Holtmann3b166292013-10-02 08:28:21 -07005665 goto drop;
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005666
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005667 if (skb->len < L2CAP_CMD_HDR_SIZE)
5668 goto drop;
Johan Hedbergc5623552013-04-29 19:35:33 +03005669
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005670 cmd = (void *) skb->data;
5671 skb_pull(skb, L2CAP_CMD_HDR_SIZE);
Johan Hedbergc5623552013-04-29 19:35:33 +03005672
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005673 len = le16_to_cpu(cmd->len);
Johan Hedbergc5623552013-04-29 19:35:33 +03005674
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005675 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd->code, len, cmd->ident);
Johan Hedbergc5623552013-04-29 19:35:33 +03005676
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005677 if (len != skb->len || !cmd->ident) {
5678 BT_DBG("corrupted command");
5679 goto drop;
5680 }
Johan Hedbergc5623552013-04-29 19:35:33 +03005681
Johan Hedberg203e6392013-05-15 10:07:15 +03005682 err = l2cap_le_sig_cmd(conn, cmd, len, skb->data);
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005683 if (err) {
5684 struct l2cap_cmd_rej_unk rej;
Johan Hedbergc5623552013-04-29 19:35:33 +03005685
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005686 BT_ERR("Wrong link type (%d)", err);
Johan Hedbergc5623552013-04-29 19:35:33 +03005687
Joe Perchesdcf4adb2014-03-12 10:52:35 -07005688 rej.reason = cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005689 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
5690 sizeof(rej), &rej);
Johan Hedbergc5623552013-04-29 19:35:33 +03005691 }
5692
Marcel Holtmann3b166292013-10-02 08:28:21 -07005693drop:
Johan Hedbergc5623552013-04-29 19:35:33 +03005694 kfree_skb(skb);
5695}
5696
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005697static inline void l2cap_sig_channel(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005698 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005699{
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005700 struct hci_conn *hcon = conn->hcon;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005701 u8 *data = skb->data;
5702 int len = skb->len;
5703 struct l2cap_cmd_hdr cmd;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005704 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005705
5706 l2cap_raw_recv(conn, skb);
5707
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005708 if (hcon->type != ACL_LINK)
Marcel Holtmann3b166292013-10-02 08:28:21 -07005709 goto drop;
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005710
Linus Torvalds1da177e2005-04-16 15:20:36 -07005711 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07005712 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005713 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
5714 data += L2CAP_CMD_HDR_SIZE;
5715 len -= L2CAP_CMD_HDR_SIZE;
5716
Al Viro88219a02007-07-29 00:17:25 -07005717 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005718
Gustavo Padovan2d792812012-10-06 10:07:01 +01005719 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len,
5720 cmd.ident);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005721
Al Viro88219a02007-07-29 00:17:25 -07005722 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005723 BT_DBG("corrupted command");
5724 break;
5725 }
5726
Johan Hedbergc5623552013-04-29 19:35:33 +03005727 err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005728 if (err) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03005729 struct l2cap_cmd_rej_unk rej;
Gustavo F. Padovan2c6d1a22011-03-23 14:38:32 -03005730
5731 BT_ERR("Wrong link type (%d)", err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005732
Joe Perchesdcf4adb2014-03-12 10:52:35 -07005733 rej.reason = cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
Gustavo Padovan2d792812012-10-06 10:07:01 +01005734 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ,
5735 sizeof(rej), &rej);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005736 }
5737
Al Viro88219a02007-07-29 00:17:25 -07005738 data += cmd_len;
5739 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005740 }
5741
Marcel Holtmann3b166292013-10-02 08:28:21 -07005742drop:
Linus Torvalds1da177e2005-04-16 15:20:36 -07005743 kfree_skb(skb);
5744}
5745
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005746static int l2cap_check_fcs(struct l2cap_chan *chan, struct sk_buff *skb)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005747{
5748 u16 our_fcs, rcv_fcs;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03005749 int hdr_size;
5750
5751 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
5752 hdr_size = L2CAP_EXT_HDR_SIZE;
5753 else
5754 hdr_size = L2CAP_ENH_HDR_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005755
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005756 if (chan->fcs == L2CAP_FCS_CRC16) {
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005757 skb_trim(skb, skb->len - L2CAP_FCS_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005758 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
5759 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
5760
5761 if (our_fcs != rcv_fcs)
João Paulo Rechi Vita7a560e52010-06-22 13:56:27 -03005762 return -EBADMSG;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005763 }
5764 return 0;
5765}
5766
Mat Martineau6ea00482012-05-17 20:53:52 -07005767static void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan)
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005768{
Mat Martineaue31f7632012-05-17 20:53:41 -07005769 struct l2cap_ctrl control;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005770
Mat Martineaue31f7632012-05-17 20:53:41 -07005771 BT_DBG("chan %p", chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005772
Mat Martineaue31f7632012-05-17 20:53:41 -07005773 memset(&control, 0, sizeof(control));
5774 control.sframe = 1;
5775 control.final = 1;
5776 control.reqseq = chan->buffer_seq;
5777 set_bit(CONN_SEND_FBIT, &chan->conn_state);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005778
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03005779 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
Mat Martineaue31f7632012-05-17 20:53:41 -07005780 control.super = L2CAP_SUPER_RNR;
5781 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005782 }
5783
Mat Martineaue31f7632012-05-17 20:53:41 -07005784 if (test_and_clear_bit(CONN_REMOTE_BUSY, &chan->conn_state) &&
5785 chan->unacked_frames > 0)
5786 __set_retrans_timer(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005787
Mat Martineaue31f7632012-05-17 20:53:41 -07005788 /* Send pending iframes */
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03005789 l2cap_ertm_send(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005790
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03005791 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
Mat Martineaue31f7632012-05-17 20:53:41 -07005792 test_bit(CONN_SEND_FBIT, &chan->conn_state)) {
5793 /* F-bit wasn't sent in an s-frame or i-frame yet, so
5794 * send it now.
5795 */
5796 control.super = L2CAP_SUPER_RR;
5797 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005798 }
5799}
5800
Gustavo Padovan2d792812012-10-06 10:07:01 +01005801static void append_skb_frag(struct sk_buff *skb, struct sk_buff *new_frag,
5802 struct sk_buff **last_frag)
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005803{
Mat Martineau84084a32011-07-22 14:54:00 -07005804 /* skb->len reflects data in skb as well as all fragments
5805 * skb->data_len reflects only data in fragments
5806 */
5807 if (!skb_has_frag_list(skb))
5808 skb_shinfo(skb)->frag_list = new_frag;
5809
5810 new_frag->next = NULL;
5811
5812 (*last_frag)->next = new_frag;
5813 *last_frag = new_frag;
5814
5815 skb->len += new_frag->len;
5816 skb->data_len += new_frag->len;
5817 skb->truesize += new_frag->truesize;
5818}
5819
Mat Martineau4b51dae92012-05-17 20:53:37 -07005820static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb,
5821 struct l2cap_ctrl *control)
Mat Martineau84084a32011-07-22 14:54:00 -07005822{
5823 int err = -EINVAL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005824
Mat Martineau4b51dae92012-05-17 20:53:37 -07005825 switch (control->sar) {
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005826 case L2CAP_SAR_UNSEGMENTED:
Mat Martineau84084a32011-07-22 14:54:00 -07005827 if (chan->sdu)
5828 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005829
Gustavo Padovan80b98022012-05-27 22:27:51 -03005830 err = chan->ops->recv(chan, skb);
Mat Martineau84084a32011-07-22 14:54:00 -07005831 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005832
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005833 case L2CAP_SAR_START:
Mat Martineau84084a32011-07-22 14:54:00 -07005834 if (chan->sdu)
5835 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005836
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005837 chan->sdu_len = get_unaligned_le16(skb->data);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005838 skb_pull(skb, L2CAP_SDULEN_SIZE);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005839
Mat Martineau84084a32011-07-22 14:54:00 -07005840 if (chan->sdu_len > chan->imtu) {
5841 err = -EMSGSIZE;
5842 break;
5843 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005844
Mat Martineau84084a32011-07-22 14:54:00 -07005845 if (skb->len >= chan->sdu_len)
5846 break;
5847
5848 chan->sdu = skb;
5849 chan->sdu_last_frag = skb;
5850
5851 skb = NULL;
5852 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005853 break;
5854
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005855 case L2CAP_SAR_CONTINUE:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005856 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07005857 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005858
Mat Martineau84084a32011-07-22 14:54:00 -07005859 append_skb_frag(chan->sdu, skb,
5860 &chan->sdu_last_frag);
5861 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005862
Mat Martineau84084a32011-07-22 14:54:00 -07005863 if (chan->sdu->len >= chan->sdu_len)
5864 break;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03005865
Mat Martineau84084a32011-07-22 14:54:00 -07005866 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005867 break;
5868
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005869 case L2CAP_SAR_END:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005870 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07005871 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005872
Mat Martineau84084a32011-07-22 14:54:00 -07005873 append_skb_frag(chan->sdu, skb,
5874 &chan->sdu_last_frag);
5875 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005876
Mat Martineau84084a32011-07-22 14:54:00 -07005877 if (chan->sdu->len != chan->sdu_len)
5878 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005879
Gustavo Padovan80b98022012-05-27 22:27:51 -03005880 err = chan->ops->recv(chan, chan->sdu);
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03005881
Mat Martineau84084a32011-07-22 14:54:00 -07005882 if (!err) {
5883 /* Reassembly complete */
5884 chan->sdu = NULL;
5885 chan->sdu_last_frag = NULL;
5886 chan->sdu_len = 0;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03005887 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005888 break;
5889 }
5890
Mat Martineau84084a32011-07-22 14:54:00 -07005891 if (err) {
5892 kfree_skb(skb);
5893 kfree_skb(chan->sdu);
5894 chan->sdu = NULL;
5895 chan->sdu_last_frag = NULL;
5896 chan->sdu_len = 0;
5897 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005898
Mat Martineau84084a32011-07-22 14:54:00 -07005899 return err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005900}
5901
Mat Martineau32b32732012-10-23 15:24:11 -07005902static int l2cap_resegment(struct l2cap_chan *chan)
5903{
5904 /* Placeholder */
5905 return 0;
5906}
5907
Mat Martineaue3281402011-07-07 09:39:02 -07005908void l2cap_chan_busy(struct l2cap_chan *chan, int busy)
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03005909{
Mat Martineau61aa4f52012-05-17 20:53:40 -07005910 u8 event;
5911
5912 if (chan->mode != L2CAP_MODE_ERTM)
5913 return;
5914
5915 event = busy ? L2CAP_EV_LOCAL_BUSY_DETECTED : L2CAP_EV_LOCAL_BUSY_CLEAR;
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03005916 l2cap_tx(chan, NULL, NULL, event);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03005917}
5918
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005919static int l2cap_rx_queued_iframes(struct l2cap_chan *chan)
5920{
Mat Martineau63838722012-05-17 20:53:45 -07005921 int err = 0;
5922 /* Pass sequential frames to l2cap_reassemble_sdu()
5923 * until a gap is encountered.
5924 */
5925
5926 BT_DBG("chan %p", chan);
5927
5928 while (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5929 struct sk_buff *skb;
5930 BT_DBG("Searching for skb with txseq %d (queue len %d)",
5931 chan->buffer_seq, skb_queue_len(&chan->srej_q));
5932
5933 skb = l2cap_ertm_seq_in_queue(&chan->srej_q, chan->buffer_seq);
5934
5935 if (!skb)
5936 break;
5937
5938 skb_unlink(skb, &chan->srej_q);
5939 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
5940 err = l2cap_reassemble_sdu(chan, skb, &bt_cb(skb)->control);
5941 if (err)
5942 break;
5943 }
5944
5945 if (skb_queue_empty(&chan->srej_q)) {
5946 chan->rx_state = L2CAP_RX_STATE_RECV;
5947 l2cap_send_ack(chan);
5948 }
5949
5950 return err;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005951}
5952
5953static void l2cap_handle_srej(struct l2cap_chan *chan,
5954 struct l2cap_ctrl *control)
5955{
Mat Martineauf80842a2012-05-17 20:53:46 -07005956 struct sk_buff *skb;
5957
5958 BT_DBG("chan %p, control %p", chan, control);
5959
5960 if (control->reqseq == chan->next_tx_seq) {
5961 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005962 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineauf80842a2012-05-17 20:53:46 -07005963 return;
5964 }
5965
5966 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
5967
5968 if (skb == NULL) {
5969 BT_DBG("Seq %d not available for retransmission",
5970 control->reqseq);
5971 return;
5972 }
5973
5974 if (chan->max_tx != 0 && bt_cb(skb)->control.retries >= chan->max_tx) {
5975 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005976 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineauf80842a2012-05-17 20:53:46 -07005977 return;
5978 }
5979
5980 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5981
5982 if (control->poll) {
5983 l2cap_pass_to_tx(chan, control);
5984
5985 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5986 l2cap_retransmit(chan, control);
5987 l2cap_ertm_send(chan);
5988
5989 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
5990 set_bit(CONN_SREJ_ACT, &chan->conn_state);
5991 chan->srej_save_reqseq = control->reqseq;
5992 }
5993 } else {
5994 l2cap_pass_to_tx_fbit(chan, control);
5995
5996 if (control->final) {
5997 if (chan->srej_save_reqseq != control->reqseq ||
5998 !test_and_clear_bit(CONN_SREJ_ACT,
5999 &chan->conn_state))
6000 l2cap_retransmit(chan, control);
6001 } else {
6002 l2cap_retransmit(chan, control);
6003 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
6004 set_bit(CONN_SREJ_ACT, &chan->conn_state);
6005 chan->srej_save_reqseq = control->reqseq;
6006 }
6007 }
6008 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006009}
6010
6011static void l2cap_handle_rej(struct l2cap_chan *chan,
6012 struct l2cap_ctrl *control)
6013{
Mat Martineaufcd289d2012-05-17 20:53:47 -07006014 struct sk_buff *skb;
6015
6016 BT_DBG("chan %p, control %p", chan, control);
6017
6018 if (control->reqseq == chan->next_tx_seq) {
6019 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006020 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaufcd289d2012-05-17 20:53:47 -07006021 return;
6022 }
6023
6024 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
6025
6026 if (chan->max_tx && skb &&
6027 bt_cb(skb)->control.retries >= chan->max_tx) {
6028 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006029 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaufcd289d2012-05-17 20:53:47 -07006030 return;
6031 }
6032
6033 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6034
6035 l2cap_pass_to_tx(chan, control);
6036
6037 if (control->final) {
6038 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state))
6039 l2cap_retransmit_all(chan, control);
6040 } else {
6041 l2cap_retransmit_all(chan, control);
6042 l2cap_ertm_send(chan);
6043 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F)
6044 set_bit(CONN_REJ_ACT, &chan->conn_state);
6045 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006046}
6047
Mat Martineau4b51dae92012-05-17 20:53:37 -07006048static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq)
6049{
6050 BT_DBG("chan %p, txseq %d", chan, txseq);
6051
6052 BT_DBG("last_acked_seq %d, expected_tx_seq %d", chan->last_acked_seq,
6053 chan->expected_tx_seq);
6054
6055 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
6056 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
Gustavo Padovan2d792812012-10-06 10:07:01 +01006057 chan->tx_win) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07006058 /* See notes below regarding "double poll" and
6059 * invalid packets.
6060 */
6061 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
6062 BT_DBG("Invalid/Ignore - after SREJ");
6063 return L2CAP_TXSEQ_INVALID_IGNORE;
6064 } else {
6065 BT_DBG("Invalid - in window after SREJ sent");
6066 return L2CAP_TXSEQ_INVALID;
6067 }
6068 }
6069
6070 if (chan->srej_list.head == txseq) {
6071 BT_DBG("Expected SREJ");
6072 return L2CAP_TXSEQ_EXPECTED_SREJ;
6073 }
6074
6075 if (l2cap_ertm_seq_in_queue(&chan->srej_q, txseq)) {
6076 BT_DBG("Duplicate SREJ - txseq already stored");
6077 return L2CAP_TXSEQ_DUPLICATE_SREJ;
6078 }
6079
6080 if (l2cap_seq_list_contains(&chan->srej_list, txseq)) {
6081 BT_DBG("Unexpected SREJ - not requested");
6082 return L2CAP_TXSEQ_UNEXPECTED_SREJ;
6083 }
6084 }
6085
6086 if (chan->expected_tx_seq == txseq) {
6087 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
6088 chan->tx_win) {
6089 BT_DBG("Invalid - txseq outside tx window");
6090 return L2CAP_TXSEQ_INVALID;
6091 } else {
6092 BT_DBG("Expected");
6093 return L2CAP_TXSEQ_EXPECTED;
6094 }
6095 }
6096
6097 if (__seq_offset(chan, txseq, chan->last_acked_seq) <
Gustavo Padovan2d792812012-10-06 10:07:01 +01006098 __seq_offset(chan, chan->expected_tx_seq, chan->last_acked_seq)) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07006099 BT_DBG("Duplicate - expected_tx_seq later than txseq");
6100 return L2CAP_TXSEQ_DUPLICATE;
6101 }
6102
6103 if (__seq_offset(chan, txseq, chan->last_acked_seq) >= chan->tx_win) {
6104 /* A source of invalid packets is a "double poll" condition,
6105 * where delays cause us to send multiple poll packets. If
6106 * the remote stack receives and processes both polls,
6107 * sequence numbers can wrap around in such a way that a
6108 * resent frame has a sequence number that looks like new data
6109 * with a sequence gap. This would trigger an erroneous SREJ
6110 * request.
6111 *
6112 * Fortunately, this is impossible with a tx window that's
6113 * less than half of the maximum sequence number, which allows
6114 * invalid frames to be safely ignored.
6115 *
6116 * With tx window sizes greater than half of the tx window
6117 * maximum, the frame is invalid and cannot be ignored. This
6118 * causes a disconnect.
6119 */
6120
6121 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
6122 BT_DBG("Invalid/Ignore - txseq outside tx window");
6123 return L2CAP_TXSEQ_INVALID_IGNORE;
6124 } else {
6125 BT_DBG("Invalid - txseq outside tx window");
6126 return L2CAP_TXSEQ_INVALID;
6127 }
6128 } else {
6129 BT_DBG("Unexpected - txseq indicates missing frames");
6130 return L2CAP_TXSEQ_UNEXPECTED;
6131 }
6132}
6133
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006134static int l2cap_rx_state_recv(struct l2cap_chan *chan,
6135 struct l2cap_ctrl *control,
6136 struct sk_buff *skb, u8 event)
6137{
6138 int err = 0;
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006139 bool skb_in_use = false;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006140
6141 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
6142 event);
6143
6144 switch (event) {
6145 case L2CAP_EV_RECV_IFRAME:
6146 switch (l2cap_classify_txseq(chan, control->txseq)) {
6147 case L2CAP_TXSEQ_EXPECTED:
6148 l2cap_pass_to_tx(chan, control);
6149
6150 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
6151 BT_DBG("Busy, discarding expected seq %d",
6152 control->txseq);
6153 break;
6154 }
6155
6156 chan->expected_tx_seq = __next_seq(chan,
6157 control->txseq);
6158
6159 chan->buffer_seq = chan->expected_tx_seq;
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006160 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006161
6162 err = l2cap_reassemble_sdu(chan, skb, control);
6163 if (err)
6164 break;
6165
6166 if (control->final) {
6167 if (!test_and_clear_bit(CONN_REJ_ACT,
6168 &chan->conn_state)) {
6169 control->final = 0;
6170 l2cap_retransmit_all(chan, control);
6171 l2cap_ertm_send(chan);
6172 }
6173 }
6174
6175 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
6176 l2cap_send_ack(chan);
6177 break;
6178 case L2CAP_TXSEQ_UNEXPECTED:
6179 l2cap_pass_to_tx(chan, control);
6180
6181 /* Can't issue SREJ frames in the local busy state.
6182 * Drop this frame, it will be seen as missing
6183 * when local busy is exited.
6184 */
6185 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
6186 BT_DBG("Busy, discarding unexpected seq %d",
6187 control->txseq);
6188 break;
6189 }
6190
6191 /* There was a gap in the sequence, so an SREJ
6192 * must be sent for each missing frame. The
6193 * current frame is stored for later use.
6194 */
6195 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006196 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006197 BT_DBG("Queued %p (queue len %d)", skb,
6198 skb_queue_len(&chan->srej_q));
6199
6200 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
6201 l2cap_seq_list_clear(&chan->srej_list);
6202 l2cap_send_srej(chan, control->txseq);
6203
6204 chan->rx_state = L2CAP_RX_STATE_SREJ_SENT;
6205 break;
6206 case L2CAP_TXSEQ_DUPLICATE:
6207 l2cap_pass_to_tx(chan, control);
6208 break;
6209 case L2CAP_TXSEQ_INVALID_IGNORE:
6210 break;
6211 case L2CAP_TXSEQ_INVALID:
6212 default:
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006213 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006214 break;
6215 }
6216 break;
6217 case L2CAP_EV_RECV_RR:
6218 l2cap_pass_to_tx(chan, control);
6219 if (control->final) {
6220 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6221
Mat Martineaue6a3ee62012-10-23 15:24:22 -07006222 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state) &&
6223 !__chan_is_moving(chan)) {
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006224 control->final = 0;
6225 l2cap_retransmit_all(chan, control);
6226 }
6227
6228 l2cap_ertm_send(chan);
6229 } else if (control->poll) {
6230 l2cap_send_i_or_rr_or_rnr(chan);
6231 } else {
6232 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6233 &chan->conn_state) &&
6234 chan->unacked_frames)
6235 __set_retrans_timer(chan);
6236
6237 l2cap_ertm_send(chan);
6238 }
6239 break;
6240 case L2CAP_EV_RECV_RNR:
6241 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6242 l2cap_pass_to_tx(chan, control);
6243 if (control && control->poll) {
6244 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6245 l2cap_send_rr_or_rnr(chan, 0);
6246 }
6247 __clear_retrans_timer(chan);
6248 l2cap_seq_list_clear(&chan->retrans_list);
6249 break;
6250 case L2CAP_EV_RECV_REJ:
6251 l2cap_handle_rej(chan, control);
6252 break;
6253 case L2CAP_EV_RECV_SREJ:
6254 l2cap_handle_srej(chan, control);
6255 break;
6256 default:
6257 break;
6258 }
6259
6260 if (skb && !skb_in_use) {
6261 BT_DBG("Freeing %p", skb);
6262 kfree_skb(skb);
6263 }
6264
6265 return err;
6266}
6267
6268static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan,
6269 struct l2cap_ctrl *control,
6270 struct sk_buff *skb, u8 event)
6271{
6272 int err = 0;
6273 u16 txseq = control->txseq;
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006274 bool skb_in_use = false;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006275
6276 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
6277 event);
6278
6279 switch (event) {
6280 case L2CAP_EV_RECV_IFRAME:
6281 switch (l2cap_classify_txseq(chan, txseq)) {
6282 case L2CAP_TXSEQ_EXPECTED:
6283 /* Keep frame for reassembly later */
6284 l2cap_pass_to_tx(chan, control);
6285 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006286 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006287 BT_DBG("Queued %p (queue len %d)", skb,
6288 skb_queue_len(&chan->srej_q));
6289
6290 chan->expected_tx_seq = __next_seq(chan, txseq);
6291 break;
6292 case L2CAP_TXSEQ_EXPECTED_SREJ:
6293 l2cap_seq_list_pop(&chan->srej_list);
6294
6295 l2cap_pass_to_tx(chan, control);
6296 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006297 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006298 BT_DBG("Queued %p (queue len %d)", skb,
6299 skb_queue_len(&chan->srej_q));
6300
6301 err = l2cap_rx_queued_iframes(chan);
6302 if (err)
6303 break;
6304
6305 break;
6306 case L2CAP_TXSEQ_UNEXPECTED:
6307 /* Got a frame that can't be reassembled yet.
6308 * Save it for later, and send SREJs to cover
6309 * the missing frames.
6310 */
6311 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006312 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006313 BT_DBG("Queued %p (queue len %d)", skb,
6314 skb_queue_len(&chan->srej_q));
6315
6316 l2cap_pass_to_tx(chan, control);
6317 l2cap_send_srej(chan, control->txseq);
6318 break;
6319 case L2CAP_TXSEQ_UNEXPECTED_SREJ:
6320 /* This frame was requested with an SREJ, but
6321 * some expected retransmitted frames are
6322 * missing. Request retransmission of missing
6323 * SREJ'd frames.
6324 */
6325 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006326 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006327 BT_DBG("Queued %p (queue len %d)", skb,
6328 skb_queue_len(&chan->srej_q));
6329
6330 l2cap_pass_to_tx(chan, control);
6331 l2cap_send_srej_list(chan, control->txseq);
6332 break;
6333 case L2CAP_TXSEQ_DUPLICATE_SREJ:
6334 /* We've already queued this frame. Drop this copy. */
6335 l2cap_pass_to_tx(chan, control);
6336 break;
6337 case L2CAP_TXSEQ_DUPLICATE:
6338 /* Expecting a later sequence number, so this frame
6339 * was already received. Ignore it completely.
6340 */
6341 break;
6342 case L2CAP_TXSEQ_INVALID_IGNORE:
6343 break;
6344 case L2CAP_TXSEQ_INVALID:
6345 default:
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006346 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006347 break;
6348 }
6349 break;
6350 case L2CAP_EV_RECV_RR:
6351 l2cap_pass_to_tx(chan, control);
6352 if (control->final) {
6353 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6354
6355 if (!test_and_clear_bit(CONN_REJ_ACT,
6356 &chan->conn_state)) {
6357 control->final = 0;
6358 l2cap_retransmit_all(chan, control);
6359 }
6360
6361 l2cap_ertm_send(chan);
6362 } else if (control->poll) {
6363 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6364 &chan->conn_state) &&
6365 chan->unacked_frames) {
6366 __set_retrans_timer(chan);
6367 }
6368
6369 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6370 l2cap_send_srej_tail(chan);
6371 } else {
6372 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6373 &chan->conn_state) &&
6374 chan->unacked_frames)
6375 __set_retrans_timer(chan);
6376
6377 l2cap_send_ack(chan);
6378 }
6379 break;
6380 case L2CAP_EV_RECV_RNR:
6381 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6382 l2cap_pass_to_tx(chan, control);
6383 if (control->poll) {
6384 l2cap_send_srej_tail(chan);
6385 } else {
6386 struct l2cap_ctrl rr_control;
6387 memset(&rr_control, 0, sizeof(rr_control));
6388 rr_control.sframe = 1;
6389 rr_control.super = L2CAP_SUPER_RR;
6390 rr_control.reqseq = chan->buffer_seq;
6391 l2cap_send_sframe(chan, &rr_control);
6392 }
6393
6394 break;
6395 case L2CAP_EV_RECV_REJ:
6396 l2cap_handle_rej(chan, control);
6397 break;
6398 case L2CAP_EV_RECV_SREJ:
6399 l2cap_handle_srej(chan, control);
6400 break;
6401 }
6402
6403 if (skb && !skb_in_use) {
6404 BT_DBG("Freeing %p", skb);
6405 kfree_skb(skb);
6406 }
6407
6408 return err;
6409}
6410
Mat Martineau32b32732012-10-23 15:24:11 -07006411static int l2cap_finish_move(struct l2cap_chan *chan)
6412{
6413 BT_DBG("chan %p", chan);
6414
6415 chan->rx_state = L2CAP_RX_STATE_RECV;
6416
6417 if (chan->hs_hcon)
6418 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
6419 else
6420 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
6421
6422 return l2cap_resegment(chan);
6423}
6424
6425static int l2cap_rx_state_wait_p(struct l2cap_chan *chan,
6426 struct l2cap_ctrl *control,
6427 struct sk_buff *skb, u8 event)
6428{
6429 int err;
6430
6431 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
6432 event);
6433
6434 if (!control->poll)
6435 return -EPROTO;
6436
6437 l2cap_process_reqseq(chan, control->reqseq);
6438
6439 if (!skb_queue_empty(&chan->tx_q))
6440 chan->tx_send_head = skb_peek(&chan->tx_q);
6441 else
6442 chan->tx_send_head = NULL;
6443
6444 /* Rewind next_tx_seq to the point expected
6445 * by the receiver.
6446 */
6447 chan->next_tx_seq = control->reqseq;
6448 chan->unacked_frames = 0;
6449
6450 err = l2cap_finish_move(chan);
6451 if (err)
6452 return err;
6453
6454 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6455 l2cap_send_i_or_rr_or_rnr(chan);
6456
6457 if (event == L2CAP_EV_RECV_IFRAME)
6458 return -EPROTO;
6459
6460 return l2cap_rx_state_recv(chan, control, NULL, event);
6461}
6462
6463static int l2cap_rx_state_wait_f(struct l2cap_chan *chan,
6464 struct l2cap_ctrl *control,
6465 struct sk_buff *skb, u8 event)
6466{
6467 int err;
6468
6469 if (!control->final)
6470 return -EPROTO;
6471
6472 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6473
6474 chan->rx_state = L2CAP_RX_STATE_RECV;
6475 l2cap_process_reqseq(chan, control->reqseq);
6476
6477 if (!skb_queue_empty(&chan->tx_q))
6478 chan->tx_send_head = skb_peek(&chan->tx_q);
6479 else
6480 chan->tx_send_head = NULL;
6481
6482 /* Rewind next_tx_seq to the point expected
6483 * by the receiver.
6484 */
6485 chan->next_tx_seq = control->reqseq;
6486 chan->unacked_frames = 0;
6487
6488 if (chan->hs_hcon)
6489 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
6490 else
6491 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
6492
6493 err = l2cap_resegment(chan);
6494
6495 if (!err)
6496 err = l2cap_rx_state_recv(chan, control, skb, event);
6497
6498 return err;
6499}
6500
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006501static bool __valid_reqseq(struct l2cap_chan *chan, u16 reqseq)
6502{
6503 /* Make sure reqseq is for a packet that has been sent but not acked */
6504 u16 unacked;
6505
6506 unacked = __seq_offset(chan, chan->next_tx_seq, chan->expected_ack_seq);
6507 return __seq_offset(chan, chan->next_tx_seq, reqseq) <= unacked;
6508}
6509
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006510static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
6511 struct sk_buff *skb, u8 event)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006512{
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006513 int err = 0;
6514
6515 BT_DBG("chan %p, control %p, skb %p, event %d, state %d", chan,
6516 control, skb, event, chan->rx_state);
6517
6518 if (__valid_reqseq(chan, control->reqseq)) {
6519 switch (chan->rx_state) {
6520 case L2CAP_RX_STATE_RECV:
6521 err = l2cap_rx_state_recv(chan, control, skb, event);
6522 break;
6523 case L2CAP_RX_STATE_SREJ_SENT:
6524 err = l2cap_rx_state_srej_sent(chan, control, skb,
6525 event);
6526 break;
Mat Martineau32b32732012-10-23 15:24:11 -07006527 case L2CAP_RX_STATE_WAIT_P:
6528 err = l2cap_rx_state_wait_p(chan, control, skb, event);
6529 break;
6530 case L2CAP_RX_STATE_WAIT_F:
6531 err = l2cap_rx_state_wait_f(chan, control, skb, event);
6532 break;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006533 default:
6534 /* shut it down */
6535 break;
6536 }
6537 } else {
6538 BT_DBG("Invalid reqseq %d (next_tx_seq %d, expected_ack_seq %d",
6539 control->reqseq, chan->next_tx_seq,
6540 chan->expected_ack_seq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006541 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006542 }
6543
6544 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006545}
6546
6547static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
6548 struct sk_buff *skb)
6549{
Mat Martineau4b51dae92012-05-17 20:53:37 -07006550 int err = 0;
6551
6552 BT_DBG("chan %p, control %p, skb %p, state %d", chan, control, skb,
6553 chan->rx_state);
6554
6555 if (l2cap_classify_txseq(chan, control->txseq) ==
6556 L2CAP_TXSEQ_EXPECTED) {
6557 l2cap_pass_to_tx(chan, control);
6558
6559 BT_DBG("buffer_seq %d->%d", chan->buffer_seq,
6560 __next_seq(chan, chan->buffer_seq));
6561
6562 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
6563
6564 l2cap_reassemble_sdu(chan, skb, control);
6565 } else {
6566 if (chan->sdu) {
6567 kfree_skb(chan->sdu);
6568 chan->sdu = NULL;
6569 }
6570 chan->sdu_last_frag = NULL;
6571 chan->sdu_len = 0;
6572
6573 if (skb) {
6574 BT_DBG("Freeing %p", skb);
6575 kfree_skb(skb);
6576 }
6577 }
6578
6579 chan->last_acked_seq = control->txseq;
6580 chan->expected_tx_seq = __next_seq(chan, control->txseq);
6581
6582 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006583}
6584
6585static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
6586{
6587 struct l2cap_ctrl *control = &bt_cb(skb)->control;
6588 u16 len;
6589 u8 event;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006590
Mat Martineaub76bbd62012-04-11 10:48:43 -07006591 __unpack_control(chan, skb);
6592
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006593 len = skb->len;
6594
6595 /*
6596 * We can just drop the corrupted I-frame here.
6597 * Receiver will miss it and start proper recovery
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006598 * procedures and ask for retransmission.
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006599 */
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006600 if (l2cap_check_fcs(chan, skb))
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006601 goto drop;
6602
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006603 if (!control->sframe && control->sar == L2CAP_SAR_START)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03006604 len -= L2CAP_SDULEN_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006605
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006606 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03006607 len -= L2CAP_FCS_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006608
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006609 if (len > chan->mps) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006610 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006611 goto drop;
6612 }
6613
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006614 if (!control->sframe) {
6615 int err;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006616
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006617 BT_DBG("iframe sar %d, reqseq %d, final %d, txseq %d",
6618 control->sar, control->reqseq, control->final,
6619 control->txseq);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03006620
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006621 /* Validate F-bit - F=0 always valid, F=1 only
6622 * valid in TX WAIT_F
6623 */
6624 if (control->final && chan->tx_state != L2CAP_TX_STATE_WAIT_F)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006625 goto drop;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006626
6627 if (chan->mode != L2CAP_MODE_STREAMING) {
6628 event = L2CAP_EV_RECV_IFRAME;
6629 err = l2cap_rx(chan, control, skb, event);
6630 } else {
6631 err = l2cap_stream_rx(chan, control, skb);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006632 }
6633
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006634 if (err)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006635 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006636 } else {
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006637 const u8 rx_func_to_event[4] = {
6638 L2CAP_EV_RECV_RR, L2CAP_EV_RECV_REJ,
6639 L2CAP_EV_RECV_RNR, L2CAP_EV_RECV_SREJ
6640 };
6641
6642 /* Only I-frames are expected in streaming mode */
6643 if (chan->mode == L2CAP_MODE_STREAMING)
6644 goto drop;
6645
6646 BT_DBG("sframe reqseq %d, final %d, poll %d, super %d",
6647 control->reqseq, control->final, control->poll,
6648 control->super);
6649
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006650 if (len != 0) {
Andrei Emeltchenko1bb166e2012-11-20 17:16:21 +02006651 BT_ERR("Trailing bytes: %d in sframe", len);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006652 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006653 goto drop;
6654 }
6655
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006656 /* Validate F and P bits */
6657 if (control->final && (control->poll ||
6658 chan->tx_state != L2CAP_TX_STATE_WAIT_F))
6659 goto drop;
6660
6661 event = rx_func_to_event[control->super];
6662 if (l2cap_rx(chan, control, skb, event))
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006663 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006664 }
6665
6666 return 0;
6667
6668drop:
6669 kfree_skb(skb);
6670 return 0;
6671}
6672
Johan Hedbergb1c325c2013-12-05 09:43:34 +02006673static void l2cap_chan_le_send_credits(struct l2cap_chan *chan)
6674{
6675 struct l2cap_conn *conn = chan->conn;
6676 struct l2cap_le_credits pkt;
6677 u16 return_credits;
6678
6679 /* We return more credits to the sender only after the amount of
6680 * credits falls below half of the initial amount.
6681 */
Johan Hedbergf15b8ec2013-12-03 15:08:25 +02006682 if (chan->rx_credits >= (le_max_credits + 1) / 2)
Johan Hedbergb1c325c2013-12-05 09:43:34 +02006683 return;
6684
Johan Hedbergf15b8ec2013-12-03 15:08:25 +02006685 return_credits = le_max_credits - chan->rx_credits;
Johan Hedbergb1c325c2013-12-05 09:43:34 +02006686
6687 BT_DBG("chan %p returning %u credits to sender", chan, return_credits);
6688
6689 chan->rx_credits += return_credits;
6690
6691 pkt.cid = cpu_to_le16(chan->scid);
6692 pkt.credits = cpu_to_le16(return_credits);
6693
6694 chan->ident = l2cap_get_ident(conn);
6695
6696 l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CREDITS, sizeof(pkt), &pkt);
6697}
6698
Johan Hedbergfad5fc892013-12-05 09:45:01 +02006699static int l2cap_le_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
6700{
Johan Hedbergaac23bf2013-06-01 10:14:57 +03006701 int err;
Johan Hedbergfad5fc892013-12-05 09:45:01 +02006702
Johan Hedbergaac23bf2013-06-01 10:14:57 +03006703 if (!chan->rx_credits) {
6704 BT_ERR("No credits to receive LE L2CAP data");
Johan Hedbergdfd97742014-01-27 15:11:34 -08006705 l2cap_send_disconn_req(chan, ECONNRESET);
Johan Hedbergfad5fc892013-12-05 09:45:01 +02006706 return -ENOBUFS;
Johan Hedbergaac23bf2013-06-01 10:14:57 +03006707 }
6708
6709 if (chan->imtu < skb->len) {
6710 BT_ERR("Too big LE L2CAP PDU");
6711 return -ENOBUFS;
6712 }
Johan Hedbergfad5fc892013-12-05 09:45:01 +02006713
6714 chan->rx_credits--;
6715 BT_DBG("rx_credits %u -> %u", chan->rx_credits + 1, chan->rx_credits);
6716
6717 l2cap_chan_le_send_credits(chan);
6718
Johan Hedbergaac23bf2013-06-01 10:14:57 +03006719 err = 0;
6720
6721 if (!chan->sdu) {
6722 u16 sdu_len;
6723
6724 sdu_len = get_unaligned_le16(skb->data);
6725 skb_pull(skb, L2CAP_SDULEN_SIZE);
6726
6727 BT_DBG("Start of new SDU. sdu_len %u skb->len %u imtu %u",
6728 sdu_len, skb->len, chan->imtu);
6729
6730 if (sdu_len > chan->imtu) {
6731 BT_ERR("Too big LE L2CAP SDU length received");
6732 err = -EMSGSIZE;
6733 goto failed;
6734 }
6735
6736 if (skb->len > sdu_len) {
6737 BT_ERR("Too much LE L2CAP data received");
6738 err = -EINVAL;
6739 goto failed;
6740 }
6741
6742 if (skb->len == sdu_len)
6743 return chan->ops->recv(chan, skb);
6744
6745 chan->sdu = skb;
6746 chan->sdu_len = sdu_len;
6747 chan->sdu_last_frag = skb;
6748
6749 return 0;
6750 }
6751
6752 BT_DBG("SDU fragment. chan->sdu->len %u skb->len %u chan->sdu_len %u",
6753 chan->sdu->len, skb->len, chan->sdu_len);
6754
6755 if (chan->sdu->len + skb->len > chan->sdu_len) {
6756 BT_ERR("Too much LE L2CAP data received");
6757 err = -EINVAL;
6758 goto failed;
6759 }
6760
6761 append_skb_frag(chan->sdu, skb, &chan->sdu_last_frag);
6762 skb = NULL;
6763
6764 if (chan->sdu->len == chan->sdu_len) {
6765 err = chan->ops->recv(chan, chan->sdu);
6766 if (!err) {
6767 chan->sdu = NULL;
6768 chan->sdu_last_frag = NULL;
6769 chan->sdu_len = 0;
6770 }
6771 }
6772
6773failed:
6774 if (err) {
6775 kfree_skb(skb);
6776 kfree_skb(chan->sdu);
6777 chan->sdu = NULL;
6778 chan->sdu_last_frag = NULL;
6779 chan->sdu_len = 0;
6780 }
6781
6782 /* We can't return an error here since we took care of the skb
6783 * freeing internally. An error return would cause the caller to
6784 * do a double-free of the skb.
6785 */
6786 return 0;
Johan Hedbergfad5fc892013-12-05 09:45:01 +02006787}
6788
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006789static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid,
6790 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006791{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006792 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006793
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03006794 chan = l2cap_get_chan_by_scid(conn, cid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006795 if (!chan) {
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006796 if (cid == L2CAP_CID_A2MP) {
6797 chan = a2mp_channel_create(conn, skb);
6798 if (!chan) {
6799 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006800 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006801 }
6802
6803 l2cap_chan_lock(chan);
6804 } else {
6805 BT_DBG("unknown cid 0x%4.4x", cid);
6806 /* Drop packet and return */
6807 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006808 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006809 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006810 }
6811
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03006812 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006813
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006814 if (chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006815 goto drop;
6816
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006817 switch (chan->mode) {
Johan Hedberg38319712013-05-17 12:49:23 +03006818 case L2CAP_MODE_LE_FLOWCTL:
Johan Hedbergfad5fc892013-12-05 09:45:01 +02006819 if (l2cap_le_data_rcv(chan, skb) < 0)
6820 goto drop;
6821
6822 goto done;
6823
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006824 case L2CAP_MODE_BASIC:
6825 /* If socket recv buffers overflows we drop data here
6826 * which is *bad* because L2CAP has to be reliable.
6827 * But we don't have any other choice. L2CAP doesn't
6828 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006829
Szymon Janc2c96e032014-02-18 20:48:34 +01006830 if (chan->imtu < skb->len) {
6831 BT_ERR("Dropping L2CAP data: receive buffer overflow");
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006832 goto drop;
Szymon Janc2c96e032014-02-18 20:48:34 +01006833 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006834
Gustavo Padovan80b98022012-05-27 22:27:51 -03006835 if (!chan->ops->recv(chan, skb))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006836 goto done;
6837 break;
6838
6839 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03006840 case L2CAP_MODE_STREAMING:
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006841 l2cap_data_rcv(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03006842 goto done;
6843
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006844 default:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006845 BT_DBG("chan %p: bad mode 0x%2.2x", chan, chan->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006846 break;
6847 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006848
6849drop:
6850 kfree_skb(skb);
6851
6852done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006853 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006854}
6855
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03006856static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm,
6857 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006858{
Marcel Holtmannae4fd2d2013-10-03 00:03:39 -07006859 struct hci_conn *hcon = conn->hcon;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006860 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006861
Marcel Holtmannae4fd2d2013-10-03 00:03:39 -07006862 if (hcon->type != ACL_LINK)
Johan Hedberga24cce12014-08-07 22:56:42 +03006863 goto free_skb;
Marcel Holtmannae4fd2d2013-10-03 00:03:39 -07006864
Johan Hedbergbf20fd42013-05-14 13:23:13 +03006865 chan = l2cap_global_chan_by_psm(0, psm, &hcon->src, &hcon->dst,
6866 ACL_LINK);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006867 if (!chan)
Johan Hedberga24cce12014-08-07 22:56:42 +03006868 goto free_skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006869
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02006870 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006871
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006872 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006873 goto drop;
6874
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03006875 if (chan->imtu < skb->len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006876 goto drop;
6877
Marcel Holtmann2edf8702013-10-13 12:55:29 -07006878 /* Store remote BD_ADDR and PSM for msg_name */
Marcel Holtmann06ae3312013-10-18 03:43:00 -07006879 bacpy(&bt_cb(skb)->bdaddr, &hcon->dst);
Marcel Holtmann2edf8702013-10-13 12:55:29 -07006880 bt_cb(skb)->psm = psm;
6881
Johan Hedberga24cce12014-08-07 22:56:42 +03006882 if (!chan->ops->recv(chan, skb)) {
6883 l2cap_chan_put(chan);
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03006884 return;
Johan Hedberga24cce12014-08-07 22:56:42 +03006885 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006886
6887drop:
Johan Hedberga24cce12014-08-07 22:56:42 +03006888 l2cap_chan_put(chan);
6889free_skb:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006890 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006891}
6892
Marcel Holtmann72f78352013-04-23 00:59:00 -07006893static void l2cap_att_channel(struct l2cap_conn *conn,
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03006894 struct sk_buff *skb)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006895{
Marcel Holtmannb99707d2013-10-03 02:54:11 -07006896 struct hci_conn *hcon = conn->hcon;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006897 struct l2cap_chan *chan;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006898
Marcel Holtmannb99707d2013-10-03 02:54:11 -07006899 if (hcon->type != LE_LINK)
Johan Hedberga24cce12014-08-07 22:56:42 +03006900 goto free_skb;
Marcel Holtmannb99707d2013-10-03 02:54:11 -07006901
Johan Hedbergaf1c0132013-04-29 19:35:42 +03006902 chan = l2cap_global_chan_by_scid(BT_CONNECTED, L2CAP_CID_ATT,
Marcel Holtmann06ae3312013-10-18 03:43:00 -07006903 &hcon->src, &hcon->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006904 if (!chan)
Johan Hedberga24cce12014-08-07 22:56:42 +03006905 goto free_skb;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006906
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02006907 BT_DBG("chan %p, len %d", chan, skb->len);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006908
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03006909 if (chan->imtu < skb->len)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006910 goto drop;
6911
Johan Hedberga24cce12014-08-07 22:56:42 +03006912 if (!chan->ops->recv(chan, skb)) {
6913 l2cap_chan_put(chan);
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03006914 return;
Johan Hedberga24cce12014-08-07 22:56:42 +03006915 }
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006916
6917drop:
Johan Hedberga24cce12014-08-07 22:56:42 +03006918 l2cap_chan_put(chan);
6919free_skb:
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006920 kfree_skb(skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006921}
6922
Linus Torvalds1da177e2005-04-16 15:20:36 -07006923static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
6924{
6925 struct l2cap_hdr *lh = (void *) skb->data;
Johan Hedberg61a939c2014-01-17 20:45:11 +02006926 struct hci_conn *hcon = conn->hcon;
Al Viro8e036fc2007-07-29 00:16:36 -07006927 u16 cid, len;
6928 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006929
Johan Hedberg61a939c2014-01-17 20:45:11 +02006930 if (hcon->state != BT_CONNECTED) {
6931 BT_DBG("queueing pending rx skb");
6932 skb_queue_tail(&conn->pending_rx, skb);
6933 return;
6934 }
6935
Linus Torvalds1da177e2005-04-16 15:20:36 -07006936 skb_pull(skb, L2CAP_HDR_SIZE);
6937 cid = __le16_to_cpu(lh->cid);
6938 len = __le16_to_cpu(lh->len);
6939
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006940 if (len != skb->len) {
6941 kfree_skb(skb);
6942 return;
6943 }
6944
Johan Hedberg9e1d7e12014-07-06 11:03:36 +03006945 /* Since we can't actively block incoming LE connections we must
6946 * at least ensure that we ignore incoming data from them.
6947 */
6948 if (hcon->type == LE_LINK &&
Johan Hedbergdcc36c12014-07-09 12:59:13 +03006949 hci_bdaddr_list_lookup(&hcon->hdev->blacklist, &hcon->dst,
6950 bdaddr_type(hcon, hcon->dst_type))) {
Johan Hedberge4931502014-07-02 09:36:21 +03006951 kfree_skb(skb);
6952 return;
6953 }
6954
Linus Torvalds1da177e2005-04-16 15:20:36 -07006955 BT_DBG("len %d, cid 0x%4.4x", len, cid);
6956
6957 switch (cid) {
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03006958 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006959 l2cap_sig_channel(conn, skb);
6960 break;
6961
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03006962 case L2CAP_CID_CONN_LESS:
Andrei Emeltchenko097db762012-03-09 14:16:17 +02006963 psm = get_unaligned((__le16 *) skb->data);
Andrei Emeltchenko0181a702012-05-29 10:04:05 +03006964 skb_pull(skb, L2CAP_PSMLEN_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006965 l2cap_conless_channel(conn, psm, skb);
6966 break;
6967
Johan Hedberg073d1cf2013-04-29 19:35:35 +03006968 case L2CAP_CID_ATT:
Marcel Holtmann72f78352013-04-23 00:59:00 -07006969 l2cap_att_channel(conn, skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006970 break;
6971
Marcel Holtmanna2877622013-10-02 23:46:54 -07006972 case L2CAP_CID_LE_SIGNALING:
6973 l2cap_le_sig_channel(conn, skb);
6974 break;
6975
Anderson Brigliab501d6a2011-06-07 18:46:31 -03006976 case L2CAP_CID_SMP:
6977 if (smp_sig_channel(conn, skb))
6978 l2cap_conn_del(conn->hcon, EACCES);
6979 break;
6980
Linus Torvalds1da177e2005-04-16 15:20:36 -07006981 default:
6982 l2cap_data_channel(conn, cid, skb);
6983 break;
6984 }
6985}
6986
Johan Hedberg61a939c2014-01-17 20:45:11 +02006987static void process_pending_rx(struct work_struct *work)
6988{
6989 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
6990 pending_rx_work);
6991 struct sk_buff *skb;
6992
6993 BT_DBG("");
6994
6995 while ((skb = skb_dequeue(&conn->pending_rx)))
6996 l2cap_recv_frame(conn, skb);
6997}
6998
Johan Hedberg162b49e2014-01-17 20:45:10 +02006999static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon)
7000{
7001 struct l2cap_conn *conn = hcon->l2cap_data;
7002 struct hci_chan *hchan;
7003
7004 if (conn)
7005 return conn;
7006
7007 hchan = hci_chan_create(hcon);
7008 if (!hchan)
7009 return NULL;
7010
Johan Hedberg27f70f32014-07-21 10:50:06 +03007011 conn = kzalloc(sizeof(*conn), GFP_KERNEL);
Johan Hedberg162b49e2014-01-17 20:45:10 +02007012 if (!conn) {
7013 hci_chan_del(hchan);
7014 return NULL;
7015 }
7016
7017 kref_init(&conn->ref);
7018 hcon->l2cap_data = conn;
7019 conn->hcon = hcon;
7020 hci_conn_get(conn->hcon);
7021 conn->hchan = hchan;
7022
7023 BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan);
7024
7025 switch (hcon->type) {
7026 case LE_LINK:
7027 if (hcon->hdev->le_mtu) {
7028 conn->mtu = hcon->hdev->le_mtu;
7029 break;
7030 }
7031 /* fall through */
7032 default:
7033 conn->mtu = hcon->hdev->acl_mtu;
7034 break;
7035 }
7036
7037 conn->feat_mask = 0;
7038
7039 if (hcon->type == ACL_LINK)
7040 conn->hs_enabled = test_bit(HCI_HS_ENABLED,
7041 &hcon->hdev->dev_flags);
7042
Marcel Holtmann5a54e7c2014-07-13 20:50:15 +02007043 mutex_init(&conn->ident_lock);
Johan Hedberg162b49e2014-01-17 20:45:10 +02007044 mutex_init(&conn->chan_lock);
7045
7046 INIT_LIST_HEAD(&conn->chan_l);
7047 INIT_LIST_HEAD(&conn->users);
7048
7049 if (hcon->type == LE_LINK)
7050 INIT_DELAYED_WORK(&conn->security_timer, security_timeout);
7051 else
7052 INIT_DELAYED_WORK(&conn->info_timer, l2cap_info_timeout);
7053
Johan Hedberg61a939c2014-01-17 20:45:11 +02007054 skb_queue_head_init(&conn->pending_rx);
7055 INIT_WORK(&conn->pending_rx_work, process_pending_rx);
7056
Johan Hedberg162b49e2014-01-17 20:45:10 +02007057 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
7058
7059 return conn;
7060}
7061
7062static bool is_valid_psm(u16 psm, u8 dst_type) {
7063 if (!psm)
7064 return false;
7065
7066 if (bdaddr_type_is_le(dst_type))
7067 return (psm <= 0x00ff);
7068
7069 /* PSM must be odd and lsb of upper byte must be 0 */
7070 return ((psm & 0x0101) == 0x0001);
7071}
7072
7073int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
7074 bdaddr_t *dst, u8 dst_type)
7075{
7076 struct l2cap_conn *conn;
7077 struct hci_conn *hcon;
7078 struct hci_dev *hdev;
Johan Hedberg162b49e2014-01-17 20:45:10 +02007079 int err;
7080
7081 BT_DBG("%pMR -> %pMR (type %u) psm 0x%2.2x", &chan->src, dst,
7082 dst_type, __le16_to_cpu(psm));
7083
7084 hdev = hci_get_route(dst, &chan->src);
7085 if (!hdev)
7086 return -EHOSTUNREACH;
7087
7088 hci_dev_lock(hdev);
7089
7090 l2cap_chan_lock(chan);
7091
7092 if (!is_valid_psm(__le16_to_cpu(psm), dst_type) && !cid &&
7093 chan->chan_type != L2CAP_CHAN_RAW) {
7094 err = -EINVAL;
7095 goto done;
7096 }
7097
Johan Hedberg21626e62014-01-24 10:35:41 +02007098 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && !psm) {
7099 err = -EINVAL;
7100 goto done;
7101 }
7102
7103 if (chan->chan_type == L2CAP_CHAN_FIXED && !cid) {
Johan Hedberg162b49e2014-01-17 20:45:10 +02007104 err = -EINVAL;
7105 goto done;
7106 }
7107
7108 switch (chan->mode) {
7109 case L2CAP_MODE_BASIC:
7110 break;
7111 case L2CAP_MODE_LE_FLOWCTL:
7112 l2cap_le_flowctl_init(chan);
7113 break;
7114 case L2CAP_MODE_ERTM:
7115 case L2CAP_MODE_STREAMING:
7116 if (!disable_ertm)
7117 break;
7118 /* fall through */
7119 default:
Johan Hedbergbeb19e42014-07-18 11:15:26 +03007120 err = -EOPNOTSUPP;
Johan Hedberg162b49e2014-01-17 20:45:10 +02007121 goto done;
7122 }
7123
7124 switch (chan->state) {
7125 case BT_CONNECT:
7126 case BT_CONNECT2:
7127 case BT_CONFIG:
7128 /* Already connecting */
7129 err = 0;
7130 goto done;
7131
7132 case BT_CONNECTED:
7133 /* Already connected */
7134 err = -EISCONN;
7135 goto done;
7136
7137 case BT_OPEN:
7138 case BT_BOUND:
7139 /* Can connect */
7140 break;
7141
7142 default:
7143 err = -EBADFD;
7144 goto done;
7145 }
7146
7147 /* Set destination address and psm */
7148 bacpy(&chan->dst, dst);
7149 chan->dst_type = dst_type;
7150
7151 chan->psm = psm;
7152 chan->dcid = cid;
7153
Andre Guedes6f77d8c2014-02-26 20:21:45 -03007154 if (bdaddr_type_is_le(dst_type)) {
Johan Hedberge804d252014-07-16 11:42:28 +03007155 u8 role;
Johan Hedbergcdd62752014-07-07 15:02:28 +03007156
Andre Guedes6f77d8c2014-02-26 20:21:45 -03007157 /* Convert from L2CAP channel address type to HCI address type
7158 */
7159 if (dst_type == BDADDR_LE_PUBLIC)
7160 dst_type = ADDR_LE_DEV_PUBLIC;
7161 else
7162 dst_type = ADDR_LE_DEV_RANDOM;
7163
Johan Hedberge804d252014-07-16 11:42:28 +03007164 if (test_bit(HCI_ADVERTISING, &hdev->dev_flags))
7165 role = HCI_ROLE_SLAVE;
7166 else
7167 role = HCI_ROLE_MASTER;
Johan Hedbergcdd62752014-07-07 15:02:28 +03007168
Andre Guedes04a6c582014-02-26 20:21:44 -03007169 hcon = hci_connect_le(hdev, dst, dst_type, chan->sec_level,
Johan Hedberge804d252014-07-16 11:42:28 +03007170 HCI_LE_CONN_TIMEOUT, role);
Andre Guedes6f77d8c2014-02-26 20:21:45 -03007171 } else {
Johan Hedbergd93375a2014-07-07 15:02:27 +03007172 u8 auth_type = l2cap_get_auth_type(chan);
Andre Guedes04a6c582014-02-26 20:21:44 -03007173 hcon = hci_connect_acl(hdev, dst, chan->sec_level, auth_type);
Andre Guedes6f77d8c2014-02-26 20:21:45 -03007174 }
Johan Hedberg162b49e2014-01-17 20:45:10 +02007175
7176 if (IS_ERR(hcon)) {
7177 err = PTR_ERR(hcon);
7178 goto done;
7179 }
7180
7181 conn = l2cap_conn_add(hcon);
7182 if (!conn) {
7183 hci_conn_drop(hcon);
7184 err = -ENOMEM;
7185 goto done;
7186 }
7187
7188 if (cid && __l2cap_get_chan_by_dcid(conn, cid)) {
7189 hci_conn_drop(hcon);
7190 err = -EBUSY;
7191 goto done;
7192 }
7193
7194 /* Update source addr of the socket */
7195 bacpy(&chan->src, &hcon->src);
7196 chan->src_type = bdaddr_type(hcon, hcon->src_type);
7197
7198 l2cap_chan_unlock(chan);
7199 l2cap_chan_add(conn, chan);
7200 l2cap_chan_lock(chan);
7201
7202 /* l2cap_chan_add takes its own ref so we can drop this one */
7203 hci_conn_drop(hcon);
7204
7205 l2cap_state_change(chan, BT_CONNECT);
7206 __set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
7207
Johan Hedberg61202e42014-01-28 15:16:48 -08007208 /* Release chan->sport so that it can be reused by other
7209 * sockets (as it's only used for listening sockets).
7210 */
7211 write_lock(&chan_list_lock);
7212 chan->sport = 0;
7213 write_unlock(&chan_list_lock);
7214
Johan Hedberg162b49e2014-01-17 20:45:10 +02007215 if (hcon->state == BT_CONNECTED) {
7216 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
7217 __clear_chan_timer(chan);
Johan Hedberge7cafc42014-07-17 15:35:38 +03007218 if (l2cap_chan_check_security(chan, true))
Johan Hedberg162b49e2014-01-17 20:45:10 +02007219 l2cap_state_change(chan, BT_CONNECTED);
7220 } else
7221 l2cap_do_start(chan);
7222 }
7223
7224 err = 0;
7225
7226done:
7227 l2cap_chan_unlock(chan);
7228 hci_dev_unlock(hdev);
7229 hci_dev_put(hdev);
7230 return err;
7231}
Jukka Rissanen6b8d4a62014-06-18 16:37:08 +03007232EXPORT_SYMBOL_GPL(l2cap_chan_connect);
Johan Hedberg162b49e2014-01-17 20:45:10 +02007233
Linus Torvalds1da177e2005-04-16 15:20:36 -07007234/* ---- L2CAP interface with lower layer (HCI) ---- */
7235
Ulisses Furquim686ebf22011-12-21 10:11:33 -02007236int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007237{
7238 int exact = 0, lm1 = 0, lm2 = 0;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007239 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007240
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03007241 BT_DBG("hdev %s, bdaddr %pMR", hdev->name, bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007242
7243 /* Find listening sockets and check their link_mode */
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007244 read_lock(&chan_list_lock);
7245 list_for_each_entry(c, &chan_list, global_l) {
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03007246 if (c->state != BT_LISTEN)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007247 continue;
7248
Marcel Holtmann7eafc592013-10-13 08:12:47 -07007249 if (!bacmp(&c->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01007250 lm1 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03007251 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01007252 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007253 exact++;
Marcel Holtmann7eafc592013-10-13 08:12:47 -07007254 } else if (!bacmp(&c->src, BDADDR_ANY)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01007255 lm2 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03007256 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01007257 lm2 |= HCI_LM_MASTER;
7258 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07007259 }
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007260 read_unlock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007261
7262 return exact ? lm1 : lm2;
7263}
7264
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03007265void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007266{
Marcel Holtmann01394182006-07-03 10:02:46 +02007267 struct l2cap_conn *conn;
7268
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03007269 BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007270
Linus Torvalds1da177e2005-04-16 15:20:36 -07007271 if (!status) {
Claudio Takahasibaf43252013-04-11 13:55:50 -03007272 conn = l2cap_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007273 if (conn)
7274 l2cap_conn_ready(conn);
Andrei Emeltchenkoba6fc312012-10-31 15:46:26 +02007275 } else {
Joe Perchese1750722011-06-29 18:18:29 -07007276 l2cap_conn_del(hcon, bt_to_errno(status));
Andrei Emeltchenkoba6fc312012-10-31 15:46:26 +02007277 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07007278}
7279
Ulisses Furquim686ebf22011-12-21 10:11:33 -02007280int l2cap_disconn_ind(struct hci_conn *hcon)
Marcel Holtmann2950f212009-02-12 14:02:50 +01007281{
7282 struct l2cap_conn *conn = hcon->l2cap_data;
7283
7284 BT_DBG("hcon %p", hcon);
7285
Ulisses Furquim686ebf22011-12-21 10:11:33 -02007286 if (!conn)
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02007287 return HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01007288 return conn->disc_reason;
7289}
7290
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03007291void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007292{
7293 BT_DBG("hcon %p reason %d", hcon, reason);
7294
Joe Perchese1750722011-06-29 18:18:29 -07007295 l2cap_conn_del(hcon, bt_to_errno(reason));
Linus Torvalds1da177e2005-04-16 15:20:36 -07007296}
7297
Gustavo F. Padovan43434782011-04-12 18:31:57 -03007298static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
Marcel Holtmannf62e4322009-01-15 21:58:44 +01007299{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03007300 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED)
Marcel Holtmann255c7602009-02-04 21:07:19 +01007301 return;
7302
Marcel Holtmannf62e4322009-01-15 21:58:44 +01007303 if (encrypt == 0x00) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03007304 if (chan->sec_level == BT_SECURITY_MEDIUM) {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08007305 __set_chan_timer(chan, L2CAP_ENC_TIMEOUT);
Marcel Holtmann7d513e92014-01-15 22:37:40 -08007306 } else if (chan->sec_level == BT_SECURITY_HIGH ||
7307 chan->sec_level == BT_SECURITY_FIPS)
Gustavo F. Padovan0f852722011-05-04 19:42:50 -03007308 l2cap_chan_close(chan, ECONNREFUSED);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01007309 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03007310 if (chan->sec_level == BT_SECURITY_MEDIUM)
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03007311 __clear_chan_timer(chan);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01007312 }
7313}
7314
Ulisses Furquim686ebf22011-12-21 10:11:33 -02007315int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007316{
Marcel Holtmann40be4922008-07-14 20:13:50 +02007317 struct l2cap_conn *conn = hcon->l2cap_data;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03007318 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007319
Marcel Holtmann01394182006-07-03 10:02:46 +02007320 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007321 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02007322
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03007323 BT_DBG("conn %p status 0x%2.2x encrypt %u", conn, status, encrypt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007324
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03007325 if (hcon->type == LE_LINK) {
Hemant Gupta35d4adcc2012-04-18 14:46:26 +05307326 if (!status && encrypt)
Johan Hedberg4bd6d382014-02-26 23:33:45 +02007327 smp_distribute_keys(conn);
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02007328 cancel_delayed_work(&conn->security_timer);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03007329 }
7330
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02007331 mutex_lock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007332
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02007333 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02007334 l2cap_chan_lock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007335
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03007336 BT_DBG("chan %p scid 0x%4.4x state %s", chan, chan->scid,
7337 state_to_string(chan->state));
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03007338
Johan Hedberg2338a7e2014-01-24 10:35:40 +02007339 if (chan->scid == L2CAP_CID_A2MP) {
Andrei Emeltchenko78eb2f92012-07-19 17:03:47 +03007340 l2cap_chan_unlock(chan);
7341 continue;
7342 }
7343
Johan Hedberg073d1cf2013-04-29 19:35:35 +03007344 if (chan->scid == L2CAP_CID_ATT) {
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03007345 if (!status && encrypt) {
7346 chan->sec_level = hcon->sec_level;
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02007347 l2cap_chan_ready(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03007348 }
7349
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02007350 l2cap_chan_unlock(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03007351 continue;
7352 }
7353
Andrei Emeltchenko96eff462012-11-15 18:14:53 +02007354 if (!__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02007355 l2cap_chan_unlock(chan);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01007356 continue;
7357 }
7358
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03007359 if (!status && (chan->state == BT_CONNECTED ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01007360 chan->state == BT_CONFIG)) {
Marcel Holtmannd97c8992013-10-14 02:53:54 -07007361 chan->ops->resume(chan);
Gustavo F. Padovan43434782011-04-12 18:31:57 -03007362 l2cap_check_encryption(chan, encrypt);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02007363 l2cap_chan_unlock(chan);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02007364 continue;
7365 }
7366
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03007367 if (chan->state == BT_CONNECT) {
Johan Hedberg6d3c15d2013-12-02 22:13:24 +02007368 if (!status)
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03007369 l2cap_start_connection(chan);
Johan Hedberg6d3c15d2013-12-02 22:13:24 +02007370 else
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08007371 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03007372 } else if (chan->state == BT_CONNECT2) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +02007373 struct l2cap_conn_rsp rsp;
Johan Hedbergdf3c3932011-06-14 12:48:19 +03007374 __u16 res, stat;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02007375
7376 if (!status) {
Marcel Holtmannbdc25782013-10-14 02:45:34 -07007377 if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
Johan Hedbergdf3c3932011-06-14 12:48:19 +03007378 res = L2CAP_CR_PEND;
7379 stat = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08007380 chan->ops->defer(chan);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03007381 } else {
Gustavo Padovanacdcabf2013-10-21 14:21:39 -02007382 l2cap_state_change(chan, BT_CONFIG);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03007383 res = L2CAP_CR_SUCCESS;
7384 stat = L2CAP_CS_NO_INFO;
7385 }
Marcel Holtmannb1235d72008-07-14 20:13:54 +02007386 } else {
Gustavo Padovanacdcabf2013-10-21 14:21:39 -02007387 l2cap_state_change(chan, BT_DISCONN);
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08007388 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03007389 res = L2CAP_CR_SEC_BLOCK;
7390 stat = L2CAP_CS_NO_INFO;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02007391 }
7392
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03007393 rsp.scid = cpu_to_le16(chan->dcid);
7394 rsp.dcid = cpu_to_le16(chan->scid);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03007395 rsp.result = cpu_to_le16(res);
7396 rsp.status = cpu_to_le16(stat);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03007397 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01007398 sizeof(rsp), &rsp);
Mat Martineau2d369352012-05-23 14:59:30 -07007399
7400 if (!test_bit(CONF_REQ_SENT, &chan->conf_state) &&
7401 res == L2CAP_CR_SUCCESS) {
7402 char buf[128];
7403 set_bit(CONF_REQ_SENT, &chan->conf_state);
7404 l2cap_send_cmd(conn, l2cap_get_ident(conn),
7405 L2CAP_CONF_REQ,
7406 l2cap_build_conf_req(chan, buf),
7407 buf);
7408 chan->num_conf_req++;
7409 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07007410 }
7411
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02007412 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007413 }
7414
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02007415 mutex_unlock(&conn->chan_lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02007416
Linus Torvalds1da177e2005-04-16 15:20:36 -07007417 return 0;
7418}
7419
Ulisses Furquim686ebf22011-12-21 10:11:33 -02007420int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007421{
7422 struct l2cap_conn *conn = hcon->l2cap_data;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03007423 struct l2cap_hdr *hdr;
7424 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007425
Andrei Emeltchenko1d13a252012-10-15 11:58:41 +03007426 /* For AMP controller do not create l2cap conn */
7427 if (!conn && hcon->hdev->dev_type != HCI_BREDR)
7428 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007429
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02007430 if (!conn)
Claudio Takahasibaf43252013-04-11 13:55:50 -03007431 conn = l2cap_conn_add(hcon);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02007432
7433 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007434 goto drop;
7435
7436 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
7437
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03007438 switch (flags) {
7439 case ACL_START:
7440 case ACL_START_NO_FLUSH:
7441 case ACL_COMPLETE:
Linus Torvalds1da177e2005-04-16 15:20:36 -07007442 if (conn->rx_len) {
7443 BT_ERR("Unexpected start frame (len %d)", skb->len);
7444 kfree_skb(conn->rx_skb);
7445 conn->rx_skb = NULL;
7446 conn->rx_len = 0;
7447 l2cap_conn_unreliable(conn, ECOMM);
7448 }
7449
Andrei Emeltchenkoaae7fe22010-09-15 14:28:43 +03007450 /* Start fragment always begin with Basic L2CAP header */
7451 if (skb->len < L2CAP_HDR_SIZE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07007452 BT_ERR("Frame is too short (len %d)", skb->len);
7453 l2cap_conn_unreliable(conn, ECOMM);
7454 goto drop;
7455 }
7456
7457 hdr = (struct l2cap_hdr *) skb->data;
7458 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
7459
7460 if (len == skb->len) {
7461 /* Complete frame received */
7462 l2cap_recv_frame(conn, skb);
7463 return 0;
7464 }
7465
7466 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
7467
7468 if (skb->len > len) {
7469 BT_ERR("Frame is too long (len %d, expected len %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01007470 skb->len, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007471 l2cap_conn_unreliable(conn, ECOMM);
7472 goto drop;
7473 }
7474
7475 /* Allocate skb for the complete frame (with header) */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03007476 conn->rx_skb = bt_skb_alloc(len, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03007477 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007478 goto drop;
7479
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03007480 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01007481 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007482 conn->rx_len = len - skb->len;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03007483 break;
7484
7485 case ACL_CONT:
Linus Torvalds1da177e2005-04-16 15:20:36 -07007486 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
7487
7488 if (!conn->rx_len) {
7489 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
7490 l2cap_conn_unreliable(conn, ECOMM);
7491 goto drop;
7492 }
7493
7494 if (skb->len > conn->rx_len) {
7495 BT_ERR("Fragment is too long (len %d, expected %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01007496 skb->len, conn->rx_len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007497 kfree_skb(conn->rx_skb);
7498 conn->rx_skb = NULL;
7499 conn->rx_len = 0;
7500 l2cap_conn_unreliable(conn, ECOMM);
7501 goto drop;
7502 }
7503
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03007504 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01007505 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007506 conn->rx_len -= skb->len;
7507
7508 if (!conn->rx_len) {
Johan Hedbergc4e5baf2013-10-10 13:33:37 +02007509 /* Complete frame received. l2cap_recv_frame
7510 * takes ownership of the skb so set the global
7511 * rx_skb pointer to NULL first.
7512 */
7513 struct sk_buff *rx_skb = conn->rx_skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007514 conn->rx_skb = NULL;
Johan Hedbergc4e5baf2013-10-10 13:33:37 +02007515 l2cap_recv_frame(conn, rx_skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007516 }
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03007517 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007518 }
7519
7520drop:
7521 kfree_skb(skb);
7522 return 0;
7523}
7524
Marcel Holtmannaef7d972010-03-21 05:27:45 +01007525static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007526{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007527 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007528
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02007529 read_lock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007530
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007531 list_for_each_entry(c, &chan_list, global_l) {
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +03007532 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 -07007533 &c->src, &c->dst,
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +03007534 c->state, __le16_to_cpu(c->psm),
7535 c->scid, c->dcid, c->imtu, c->omtu,
7536 c->sec_level, c->mode);
Andrei Emeltchenko61e1b4b2012-01-19 11:19:50 +02007537 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07007538
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02007539 read_unlock(&chan_list_lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08007540
Marcel Holtmannaef7d972010-03-21 05:27:45 +01007541 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007542}
7543
Marcel Holtmannaef7d972010-03-21 05:27:45 +01007544static int l2cap_debugfs_open(struct inode *inode, struct file *file)
7545{
7546 return single_open(file, l2cap_debugfs_show, inode->i_private);
7547}
7548
7549static const struct file_operations l2cap_debugfs_fops = {
7550 .open = l2cap_debugfs_open,
7551 .read = seq_read,
7552 .llseek = seq_lseek,
7553 .release = single_release,
7554};
7555
7556static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007557
Gustavo F. Padovan64274512011-02-07 20:08:52 -02007558int __init l2cap_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007559{
7560 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08007561
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02007562 err = l2cap_init_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07007563 if (err < 0)
7564 return err;
7565
Marcel Holtmann1120e4b2013-10-17 17:24:16 -07007566 if (IS_ERR_OR_NULL(bt_debugfs))
7567 return 0;
7568
7569 l2cap_debugfs = debugfs_create_file("l2cap", 0444, bt_debugfs,
7570 NULL, &l2cap_debugfs_fops);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007571
Samuel Ortiz40b93972014-05-14 17:53:35 +02007572 debugfs_create_u16("l2cap_le_max_credits", 0644, bt_debugfs,
Johan Hedbergf15b8ec2013-12-03 15:08:25 +02007573 &le_max_credits);
Samuel Ortiz40b93972014-05-14 17:53:35 +02007574 debugfs_create_u16("l2cap_le_default_mps", 0644, bt_debugfs,
Johan Hedbergf15b8ec2013-12-03 15:08:25 +02007575 &le_default_mps);
7576
Linus Torvalds1da177e2005-04-16 15:20:36 -07007577 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007578}
7579
Gustavo F. Padovan64274512011-02-07 20:08:52 -02007580void l2cap_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007581{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01007582 debugfs_remove(l2cap_debugfs);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02007583 l2cap_cleanup_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07007584}
7585
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03007586module_param(disable_ertm, bool, 0644);
7587MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode");