blob: 66fbac91eaedd9acf24245e0bcfe79137c4043b9 [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"
Jukka Rissanen18722c22013-12-11 17:05:37 +020043#include "6lowpan.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070044
Johan Hedberg0f1bfe42014-01-27 15:11:35 -080045#define LE_FLOWCTL_MAX_CREDITS 65535
46
Mat Martineaud1de6d42012-05-17 20:53:55 -070047bool disable_ertm;
Marcel Holtmannf0709e02007-10-20 13:38:51 +020048
Marcel Holtmann547d1032013-10-12 08:18:19 -070049static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN | L2CAP_FEAT_UCD;
Marcel Holtmannd40bffb2013-10-12 08:18:18 -070050static u8 l2cap_fixed_chan[8] = { L2CAP_FC_L2CAP | L2CAP_FC_CONNLESS, };
Linus Torvalds1da177e2005-04-16 15:20:36 -070051
Johannes Bergb5ad8b72011-06-01 08:54:45 +020052static LIST_HEAD(chan_list);
53static DEFINE_RWLOCK(chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -070054
Johan Hedbergf15b8ec2013-12-03 15:08:25 +020055static u16 le_max_credits = L2CAP_LE_MAX_CREDITS;
56static u16 le_default_mps = L2CAP_LE_DEFAULT_MPS;
57
Linus Torvalds1da177e2005-04-16 15:20:36 -070058static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +010059 u8 code, u8 ident, u16 dlen, void *data);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -030060static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
Gustavo Padovan2d792812012-10-06 10:07:01 +010061 void *data);
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -030062static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +020063static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err);
Linus Torvalds1da177e2005-04-16 15:20:36 -070064
Gustavo Padovand6603662012-05-21 13:58:22 -030065static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
Gustavo Padovan2d792812012-10-06 10:07:01 +010066 struct sk_buff_head *skbs, u8 event);
Mat Martineau608bcc62012-05-17 20:53:32 -070067
Marcel Holtmann4f1654e2013-10-13 08:50:41 -070068static inline __u8 bdaddr_type(struct hci_conn *hcon, __u8 type)
69{
70 if (hcon->type == LE_LINK) {
71 if (type == ADDR_LE_DEV_PUBLIC)
72 return BDADDR_LE_PUBLIC;
73 else
74 return BDADDR_LE_RANDOM;
75 }
76
77 return BDADDR_BREDR;
78}
79
Marcel Holtmann01394182006-07-03 10:02:46 +020080/* ---- L2CAP channels ---- */
Gustavo F. Padovan71ba0e52011-05-17 14:34:52 -030081
Gustavo Padovan2d792812012-10-06 10:07:01 +010082static struct l2cap_chan *__l2cap_get_chan_by_dcid(struct l2cap_conn *conn,
83 u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +020084{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020085 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030086
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020087 list_for_each_entry(c, &conn->chan_l, list) {
88 if (c->dcid == cid)
89 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +020090 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020091 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +020092}
93
Gustavo Padovan2d792812012-10-06 10:07:01 +010094static struct l2cap_chan *__l2cap_get_chan_by_scid(struct l2cap_conn *conn,
95 u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +020096{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020097 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030098
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020099 list_for_each_entry(c, &conn->chan_l, list) {
100 if (c->scid == cid)
101 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +0200102 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200103 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200104}
105
106/* Find channel with given SCID.
Mat Martineauef191ad2012-05-02 09:42:00 -0700107 * Returns locked channel. */
Gustavo Padovan2d792812012-10-06 10:07:01 +0100108static struct l2cap_chan *l2cap_get_chan_by_scid(struct l2cap_conn *conn,
109 u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +0200110{
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300111 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300112
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200113 mutex_lock(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300114 c = __l2cap_get_chan_by_scid(conn, cid);
Mat Martineauef191ad2012-05-02 09:42:00 -0700115 if (c)
116 l2cap_chan_lock(c);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200117 mutex_unlock(&conn->chan_lock);
118
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300119 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +0200120}
121
Mat Martineaub1a130b2012-10-23 15:24:09 -0700122/* Find channel with given DCID.
123 * Returns locked channel.
124 */
125static struct l2cap_chan *l2cap_get_chan_by_dcid(struct l2cap_conn *conn,
126 u16 cid)
127{
128 struct l2cap_chan *c;
129
130 mutex_lock(&conn->chan_lock);
131 c = __l2cap_get_chan_by_dcid(conn, cid);
132 if (c)
133 l2cap_chan_lock(c);
134 mutex_unlock(&conn->chan_lock);
135
136 return c;
137}
138
Gustavo Padovan2d792812012-10-06 10:07:01 +0100139static struct l2cap_chan *__l2cap_get_chan_by_ident(struct l2cap_conn *conn,
140 u8 ident)
Marcel Holtmann01394182006-07-03 10:02:46 +0200141{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200142 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300143
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200144 list_for_each_entry(c, &conn->chan_l, list) {
145 if (c->ident == ident)
146 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +0200147 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200148 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200149}
150
Mat Martineau5b155ef2012-10-23 15:24:14 -0700151static struct l2cap_chan *l2cap_get_chan_by_ident(struct l2cap_conn *conn,
152 u8 ident)
153{
154 struct l2cap_chan *c;
155
156 mutex_lock(&conn->chan_lock);
157 c = __l2cap_get_chan_by_ident(conn, ident);
158 if (c)
159 l2cap_chan_lock(c);
160 mutex_unlock(&conn->chan_lock);
161
162 return c;
163}
164
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300165static struct l2cap_chan *__l2cap_global_chan_by_addr(__le16 psm, bdaddr_t *src)
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300166{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300167 struct l2cap_chan *c;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300168
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300169 list_for_each_entry(c, &chan_list, global_l) {
Marcel Holtmann7eafc592013-10-13 08:12:47 -0700170 if (c->sport == psm && !bacmp(&c->src, src))
Szymon Janc250938c2011-11-16 09:32:22 +0100171 return c;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300172 }
Szymon Janc250938c2011-11-16 09:32:22 +0100173 return NULL;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300174}
175
176int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm)
177{
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300178 int err;
179
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200180 write_lock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300181
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300182 if (psm && __l2cap_global_chan_by_addr(psm, src)) {
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300183 err = -EADDRINUSE;
184 goto done;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300185 }
186
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300187 if (psm) {
188 chan->psm = psm;
189 chan->sport = psm;
190 err = 0;
191 } else {
192 u16 p;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300193
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300194 err = -EINVAL;
195 for (p = 0x1001; p < 0x1100; p += 2)
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300196 if (!__l2cap_global_chan_by_addr(cpu_to_le16(p), src)) {
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300197 chan->psm = cpu_to_le16(p);
198 chan->sport = cpu_to_le16(p);
199 err = 0;
200 break;
201 }
202 }
203
204done:
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200205 write_unlock(&chan_list_lock);
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300206 return err;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300207}
208
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}
440
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530441static void l2cap_chan_destroy(struct kref *kref)
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300442{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530443 struct l2cap_chan *chan = container_of(kref, struct l2cap_chan, kref);
444
Jaganath Kanakkassery4af66c62012-07-13 18:17:55 +0530445 BT_DBG("chan %p", chan);
446
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200447 write_lock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300448 list_del(&chan->global_l);
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200449 write_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300450
Jaganath Kanakkassery4af66c62012-07-13 18:17:55 +0530451 kfree(chan);
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300452}
453
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530454void l2cap_chan_hold(struct l2cap_chan *c)
455{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530456 BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->kref.refcount));
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530457
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530458 kref_get(&c->kref);
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530459}
460
461void l2cap_chan_put(struct l2cap_chan *c)
462{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530463 BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->kref.refcount));
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530464
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530465 kref_put(&c->kref, l2cap_chan_destroy);
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530466}
467
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +0300468void l2cap_chan_set_defaults(struct l2cap_chan *chan)
469{
470 chan->fcs = L2CAP_FCS_CRC16;
471 chan->max_tx = L2CAP_DEFAULT_MAX_TX;
472 chan->tx_win = L2CAP_DEFAULT_TX_WINDOW;
473 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
Mat Martineauc20f8e32012-07-10 05:47:07 -0700474 chan->ack_win = L2CAP_DEFAULT_TX_WINDOW;
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +0300475 chan->sec_level = BT_SECURITY_LOW;
476
477 set_bit(FLAG_FORCE_ACTIVE, &chan->flags);
478}
479
Johan Hedberg0ce43ce2013-12-05 14:55:33 +0200480static void l2cap_le_flowctl_init(struct l2cap_chan *chan)
Johan Hedberg38319712013-05-17 12:49:23 +0300481{
Johan Hedberg0ce43ce2013-12-05 14:55:33 +0200482 chan->sdu = NULL;
483 chan->sdu_last_frag = NULL;
484 chan->sdu_len = 0;
Johan Hedberg0cd75f72013-05-17 13:09:05 +0300485 chan->tx_credits = 0;
Johan Hedbergf15b8ec2013-12-03 15:08:25 +0200486 chan->rx_credits = le_max_credits;
Johan Hedbergd1d79412014-01-27 15:11:33 -0800487 chan->mps = min_t(u16, chan->imtu, le_default_mps);
Johan Hedberg0ce43ce2013-12-05 14:55:33 +0200488
489 skb_queue_head_init(&chan->tx_q);
Johan Hedberg38319712013-05-17 12:49:23 +0300490}
491
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +0300492void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Marcel Holtmann01394182006-07-03 10:02:46 +0200493{
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300494 BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
Andrei Emeltchenko097db762012-03-09 14:16:17 +0200495 __le16_to_cpu(chan->psm), chan->dcid);
Marcel Holtmann01394182006-07-03 10:02:46 +0200496
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +0200497 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +0100498
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300499 chan->conn = conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200500
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200501 switch (chan->chan_type) {
502 case L2CAP_CHAN_CONN_ORIENTED:
Johan Hedberg21626e62014-01-24 10:35:41 +0200503 /* Alloc CID for connection-oriented socket */
504 chan->scid = l2cap_alloc_cid(conn);
505 if (conn->hcon->type == ACL_LINK)
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300506 chan->omtu = L2CAP_DEFAULT_MTU;
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200507 break;
508
509 case L2CAP_CHAN_CONN_LESS:
Marcel Holtmann01394182006-07-03 10:02:46 +0200510 /* Connectionless socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300511 chan->scid = L2CAP_CID_CONN_LESS;
512 chan->dcid = L2CAP_CID_CONN_LESS;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300513 chan->omtu = L2CAP_DEFAULT_MTU;
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200514 break;
515
Johan Hedberg2338a7e2014-01-24 10:35:40 +0200516 case L2CAP_CHAN_FIXED:
517 /* Caller will set CID and CID specific MTU values */
Andrei Emeltchenko416fa752012-05-29 13:59:16 +0300518 break;
519
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200520 default:
Marcel Holtmann01394182006-07-03 10:02:46 +0200521 /* Raw socket can send/recv signalling messages only */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300522 chan->scid = L2CAP_CID_SIGNALING;
523 chan->dcid = L2CAP_CID_SIGNALING;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300524 chan->omtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann01394182006-07-03 10:02:46 +0200525 }
526
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300527 chan->local_id = L2CAP_BESTEFFORT_ID;
528 chan->local_stype = L2CAP_SERV_BESTEFFORT;
529 chan->local_msdu = L2CAP_DEFAULT_MAX_SDU_SIZE;
530 chan->local_sdu_itime = L2CAP_DEFAULT_SDU_ITIME;
531 chan->local_acc_lat = L2CAP_DEFAULT_ACC_LAT;
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +0300532 chan->local_flush_to = L2CAP_EFS_DEFAULT_FLUSH_TO;
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300533
Ulisses Furquim371fd832011-12-21 20:02:36 -0200534 l2cap_chan_hold(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300535
Johan Hedberg5ee98912013-04-29 19:35:43 +0300536 hci_conn_hold(conn->hcon);
537
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200538 list_add(&chan->list, &conn->chan_l);
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200539}
540
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300541void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200542{
543 mutex_lock(&conn->chan_lock);
544 __l2cap_chan_add(conn, chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200545 mutex_unlock(&conn->chan_lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200546}
547
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300548void l2cap_chan_del(struct l2cap_chan *chan, int err)
Marcel Holtmann01394182006-07-03 10:02:46 +0200549{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300550 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200551
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300552 __clear_chan_timer(chan);
Marcel Holtmann01394182006-07-03 10:02:46 +0200553
Gustavo F. Padovan49208c92011-04-04 15:59:54 -0300554 BT_DBG("chan %p, conn %p, err %d", chan, conn, err);
Marcel Holtmann01394182006-07-03 10:02:46 +0200555
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900556 if (conn) {
Andrei Emeltchenko56f60982012-10-15 11:58:44 +0300557 struct amp_mgr *mgr = conn->hcon->amp_mgr;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300558 /* Delete from channel list */
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200559 list_del(&chan->list);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -0200560
Ulisses Furquim371fd832011-12-21 20:02:36 -0200561 l2cap_chan_put(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300562
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300563 chan->conn = NULL;
Andrei Emeltchenko3cabbfd2012-05-31 11:01:37 +0300564
Johan Hedberg2338a7e2014-01-24 10:35:40 +0200565 if (chan->scid != L2CAP_CID_A2MP)
David Herrmann76a68ba2013-04-06 20:28:37 +0200566 hci_conn_drop(conn->hcon);
Andrei Emeltchenko56f60982012-10-15 11:58:44 +0300567
568 if (mgr && mgr->bredr_chan == chan)
569 mgr->bredr_chan = NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200570 }
571
Andrei Emeltchenko419e08c2012-10-31 15:46:34 +0200572 if (chan->hs_hchan) {
573 struct hci_chan *hs_hchan = chan->hs_hchan;
574
575 BT_DBG("chan %p disconnect hs_hchan %p", chan, hs_hchan);
576 amp_disconnect_logical_link(hs_hchan);
577 }
578
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100579 chan->ops->teardown(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200580
Mat Martineau28270112012-05-17 21:14:09 -0700581 if (test_bit(CONF_NOT_COMPLETE, &chan->conf_state))
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300582 return;
Gustavo F. Padovan2ead70b2011-04-01 15:13:36 -0300583
Gustavo Padovanee556f62012-05-18 20:22:38 -0300584 switch(chan->mode) {
585 case L2CAP_MODE_BASIC:
586 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300587
Johan Hedberg38319712013-05-17 12:49:23 +0300588 case L2CAP_MODE_LE_FLOWCTL:
Johan Hedberg177f8f22013-05-31 17:54:51 +0300589 skb_queue_purge(&chan->tx_q);
Johan Hedberg38319712013-05-17 12:49:23 +0300590 break;
591
Gustavo Padovanee556f62012-05-18 20:22:38 -0300592 case L2CAP_MODE_ERTM:
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -0300593 __clear_retrans_timer(chan);
594 __clear_monitor_timer(chan);
595 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300596
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -0300597 skb_queue_purge(&chan->srej_q);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300598
Mat Martineau3c588192012-04-11 10:48:42 -0700599 l2cap_seq_list_free(&chan->srej_list);
600 l2cap_seq_list_free(&chan->retrans_list);
Gustavo Padovanee556f62012-05-18 20:22:38 -0300601
602 /* fall through */
603
604 case L2CAP_MODE_STREAMING:
605 skb_queue_purge(&chan->tx_q);
606 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300607 }
Gustavo Padovanee556f62012-05-18 20:22:38 -0300608
609 return;
Marcel Holtmann01394182006-07-03 10:02:46 +0200610}
611
Johan Hedberg27e2d4c2013-05-14 13:27:21 +0300612static void l2cap_chan_le_connect_reject(struct l2cap_chan *chan)
613{
614 struct l2cap_conn *conn = chan->conn;
615 struct l2cap_le_conn_rsp rsp;
616 u16 result;
617
618 if (test_bit(FLAG_DEFER_SETUP, &chan->flags))
619 result = L2CAP_CR_AUTHORIZATION;
620 else
621 result = L2CAP_CR_BAD_PSM;
622
623 l2cap_state_change(chan, BT_DISCONN);
624
625 rsp.dcid = cpu_to_le16(chan->scid);
626 rsp.mtu = cpu_to_le16(chan->imtu);
Johan Hedberg3916aed2013-10-07 15:35:26 +0200627 rsp.mps = cpu_to_le16(chan->mps);
Johan Hedberg0cd75f72013-05-17 13:09:05 +0300628 rsp.credits = cpu_to_le16(chan->rx_credits);
Johan Hedberg27e2d4c2013-05-14 13:27:21 +0300629 rsp.result = cpu_to_le16(result);
630
631 l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CONN_RSP, sizeof(rsp),
632 &rsp);
633}
634
Johan Hedberg791d60f2013-05-14 22:24:44 +0300635static void l2cap_chan_connect_reject(struct l2cap_chan *chan)
636{
637 struct l2cap_conn *conn = chan->conn;
638 struct l2cap_conn_rsp rsp;
639 u16 result;
640
641 if (test_bit(FLAG_DEFER_SETUP, &chan->flags))
642 result = L2CAP_CR_SEC_BLOCK;
643 else
644 result = L2CAP_CR_BAD_PSM;
645
646 l2cap_state_change(chan, BT_DISCONN);
647
648 rsp.scid = cpu_to_le16(chan->dcid);
649 rsp.dcid = cpu_to_le16(chan->scid);
650 rsp.result = cpu_to_le16(result);
651 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
652
653 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
654}
655
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300656void l2cap_chan_close(struct l2cap_chan *chan, int reason)
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300657{
658 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300659
Marcel Holtmann7eafc592013-10-13 08:12:47 -0700660 BT_DBG("chan %p state %s", chan, state_to_string(chan->state));
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300661
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300662 switch (chan->state) {
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300663 case BT_LISTEN:
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100664 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300665 break;
666
667 case BT_CONNECTED:
668 case BT_CONFIG:
Johan Hedberg7b25c9b2014-01-28 15:28:04 -0800669 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED) {
Gustavo Padovan8d836d72013-10-15 19:24:47 -0300670 __set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +0200671 l2cap_send_disconn_req(chan, reason);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300672 } else
673 l2cap_chan_del(chan, reason);
674 break;
675
676 case BT_CONNECT2:
Johan Hedberg791d60f2013-05-14 22:24:44 +0300677 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED) {
678 if (conn->hcon->type == ACL_LINK)
679 l2cap_chan_connect_reject(chan);
Johan Hedberg27e2d4c2013-05-14 13:27:21 +0300680 else if (conn->hcon->type == LE_LINK)
681 l2cap_chan_le_connect_reject(chan);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300682 }
683
684 l2cap_chan_del(chan, reason);
685 break;
686
687 case BT_CONNECT:
688 case BT_DISCONN:
689 l2cap_chan_del(chan, reason);
690 break;
691
692 default:
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100693 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300694 break;
695 }
696}
697
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300698static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530699{
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700700 switch (chan->chan_type) {
701 case L2CAP_CHAN_RAW:
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300702 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530703 case BT_SECURITY_HIGH:
Marcel Holtmann7d513e92014-01-15 22:37:40 -0800704 case BT_SECURITY_FIPS:
Johan Hedberg8556edd32011-01-19 12:06:50 +0530705 return HCI_AT_DEDICATED_BONDING_MITM;
706 case BT_SECURITY_MEDIUM:
707 return HCI_AT_DEDICATED_BONDING;
708 default:
709 return HCI_AT_NO_BONDING;
710 }
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700711 break;
Marcel Holtmann3124b842013-10-12 07:19:32 -0700712 case L2CAP_CHAN_CONN_LESS:
713 if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_3DSP)) {
714 if (chan->sec_level == BT_SECURITY_LOW)
715 chan->sec_level = BT_SECURITY_SDP;
716 }
Marcel Holtmann7d513e92014-01-15 22:37:40 -0800717 if (chan->sec_level == BT_SECURITY_HIGH ||
718 chan->sec_level == BT_SECURITY_FIPS)
Marcel Holtmann3124b842013-10-12 07:19:32 -0700719 return HCI_AT_NO_BONDING_MITM;
720 else
721 return HCI_AT_NO_BONDING;
722 break;
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700723 case L2CAP_CHAN_CONN_ORIENTED:
724 if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_SDP)) {
725 if (chan->sec_level == BT_SECURITY_LOW)
726 chan->sec_level = BT_SECURITY_SDP;
Johan Hedberg8556edd32011-01-19 12:06:50 +0530727
Marcel Holtmann7d513e92014-01-15 22:37:40 -0800728 if (chan->sec_level == BT_SECURITY_HIGH ||
729 chan->sec_level == BT_SECURITY_FIPS)
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700730 return HCI_AT_NO_BONDING_MITM;
731 else
732 return HCI_AT_NO_BONDING;
733 }
734 /* fall through */
735 default:
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300736 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530737 case BT_SECURITY_HIGH:
Marcel Holtmann7d513e92014-01-15 22:37:40 -0800738 case BT_SECURITY_FIPS:
Johan Hedberg8556edd32011-01-19 12:06:50 +0530739 return HCI_AT_GENERAL_BONDING_MITM;
740 case BT_SECURITY_MEDIUM:
741 return HCI_AT_GENERAL_BONDING;
742 default:
743 return HCI_AT_NO_BONDING;
744 }
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700745 break;
Johan Hedberg8556edd32011-01-19 12:06:50 +0530746 }
747}
748
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200749/* Service level security */
Gustavo F. Padovand45fc422011-11-05 19:54:24 -0200750int l2cap_chan_check_security(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200751{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300752 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100753 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200754
Johan Hedberga17de2f2013-05-14 13:25:37 +0300755 if (conn->hcon->type == LE_LINK)
756 return smp_conn_security(conn->hcon, chan->sec_level);
757
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300758 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100759
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300760 return hci_conn_security(conn->hcon, chan->sec_level, auth_type);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200761}
762
Johannes Bergb5ad8b72011-06-01 08:54:45 +0200763static u8 l2cap_get_ident(struct l2cap_conn *conn)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200764{
765 u8 id;
766
767 /* Get next available identificator.
768 * 1 - 128 are used by kernel.
769 * 129 - 199 are reserved.
770 * 200 - 254 are used by utilities like l2ping, etc.
771 */
772
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200773 spin_lock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200774
775 if (++conn->tx_ident > 128)
776 conn->tx_ident = 1;
777
778 id = conn->tx_ident;
779
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200780 spin_unlock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200781
782 return id;
783}
784
Gustavo Padovan2d792812012-10-06 10:07:01 +0100785static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
786 void *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200787{
788 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200789 u8 flags;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200790
791 BT_DBG("code 0x%2.2x", code);
792
793 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300794 return;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200795
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200796 if (lmp_no_flush_capable(conn->hcon->hdev))
797 flags = ACL_START_NO_FLUSH;
798 else
799 flags = ACL_START;
800
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700801 bt_cb(skb)->force_active = BT_POWER_FORCE_ACTIVE_ON;
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +0200802 skb->priority = HCI_PRIO_MAX;
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700803
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200804 hci_send_acl(conn->hchan, skb, flags);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200805}
806
Mat Martineau02b0fbb2012-10-23 15:24:10 -0700807static bool __chan_is_moving(struct l2cap_chan *chan)
808{
809 return chan->move_state != L2CAP_MOVE_STABLE &&
810 chan->move_state != L2CAP_MOVE_WAIT_PREPARE;
811}
812
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200813static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb)
814{
815 struct hci_conn *hcon = chan->conn->hcon;
816 u16 flags;
817
818 BT_DBG("chan %p, skb %p len %d priority %u", chan, skb, skb->len,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100819 skb->priority);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200820
Mat Martineaud5f8a752012-10-23 15:24:18 -0700821 if (chan->hs_hcon && !__chan_is_moving(chan)) {
822 if (chan->hs_hchan)
823 hci_send_acl(chan->hs_hchan, skb, ACL_COMPLETE);
824 else
825 kfree_skb(skb);
826
827 return;
828 }
829
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200830 if (!test_bit(FLAG_FLUSHABLE, &chan->flags) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100831 lmp_no_flush_capable(hcon->hdev))
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200832 flags = ACL_START_NO_FLUSH;
833 else
834 flags = ACL_START;
835
836 bt_cb(skb)->force_active = test_bit(FLAG_FORCE_ACTIVE, &chan->flags);
837 hci_send_acl(chan->conn->hchan, skb, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700838}
839
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700840static void __unpack_enhanced_control(u16 enh, struct l2cap_ctrl *control)
841{
842 control->reqseq = (enh & L2CAP_CTRL_REQSEQ) >> L2CAP_CTRL_REQSEQ_SHIFT;
843 control->final = (enh & L2CAP_CTRL_FINAL) >> L2CAP_CTRL_FINAL_SHIFT;
844
845 if (enh & L2CAP_CTRL_FRAME_TYPE) {
846 /* S-Frame */
847 control->sframe = 1;
848 control->poll = (enh & L2CAP_CTRL_POLL) >> L2CAP_CTRL_POLL_SHIFT;
849 control->super = (enh & L2CAP_CTRL_SUPERVISE) >> L2CAP_CTRL_SUPER_SHIFT;
850
851 control->sar = 0;
852 control->txseq = 0;
853 } else {
854 /* I-Frame */
855 control->sframe = 0;
856 control->sar = (enh & L2CAP_CTRL_SAR) >> L2CAP_CTRL_SAR_SHIFT;
857 control->txseq = (enh & L2CAP_CTRL_TXSEQ) >> L2CAP_CTRL_TXSEQ_SHIFT;
858
859 control->poll = 0;
860 control->super = 0;
861 }
862}
863
864static void __unpack_extended_control(u32 ext, struct l2cap_ctrl *control)
865{
866 control->reqseq = (ext & L2CAP_EXT_CTRL_REQSEQ) >> L2CAP_EXT_CTRL_REQSEQ_SHIFT;
867 control->final = (ext & L2CAP_EXT_CTRL_FINAL) >> L2CAP_EXT_CTRL_FINAL_SHIFT;
868
869 if (ext & L2CAP_EXT_CTRL_FRAME_TYPE) {
870 /* S-Frame */
871 control->sframe = 1;
872 control->poll = (ext & L2CAP_EXT_CTRL_POLL) >> L2CAP_EXT_CTRL_POLL_SHIFT;
873 control->super = (ext & L2CAP_EXT_CTRL_SUPERVISE) >> L2CAP_EXT_CTRL_SUPER_SHIFT;
874
875 control->sar = 0;
876 control->txseq = 0;
877 } else {
878 /* I-Frame */
879 control->sframe = 0;
880 control->sar = (ext & L2CAP_EXT_CTRL_SAR) >> L2CAP_EXT_CTRL_SAR_SHIFT;
881 control->txseq = (ext & L2CAP_EXT_CTRL_TXSEQ) >> L2CAP_EXT_CTRL_TXSEQ_SHIFT;
882
883 control->poll = 0;
884 control->super = 0;
885 }
886}
887
888static inline void __unpack_control(struct l2cap_chan *chan,
889 struct sk_buff *skb)
890{
891 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
892 __unpack_extended_control(get_unaligned_le32(skb->data),
893 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700894 skb_pull(skb, L2CAP_EXT_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700895 } else {
896 __unpack_enhanced_control(get_unaligned_le16(skb->data),
897 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700898 skb_pull(skb, L2CAP_ENH_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700899 }
900}
901
902static u32 __pack_extended_control(struct l2cap_ctrl *control)
903{
904 u32 packed;
905
906 packed = control->reqseq << L2CAP_EXT_CTRL_REQSEQ_SHIFT;
907 packed |= control->final << L2CAP_EXT_CTRL_FINAL_SHIFT;
908
909 if (control->sframe) {
910 packed |= control->poll << L2CAP_EXT_CTRL_POLL_SHIFT;
911 packed |= control->super << L2CAP_EXT_CTRL_SUPER_SHIFT;
912 packed |= L2CAP_EXT_CTRL_FRAME_TYPE;
913 } else {
914 packed |= control->sar << L2CAP_EXT_CTRL_SAR_SHIFT;
915 packed |= control->txseq << L2CAP_EXT_CTRL_TXSEQ_SHIFT;
916 }
917
918 return packed;
919}
920
921static u16 __pack_enhanced_control(struct l2cap_ctrl *control)
922{
923 u16 packed;
924
925 packed = control->reqseq << L2CAP_CTRL_REQSEQ_SHIFT;
926 packed |= control->final << L2CAP_CTRL_FINAL_SHIFT;
927
928 if (control->sframe) {
929 packed |= control->poll << L2CAP_CTRL_POLL_SHIFT;
930 packed |= control->super << L2CAP_CTRL_SUPER_SHIFT;
931 packed |= L2CAP_CTRL_FRAME_TYPE;
932 } else {
933 packed |= control->sar << L2CAP_CTRL_SAR_SHIFT;
934 packed |= control->txseq << L2CAP_CTRL_TXSEQ_SHIFT;
935 }
936
937 return packed;
938}
939
940static inline void __pack_control(struct l2cap_chan *chan,
941 struct l2cap_ctrl *control,
942 struct sk_buff *skb)
943{
944 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
945 put_unaligned_le32(__pack_extended_control(control),
946 skb->data + L2CAP_HDR_SIZE);
947 } else {
948 put_unaligned_le16(__pack_enhanced_control(control),
949 skb->data + L2CAP_HDR_SIZE);
950 }
951}
952
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300953static inline unsigned int __ertm_hdr_size(struct l2cap_chan *chan)
954{
955 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
956 return L2CAP_EXT_HDR_SIZE;
957 else
958 return L2CAP_ENH_HDR_SIZE;
959}
960
Mat Martineaua67d7f62012-05-17 20:53:35 -0700961static struct sk_buff *l2cap_create_sframe_pdu(struct l2cap_chan *chan,
962 u32 control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300963{
964 struct sk_buff *skb;
965 struct l2cap_hdr *lh;
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300966 int hlen = __ertm_hdr_size(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300967
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300968 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300969 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300970
Mat Martineaua67d7f62012-05-17 20:53:35 -0700971 skb = bt_skb_alloc(hlen, GFP_KERNEL);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300972
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300973 if (!skb)
Mat Martineaua67d7f62012-05-17 20:53:35 -0700974 return ERR_PTR(-ENOMEM);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300975
976 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300977 lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300978 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +0300979
Mat Martineaua67d7f62012-05-17 20:53:35 -0700980 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
981 put_unaligned_le32(control, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
982 else
983 put_unaligned_le16(control, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300984
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -0300985 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineaua67d7f62012-05-17 20:53:35 -0700986 u16 fcs = crc16(0, (u8 *)skb->data, skb->len);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300987 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300988 }
989
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200990 skb->priority = HCI_PRIO_MAX;
Mat Martineaua67d7f62012-05-17 20:53:35 -0700991 return skb;
992}
993
994static void l2cap_send_sframe(struct l2cap_chan *chan,
995 struct l2cap_ctrl *control)
996{
997 struct sk_buff *skb;
998 u32 control_field;
999
1000 BT_DBG("chan %p, control %p", chan, control);
1001
1002 if (!control->sframe)
1003 return;
1004
Mat Martineaub99e13a2012-10-23 15:24:19 -07001005 if (__chan_is_moving(chan))
1006 return;
1007
Mat Martineaua67d7f62012-05-17 20:53:35 -07001008 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state) &&
1009 !control->poll)
1010 control->final = 1;
1011
1012 if (control->super == L2CAP_SUPER_RR)
1013 clear_bit(CONN_RNR_SENT, &chan->conn_state);
1014 else if (control->super == L2CAP_SUPER_RNR)
1015 set_bit(CONN_RNR_SENT, &chan->conn_state);
1016
1017 if (control->super != L2CAP_SUPER_SREJ) {
1018 chan->last_acked_seq = control->reqseq;
1019 __clear_ack_timer(chan);
1020 }
1021
1022 BT_DBG("reqseq %d, final %d, poll %d, super %d", control->reqseq,
1023 control->final, control->poll, control->super);
1024
1025 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
1026 control_field = __pack_extended_control(control);
1027 else
1028 control_field = __pack_enhanced_control(control);
1029
1030 skb = l2cap_create_sframe_pdu(chan, control_field);
1031 if (!IS_ERR(skb))
1032 l2cap_do_send(chan, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001033}
1034
Mat Martineauc9e3d5e2012-05-17 20:53:48 -07001035static void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, bool poll)
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001036{
Mat Martineauc9e3d5e2012-05-17 20:53:48 -07001037 struct l2cap_ctrl control;
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001038
Mat Martineauc9e3d5e2012-05-17 20:53:48 -07001039 BT_DBG("chan %p, poll %d", chan, poll);
1040
1041 memset(&control, 0, sizeof(control));
1042 control.sframe = 1;
1043 control.poll = poll;
1044
1045 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
1046 control.super = L2CAP_SUPER_RNR;
1047 else
1048 control.super = L2CAP_SUPER_RR;
1049
1050 control.reqseq = chan->buffer_seq;
1051 l2cap_send_sframe(chan, &control);
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001052}
1053
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03001054static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan)
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03001055{
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001056 return !test_bit(CONF_CONNECT_PEND, &chan->conf_state);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03001057}
1058
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001059static bool __amp_capable(struct l2cap_chan *chan)
1060{
1061 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann1df7b172013-10-05 11:47:49 -07001062 struct hci_dev *hdev;
1063 bool amp_available = false;
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001064
Marcel Holtmann1df7b172013-10-05 11:47:49 -07001065 if (!conn->hs_enabled)
1066 return false;
1067
1068 if (!(conn->fixed_chan_mask & L2CAP_FC_A2MP))
1069 return false;
1070
1071 read_lock(&hci_dev_list_lock);
1072 list_for_each_entry(hdev, &hci_dev_list, list) {
1073 if (hdev->amp_type != AMP_TYPE_BREDR &&
1074 test_bit(HCI_UP, &hdev->flags)) {
1075 amp_available = true;
1076 break;
1077 }
1078 }
1079 read_unlock(&hci_dev_list_lock);
1080
1081 if (chan->chan_policy == BT_CHANNEL_POLICY_AMP_PREFERRED)
1082 return amp_available;
Marcel Holtmann848566b2013-10-01 22:59:22 -07001083
1084 return false;
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001085}
1086
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +02001087static bool l2cap_check_efs(struct l2cap_chan *chan)
1088{
1089 /* Check EFS parameters */
1090 return true;
1091}
1092
Andrei Emeltchenko2766be42012-09-27 17:26:21 +03001093void l2cap_send_conn_req(struct l2cap_chan *chan)
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +02001094{
1095 struct l2cap_conn *conn = chan->conn;
1096 struct l2cap_conn_req req;
1097
1098 req.scid = cpu_to_le16(chan->scid);
1099 req.psm = chan->psm;
1100
1101 chan->ident = l2cap_get_ident(conn);
1102
1103 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
1104
1105 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, sizeof(req), &req);
1106}
1107
Mat Martineau8eb200b2012-10-23 15:24:17 -07001108static void l2cap_send_create_chan_req(struct l2cap_chan *chan, u8 amp_id)
1109{
1110 struct l2cap_create_chan_req req;
1111 req.scid = cpu_to_le16(chan->scid);
1112 req.psm = chan->psm;
1113 req.amp_id = amp_id;
1114
1115 chan->ident = l2cap_get_ident(chan->conn);
1116
1117 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_REQ,
1118 sizeof(req), &req);
1119}
1120
Mat Martineau02b0fbb2012-10-23 15:24:10 -07001121static void l2cap_move_setup(struct l2cap_chan *chan)
1122{
1123 struct sk_buff *skb;
1124
1125 BT_DBG("chan %p", chan);
1126
1127 if (chan->mode != L2CAP_MODE_ERTM)
1128 return;
1129
1130 __clear_retrans_timer(chan);
1131 __clear_monitor_timer(chan);
1132 __clear_ack_timer(chan);
1133
1134 chan->retry_count = 0;
1135 skb_queue_walk(&chan->tx_q, skb) {
1136 if (bt_cb(skb)->control.retries)
1137 bt_cb(skb)->control.retries = 1;
1138 else
1139 break;
1140 }
1141
1142 chan->expected_tx_seq = chan->buffer_seq;
1143
1144 clear_bit(CONN_REJ_ACT, &chan->conn_state);
1145 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
1146 l2cap_seq_list_clear(&chan->retrans_list);
1147 l2cap_seq_list_clear(&chan->srej_list);
1148 skb_queue_purge(&chan->srej_q);
1149
1150 chan->tx_state = L2CAP_TX_STATE_XMIT;
1151 chan->rx_state = L2CAP_RX_STATE_MOVE;
1152
1153 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
1154}
1155
Mat Martineau5f3847a2012-10-23 15:24:12 -07001156static void l2cap_move_done(struct l2cap_chan *chan)
1157{
1158 u8 move_role = chan->move_role;
1159 BT_DBG("chan %p", chan);
1160
1161 chan->move_state = L2CAP_MOVE_STABLE;
1162 chan->move_role = L2CAP_MOVE_ROLE_NONE;
1163
1164 if (chan->mode != L2CAP_MODE_ERTM)
1165 return;
1166
1167 switch (move_role) {
1168 case L2CAP_MOVE_ROLE_INITIATOR:
1169 l2cap_tx(chan, NULL, NULL, L2CAP_EV_EXPLICIT_POLL);
1170 chan->rx_state = L2CAP_RX_STATE_WAIT_F;
1171 break;
1172 case L2CAP_MOVE_ROLE_RESPONDER:
1173 chan->rx_state = L2CAP_RX_STATE_WAIT_P;
1174 break;
1175 }
1176}
1177
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001178static void l2cap_chan_ready(struct l2cap_chan *chan)
1179{
Mat Martineau28270112012-05-17 21:14:09 -07001180 /* This clears all conf flags, including CONF_NOT_COMPLETE */
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001181 chan->conf_state = 0;
1182 __clear_chan_timer(chan);
1183
Johan Hedberg0ce43ce2013-12-05 14:55:33 +02001184 if (chan->mode == L2CAP_MODE_LE_FLOWCTL && !chan->tx_credits)
1185 chan->ops->suspend(chan);
Johan Hedberg177f8f22013-05-31 17:54:51 +03001186
Andrei Emeltchenko54a59aa2012-05-27 22:27:53 -03001187 chan->state = BT_CONNECTED;
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001188
Andrei Emeltchenkofd83e2c2012-05-30 09:55:32 +03001189 chan->ops->ready(chan);
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001190}
1191
Johan Hedbergf1496de2013-05-13 14:15:56 +03001192static void l2cap_le_connect(struct l2cap_chan *chan)
1193{
1194 struct l2cap_conn *conn = chan->conn;
1195 struct l2cap_le_conn_req req;
1196
Johan Hedberg595177f2013-12-02 22:12:22 +02001197 if (test_and_set_bit(FLAG_LE_CONN_REQ_SENT, &chan->flags))
1198 return;
1199
Johan Hedbergf1496de2013-05-13 14:15:56 +03001200 req.psm = chan->psm;
1201 req.scid = cpu_to_le16(chan->scid);
1202 req.mtu = cpu_to_le16(chan->imtu);
Johan Hedberg3916aed2013-10-07 15:35:26 +02001203 req.mps = cpu_to_le16(chan->mps);
Johan Hedberg0cd75f72013-05-17 13:09:05 +03001204 req.credits = cpu_to_le16(chan->rx_credits);
Johan Hedbergf1496de2013-05-13 14:15:56 +03001205
1206 chan->ident = l2cap_get_ident(conn);
1207
1208 l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CONN_REQ,
1209 sizeof(req), &req);
1210}
1211
1212static void l2cap_le_start(struct l2cap_chan *chan)
1213{
1214 struct l2cap_conn *conn = chan->conn;
1215
1216 if (!smp_conn_security(conn->hcon, chan->sec_level))
1217 return;
1218
1219 if (!chan->psm) {
1220 l2cap_chan_ready(chan);
1221 return;
1222 }
1223
1224 if (chan->state == BT_CONNECT)
1225 l2cap_le_connect(chan);
1226}
1227
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001228static void l2cap_start_connection(struct l2cap_chan *chan)
1229{
1230 if (__amp_capable(chan)) {
1231 BT_DBG("chan %p AMP capable: discover AMPs", chan);
1232 a2mp_discover_amp(chan);
Johan Hedbergf1496de2013-05-13 14:15:56 +03001233 } else if (chan->conn->hcon->type == LE_LINK) {
1234 l2cap_le_start(chan);
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001235 } else {
1236 l2cap_send_conn_req(chan);
1237 }
1238}
1239
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001240static void l2cap_do_start(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001241{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001242 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001243
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001244 if (conn->hcon->type == LE_LINK) {
Johan Hedberg96ac34f2013-05-13 11:15:07 +03001245 l2cap_le_start(chan);
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001246 return;
1247 }
1248
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001249 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01001250 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
1251 return;
1252
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001253 if (l2cap_chan_check_security(chan) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01001254 __l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001255 l2cap_start_connection(chan);
1256 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001257 } else {
1258 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001259 req.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001260
1261 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
1262 conn->info_ident = l2cap_get_ident(conn);
1263
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08001264 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001265
Gustavo Padovan2d792812012-10-06 10:07:01 +01001266 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
1267 sizeof(req), &req);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001268 }
1269}
1270
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001271static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
1272{
1273 u32 local_feat_mask = l2cap_feat_mask;
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03001274 if (!disable_ertm)
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001275 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
1276
1277 switch (mode) {
1278 case L2CAP_MODE_ERTM:
1279 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
1280 case L2CAP_MODE_STREAMING:
1281 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
1282 default:
1283 return 0x00;
1284 }
1285}
1286
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02001287static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err)
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001288{
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02001289 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001290 struct l2cap_disconn_req req;
1291
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001292 if (!conn)
1293 return;
1294
Andrei Emeltchenkoaad3d0e2012-09-06 15:05:42 +03001295 if (chan->mode == L2CAP_MODE_ERTM && chan->state == BT_CONNECTED) {
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03001296 __clear_retrans_timer(chan);
1297 __clear_monitor_timer(chan);
1298 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001299 }
1300
Johan Hedberg2338a7e2014-01-24 10:35:40 +02001301 if (chan->scid == L2CAP_CID_A2MP) {
Gustavo Padovand1177732012-10-06 11:47:38 +01001302 l2cap_state_change(chan, BT_DISCONN);
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001303 return;
1304 }
1305
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001306 req.dcid = cpu_to_le16(chan->dcid);
1307 req.scid = cpu_to_le16(chan->scid);
Gustavo Padovan2d792812012-10-06 10:07:01 +01001308 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_DISCONN_REQ,
1309 sizeof(req), &req);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001310
Gustavo Padovanf8e73012013-10-15 19:24:46 -03001311 l2cap_state_change_and_error(chan, BT_DISCONN, err);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001312}
1313
Linus Torvalds1da177e2005-04-16 15:20:36 -07001314/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001315static void l2cap_conn_start(struct l2cap_conn *conn)
1316{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001317 struct l2cap_chan *chan, *tmp;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001318
1319 BT_DBG("conn %p", conn);
1320
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001321 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001322
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001323 list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001324 l2cap_chan_lock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001325
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001326 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001327 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001328 continue;
1329 }
1330
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001331 if (chan->state == BT_CONNECT) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001332 if (!l2cap_chan_check_security(chan) ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001333 !__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001334 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001335 continue;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02001336 }
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001337
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001338 if (!l2cap_mode_supported(chan->mode, conn->feat_mask)
Gustavo Padovan2d792812012-10-06 10:07:01 +01001339 && test_bit(CONF_STATE2_DEVICE,
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001340 &chan->conf_state)) {
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001341 l2cap_chan_close(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001342 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001343 continue;
1344 }
1345
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001346 l2cap_start_connection(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001347
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001348 } else if (chan->state == BT_CONNECT2) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001349 struct l2cap_conn_rsp rsp;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001350 char buf[128];
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001351 rsp.scid = cpu_to_le16(chan->dcid);
1352 rsp.dcid = cpu_to_le16(chan->scid);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001353
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001354 if (l2cap_chan_check_security(chan)) {
Marcel Holtmannbdc25782013-10-14 02:45:34 -07001355 if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001356 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1357 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08001358 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001359
1360 } else {
Gustavo Padovanacdcabf2013-10-21 14:21:39 -02001361 l2cap_state_change(chan, BT_CONFIG);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001362 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
1363 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001364 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001365 } else {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001366 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1367 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001368 }
1369
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001370 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001371 sizeof(rsp), &rsp);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001372
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001373 if (test_bit(CONF_REQ_SENT, &chan->conf_state) ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001374 rsp.result != L2CAP_CR_SUCCESS) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001375 l2cap_chan_unlock(chan);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001376 continue;
1377 }
1378
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001379 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001380 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001381 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03001382 chan->num_conf_req++;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001383 }
1384
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001385 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001386 }
1387
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001388 mutex_unlock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001389}
1390
Ido Yarivc2287682012-04-20 15:46:07 -03001391/* Find socket with cid and source/destination bdaddr.
Ville Tervob62f3282011-02-10 22:38:50 -03001392 * Returns closest match, locked.
1393 */
Andrei Emeltchenkod9b88702012-03-12 12:13:08 +02001394static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid,
Ido Yarivc2287682012-04-20 15:46:07 -03001395 bdaddr_t *src,
1396 bdaddr_t *dst)
Ville Tervob62f3282011-02-10 22:38:50 -03001397{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001398 struct l2cap_chan *c, *c1 = NULL;
Ville Tervob62f3282011-02-10 22:38:50 -03001399
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001400 read_lock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001401
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001402 list_for_each_entry(c, &chan_list, global_l) {
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001403 if (state && c->state != state)
Ville Tervob62f3282011-02-10 22:38:50 -03001404 continue;
1405
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001406 if (c->scid == cid) {
Ido Yarivc2287682012-04-20 15:46:07 -03001407 int src_match, dst_match;
1408 int src_any, dst_any;
1409
Ville Tervob62f3282011-02-10 22:38:50 -03001410 /* Exact match. */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001411 src_match = !bacmp(&c->src, src);
1412 dst_match = !bacmp(&c->dst, dst);
Ido Yarivc2287682012-04-20 15:46:07 -03001413 if (src_match && dst_match) {
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001414 read_unlock(&chan_list_lock);
1415 return c;
1416 }
Ville Tervob62f3282011-02-10 22:38:50 -03001417
1418 /* Closest match */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001419 src_any = !bacmp(&c->src, BDADDR_ANY);
1420 dst_any = !bacmp(&c->dst, BDADDR_ANY);
Ido Yarivc2287682012-04-20 15:46:07 -03001421 if ((src_match && dst_any) || (src_any && dst_match) ||
1422 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001423 c1 = c;
Ville Tervob62f3282011-02-10 22:38:50 -03001424 }
1425 }
Gustavo F. Padovan280f2942011-04-13 19:01:22 -03001426
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001427 read_unlock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001428
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001429 return c1;
Ville Tervob62f3282011-02-10 22:38:50 -03001430}
1431
1432static void l2cap_le_conn_ready(struct l2cap_conn *conn)
1433{
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001434 struct hci_conn *hcon = conn->hcon;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001435 struct l2cap_chan *chan, *pchan;
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001436 u8 dst_type;
Ville Tervob62f3282011-02-10 22:38:50 -03001437
1438 BT_DBG("");
1439
Jukka Rissanen18722c22013-12-11 17:05:37 +02001440 bt_6lowpan_add_conn(conn);
1441
Ville Tervob62f3282011-02-10 22:38:50 -03001442 /* Check if we have socket listening on cid */
Johan Hedberg073d1cf2013-04-29 19:35:35 +03001443 pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_ATT,
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001444 &hcon->src, &hcon->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001445 if (!pchan)
Ville Tervob62f3282011-02-10 22:38:50 -03001446 return;
1447
Johan Hedberg44f3b0f2013-04-29 19:35:45 +03001448 /* Client ATT sockets should override the server one */
1449 if (__l2cap_get_chan_by_dcid(conn, L2CAP_CID_ATT))
1450 return;
1451
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001452 dst_type = bdaddr_type(hcon, hcon->dst_type);
1453
1454 /* If device is blocked, do not create a channel for it */
1455 if (hci_blacklist_lookup(hcon->hdev, &hcon->dst, dst_type))
1456 return;
1457
Gustavo Padovan8ffb9292013-10-21 14:21:41 -02001458 l2cap_chan_lock(pchan);
Gustavo F. Padovan62f3a2c2011-04-14 18:34:34 -03001459
Gustavo Padovan80b98022012-05-27 22:27:51 -03001460 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001461 if (!chan)
Ville Tervob62f3282011-02-10 22:38:50 -03001462 goto clean;
1463
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001464 bacpy(&chan->src, &hcon->src);
1465 bacpy(&chan->dst, &hcon->dst);
1466 chan->src_type = bdaddr_type(hcon, hcon->src_type);
1467 chan->dst_type = dst_type;
Ville Tervob62f3282011-02-10 22:38:50 -03001468
Johan Hedberg44f3b0f2013-04-29 19:35:45 +03001469 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001470
Ville Tervob62f3282011-02-10 22:38:50 -03001471clean:
Gustavo Padovan8ffb9292013-10-21 14:21:41 -02001472 l2cap_chan_unlock(pchan);
Ville Tervob62f3282011-02-10 22:38:50 -03001473}
1474
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001475static void l2cap_conn_ready(struct l2cap_conn *conn)
1476{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001477 struct l2cap_chan *chan;
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001478 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001479
1480 BT_DBG("conn %p", conn);
1481
Johan Hedbergd8729922013-04-29 19:35:39 +03001482 /* For outgoing pairing which doesn't necessarily have an
1483 * associated socket (e.g. mgmt_pair_device).
1484 */
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001485 if (hcon->out && hcon->type == LE_LINK)
1486 smp_conn_security(hcon, hcon->pending_sec_level);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03001487
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001488 mutex_lock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001489
Johan Hedberg44f3b0f2013-04-29 19:35:45 +03001490 if (hcon->type == LE_LINK)
1491 l2cap_le_conn_ready(conn);
1492
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001493 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001494
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001495 l2cap_chan_lock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001496
Johan Hedberg2338a7e2014-01-24 10:35:40 +02001497 if (chan->scid == L2CAP_CID_A2MP) {
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001498 l2cap_chan_unlock(chan);
1499 continue;
1500 }
1501
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001502 if (hcon->type == LE_LINK) {
Johan Hedbergf1496de2013-05-13 14:15:56 +03001503 l2cap_le_start(chan);
Vinicius Costa Gomes63128452011-06-17 22:46:26 -03001504 } else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Gustavo Padovan74e75742013-10-15 19:24:51 -03001505 l2cap_chan_ready(chan);
Anderson Brigliab501d6a2011-06-07 18:46:31 -03001506
Gustavo Padovan1c244f72012-12-07 03:29:10 -02001507 } else if (chan->state == BT_CONNECT) {
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001508 l2cap_do_start(chan);
Gustavo Padovan1c244f72012-12-07 03:29:10 -02001509 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001510
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001511 l2cap_chan_unlock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001512 }
1513
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001514 mutex_unlock(&conn->chan_lock);
Johan Hedberg61a939c2014-01-17 20:45:11 +02001515
1516 queue_work(hcon->hdev->workqueue, &conn->pending_rx_work);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001517}
1518
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001519/* Notify sockets that we cannot guaranty reliability anymore */
1520static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
1521{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001522 struct l2cap_chan *chan;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001523
1524 BT_DBG("conn %p", conn);
1525
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001526 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001527
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001528 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenkoecf61bd2011-10-11 14:04:32 +03001529 if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags))
Gustavo Padovan1d8b1fd2012-10-06 11:34:52 +01001530 l2cap_chan_set_err(chan, err);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001531 }
1532
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001533 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001534}
1535
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001536static void l2cap_info_timeout(struct work_struct *work)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001537{
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001538 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001539 info_timer.work);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001540
Marcel Holtmann984947d2009-02-06 23:35:19 +01001541 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01001542 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01001543
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001544 l2cap_conn_start(conn);
1545}
1546
David Herrmann2c8e1412013-04-06 20:28:45 +02001547/*
1548 * l2cap_user
1549 * External modules can register l2cap_user objects on l2cap_conn. The ->probe
1550 * callback is called during registration. The ->remove callback is called
1551 * during unregistration.
1552 * An l2cap_user object can either be explicitly unregistered or when the
1553 * underlying l2cap_conn object is deleted. This guarantees that l2cap->hcon,
1554 * l2cap->hchan, .. are valid as long as the remove callback hasn't been called.
1555 * External modules must own a reference to the l2cap_conn object if they intend
1556 * to call l2cap_unregister_user(). The l2cap_conn object might get destroyed at
1557 * any time if they don't.
1558 */
1559
1560int l2cap_register_user(struct l2cap_conn *conn, struct l2cap_user *user)
1561{
1562 struct hci_dev *hdev = conn->hcon->hdev;
1563 int ret;
1564
1565 /* We need to check whether l2cap_conn is registered. If it is not, we
1566 * must not register the l2cap_user. l2cap_conn_del() is unregisters
1567 * l2cap_conn objects, but doesn't provide its own locking. Instead, it
1568 * relies on the parent hci_conn object to be locked. This itself relies
1569 * on the hci_dev object to be locked. So we must lock the hci device
1570 * here, too. */
1571
1572 hci_dev_lock(hdev);
1573
1574 if (user->list.next || user->list.prev) {
1575 ret = -EINVAL;
1576 goto out_unlock;
1577 }
1578
1579 /* conn->hchan is NULL after l2cap_conn_del() was called */
1580 if (!conn->hchan) {
1581 ret = -ENODEV;
1582 goto out_unlock;
1583 }
1584
1585 ret = user->probe(conn, user);
1586 if (ret)
1587 goto out_unlock;
1588
1589 list_add(&user->list, &conn->users);
1590 ret = 0;
1591
1592out_unlock:
1593 hci_dev_unlock(hdev);
1594 return ret;
1595}
1596EXPORT_SYMBOL(l2cap_register_user);
1597
1598void l2cap_unregister_user(struct l2cap_conn *conn, struct l2cap_user *user)
1599{
1600 struct hci_dev *hdev = conn->hcon->hdev;
1601
1602 hci_dev_lock(hdev);
1603
1604 if (!user->list.next || !user->list.prev)
1605 goto out_unlock;
1606
1607 list_del(&user->list);
1608 user->list.next = NULL;
1609 user->list.prev = NULL;
1610 user->remove(conn, user);
1611
1612out_unlock:
1613 hci_dev_unlock(hdev);
1614}
1615EXPORT_SYMBOL(l2cap_unregister_user);
1616
1617static void l2cap_unregister_all_users(struct l2cap_conn *conn)
1618{
1619 struct l2cap_user *user;
1620
1621 while (!list_empty(&conn->users)) {
1622 user = list_first_entry(&conn->users, struct l2cap_user, list);
1623 list_del(&user->list);
1624 user->list.next = NULL;
1625 user->list.prev = NULL;
1626 user->remove(conn, user);
1627 }
1628}
1629
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001630static void l2cap_conn_del(struct hci_conn *hcon, int err)
1631{
1632 struct l2cap_conn *conn = hcon->l2cap_data;
1633 struct l2cap_chan *chan, *l;
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001634
1635 if (!conn)
1636 return;
1637
1638 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
1639
1640 kfree_skb(conn->rx_skb);
1641
Johan Hedberg61a939c2014-01-17 20:45:11 +02001642 skb_queue_purge(&conn->pending_rx);
1643 flush_work(&conn->pending_rx_work);
1644
David Herrmann2c8e1412013-04-06 20:28:45 +02001645 l2cap_unregister_all_users(conn);
1646
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001647 mutex_lock(&conn->chan_lock);
1648
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001649 /* Kill channels */
1650 list_for_each_entry_safe(chan, l, &conn->chan_l, list) {
Mat Martineau61d6ef32012-04-27 16:50:50 -07001651 l2cap_chan_hold(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001652 l2cap_chan_lock(chan);
1653
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001654 l2cap_chan_del(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001655
1656 l2cap_chan_unlock(chan);
1657
Gustavo Padovan80b98022012-05-27 22:27:51 -03001658 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07001659 l2cap_chan_put(chan);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001660 }
1661
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001662 mutex_unlock(&conn->chan_lock);
1663
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001664 hci_chan_del(conn->hchan);
1665
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001666 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
Ulisses Furquim127074b2012-01-30 18:26:29 -02001667 cancel_delayed_work_sync(&conn->info_timer);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001668
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001669 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) {
Ulisses Furquim127074b2012-01-30 18:26:29 -02001670 cancel_delayed_work_sync(&conn->security_timer);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -03001671 smp_chan_destroy(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001672 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001673
1674 hcon->l2cap_data = NULL;
David Herrmann9c903e32013-04-06 20:28:44 +02001675 conn->hchan = NULL;
1676 l2cap_conn_put(conn);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001677}
1678
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001679static void security_timeout(struct work_struct *work)
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001680{
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001681 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001682 security_timer.work);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001683
Johan Hedbergd06cc412012-06-06 18:44:11 +08001684 BT_DBG("conn %p", conn);
1685
1686 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) {
1687 smp_chan_destroy(conn);
1688 l2cap_conn_del(conn->hcon, ETIMEDOUT);
1689 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001690}
1691
David Herrmann9c903e32013-04-06 20:28:44 +02001692static void l2cap_conn_free(struct kref *ref)
1693{
1694 struct l2cap_conn *conn = container_of(ref, struct l2cap_conn, ref);
1695
1696 hci_conn_put(conn->hcon);
1697 kfree(conn);
1698}
1699
1700void l2cap_conn_get(struct l2cap_conn *conn)
1701{
1702 kref_get(&conn->ref);
1703}
1704EXPORT_SYMBOL(l2cap_conn_get);
1705
1706void l2cap_conn_put(struct l2cap_conn *conn)
1707{
1708 kref_put(&conn->ref, l2cap_conn_free);
1709}
1710EXPORT_SYMBOL(l2cap_conn_put);
1711
Linus Torvalds1da177e2005-04-16 15:20:36 -07001712/* ---- Socket interface ---- */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001713
Ido Yarivc2287682012-04-20 15:46:07 -03001714/* Find socket with psm and source / destination bdaddr.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001715 * Returns closest match.
1716 */
Ido Yarivc2287682012-04-20 15:46:07 -03001717static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
1718 bdaddr_t *src,
Johan Hedbergbf20fd42013-05-14 13:23:13 +03001719 bdaddr_t *dst,
1720 u8 link_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001721{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001722 struct l2cap_chan *c, *c1 = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001723
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001724 read_lock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001725
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001726 list_for_each_entry(c, &chan_list, global_l) {
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001727 if (state && c->state != state)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001728 continue;
1729
Johan Hedbergbf20fd42013-05-14 13:23:13 +03001730 if (link_type == ACL_LINK && c->src_type != BDADDR_BREDR)
1731 continue;
1732
1733 if (link_type == LE_LINK && c->src_type == BDADDR_BREDR)
1734 continue;
1735
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001736 if (c->psm == psm) {
Ido Yarivc2287682012-04-20 15:46:07 -03001737 int src_match, dst_match;
1738 int src_any, dst_any;
1739
Linus Torvalds1da177e2005-04-16 15:20:36 -07001740 /* Exact match. */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001741 src_match = !bacmp(&c->src, src);
1742 dst_match = !bacmp(&c->dst, dst);
Ido Yarivc2287682012-04-20 15:46:07 -03001743 if (src_match && dst_match) {
Johannes Berga7567b22011-06-01 08:29:54 +02001744 read_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001745 return c;
1746 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001747
1748 /* Closest match */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001749 src_any = !bacmp(&c->src, BDADDR_ANY);
1750 dst_any = !bacmp(&c->dst, BDADDR_ANY);
Ido Yarivc2287682012-04-20 15:46:07 -03001751 if ((src_match && dst_any) || (src_any && dst_match) ||
1752 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001753 c1 = c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001754 }
1755 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001756
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001757 read_unlock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001758
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001759 return c1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001760}
1761
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001762static void l2cap_monitor_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001763{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001764 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001765 monitor_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001766
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03001767 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001768
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001769 l2cap_chan_lock(chan);
1770
Mat Martineau80909e02012-05-17 20:53:50 -07001771 if (!chan->conn) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001772 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001773 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001774 return;
1775 }
1776
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001777 l2cap_tx(chan, NULL, NULL, L2CAP_EV_MONITOR_TO);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001778
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001779 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001780 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001781}
1782
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001783static void l2cap_retrans_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001784{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001785 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001786 retrans_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001787
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03001788 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001789
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001790 l2cap_chan_lock(chan);
1791
Mat Martineau80909e02012-05-17 20:53:50 -07001792 if (!chan->conn) {
1793 l2cap_chan_unlock(chan);
1794 l2cap_chan_put(chan);
1795 return;
1796 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001797
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001798 l2cap_tx(chan, NULL, NULL, L2CAP_EV_RETRANS_TO);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001799 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001800 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001801}
1802
Gustavo Padovand6603662012-05-21 13:58:22 -03001803static void l2cap_streaming_send(struct l2cap_chan *chan,
1804 struct sk_buff_head *skbs)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001805{
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001806 struct sk_buff *skb;
Mat Martineau37339372012-05-17 20:53:33 -07001807 struct l2cap_ctrl *control;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001808
Mat Martineau37339372012-05-17 20:53:33 -07001809 BT_DBG("chan %p, skbs %p", chan, skbs);
1810
Mat Martineaub99e13a2012-10-23 15:24:19 -07001811 if (__chan_is_moving(chan))
1812 return;
1813
Mat Martineau37339372012-05-17 20:53:33 -07001814 skb_queue_splice_tail_init(skbs, &chan->tx_q);
1815
1816 while (!skb_queue_empty(&chan->tx_q)) {
1817
1818 skb = skb_dequeue(&chan->tx_q);
1819
1820 bt_cb(skb)->control.retries = 1;
1821 control = &bt_cb(skb)->control;
1822
1823 control->reqseq = 0;
1824 control->txseq = chan->next_tx_seq;
1825
1826 __pack_control(chan, control, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001827
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001828 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau37339372012-05-17 20:53:33 -07001829 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
1830 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001831 }
1832
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001833 l2cap_do_send(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001834
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001835 BT_DBG("Sent txseq %u", control->txseq);
Mat Martineau37339372012-05-17 20:53:33 -07001836
Andrei Emeltchenko836be932011-10-17 12:19:57 +03001837 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau37339372012-05-17 20:53:33 -07001838 chan->frames_sent++;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001839 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001840}
1841
Szymon Janc67c9e842011-07-28 16:24:33 +02001842static int l2cap_ertm_send(struct l2cap_chan *chan)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001843{
1844 struct sk_buff *skb, *tx_skb;
Mat Martineau18a48e72012-05-17 20:53:34 -07001845 struct l2cap_ctrl *control;
1846 int sent = 0;
1847
1848 BT_DBG("chan %p", chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001849
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001850 if (chan->state != BT_CONNECTED)
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001851 return -ENOTCONN;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001852
Mat Martineau94122bb2012-05-02 09:42:02 -07001853 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1854 return 0;
1855
Mat Martineaub99e13a2012-10-23 15:24:19 -07001856 if (__chan_is_moving(chan))
1857 return 0;
1858
Mat Martineau18a48e72012-05-17 20:53:34 -07001859 while (chan->tx_send_head &&
1860 chan->unacked_frames < chan->remote_tx_win &&
1861 chan->tx_state == L2CAP_TX_STATE_XMIT) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001862
Mat Martineau18a48e72012-05-17 20:53:34 -07001863 skb = chan->tx_send_head;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001864
Mat Martineau18a48e72012-05-17 20:53:34 -07001865 bt_cb(skb)->control.retries = 1;
1866 control = &bt_cb(skb)->control;
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03001867
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03001868 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
Mat Martineau18a48e72012-05-17 20:53:34 -07001869 control->final = 1;
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03001870
Mat Martineau18a48e72012-05-17 20:53:34 -07001871 control->reqseq = chan->buffer_seq;
1872 chan->last_acked_seq = chan->buffer_seq;
1873 control->txseq = chan->next_tx_seq;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001874
Mat Martineau18a48e72012-05-17 20:53:34 -07001875 __pack_control(chan, control, skb);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001876
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001877 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau18a48e72012-05-17 20:53:34 -07001878 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
1879 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001880 }
1881
Mat Martineau18a48e72012-05-17 20:53:34 -07001882 /* Clone after data has been modified. Data is assumed to be
1883 read-only (for locking purposes) on cloned sk_buffs.
1884 */
1885 tx_skb = skb_clone(skb, GFP_KERNEL);
1886
1887 if (!tx_skb)
1888 break;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001889
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03001890 __set_retrans_timer(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001891
Andrei Emeltchenko836be932011-10-17 12:19:57 +03001892 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau18a48e72012-05-17 20:53:34 -07001893 chan->unacked_frames++;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03001894 chan->frames_sent++;
Mat Martineau18a48e72012-05-17 20:53:34 -07001895 sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001896
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03001897 if (skb_queue_is_last(&chan->tx_q, skb))
1898 chan->tx_send_head = NULL;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001899 else
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03001900 chan->tx_send_head = skb_queue_next(&chan->tx_q, skb);
Mat Martineau18a48e72012-05-17 20:53:34 -07001901
1902 l2cap_do_send(chan, tx_skb);
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001903 BT_DBG("Sent txseq %u", control->txseq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001904 }
1905
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001906 BT_DBG("Sent %d, %u unacked, %u in ERTM queue", sent,
1907 chan->unacked_frames, skb_queue_len(&chan->tx_q));
Mat Martineau18a48e72012-05-17 20:53:34 -07001908
1909 return sent;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001910}
1911
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001912static void l2cap_ertm_resend(struct l2cap_chan *chan)
1913{
1914 struct l2cap_ctrl control;
1915 struct sk_buff *skb;
1916 struct sk_buff *tx_skb;
1917 u16 seq;
1918
1919 BT_DBG("chan %p", chan);
1920
1921 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1922 return;
1923
Mat Martineaub99e13a2012-10-23 15:24:19 -07001924 if (__chan_is_moving(chan))
1925 return;
1926
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001927 while (chan->retrans_list.head != L2CAP_SEQ_LIST_CLEAR) {
1928 seq = l2cap_seq_list_pop(&chan->retrans_list);
1929
1930 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, seq);
1931 if (!skb) {
1932 BT_DBG("Error: Can't retransmit seq %d, frame missing",
Gustavo Padovan2d792812012-10-06 10:07:01 +01001933 seq);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001934 continue;
1935 }
1936
1937 bt_cb(skb)->control.retries++;
1938 control = bt_cb(skb)->control;
1939
1940 if (chan->max_tx != 0 &&
1941 bt_cb(skb)->control.retries > chan->max_tx) {
1942 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02001943 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001944 l2cap_seq_list_clear(&chan->retrans_list);
1945 break;
1946 }
1947
1948 control.reqseq = chan->buffer_seq;
1949 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
1950 control.final = 1;
1951 else
1952 control.final = 0;
1953
1954 if (skb_cloned(skb)) {
1955 /* Cloned sk_buffs are read-only, so we need a
1956 * writeable copy
1957 */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03001958 tx_skb = skb_copy(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001959 } else {
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03001960 tx_skb = skb_clone(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001961 }
1962
1963 if (!tx_skb) {
1964 l2cap_seq_list_clear(&chan->retrans_list);
1965 break;
1966 }
1967
1968 /* Update skb contents */
1969 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
1970 put_unaligned_le32(__pack_extended_control(&control),
1971 tx_skb->data + L2CAP_HDR_SIZE);
1972 } else {
1973 put_unaligned_le16(__pack_enhanced_control(&control),
1974 tx_skb->data + L2CAP_HDR_SIZE);
1975 }
1976
1977 if (chan->fcs == L2CAP_FCS_CRC16) {
1978 u16 fcs = crc16(0, (u8 *) tx_skb->data, tx_skb->len);
1979 put_unaligned_le16(fcs, skb_put(tx_skb,
1980 L2CAP_FCS_SIZE));
1981 }
1982
1983 l2cap_do_send(chan, tx_skb);
1984
1985 BT_DBG("Resent txseq %d", control.txseq);
1986
1987 chan->last_acked_seq = chan->buffer_seq;
1988 }
1989}
1990
Mat Martineauf80842a2012-05-17 20:53:46 -07001991static void l2cap_retransmit(struct l2cap_chan *chan,
1992 struct l2cap_ctrl *control)
1993{
1994 BT_DBG("chan %p, control %p", chan, control);
1995
1996 l2cap_seq_list_append(&chan->retrans_list, control->reqseq);
1997 l2cap_ertm_resend(chan);
1998}
1999
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002000static void l2cap_retransmit_all(struct l2cap_chan *chan,
2001 struct l2cap_ctrl *control)
2002{
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002003 struct sk_buff *skb;
2004
2005 BT_DBG("chan %p, control %p", chan, control);
2006
2007 if (control->poll)
2008 set_bit(CONN_SEND_FBIT, &chan->conn_state);
2009
2010 l2cap_seq_list_clear(&chan->retrans_list);
2011
2012 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2013 return;
2014
2015 if (chan->unacked_frames) {
2016 skb_queue_walk(&chan->tx_q, skb) {
2017 if (bt_cb(skb)->control.txseq == control->reqseq ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01002018 skb == chan->tx_send_head)
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002019 break;
2020 }
2021
2022 skb_queue_walk_from(&chan->tx_q, skb) {
2023 if (skb == chan->tx_send_head)
2024 break;
2025
2026 l2cap_seq_list_append(&chan->retrans_list,
2027 bt_cb(skb)->control.txseq);
2028 }
2029
2030 l2cap_ertm_resend(chan);
2031 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002032}
2033
Szymon Jancb17e73b2012-01-11 10:59:47 +01002034static void l2cap_send_ack(struct l2cap_chan *chan)
2035{
Mat Martineau0a0aba42012-05-17 20:53:39 -07002036 struct l2cap_ctrl control;
2037 u16 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
2038 chan->last_acked_seq);
2039 int threshold;
2040
2041 BT_DBG("chan %p last_acked_seq %d buffer_seq %d",
2042 chan, chan->last_acked_seq, chan->buffer_seq);
2043
2044 memset(&control, 0, sizeof(control));
2045 control.sframe = 1;
2046
2047 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
2048 chan->rx_state == L2CAP_RX_STATE_RECV) {
2049 __clear_ack_timer(chan);
2050 control.super = L2CAP_SUPER_RNR;
2051 control.reqseq = chan->buffer_seq;
2052 l2cap_send_sframe(chan, &control);
2053 } else {
2054 if (!test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) {
2055 l2cap_ertm_send(chan);
2056 /* If any i-frames were sent, they included an ack */
2057 if (chan->buffer_seq == chan->last_acked_seq)
2058 frames_to_ack = 0;
2059 }
2060
Mat Martineauc20f8e32012-07-10 05:47:07 -07002061 /* Ack now if the window is 3/4ths full.
Mat Martineau0a0aba42012-05-17 20:53:39 -07002062 * Calculate without mul or div
2063 */
Mat Martineauc20f8e32012-07-10 05:47:07 -07002064 threshold = chan->ack_win;
Mat Martineau0a0aba42012-05-17 20:53:39 -07002065 threshold += threshold << 1;
2066 threshold >>= 2;
2067
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002068 BT_DBG("frames_to_ack %u, threshold %d", frames_to_ack,
Mat Martineau0a0aba42012-05-17 20:53:39 -07002069 threshold);
2070
2071 if (frames_to_ack >= threshold) {
2072 __clear_ack_timer(chan);
2073 control.super = L2CAP_SUPER_RR;
2074 control.reqseq = chan->buffer_seq;
2075 l2cap_send_sframe(chan, &control);
2076 frames_to_ack = 0;
2077 }
2078
2079 if (frames_to_ack)
2080 __set_ack_timer(chan);
2081 }
Szymon Jancb17e73b2012-01-11 10:59:47 +01002082}
2083
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002084static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
2085 struct msghdr *msg, int len,
2086 int count, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002087{
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002088 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002089 struct sk_buff **frag;
Gustavo Padovan90338942012-04-06 20:15:47 -03002090 int sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002091
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03002092 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002093 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002094
2095 sent += count;
2096 len -= count;
2097
2098 /* Continuation fragments (no L2CAP header) */
2099 frag = &skb_shinfo(skb)->frag_list;
2100 while (len) {
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002101 struct sk_buff *tmp;
2102
Linus Torvalds1da177e2005-04-16 15:20:36 -07002103 count = min_t(unsigned int, conn->mtu, len);
2104
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002105 tmp = chan->ops->alloc_skb(chan, count,
2106 msg->msg_flags & MSG_DONTWAIT);
2107 if (IS_ERR(tmp))
2108 return PTR_ERR(tmp);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002109
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002110 *frag = tmp;
2111
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002112 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
2113 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002114
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002115 (*frag)->priority = skb->priority;
2116
Linus Torvalds1da177e2005-04-16 15:20:36 -07002117 sent += count;
2118 len -= count;
2119
Gustavo Padovan2d0ed3d2012-05-11 13:16:12 -03002120 skb->len += (*frag)->len;
2121 skb->data_len += (*frag)->len;
2122
Linus Torvalds1da177e2005-04-16 15:20:36 -07002123 frag = &(*frag)->next;
2124 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002125
2126 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002127}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002128
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002129static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002130 struct msghdr *msg, size_t len,
2131 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002132{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002133 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002134 struct sk_buff *skb;
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002135 int err, count, hlen = L2CAP_HDR_SIZE + L2CAP_PSMLEN_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002136 struct l2cap_hdr *lh;
2137
Marcel Holtmann43b1b8d2013-10-12 06:01:26 -07002138 BT_DBG("chan %p psm 0x%2.2x len %zu priority %u", chan,
2139 __le16_to_cpu(chan->psm), len, priority);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002140
2141 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002142
2143 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002144 msg->msg_flags & MSG_DONTWAIT);
2145 if (IS_ERR(skb))
2146 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002147
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002148 skb->priority = priority;
2149
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002150 /* Create L2CAP header */
2151 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002152 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenkodaf6a78c2012-05-03 10:55:52 +03002153 lh->len = cpu_to_le16(len + L2CAP_PSMLEN_SIZE);
Marcel Holtmann43b1b8d2013-10-12 06:01:26 -07002154 put_unaligned(chan->psm, (__le16 *) skb_put(skb, L2CAP_PSMLEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002155
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002156 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002157 if (unlikely(err < 0)) {
2158 kfree_skb(skb);
2159 return ERR_PTR(err);
2160 }
2161 return skb;
2162}
2163
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002164static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002165 struct msghdr *msg, size_t len,
2166 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002167{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002168 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002169 struct sk_buff *skb;
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002170 int err, count;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002171 struct l2cap_hdr *lh;
2172
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002173 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002174
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002175 count = min_t(unsigned int, (conn->mtu - L2CAP_HDR_SIZE), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002176
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002177 skb = chan->ops->alloc_skb(chan, count + L2CAP_HDR_SIZE,
Gustavo Padovan90338942012-04-06 20:15:47 -03002178 msg->msg_flags & MSG_DONTWAIT);
2179 if (IS_ERR(skb))
2180 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002181
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002182 skb->priority = priority;
2183
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002184 /* Create L2CAP header */
2185 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002186 lh->cid = cpu_to_le16(chan->dcid);
Gustavo Padovan6ff9b5e2012-05-02 11:56:17 -03002187 lh->len = cpu_to_le16(len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002188
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002189 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002190 if (unlikely(err < 0)) {
2191 kfree_skb(skb);
2192 return ERR_PTR(err);
2193 }
2194 return skb;
2195}
2196
Luiz Augusto von Dentzab0ff762011-09-12 20:00:50 +03002197static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002198 struct msghdr *msg, size_t len,
2199 u16 sdulen)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002200{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002201 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002202 struct sk_buff *skb;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002203 int err, count, hlen;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002204 struct l2cap_hdr *lh;
2205
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002206 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002207
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03002208 if (!conn)
2209 return ERR_PTR(-ENOTCONN);
2210
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002211 hlen = __ertm_hdr_size(chan);
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002212
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002213 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002214 hlen += L2CAP_SDULEN_SIZE;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002215
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002216 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002217 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002218
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002219 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002220
2221 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002222 msg->msg_flags & MSG_DONTWAIT);
2223 if (IS_ERR(skb))
2224 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002225
2226 /* Create L2CAP header */
2227 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002228 lh->cid = cpu_to_le16(chan->dcid);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002229 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002230
Mat Martineau18a48e72012-05-17 20:53:34 -07002231 /* Control header is populated later */
2232 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
2233 put_unaligned_le32(0, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
2234 else
2235 put_unaligned_le16(0, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002236
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002237 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002238 put_unaligned_le16(sdulen, skb_put(skb, L2CAP_SDULEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002239
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002240 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002241 if (unlikely(err < 0)) {
2242 kfree_skb(skb);
2243 return ERR_PTR(err);
2244 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002245
Mat Martineau18a48e72012-05-17 20:53:34 -07002246 bt_cb(skb)->control.fcs = chan->fcs;
Mat Martineau3ce35142012-04-25 16:36:14 -07002247 bt_cb(skb)->control.retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002248 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002249}
2250
Mat Martineau94122bb2012-05-02 09:42:02 -07002251static int l2cap_segment_sdu(struct l2cap_chan *chan,
2252 struct sk_buff_head *seg_queue,
2253 struct msghdr *msg, size_t len)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002254{
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002255 struct sk_buff *skb;
Mat Martineau94122bb2012-05-02 09:42:02 -07002256 u16 sdu_len;
2257 size_t pdu_len;
Mat Martineau94122bb2012-05-02 09:42:02 -07002258 u8 sar;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002259
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002260 BT_DBG("chan %p, msg %p, len %zu", chan, msg, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002261
Mat Martineau94122bb2012-05-02 09:42:02 -07002262 /* It is critical that ERTM PDUs fit in a single HCI fragment,
2263 * so fragmented skbs are not used. The HCI layer's handling
2264 * of fragmented skbs is not compatible with ERTM's queueing.
2265 */
2266
2267 /* PDU size is derived from the HCI MTU */
2268 pdu_len = chan->conn->mtu;
2269
Mat Martineaua5495742012-10-23 15:24:21 -07002270 /* Constrain PDU size for BR/EDR connections */
2271 if (!chan->hs_hcon)
2272 pdu_len = min_t(size_t, pdu_len, L2CAP_BREDR_MAX_PAYLOAD);
Mat Martineau94122bb2012-05-02 09:42:02 -07002273
2274 /* Adjust for largest possible L2CAP overhead. */
Gustavo Padovan35d401d2012-05-25 18:57:05 -03002275 if (chan->fcs)
2276 pdu_len -= L2CAP_FCS_SIZE;
2277
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002278 pdu_len -= __ertm_hdr_size(chan);
Mat Martineau94122bb2012-05-02 09:42:02 -07002279
2280 /* Remote device may have requested smaller PDUs */
2281 pdu_len = min_t(size_t, pdu_len, chan->remote_mps);
2282
2283 if (len <= pdu_len) {
2284 sar = L2CAP_SAR_UNSEGMENTED;
2285 sdu_len = 0;
2286 pdu_len = len;
2287 } else {
2288 sar = L2CAP_SAR_START;
2289 sdu_len = len;
2290 pdu_len -= L2CAP_SDULEN_SIZE;
2291 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002292
2293 while (len > 0) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002294 skb = l2cap_create_iframe_pdu(chan, msg, pdu_len, sdu_len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002295
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002296 if (IS_ERR(skb)) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002297 __skb_queue_purge(seg_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002298 return PTR_ERR(skb);
2299 }
2300
Mat Martineau94122bb2012-05-02 09:42:02 -07002301 bt_cb(skb)->control.sar = sar;
2302 __skb_queue_tail(seg_queue, skb);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002303
Mat Martineau94122bb2012-05-02 09:42:02 -07002304 len -= pdu_len;
2305 if (sdu_len) {
2306 sdu_len = 0;
2307 pdu_len += L2CAP_SDULEN_SIZE;
2308 }
2309
2310 if (len <= pdu_len) {
2311 sar = L2CAP_SAR_END;
2312 pdu_len = len;
2313 } else {
2314 sar = L2CAP_SAR_CONTINUE;
2315 }
2316 }
2317
Gustavo Padovanf0f62792012-05-29 13:29:17 -03002318 return 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002319}
2320
Johan Hedberg177f8f22013-05-31 17:54:51 +03002321static struct sk_buff *l2cap_create_le_flowctl_pdu(struct l2cap_chan *chan,
2322 struct msghdr *msg,
2323 size_t len, u16 sdulen)
2324{
2325 struct l2cap_conn *conn = chan->conn;
2326 struct sk_buff *skb;
2327 int err, count, hlen;
2328 struct l2cap_hdr *lh;
2329
2330 BT_DBG("chan %p len %zu", chan, len);
2331
2332 if (!conn)
2333 return ERR_PTR(-ENOTCONN);
2334
2335 hlen = L2CAP_HDR_SIZE;
2336
2337 if (sdulen)
2338 hlen += L2CAP_SDULEN_SIZE;
2339
2340 count = min_t(unsigned int, (conn->mtu - hlen), len);
2341
2342 skb = chan->ops->alloc_skb(chan, count + hlen,
2343 msg->msg_flags & MSG_DONTWAIT);
2344 if (IS_ERR(skb))
2345 return skb;
2346
2347 /* Create L2CAP header */
2348 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
2349 lh->cid = cpu_to_le16(chan->dcid);
2350 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
2351
2352 if (sdulen)
2353 put_unaligned_le16(sdulen, skb_put(skb, L2CAP_SDULEN_SIZE));
2354
2355 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
2356 if (unlikely(err < 0)) {
2357 kfree_skb(skb);
2358 return ERR_PTR(err);
2359 }
2360
2361 return skb;
2362}
2363
2364static int l2cap_segment_le_sdu(struct l2cap_chan *chan,
2365 struct sk_buff_head *seg_queue,
2366 struct msghdr *msg, size_t len)
2367{
2368 struct sk_buff *skb;
2369 size_t pdu_len;
2370 u16 sdu_len;
2371
2372 BT_DBG("chan %p, msg %p, len %zu", chan, msg, len);
2373
2374 pdu_len = chan->conn->mtu - L2CAP_HDR_SIZE;
2375
2376 pdu_len = min_t(size_t, pdu_len, chan->remote_mps);
2377
2378 sdu_len = len;
2379 pdu_len -= L2CAP_SDULEN_SIZE;
2380
2381 while (len > 0) {
2382 if (len <= pdu_len)
2383 pdu_len = len;
2384
2385 skb = l2cap_create_le_flowctl_pdu(chan, msg, pdu_len, sdu_len);
2386 if (IS_ERR(skb)) {
2387 __skb_queue_purge(seg_queue);
2388 return PTR_ERR(skb);
2389 }
2390
2391 __skb_queue_tail(seg_queue, skb);
2392
2393 len -= pdu_len;
2394
2395 if (sdu_len) {
2396 sdu_len = 0;
2397 pdu_len += L2CAP_SDULEN_SIZE;
2398 }
2399 }
2400
2401 return 0;
2402}
2403
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002404int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01002405 u32 priority)
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002406{
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002407 struct sk_buff *skb;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002408 int err;
Mat Martineau94122bb2012-05-02 09:42:02 -07002409 struct sk_buff_head seg_queue;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002410
Seung-Woo Kim31e8ce82013-11-05 18:46:33 +09002411 if (!chan->conn)
2412 return -ENOTCONN;
2413
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002414 /* Connectionless channel */
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002415 if (chan->chan_type == L2CAP_CHAN_CONN_LESS) {
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002416 skb = l2cap_create_connless_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002417 if (IS_ERR(skb))
2418 return PTR_ERR(skb);
2419
2420 l2cap_do_send(chan, skb);
2421 return len;
2422 }
2423
2424 switch (chan->mode) {
Johan Hedberg38319712013-05-17 12:49:23 +03002425 case L2CAP_MODE_LE_FLOWCTL:
Johan Hedberg177f8f22013-05-31 17:54:51 +03002426 /* Check outgoing MTU */
2427 if (len > chan->omtu)
2428 return -EMSGSIZE;
2429
Johan Hedbergfad5fc892013-12-05 09:45:01 +02002430 if (!chan->tx_credits)
2431 return -EAGAIN;
2432
Johan Hedberg177f8f22013-05-31 17:54:51 +03002433 __skb_queue_head_init(&seg_queue);
2434
2435 err = l2cap_segment_le_sdu(chan, &seg_queue, msg, len);
2436
2437 if (chan->state != BT_CONNECTED) {
2438 __skb_queue_purge(&seg_queue);
2439 err = -ENOTCONN;
2440 }
2441
2442 if (err)
2443 return err;
2444
2445 skb_queue_splice_tail_init(&seg_queue, &chan->tx_q);
2446
2447 while (chan->tx_credits && !skb_queue_empty(&chan->tx_q)) {
2448 l2cap_do_send(chan, skb_dequeue(&chan->tx_q));
2449 chan->tx_credits--;
2450 }
2451
2452 if (!chan->tx_credits)
2453 chan->ops->suspend(chan);
2454
2455 err = len;
2456
2457 break;
2458
Johan Hedbergfad5fc892013-12-05 09:45:01 +02002459 case L2CAP_MODE_BASIC:
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002460 /* Check outgoing MTU */
2461 if (len > chan->omtu)
2462 return -EMSGSIZE;
2463
2464 /* Create a basic PDU */
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002465 skb = l2cap_create_basic_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002466 if (IS_ERR(skb))
2467 return PTR_ERR(skb);
2468
2469 l2cap_do_send(chan, skb);
2470 err = len;
2471 break;
2472
2473 case L2CAP_MODE_ERTM:
2474 case L2CAP_MODE_STREAMING:
Mat Martineau94122bb2012-05-02 09:42:02 -07002475 /* Check outgoing MTU */
2476 if (len > chan->omtu) {
2477 err = -EMSGSIZE;
2478 break;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002479 }
2480
Mat Martineau94122bb2012-05-02 09:42:02 -07002481 __skb_queue_head_init(&seg_queue);
2482
2483 /* Do segmentation before calling in to the state machine,
2484 * since it's possible to block while waiting for memory
2485 * allocation.
2486 */
2487 err = l2cap_segment_sdu(chan, &seg_queue, msg, len);
2488
2489 /* The channel could have been closed while segmenting,
2490 * check that it is still connected.
2491 */
2492 if (chan->state != BT_CONNECTED) {
2493 __skb_queue_purge(&seg_queue);
2494 err = -ENOTCONN;
2495 }
2496
2497 if (err)
2498 break;
2499
Mat Martineau37339372012-05-17 20:53:33 -07002500 if (chan->mode == L2CAP_MODE_ERTM)
Gustavo Padovand6603662012-05-21 13:58:22 -03002501 l2cap_tx(chan, NULL, &seg_queue, L2CAP_EV_DATA_REQUEST);
Mat Martineau37339372012-05-17 20:53:33 -07002502 else
Gustavo Padovand6603662012-05-21 13:58:22 -03002503 l2cap_streaming_send(chan, &seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002504
Gustavo Padovand6603662012-05-21 13:58:22 -03002505 err = len;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002506
Mat Martineau94122bb2012-05-02 09:42:02 -07002507 /* If the skbs were not queued for sending, they'll still be in
2508 * seg_queue and need to be purged.
2509 */
2510 __skb_queue_purge(&seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002511 break;
2512
2513 default:
2514 BT_DBG("bad state %1.1x", chan->mode);
2515 err = -EBADFD;
2516 }
2517
2518 return err;
2519}
2520
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002521static void l2cap_send_srej(struct l2cap_chan *chan, u16 txseq)
2522{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002523 struct l2cap_ctrl control;
2524 u16 seq;
2525
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002526 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002527
2528 memset(&control, 0, sizeof(control));
2529 control.sframe = 1;
2530 control.super = L2CAP_SUPER_SREJ;
2531
2532 for (seq = chan->expected_tx_seq; seq != txseq;
2533 seq = __next_seq(chan, seq)) {
2534 if (!l2cap_ertm_seq_in_queue(&chan->srej_q, seq)) {
2535 control.reqseq = seq;
2536 l2cap_send_sframe(chan, &control);
2537 l2cap_seq_list_append(&chan->srej_list, seq);
2538 }
2539 }
2540
2541 chan->expected_tx_seq = __next_seq(chan, txseq);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002542}
2543
2544static void l2cap_send_srej_tail(struct l2cap_chan *chan)
2545{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002546 struct l2cap_ctrl control;
2547
2548 BT_DBG("chan %p", chan);
2549
2550 if (chan->srej_list.tail == L2CAP_SEQ_LIST_CLEAR)
2551 return;
2552
2553 memset(&control, 0, sizeof(control));
2554 control.sframe = 1;
2555 control.super = L2CAP_SUPER_SREJ;
2556 control.reqseq = chan->srej_list.tail;
2557 l2cap_send_sframe(chan, &control);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002558}
2559
2560static void l2cap_send_srej_list(struct l2cap_chan *chan, u16 txseq)
2561{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002562 struct l2cap_ctrl control;
2563 u16 initial_head;
2564 u16 seq;
2565
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002566 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002567
2568 memset(&control, 0, sizeof(control));
2569 control.sframe = 1;
2570 control.super = L2CAP_SUPER_SREJ;
2571
2572 /* Capture initial list head to allow only one pass through the list. */
2573 initial_head = chan->srej_list.head;
2574
2575 do {
2576 seq = l2cap_seq_list_pop(&chan->srej_list);
2577 if (seq == txseq || seq == L2CAP_SEQ_LIST_CLEAR)
2578 break;
2579
2580 control.reqseq = seq;
2581 l2cap_send_sframe(chan, &control);
2582 l2cap_seq_list_append(&chan->srej_list, seq);
2583 } while (chan->srej_list.head != initial_head);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002584}
2585
Mat Martineau608bcc62012-05-17 20:53:32 -07002586static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq)
2587{
2588 struct sk_buff *acked_skb;
2589 u16 ackseq;
2590
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002591 BT_DBG("chan %p, reqseq %u", chan, reqseq);
Mat Martineau608bcc62012-05-17 20:53:32 -07002592
2593 if (chan->unacked_frames == 0 || reqseq == chan->expected_ack_seq)
2594 return;
2595
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002596 BT_DBG("expected_ack_seq %u, unacked_frames %u",
Mat Martineau608bcc62012-05-17 20:53:32 -07002597 chan->expected_ack_seq, chan->unacked_frames);
2598
2599 for (ackseq = chan->expected_ack_seq; ackseq != reqseq;
2600 ackseq = __next_seq(chan, ackseq)) {
2601
2602 acked_skb = l2cap_ertm_seq_in_queue(&chan->tx_q, ackseq);
2603 if (acked_skb) {
2604 skb_unlink(acked_skb, &chan->tx_q);
2605 kfree_skb(acked_skb);
2606 chan->unacked_frames--;
2607 }
2608 }
2609
2610 chan->expected_ack_seq = reqseq;
2611
2612 if (chan->unacked_frames == 0)
2613 __clear_retrans_timer(chan);
2614
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002615 BT_DBG("unacked_frames %u", chan->unacked_frames);
Mat Martineau608bcc62012-05-17 20:53:32 -07002616}
2617
2618static void l2cap_abort_rx_srej_sent(struct l2cap_chan *chan)
2619{
2620 BT_DBG("chan %p", chan);
2621
2622 chan->expected_tx_seq = chan->buffer_seq;
2623 l2cap_seq_list_clear(&chan->srej_list);
2624 skb_queue_purge(&chan->srej_q);
2625 chan->rx_state = L2CAP_RX_STATE_RECV;
2626}
2627
Gustavo Padovand6603662012-05-21 13:58:22 -03002628static void l2cap_tx_state_xmit(struct l2cap_chan *chan,
2629 struct l2cap_ctrl *control,
2630 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002631{
Mat Martineau608bcc62012-05-17 20:53:32 -07002632 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2633 event);
2634
2635 switch (event) {
2636 case L2CAP_EV_DATA_REQUEST:
2637 if (chan->tx_send_head == NULL)
2638 chan->tx_send_head = skb_peek(skbs);
2639
2640 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2641 l2cap_ertm_send(chan);
2642 break;
2643 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2644 BT_DBG("Enter LOCAL_BUSY");
2645 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2646
2647 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2648 /* The SREJ_SENT state must be aborted if we are to
2649 * enter the LOCAL_BUSY state.
2650 */
2651 l2cap_abort_rx_srej_sent(chan);
2652 }
2653
2654 l2cap_send_ack(chan);
2655
2656 break;
2657 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2658 BT_DBG("Exit LOCAL_BUSY");
2659 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2660
2661 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2662 struct l2cap_ctrl local_control;
2663
2664 memset(&local_control, 0, sizeof(local_control));
2665 local_control.sframe = 1;
2666 local_control.super = L2CAP_SUPER_RR;
2667 local_control.poll = 1;
2668 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002669 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002670
2671 chan->retry_count = 1;
2672 __set_monitor_timer(chan);
2673 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2674 }
2675 break;
2676 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2677 l2cap_process_reqseq(chan, control->reqseq);
2678 break;
2679 case L2CAP_EV_EXPLICIT_POLL:
2680 l2cap_send_rr_or_rnr(chan, 1);
2681 chan->retry_count = 1;
2682 __set_monitor_timer(chan);
2683 __clear_ack_timer(chan);
2684 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2685 break;
2686 case L2CAP_EV_RETRANS_TO:
2687 l2cap_send_rr_or_rnr(chan, 1);
2688 chan->retry_count = 1;
2689 __set_monitor_timer(chan);
2690 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2691 break;
2692 case L2CAP_EV_RECV_FBIT:
2693 /* Nothing to process */
2694 break;
2695 default:
2696 break;
2697 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002698}
2699
Gustavo Padovand6603662012-05-21 13:58:22 -03002700static void l2cap_tx_state_wait_f(struct l2cap_chan *chan,
2701 struct l2cap_ctrl *control,
2702 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002703{
Mat Martineau608bcc62012-05-17 20:53:32 -07002704 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2705 event);
2706
2707 switch (event) {
2708 case L2CAP_EV_DATA_REQUEST:
2709 if (chan->tx_send_head == NULL)
2710 chan->tx_send_head = skb_peek(skbs);
2711 /* Queue data, but don't send. */
2712 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2713 break;
2714 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2715 BT_DBG("Enter LOCAL_BUSY");
2716 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2717
2718 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2719 /* The SREJ_SENT state must be aborted if we are to
2720 * enter the LOCAL_BUSY state.
2721 */
2722 l2cap_abort_rx_srej_sent(chan);
2723 }
2724
2725 l2cap_send_ack(chan);
2726
2727 break;
2728 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2729 BT_DBG("Exit LOCAL_BUSY");
2730 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2731
2732 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2733 struct l2cap_ctrl local_control;
2734 memset(&local_control, 0, sizeof(local_control));
2735 local_control.sframe = 1;
2736 local_control.super = L2CAP_SUPER_RR;
2737 local_control.poll = 1;
2738 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002739 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002740
2741 chan->retry_count = 1;
2742 __set_monitor_timer(chan);
2743 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2744 }
2745 break;
2746 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2747 l2cap_process_reqseq(chan, control->reqseq);
2748
2749 /* Fall through */
2750
2751 case L2CAP_EV_RECV_FBIT:
2752 if (control && control->final) {
2753 __clear_monitor_timer(chan);
2754 if (chan->unacked_frames > 0)
2755 __set_retrans_timer(chan);
2756 chan->retry_count = 0;
2757 chan->tx_state = L2CAP_TX_STATE_XMIT;
2758 BT_DBG("recv fbit tx_state 0x2.2%x", chan->tx_state);
2759 }
2760 break;
2761 case L2CAP_EV_EXPLICIT_POLL:
2762 /* Ignore */
2763 break;
2764 case L2CAP_EV_MONITOR_TO:
2765 if (chan->max_tx == 0 || chan->retry_count < chan->max_tx) {
2766 l2cap_send_rr_or_rnr(chan, 1);
2767 __set_monitor_timer(chan);
2768 chan->retry_count++;
2769 } else {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02002770 l2cap_send_disconn_req(chan, ECONNABORTED);
Mat Martineau608bcc62012-05-17 20:53:32 -07002771 }
2772 break;
2773 default:
2774 break;
2775 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002776}
2777
Gustavo Padovand6603662012-05-21 13:58:22 -03002778static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
2779 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002780{
Mat Martineau608bcc62012-05-17 20:53:32 -07002781 BT_DBG("chan %p, control %p, skbs %p, event %d, state %d",
2782 chan, control, skbs, event, chan->tx_state);
2783
2784 switch (chan->tx_state) {
2785 case L2CAP_TX_STATE_XMIT:
Gustavo Padovand6603662012-05-21 13:58:22 -03002786 l2cap_tx_state_xmit(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002787 break;
2788 case L2CAP_TX_STATE_WAIT_F:
Gustavo Padovand6603662012-05-21 13:58:22 -03002789 l2cap_tx_state_wait_f(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002790 break;
2791 default:
2792 /* Ignore event */
2793 break;
2794 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002795}
2796
Mat Martineau4b51dae92012-05-17 20:53:37 -07002797static void l2cap_pass_to_tx(struct l2cap_chan *chan,
2798 struct l2cap_ctrl *control)
2799{
2800 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002801 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_REQSEQ_AND_FBIT);
Mat Martineau4b51dae92012-05-17 20:53:37 -07002802}
2803
Mat Martineauf80842a2012-05-17 20:53:46 -07002804static void l2cap_pass_to_tx_fbit(struct l2cap_chan *chan,
2805 struct l2cap_ctrl *control)
2806{
2807 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002808 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_FBIT);
Mat Martineauf80842a2012-05-17 20:53:46 -07002809}
2810
Linus Torvalds1da177e2005-04-16 15:20:36 -07002811/* Copy frame to all raw sockets on that connection */
2812static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2813{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002814 struct sk_buff *nskb;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002815 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002816
2817 BT_DBG("conn %p", conn);
2818
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002819 mutex_lock(&conn->chan_lock);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002820
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002821 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002822 if (chan->chan_type != L2CAP_CHAN_RAW)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002823 continue;
2824
Gustavo Padovan7f5396a2013-10-21 18:22:25 -02002825 /* Don't send frame to the channel it came from */
2826 if (bt_cb(skb)->chan == chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002827 continue;
Gustavo Padovan7f5396a2013-10-21 18:22:25 -02002828
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002829 nskb = skb_clone(skb, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002830 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002831 continue;
Gustavo Padovan80b98022012-05-27 22:27:51 -03002832 if (chan->ops->recv(chan, nskb))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002833 kfree_skb(nskb);
2834 }
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002835
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002836 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002837}
2838
2839/* ---- L2CAP signalling commands ---- */
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002840static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code,
2841 u8 ident, u16 dlen, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002842{
2843 struct sk_buff *skb, **frag;
2844 struct l2cap_cmd_hdr *cmd;
2845 struct l2cap_hdr *lh;
2846 int len, count;
2847
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002848 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %u",
2849 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002850
Anderson Lizardo300b9622013-06-02 16:30:40 -04002851 if (conn->mtu < L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE)
2852 return NULL;
2853
Linus Torvalds1da177e2005-04-16 15:20:36 -07002854 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2855 count = min_t(unsigned int, conn->mtu, len);
2856
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002857 skb = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002858 if (!skb)
2859 return NULL;
2860
2861 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002862 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002863
2864 if (conn->hcon->type == LE_LINK)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002865 lh->cid = __constant_cpu_to_le16(L2CAP_CID_LE_SIGNALING);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002866 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002867 lh->cid = __constant_cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002868
2869 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2870 cmd->code = code;
2871 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002872 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002873
2874 if (dlen) {
2875 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2876 memcpy(skb_put(skb, count), data, count);
2877 data += count;
2878 }
2879
2880 len -= skb->len;
2881
2882 /* Continuation fragments (no L2CAP header) */
2883 frag = &skb_shinfo(skb)->frag_list;
2884 while (len) {
2885 count = min_t(unsigned int, conn->mtu, len);
2886
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002887 *frag = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002888 if (!*frag)
2889 goto fail;
2890
2891 memcpy(skb_put(*frag, count), data, count);
2892
2893 len -= count;
2894 data += count;
2895
2896 frag = &(*frag)->next;
2897 }
2898
2899 return skb;
2900
2901fail:
2902 kfree_skb(skb);
2903 return NULL;
2904}
2905
Gustavo Padovan2d792812012-10-06 10:07:01 +01002906static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen,
2907 unsigned long *val)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002908{
2909 struct l2cap_conf_opt *opt = *ptr;
2910 int len;
2911
2912 len = L2CAP_CONF_OPT_SIZE + opt->len;
2913 *ptr += len;
2914
2915 *type = opt->type;
2916 *olen = opt->len;
2917
2918 switch (opt->len) {
2919 case 1:
2920 *val = *((u8 *) opt->val);
2921 break;
2922
2923 case 2:
steven miaobfaaeb32010-10-16 18:29:47 -04002924 *val = get_unaligned_le16(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002925 break;
2926
2927 case 4:
steven miaobfaaeb32010-10-16 18:29:47 -04002928 *val = get_unaligned_le32(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002929 break;
2930
2931 default:
2932 *val = (unsigned long) opt->val;
2933 break;
2934 }
2935
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002936 BT_DBG("type 0x%2.2x len %u val 0x%lx", *type, opt->len, *val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002937 return len;
2938}
2939
Linus Torvalds1da177e2005-04-16 15:20:36 -07002940static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2941{
2942 struct l2cap_conf_opt *opt = *ptr;
2943
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002944 BT_DBG("type 0x%2.2x len %u val 0x%lx", type, len, val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002945
2946 opt->type = type;
2947 opt->len = len;
2948
2949 switch (len) {
2950 case 1:
2951 *((u8 *) opt->val) = val;
2952 break;
2953
2954 case 2:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002955 put_unaligned_le16(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002956 break;
2957
2958 case 4:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002959 put_unaligned_le32(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002960 break;
2961
2962 default:
2963 memcpy(opt->val, (void *) val, len);
2964 break;
2965 }
2966
2967 *ptr += L2CAP_CONF_OPT_SIZE + len;
2968}
2969
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002970static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan)
2971{
2972 struct l2cap_conf_efs efs;
2973
Szymon Janc1ec918c2011-11-16 09:32:21 +01002974 switch (chan->mode) {
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002975 case L2CAP_MODE_ERTM:
2976 efs.id = chan->local_id;
2977 efs.stype = chan->local_stype;
2978 efs.msdu = cpu_to_le16(chan->local_msdu);
2979 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002980 efs.acc_lat = __constant_cpu_to_le32(L2CAP_DEFAULT_ACC_LAT);
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03002981 efs.flush_to = __constant_cpu_to_le32(L2CAP_EFS_DEFAULT_FLUSH_TO);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002982 break;
2983
2984 case L2CAP_MODE_STREAMING:
2985 efs.id = 1;
2986 efs.stype = L2CAP_SERV_BESTEFFORT;
2987 efs.msdu = cpu_to_le16(chan->local_msdu);
2988 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
2989 efs.acc_lat = 0;
2990 efs.flush_to = 0;
2991 break;
2992
2993 default:
2994 return;
2995 }
2996
2997 l2cap_add_conf_opt(ptr, L2CAP_CONF_EFS, sizeof(efs),
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03002998 (unsigned long) &efs);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002999}
3000
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003001static void l2cap_ack_timeout(struct work_struct *work)
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003002{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003003 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau03625202012-05-17 20:53:51 -07003004 ack_timer.work);
3005 u16 frames_to_ack;
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003006
Gustavo F. Padovan2fb9b3d2011-12-22 16:56:05 -02003007 BT_DBG("chan %p", chan);
3008
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003009 l2cap_chan_lock(chan);
3010
Mat Martineau03625202012-05-17 20:53:51 -07003011 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
3012 chan->last_acked_seq);
3013
3014 if (frames_to_ack)
3015 l2cap_send_rr_or_rnr(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003016
3017 l2cap_chan_unlock(chan);
Szymon Janc09bfb2e2012-01-11 10:59:49 +01003018 l2cap_chan_put(chan);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003019}
3020
Andrei Emeltchenko466f8002012-05-29 13:59:01 +03003021int l2cap_ertm_init(struct l2cap_chan *chan)
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003022{
Mat Martineau3c588192012-04-11 10:48:42 -07003023 int err;
3024
Mat Martineau105bdf92012-04-27 16:50:48 -07003025 chan->next_tx_seq = 0;
3026 chan->expected_tx_seq = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03003027 chan->expected_ack_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03003028 chan->unacked_frames = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03003029 chan->buffer_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03003030 chan->frames_sent = 0;
Mat Martineau105bdf92012-04-27 16:50:48 -07003031 chan->last_acked_seq = 0;
3032 chan->sdu = NULL;
3033 chan->sdu_last_frag = NULL;
3034 chan->sdu_len = 0;
3035
Mat Martineaud34c34f2012-05-14 14:49:27 -07003036 skb_queue_head_init(&chan->tx_q);
3037
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003038 chan->local_amp_id = AMP_ID_BREDR;
3039 chan->move_id = AMP_ID_BREDR;
Mat Martineau08333282012-10-23 15:24:06 -07003040 chan->move_state = L2CAP_MOVE_STABLE;
3041 chan->move_role = L2CAP_MOVE_ROLE_NONE;
3042
Mat Martineau105bdf92012-04-27 16:50:48 -07003043 if (chan->mode != L2CAP_MODE_ERTM)
3044 return 0;
3045
3046 chan->rx_state = L2CAP_RX_STATE_RECV;
3047 chan->tx_state = L2CAP_TX_STATE_XMIT;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003048
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003049 INIT_DELAYED_WORK(&chan->retrans_timer, l2cap_retrans_timeout);
3050 INIT_DELAYED_WORK(&chan->monitor_timer, l2cap_monitor_timeout);
3051 INIT_DELAYED_WORK(&chan->ack_timer, l2cap_ack_timeout);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003052
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -03003053 skb_queue_head_init(&chan->srej_q);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003054
Mat Martineau3c588192012-04-11 10:48:42 -07003055 err = l2cap_seq_list_init(&chan->srej_list, chan->tx_win);
3056 if (err < 0)
3057 return err;
3058
Mat Martineau9dc9aff2012-05-17 16:20:14 -07003059 err = l2cap_seq_list_init(&chan->retrans_list, chan->remote_tx_win);
3060 if (err < 0)
3061 l2cap_seq_list_free(&chan->srej_list);
3062
3063 return err;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003064}
3065
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003066static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
3067{
3068 switch (mode) {
3069 case L2CAP_MODE_STREAMING:
3070 case L2CAP_MODE_ERTM:
3071 if (l2cap_mode_supported(mode, remote_feat_mask))
3072 return mode;
3073 /* fall through */
3074 default:
3075 return L2CAP_MODE_BASIC;
3076 }
3077}
3078
Marcel Holtmann848566b2013-10-01 22:59:22 -07003079static inline bool __l2cap_ews_supported(struct l2cap_conn *conn)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003080{
Marcel Holtmann848566b2013-10-01 22:59:22 -07003081 return conn->hs_enabled && conn->feat_mask & L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003082}
3083
Marcel Holtmann848566b2013-10-01 22:59:22 -07003084static inline bool __l2cap_efs_supported(struct l2cap_conn *conn)
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003085{
Marcel Holtmann848566b2013-10-01 22:59:22 -07003086 return conn->hs_enabled && conn->feat_mask & L2CAP_FEAT_EXT_FLOW;
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003087}
3088
Mat Martineau36c86c82012-10-23 15:24:20 -07003089static void __l2cap_set_ertm_timeouts(struct l2cap_chan *chan,
3090 struct l2cap_conf_rfc *rfc)
3091{
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003092 if (chan->local_amp_id != AMP_ID_BREDR && chan->hs_hcon) {
Mat Martineau36c86c82012-10-23 15:24:20 -07003093 u64 ertm_to = chan->hs_hcon->hdev->amp_be_flush_to;
3094
3095 /* Class 1 devices have must have ERTM timeouts
3096 * exceeding the Link Supervision Timeout. The
3097 * default Link Supervision Timeout for AMP
3098 * controllers is 10 seconds.
3099 *
3100 * Class 1 devices use 0xffffffff for their
3101 * best-effort flush timeout, so the clamping logic
3102 * will result in a timeout that meets the above
3103 * requirement. ERTM timeouts are 16-bit values, so
3104 * the maximum timeout is 65.535 seconds.
3105 */
3106
3107 /* Convert timeout to milliseconds and round */
3108 ertm_to = DIV_ROUND_UP_ULL(ertm_to, 1000);
3109
3110 /* This is the recommended formula for class 2 devices
3111 * that start ERTM timers when packets are sent to the
3112 * controller.
3113 */
3114 ertm_to = 3 * ertm_to + 500;
3115
3116 if (ertm_to > 0xffff)
3117 ertm_to = 0xffff;
3118
3119 rfc->retrans_timeout = cpu_to_le16((u16) ertm_to);
3120 rfc->monitor_timeout = rfc->retrans_timeout;
3121 } else {
3122 rfc->retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
3123 rfc->monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
3124 }
3125}
3126
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003127static inline void l2cap_txwin_setup(struct l2cap_chan *chan)
3128{
3129 if (chan->tx_win > L2CAP_DEFAULT_TX_WINDOW &&
Marcel Holtmann848566b2013-10-01 22:59:22 -07003130 __l2cap_ews_supported(chan->conn)) {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003131 /* use extended control field */
3132 set_bit(FLAG_EXT_CTRL, &chan->flags);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003133 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
3134 } else {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003135 chan->tx_win = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003136 L2CAP_DEFAULT_TX_WINDOW);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003137 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
3138 }
Mat Martineauc20f8e32012-07-10 05:47:07 -07003139 chan->ack_win = chan->tx_win;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003140}
3141
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003142static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003143{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003144 struct l2cap_conf_req *req = data;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003145 struct l2cap_conf_rfc rfc = { .mode = chan->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07003146 void *ptr = req->data;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003147 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003148
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03003149 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003150
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003151 if (chan->num_conf_req || chan->num_conf_rsp)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003152 goto done;
3153
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003154 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003155 case L2CAP_MODE_STREAMING:
3156 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003157 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state))
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003158 break;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003159
Marcel Holtmann848566b2013-10-01 22:59:22 -07003160 if (__l2cap_efs_supported(chan->conn))
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003161 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3162
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03003163 /* fall through */
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003164 default:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003165 chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003166 break;
3167 }
3168
3169done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003170 if (chan->imtu != L2CAP_DEFAULT_MTU)
3171 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovan7990681c2011-01-24 16:01:43 -02003172
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003173 switch (chan->mode) {
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003174 case L2CAP_MODE_BASIC:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003175 if (!(chan->conn->feat_mask & L2CAP_FEAT_ERTM) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003176 !(chan->conn->feat_mask & L2CAP_FEAT_STREAMING))
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003177 break;
3178
Gustavo F. Padovan62547752010-06-08 20:05:31 -03003179 rfc.mode = L2CAP_MODE_BASIC;
3180 rfc.txwin_size = 0;
3181 rfc.max_transmit = 0;
3182 rfc.retrans_timeout = 0;
3183 rfc.monitor_timeout = 0;
3184 rfc.max_pdu_size = 0;
3185
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003186 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003187 (unsigned long) &rfc);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003188 break;
3189
3190 case L2CAP_MODE_ERTM:
3191 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003192 rfc.max_transmit = chan->max_tx;
Mat Martineau36c86c82012-10-23 15:24:20 -07003193
3194 __l2cap_set_ertm_timeouts(chan, &rfc);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003195
3196 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003197 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3198 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003199 rfc.max_pdu_size = cpu_to_le16(size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003200
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003201 l2cap_txwin_setup(chan);
3202
3203 rfc.txwin_size = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003204 L2CAP_DEFAULT_TX_WINDOW);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003205
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003206 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003207 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003208
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003209 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3210 l2cap_add_opt_efs(&ptr, chan);
3211
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003212 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3213 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003214 chan->tx_win);
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003215
3216 if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
3217 if (chan->fcs == L2CAP_FCS_NONE ||
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003218 test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003219 chan->fcs = L2CAP_FCS_NONE;
3220 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
3221 chan->fcs);
3222 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003223 break;
3224
3225 case L2CAP_MODE_STREAMING:
Mat Martineau273759e2012-05-17 20:53:53 -07003226 l2cap_txwin_setup(chan);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003227 rfc.mode = L2CAP_MODE_STREAMING;
3228 rfc.txwin_size = 0;
3229 rfc.max_transmit = 0;
3230 rfc.retrans_timeout = 0;
3231 rfc.monitor_timeout = 0;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003232
3233 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003234 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3235 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003236 rfc.max_pdu_size = cpu_to_le16(size);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003237
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003238 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003239 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003240
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003241 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3242 l2cap_add_opt_efs(&ptr, chan);
3243
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003244 if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
3245 if (chan->fcs == L2CAP_FCS_NONE ||
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003246 test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003247 chan->fcs = L2CAP_FCS_NONE;
3248 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
3249 chan->fcs);
3250 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003251 break;
3252 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003253
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003254 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003255 req->flags = __constant_cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003256
3257 return ptr - data;
3258}
3259
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003260static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003261{
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003262 struct l2cap_conf_rsp *rsp = data;
3263 void *ptr = rsp->data;
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003264 void *req = chan->conf_req;
3265 int len = chan->conf_len;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003266 int type, hint, olen;
3267 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003268 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003269 struct l2cap_conf_efs efs;
3270 u8 remote_efs = 0;
Marcel Holtmann861d6882007-10-20 13:37:06 +02003271 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003272 u16 result = L2CAP_CONF_SUCCESS;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003273 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003274
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003275 BT_DBG("chan %p", chan);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01003276
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003277 while (len >= L2CAP_CONF_OPT_SIZE) {
3278 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003279
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03003280 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003281 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003282
3283 switch (type) {
3284 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02003285 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003286 break;
3287
3288 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003289 chan->flush_to = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003290 break;
3291
3292 case L2CAP_CONF_QOS:
3293 break;
3294
Marcel Holtmann6464f352007-10-20 13:39:51 +02003295 case L2CAP_CONF_RFC:
3296 if (olen == sizeof(rfc))
3297 memcpy(&rfc, (void *) val, olen);
3298 break;
3299
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003300 case L2CAP_CONF_FCS:
3301 if (val == L2CAP_FCS_NONE)
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003302 set_bit(CONF_RECV_NO_FCS, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003303 break;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003304
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003305 case L2CAP_CONF_EFS:
3306 remote_efs = 1;
3307 if (olen == sizeof(efs))
3308 memcpy(&efs, (void *) val, olen);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003309 break;
3310
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003311 case L2CAP_CONF_EWS:
Marcel Holtmann848566b2013-10-01 22:59:22 -07003312 if (!chan->conn->hs_enabled)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003313 return -ECONNREFUSED;
3314
3315 set_bit(FLAG_EXT_CTRL, &chan->flags);
3316 set_bit(CONF_EWS_RECV, &chan->conf_state);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003317 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003318 chan->remote_tx_win = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003319 break;
3320
3321 default:
3322 if (hint)
3323 break;
3324
3325 result = L2CAP_CONF_UNKNOWN;
3326 *((u8 *) ptr++) = type;
3327 break;
3328 }
3329 }
3330
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003331 if (chan->num_conf_rsp || chan->num_conf_req > 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003332 goto done;
3333
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003334 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003335 case L2CAP_MODE_STREAMING:
3336 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003337 if (!test_bit(CONF_STATE2_DEVICE, &chan->conf_state)) {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003338 chan->mode = l2cap_select_mode(rfc.mode,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003339 chan->conn->feat_mask);
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003340 break;
3341 }
3342
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003343 if (remote_efs) {
Marcel Holtmann848566b2013-10-01 22:59:22 -07003344 if (__l2cap_efs_supported(chan->conn))
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003345 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3346 else
3347 return -ECONNREFUSED;
3348 }
3349
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003350 if (chan->mode != rfc.mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003351 return -ECONNREFUSED;
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03003352
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003353 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003354 }
3355
3356done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003357 if (chan->mode != rfc.mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003358 result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003359 rfc.mode = chan->mode;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003360
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003361 if (chan->num_conf_rsp == 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003362 return -ECONNREFUSED;
3363
Gustavo Padovan2d792812012-10-06 10:07:01 +01003364 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3365 (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003366 }
3367
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003368 if (result == L2CAP_CONF_SUCCESS) {
3369 /* Configure output options and let the other side know
3370 * which ones we don't like. */
3371
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003372 if (mtu < L2CAP_DEFAULT_MIN_MTU)
3373 result = L2CAP_CONF_UNACCEPT;
3374 else {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003375 chan->omtu = mtu;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003376 set_bit(CONF_MTU_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003377 }
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003378 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003379
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003380 if (remote_efs) {
3381 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003382 efs.stype != L2CAP_SERV_NOTRAFIC &&
3383 efs.stype != chan->local_stype) {
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003384
3385 result = L2CAP_CONF_UNACCEPT;
3386
3387 if (chan->num_conf_req >= 1)
3388 return -ECONNREFUSED;
3389
3390 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003391 sizeof(efs),
3392 (unsigned long) &efs);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003393 } else {
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003394 /* Send PENDING Conf Rsp */
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003395 result = L2CAP_CONF_PENDING;
3396 set_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003397 }
3398 }
3399
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003400 switch (rfc.mode) {
3401 case L2CAP_MODE_BASIC:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003402 chan->fcs = L2CAP_FCS_NONE;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003403 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003404 break;
3405
3406 case L2CAP_MODE_ERTM:
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003407 if (!test_bit(CONF_EWS_RECV, &chan->conf_state))
3408 chan->remote_tx_win = rfc.txwin_size;
3409 else
3410 rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW;
3411
Gustavo F. Padovan2c03a7a2011-03-25 20:15:28 -03003412 chan->remote_max_tx = rfc.max_transmit;
Mat Martineau86b1b262010-08-05 15:54:22 -07003413
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003414 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003415 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3416 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003417 rfc.max_pdu_size = cpu_to_le16(size);
3418 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003419
Mat Martineau36c86c82012-10-23 15:24:20 -07003420 __l2cap_set_ertm_timeouts(chan, &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003421
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003422 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003423
3424 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003425 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003426
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003427 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3428 chan->remote_id = efs.id;
3429 chan->remote_stype = efs.stype;
3430 chan->remote_msdu = le16_to_cpu(efs.msdu);
3431 chan->remote_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003432 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003433 chan->remote_acc_lat =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003434 le32_to_cpu(efs.acc_lat);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003435 chan->remote_sdu_itime =
3436 le32_to_cpu(efs.sdu_itime);
3437 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003438 sizeof(efs),
3439 (unsigned long) &efs);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003440 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003441 break;
3442
3443 case L2CAP_MODE_STREAMING:
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003444 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003445 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3446 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003447 rfc.max_pdu_size = cpu_to_le16(size);
3448 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003449
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003450 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003451
Gustavo Padovan2d792812012-10-06 10:07:01 +01003452 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3453 (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003454
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003455 break;
3456
3457 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02003458 result = L2CAP_CONF_UNACCEPT;
3459
3460 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003461 rfc.mode = chan->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003462 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003463
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003464 if (result == L2CAP_CONF_SUCCESS)
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003465 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003466 }
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003467 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003468 rsp->result = cpu_to_le16(result);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003469 rsp->flags = __constant_cpu_to_le16(0);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003470
3471 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003472}
3473
Gustavo Padovan2d792812012-10-06 10:07:01 +01003474static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len,
3475 void *data, u16 *result)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003476{
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003477 struct l2cap_conf_req *req = data;
3478 void *ptr = req->data;
3479 int type, olen;
3480 unsigned long val;
Mat Martineau36e999a2011-12-08 17:23:21 -08003481 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003482 struct l2cap_conf_efs efs;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003483
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003484 BT_DBG("chan %p, rsp %p, len %d, req %p", chan, rsp, len, data);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003485
3486 while (len >= L2CAP_CONF_OPT_SIZE) {
3487 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3488
3489 switch (type) {
3490 case L2CAP_CONF_MTU:
3491 if (val < L2CAP_DEFAULT_MIN_MTU) {
3492 *result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003493 chan->imtu = L2CAP_DEFAULT_MIN_MTU;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003494 } else
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003495 chan->imtu = val;
3496 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003497 break;
3498
3499 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003500 chan->flush_to = val;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003501 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003502 2, chan->flush_to);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003503 break;
3504
3505 case L2CAP_CONF_RFC:
3506 if (olen == sizeof(rfc))
3507 memcpy(&rfc, (void *)val, olen);
3508
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003509 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003510 rfc.mode != chan->mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003511 return -ECONNREFUSED;
3512
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003513 chan->fcs = 0;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003514
3515 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003516 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003517 break;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003518
3519 case L2CAP_CONF_EWS:
Mat Martineauc20f8e32012-07-10 05:47:07 -07003520 chan->ack_win = min_t(u16, val, chan->ack_win);
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003521 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Mat Martineauc20f8e32012-07-10 05:47:07 -07003522 chan->tx_win);
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003523 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003524
3525 case L2CAP_CONF_EFS:
3526 if (olen == sizeof(efs))
3527 memcpy(&efs, (void *)val, olen);
3528
3529 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003530 efs.stype != L2CAP_SERV_NOTRAFIC &&
3531 efs.stype != chan->local_stype)
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003532 return -ECONNREFUSED;
3533
Gustavo Padovan2d792812012-10-06 10:07:01 +01003534 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs),
3535 (unsigned long) &efs);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003536 break;
Andrei Emeltchenkocbabee72012-11-29 17:46:07 +02003537
3538 case L2CAP_CONF_FCS:
3539 if (*result == L2CAP_CONF_PENDING)
3540 if (val == L2CAP_FCS_NONE)
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003541 set_bit(CONF_RECV_NO_FCS,
Andrei Emeltchenkocbabee72012-11-29 17:46:07 +02003542 &chan->conf_state);
3543 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003544 }
3545 }
3546
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003547 if (chan->mode == L2CAP_MODE_BASIC && chan->mode != rfc.mode)
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003548 return -ECONNREFUSED;
3549
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003550 chan->mode = rfc.mode;
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003551
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003552 if (*result == L2CAP_CONF_SUCCESS || *result == L2CAP_CONF_PENDING) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003553 switch (rfc.mode) {
3554 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003555 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3556 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
3557 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003558 if (!test_bit(FLAG_EXT_CTRL, &chan->flags))
3559 chan->ack_win = min_t(u16, chan->ack_win,
3560 rfc.txwin_size);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003561
3562 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3563 chan->local_msdu = le16_to_cpu(efs.msdu);
3564 chan->local_sdu_itime =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003565 le32_to_cpu(efs.sdu_itime);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003566 chan->local_acc_lat = le32_to_cpu(efs.acc_lat);
3567 chan->local_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003568 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003569 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003570 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003571
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003572 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003573 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003574 }
3575 }
3576
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003577 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003578 req->flags = __constant_cpu_to_le16(0);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003579
3580 return ptr - data;
3581}
3582
Gustavo Padovan2d792812012-10-06 10:07:01 +01003583static int l2cap_build_conf_rsp(struct l2cap_chan *chan, void *data,
3584 u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003585{
3586 struct l2cap_conf_rsp *rsp = data;
3587 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003588
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003589 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003590
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003591 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003592 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003593 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003594
3595 return ptr - data;
3596}
3597
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03003598void __l2cap_le_connect_rsp_defer(struct l2cap_chan *chan)
3599{
3600 struct l2cap_le_conn_rsp rsp;
3601 struct l2cap_conn *conn = chan->conn;
3602
3603 BT_DBG("chan %p", chan);
3604
3605 rsp.dcid = cpu_to_le16(chan->scid);
3606 rsp.mtu = cpu_to_le16(chan->imtu);
Johan Hedberg3916aed2013-10-07 15:35:26 +02003607 rsp.mps = cpu_to_le16(chan->mps);
Johan Hedberg0cd75f72013-05-17 13:09:05 +03003608 rsp.credits = cpu_to_le16(chan->rx_credits);
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03003609 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
3610
3611 l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CONN_RSP, sizeof(rsp),
3612 &rsp);
3613}
3614
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003615void __l2cap_connect_rsp_defer(struct l2cap_chan *chan)
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003616{
3617 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003618 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003619 u8 buf[128];
Andrei Emeltchenko439f34a2012-10-31 15:46:28 +02003620 u8 rsp_code;
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003621
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003622 rsp.scid = cpu_to_le16(chan->dcid);
3623 rsp.dcid = cpu_to_le16(chan->scid);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003624 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
3625 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Andrei Emeltchenko439f34a2012-10-31 15:46:28 +02003626
3627 if (chan->hs_hcon)
3628 rsp_code = L2CAP_CREATE_CHAN_RSP;
3629 else
3630 rsp_code = L2CAP_CONN_RSP;
3631
3632 BT_DBG("chan %p rsp_code %u", chan, rsp_code);
3633
3634 l2cap_send_cmd(conn, chan->ident, rsp_code, sizeof(rsp), &rsp);
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003635
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003636 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003637 return;
3638
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003639 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003640 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003641 chan->num_conf_req++;
3642}
3643
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003644static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003645{
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003646 int type, olen;
3647 unsigned long val;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003648 /* Use sane default values in case a misbehaving remote device
3649 * did not send an RFC or extended window size option.
3650 */
3651 u16 txwin_ext = chan->ack_win;
3652 struct l2cap_conf_rfc rfc = {
3653 .mode = chan->mode,
3654 .retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO),
3655 .monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO),
3656 .max_pdu_size = cpu_to_le16(chan->imtu),
3657 .txwin_size = min_t(u16, chan->ack_win, L2CAP_DEFAULT_TX_WINDOW),
3658 };
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003659
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003660 BT_DBG("chan %p, rsp %p, len %d", chan, rsp, len);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003661
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003662 if ((chan->mode != L2CAP_MODE_ERTM) && (chan->mode != L2CAP_MODE_STREAMING))
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003663 return;
3664
3665 while (len >= L2CAP_CONF_OPT_SIZE) {
3666 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3667
Mat Martineauc20f8e32012-07-10 05:47:07 -07003668 switch (type) {
3669 case L2CAP_CONF_RFC:
3670 if (olen == sizeof(rfc))
3671 memcpy(&rfc, (void *)val, olen);
Szymon Janc8f321f82012-06-08 11:33:33 +02003672 break;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003673 case L2CAP_CONF_EWS:
3674 txwin_ext = val;
3675 break;
3676 }
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003677 }
3678
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003679 switch (rfc.mode) {
3680 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003681 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3682 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003683 chan->mps = le16_to_cpu(rfc.max_pdu_size);
3684 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3685 chan->ack_win = min_t(u16, chan->ack_win, txwin_ext);
3686 else
3687 chan->ack_win = min_t(u16, chan->ack_win,
3688 rfc.txwin_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003689 break;
3690 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003691 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003692 }
3693}
3694
Gustavo Padovan2d792812012-10-06 10:07:01 +01003695static inline int l2cap_command_rej(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003696 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3697 u8 *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003698{
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003699 struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003700
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003701 if (cmd_len < sizeof(*rej))
3702 return -EPROTO;
3703
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003704 if (rej->reason != L2CAP_REJ_NOT_UNDERSTOOD)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003705 return 0;
3706
3707 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003708 cmd->ident == conn->info_ident) {
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02003709 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01003710
3711 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003712 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003713
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003714 l2cap_conn_start(conn);
3715 }
3716
3717 return 0;
3718}
3719
Mat Martineau17009152012-10-23 15:24:07 -07003720static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
3721 struct l2cap_cmd_hdr *cmd,
3722 u8 *data, u8 rsp_code, u8 amp_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003723{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003724 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
3725 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003726 struct l2cap_chan *chan = NULL, *pchan;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003727 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003728
3729 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003730 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003731
Andrei Emeltchenko097db762012-03-09 14:16:17 +02003732 BT_DBG("psm 0x%2.2x scid 0x%4.4x", __le16_to_cpu(psm), scid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003733
3734 /* Check if we have socket listening on psm */
Marcel Holtmann6f59b902013-10-13 05:24:01 -07003735 pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, &conn->hcon->src,
Johan Hedbergbf20fd42013-05-14 13:23:13 +03003736 &conn->hcon->dst, ACL_LINK);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003737 if (!pchan) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003738 result = L2CAP_CR_BAD_PSM;
3739 goto sendresp;
3740 }
3741
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003742 mutex_lock(&conn->chan_lock);
Gustavo Padovan8ffb9292013-10-21 14:21:41 -02003743 l2cap_chan_lock(pchan);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00003744
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003745 /* Check if the ACL is secure enough (if not SDP) */
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +03003746 if (psm != __constant_cpu_to_le16(L2CAP_PSM_SDP) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003747 !hci_conn_check_link_mode(conn->hcon)) {
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003748 conn->disc_reason = HCI_ERROR_AUTH_FAILURE;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003749 result = L2CAP_CR_SEC_BLOCK;
3750 goto response;
3751 }
3752
Linus Torvalds1da177e2005-04-16 15:20:36 -07003753 result = L2CAP_CR_NO_MEM;
3754
Gustavo Padovan2dfa1002012-05-27 22:27:58 -03003755 /* Check if we already have channel with that dcid */
3756 if (__l2cap_get_chan_by_dcid(conn, scid))
3757 goto response;
3758
Gustavo Padovan80b98022012-05-27 22:27:51 -03003759 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003760 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003761 goto response;
3762
Syam Sidhardhan330b6c12013-08-06 01:59:12 +09003763 /* For certain devices (ex: HID mouse), support for authentication,
3764 * pairing and bonding is optional. For such devices, inorder to avoid
3765 * the ACL alive for too long after L2CAP disconnection, reset the ACL
3766 * disc_timeout back to HCI_DISCONN_TIMEOUT during L2CAP connect.
3767 */
3768 conn->hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
3769
Marcel Holtmann7eafc592013-10-13 08:12:47 -07003770 bacpy(&chan->src, &conn->hcon->src);
3771 bacpy(&chan->dst, &conn->hcon->dst);
Marcel Holtmann4f1654e2013-10-13 08:50:41 -07003772 chan->src_type = bdaddr_type(conn->hcon, conn->hcon->src_type);
3773 chan->dst_type = bdaddr_type(conn->hcon, conn->hcon->dst_type);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003774 chan->psm = psm;
3775 chan->dcid = scid;
Mat Martineau17009152012-10-23 15:24:07 -07003776 chan->local_amp_id = amp_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003777
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003778 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003779
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003780 dcid = chan->scid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003781
Gustavo Padovan8d836d72013-10-15 19:24:47 -03003782 __set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003783
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003784 chan->ident = cmd->ident;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003785
Marcel Holtmann984947d2009-02-06 23:35:19 +01003786 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02003787 if (l2cap_chan_check_security(chan)) {
Marcel Holtmannbdc25782013-10-14 02:45:34 -07003788 if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02003789 l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003790 result = L2CAP_CR_PEND;
3791 status = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08003792 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003793 } else {
Mat Martineau17009152012-10-23 15:24:07 -07003794 /* Force pending result for AMP controllers.
3795 * The connection will succeed after the
3796 * physical link is up.
3797 */
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003798 if (amp_id == AMP_ID_BREDR) {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02003799 l2cap_state_change(chan, BT_CONFIG);
Mat Martineau17009152012-10-23 15:24:07 -07003800 result = L2CAP_CR_SUCCESS;
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003801 } else {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02003802 l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003803 result = L2CAP_CR_PEND;
Mat Martineau17009152012-10-23 15:24:07 -07003804 }
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003805 status = L2CAP_CS_NO_INFO;
3806 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003807 } else {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02003808 l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003809 result = L2CAP_CR_PEND;
3810 status = L2CAP_CS_AUTHEN_PEND;
3811 }
3812 } else {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02003813 l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003814 result = L2CAP_CR_PEND;
3815 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003816 }
3817
Linus Torvalds1da177e2005-04-16 15:20:36 -07003818response:
Gustavo Padovan8ffb9292013-10-21 14:21:41 -02003819 l2cap_chan_unlock(pchan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003820 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003821
3822sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003823 rsp.scid = cpu_to_le16(scid);
3824 rsp.dcid = cpu_to_le16(dcid);
3825 rsp.result = cpu_to_le16(result);
3826 rsp.status = cpu_to_le16(status);
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003827 l2cap_send_cmd(conn, cmd->ident, rsp_code, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003828
3829 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
3830 struct l2cap_info_req info;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003831 info.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003832
3833 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
3834 conn->info_ident = l2cap_get_ident(conn);
3835
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08003836 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003837
Gustavo Padovan2d792812012-10-06 10:07:01 +01003838 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
3839 sizeof(info), &info);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003840 }
3841
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003842 if (chan && !test_bit(CONF_REQ_SENT, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003843 result == L2CAP_CR_SUCCESS) {
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003844 u8 buf[128];
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003845 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003846 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003847 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003848 chan->num_conf_req++;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003849 }
Mat Martineau17009152012-10-23 15:24:07 -07003850
3851 return chan;
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003852}
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003853
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003854static int l2cap_connect_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003855 struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003856{
Jaganath Kanakkassery7b064ed2013-01-10 10:28:35 +05303857 struct hci_dev *hdev = conn->hcon->hdev;
3858 struct hci_conn *hcon = conn->hcon;
3859
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003860 if (cmd_len < sizeof(struct l2cap_conn_req))
3861 return -EPROTO;
3862
Jaganath Kanakkassery7b064ed2013-01-10 10:28:35 +05303863 hci_dev_lock(hdev);
3864 if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
3865 !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &hcon->flags))
3866 mgmt_device_connected(hdev, &hcon->dst, hcon->type,
3867 hcon->dst_type, 0, NULL, 0,
3868 hcon->dev_class);
3869 hci_dev_unlock(hdev);
3870
Gustavo Padovan300229f2012-10-12 19:40:40 +08003871 l2cap_connect(conn, cmd, data, L2CAP_CONN_RSP, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003872 return 0;
3873}
3874
Mat Martineau5909cf32012-10-23 15:24:08 -07003875static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003876 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3877 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003878{
3879 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
3880 u16 scid, dcid, result, status;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003881 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003882 u8 req[128];
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003883 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003884
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003885 if (cmd_len < sizeof(*rsp))
3886 return -EPROTO;
3887
Linus Torvalds1da177e2005-04-16 15:20:36 -07003888 scid = __le16_to_cpu(rsp->scid);
3889 dcid = __le16_to_cpu(rsp->dcid);
3890 result = __le16_to_cpu(rsp->result);
3891 status = __le16_to_cpu(rsp->status);
3892
Andrei Emeltchenko1b009c92012-02-21 12:54:54 +02003893 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 +01003894 dcid, scid, result, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003895
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003896 mutex_lock(&conn->chan_lock);
3897
Linus Torvalds1da177e2005-04-16 15:20:36 -07003898 if (scid) {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003899 chan = __l2cap_get_chan_by_scid(conn, scid);
3900 if (!chan) {
Johan Hedberg21870b52013-09-16 13:05:14 +03003901 err = -EBADSLT;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003902 goto unlock;
3903 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003904 } else {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003905 chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
3906 if (!chan) {
Johan Hedberg21870b52013-09-16 13:05:14 +03003907 err = -EBADSLT;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003908 goto unlock;
3909 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003910 }
3911
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003912 err = 0;
3913
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003914 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003915
Linus Torvalds1da177e2005-04-16 15:20:36 -07003916 switch (result) {
3917 case L2CAP_CR_SUCCESS:
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03003918 l2cap_state_change(chan, BT_CONFIG);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003919 chan->ident = 0;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003920 chan->dcid = dcid;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003921 clear_bit(CONF_CONNECT_PEND, &chan->conf_state);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003922
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003923 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003924 break;
3925
Linus Torvalds1da177e2005-04-16 15:20:36 -07003926 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003927 l2cap_build_conf_req(chan, req), req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003928 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003929 break;
3930
3931 case L2CAP_CR_PEND:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003932 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003933 break;
3934
3935 default:
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003936 l2cap_chan_del(chan, ECONNREFUSED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003937 break;
3938 }
3939
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003940 l2cap_chan_unlock(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003941
3942unlock:
3943 mutex_unlock(&conn->chan_lock);
3944
3945 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003946}
3947
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003948static inline void set_default_fcs(struct l2cap_chan *chan)
Mat Martineau8c462b62010-08-24 15:35:42 -07003949{
3950 /* FCS is enabled only in ERTM or streaming mode, if one or both
3951 * sides request it.
3952 */
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003953 if (chan->mode != L2CAP_MODE_ERTM && chan->mode != L2CAP_MODE_STREAMING)
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003954 chan->fcs = L2CAP_FCS_NONE;
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003955 else if (!test_bit(CONF_RECV_NO_FCS, &chan->conf_state))
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003956 chan->fcs = L2CAP_FCS_CRC16;
Mat Martineau8c462b62010-08-24 15:35:42 -07003957}
3958
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03003959static void l2cap_send_efs_conf_rsp(struct l2cap_chan *chan, void *data,
3960 u8 ident, u16 flags)
3961{
3962 struct l2cap_conn *conn = chan->conn;
3963
3964 BT_DBG("conn %p chan %p ident %d flags 0x%4.4x", conn, chan, ident,
3965 flags);
3966
3967 clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
3968 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
3969
3970 l2cap_send_cmd(conn, ident, L2CAP_CONF_RSP,
3971 l2cap_build_conf_rsp(chan, data,
3972 L2CAP_CONF_SUCCESS, flags), data);
3973}
3974
Johan Hedberg662d6522013-10-16 11:20:47 +03003975static void cmd_reject_invalid_cid(struct l2cap_conn *conn, u8 ident,
3976 u16 scid, u16 dcid)
3977{
3978 struct l2cap_cmd_rej_cid rej;
3979
3980 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_INVALID_CID);
3981 rej.scid = __cpu_to_le16(scid);
3982 rej.dcid = __cpu_to_le16(dcid);
3983
3984 l2cap_send_cmd(conn, ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
3985}
3986
Gustavo Padovan2d792812012-10-06 10:07:01 +01003987static inline int l2cap_config_req(struct l2cap_conn *conn,
3988 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3989 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003990{
3991 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
3992 u16 dcid, flags;
3993 u8 rsp[64];
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003994 struct l2cap_chan *chan;
Mat Martineau3c588192012-04-11 10:48:42 -07003995 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003996
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003997 if (cmd_len < sizeof(*req))
3998 return -EPROTO;
3999
Linus Torvalds1da177e2005-04-16 15:20:36 -07004000 dcid = __le16_to_cpu(req->dcid);
4001 flags = __le16_to_cpu(req->flags);
4002
4003 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
4004
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03004005 chan = l2cap_get_chan_by_scid(conn, dcid);
Johan Hedberg662d6522013-10-16 11:20:47 +03004006 if (!chan) {
4007 cmd_reject_invalid_cid(conn, cmd->ident, dcid, 0);
4008 return 0;
4009 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004010
David S. Miller033b1142011-07-21 13:38:42 -07004011 if (chan->state != BT_CONFIG && chan->state != BT_CONNECT2) {
Johan Hedberg662d6522013-10-16 11:20:47 +03004012 cmd_reject_invalid_cid(conn, cmd->ident, chan->scid,
4013 chan->dcid);
Marcel Holtmann354f60a2006-11-18 22:15:20 +01004014 goto unlock;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03004015 }
Marcel Holtmann354f60a2006-11-18 22:15:20 +01004016
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004017 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07004018 len = cmd_len - sizeof(*req);
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004019 if (chan->conf_len + len > sizeof(chan->conf_req)) {
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004020 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004021 l2cap_build_conf_rsp(chan, rsp,
4022 L2CAP_CONF_REJECT, flags), rsp);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004023 goto unlock;
4024 }
4025
4026 /* Store config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004027 memcpy(chan->conf_req + chan->conf_len, req->data, len);
4028 chan->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004029
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03004030 if (flags & L2CAP_CONF_FLAG_CONTINUATION) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004031 /* Incomplete config. Send empty response. */
4032 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004033 l2cap_build_conf_rsp(chan, rsp,
4034 L2CAP_CONF_SUCCESS, flags), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004035 goto unlock;
4036 }
4037
4038 /* Complete config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004039 len = l2cap_parse_conf_req(chan, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004040 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004041 l2cap_send_disconn_req(chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004042 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004043 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004044
Mat Martineau1500109b2012-10-23 15:24:15 -07004045 chan->ident = cmd->ident;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004046 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004047 chan->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004048
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004049 /* Reset config buffer. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004050 chan->conf_len = 0;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004051
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004052 if (!test_bit(CONF_OUTPUT_DONE, &chan->conf_state))
Marcel Holtmann876d9482007-10-20 13:35:42 +02004053 goto unlock;
4054
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004055 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004056 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004057
Mat Martineau105bdf92012-04-27 16:50:48 -07004058 if (chan->mode == L2CAP_MODE_ERTM ||
4059 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07004060 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03004061
Mat Martineau3c588192012-04-11 10:48:42 -07004062 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004063 l2cap_send_disconn_req(chan, -err);
Mat Martineau3c588192012-04-11 10:48:42 -07004064 else
4065 l2cap_chan_ready(chan);
4066
Marcel Holtmann876d9482007-10-20 13:35:42 +02004067 goto unlock;
4068 }
4069
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004070 if (!test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004071 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004072 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004073 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004074 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004075 }
4076
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004077 /* Got Conf Rsp PENDING from remote side and asume we sent
4078 Conf Rsp PENDING in the code above */
4079 if (test_bit(CONF_REM_CONF_PEND, &chan->conf_state) &&
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03004080 test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004081
4082 /* check compatibility */
4083
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004084 /* Send rsp for BR/EDR channel */
Andrei Emeltchenkof351bc72012-10-31 15:46:35 +02004085 if (!chan->hs_hcon)
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004086 l2cap_send_efs_conf_rsp(chan, rsp, cmd->ident, flags);
4087 else
4088 chan->ident = cmd->ident;
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004089 }
4090
Linus Torvalds1da177e2005-04-16 15:20:36 -07004091unlock:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004092 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07004093 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004094}
4095
Gustavo Padovan2d792812012-10-06 10:07:01 +01004096static inline int l2cap_config_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004097 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4098 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004099{
4100 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
4101 u16 scid, flags, result;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004102 struct l2cap_chan *chan;
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004103 int len = cmd_len - sizeof(*rsp);
Mat Martineau3c588192012-04-11 10:48:42 -07004104 int err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004105
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004106 if (cmd_len < sizeof(*rsp))
4107 return -EPROTO;
4108
Linus Torvalds1da177e2005-04-16 15:20:36 -07004109 scid = __le16_to_cpu(rsp->scid);
4110 flags = __le16_to_cpu(rsp->flags);
4111 result = __le16_to_cpu(rsp->result);
4112
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02004113 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x len %d", scid, flags,
4114 result, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004115
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03004116 chan = l2cap_get_chan_by_scid(conn, scid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004117 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004118 return 0;
4119
4120 switch (result) {
4121 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004122 l2cap_conf_rfc_get(chan, rsp->data, len);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004123 clear_bit(CONF_REM_CONF_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004124 break;
4125
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004126 case L2CAP_CONF_PENDING:
4127 set_bit(CONF_REM_CONF_PEND, &chan->conf_state);
4128
4129 if (test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
4130 char buf[64];
4131
4132 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004133 buf, &result);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004134 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004135 l2cap_send_disconn_req(chan, ECONNRESET);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004136 goto done;
4137 }
4138
Andrei Emeltchenkof351bc72012-10-31 15:46:35 +02004139 if (!chan->hs_hcon) {
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004140 l2cap_send_efs_conf_rsp(chan, buf, cmd->ident,
4141 0);
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +02004142 } else {
4143 if (l2cap_check_efs(chan)) {
4144 amp_create_logical_link(chan);
4145 chan->ident = cmd->ident;
4146 }
4147 }
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004148 }
4149 goto done;
4150
Linus Torvalds1da177e2005-04-16 15:20:36 -07004151 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004152 if (chan->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004153 char req[64];
4154
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02004155 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004156 l2cap_send_disconn_req(chan, ECONNRESET);
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02004157 goto done;
4158 }
4159
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004160 /* throw out any old stored conf requests */
4161 result = L2CAP_CONF_SUCCESS;
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03004162 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004163 req, &result);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004164 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004165 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004166 goto done;
4167 }
4168
4169 l2cap_send_cmd(conn, l2cap_get_ident(conn),
Gustavo Padovan2d792812012-10-06 10:07:01 +01004170 L2CAP_CONF_REQ, len, req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004171 chan->num_conf_req++;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004172 if (result != L2CAP_CONF_SUCCESS)
4173 goto done;
4174 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004175 }
4176
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09004177 default:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004178 l2cap_chan_set_err(chan, ECONNRESET);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02004179
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08004180 __set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004181 l2cap_send_disconn_req(chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004182 goto done;
4183 }
4184
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03004185 if (flags & L2CAP_CONF_FLAG_CONTINUATION)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004186 goto done;
4187
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004188 set_bit(CONF_INPUT_DONE, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004189
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004190 if (test_bit(CONF_OUTPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004191 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004192
Mat Martineau105bdf92012-04-27 16:50:48 -07004193 if (chan->mode == L2CAP_MODE_ERTM ||
4194 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07004195 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03004196
Mat Martineau3c588192012-04-11 10:48:42 -07004197 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004198 l2cap_send_disconn_req(chan, -err);
Mat Martineau3c588192012-04-11 10:48:42 -07004199 else
4200 l2cap_chan_ready(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004201 }
4202
4203done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004204 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07004205 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004206}
4207
Gustavo Padovan2d792812012-10-06 10:07:01 +01004208static inline int l2cap_disconnect_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004209 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4210 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004211{
4212 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
4213 struct l2cap_disconn_rsp rsp;
4214 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004215 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004216
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004217 if (cmd_len != sizeof(*req))
4218 return -EPROTO;
4219
Linus Torvalds1da177e2005-04-16 15:20:36 -07004220 scid = __le16_to_cpu(req->scid);
4221 dcid = __le16_to_cpu(req->dcid);
4222
4223 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
4224
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004225 mutex_lock(&conn->chan_lock);
4226
4227 chan = __l2cap_get_chan_by_scid(conn, dcid);
4228 if (!chan) {
4229 mutex_unlock(&conn->chan_lock);
Johan Hedberg662d6522013-10-16 11:20:47 +03004230 cmd_reject_invalid_cid(conn, cmd->ident, dcid, scid);
4231 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004232 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004233
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004234 l2cap_chan_lock(chan);
4235
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03004236 rsp.dcid = cpu_to_le16(chan->scid);
4237 rsp.scid = cpu_to_le16(chan->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004238 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
4239
Gustavo Padovan5ec1bbe2013-10-15 19:24:48 -03004240 chan->ops->set_shutdown(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004241
Mat Martineau61d6ef32012-04-27 16:50:50 -07004242 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004243 l2cap_chan_del(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004244
4245 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004246
Gustavo Padovan80b98022012-05-27 22:27:51 -03004247 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004248 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004249
4250 mutex_unlock(&conn->chan_lock);
4251
Linus Torvalds1da177e2005-04-16 15:20:36 -07004252 return 0;
4253}
4254
Gustavo Padovan2d792812012-10-06 10:07:01 +01004255static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004256 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4257 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004258{
4259 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
4260 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004261 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004262
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004263 if (cmd_len != sizeof(*rsp))
4264 return -EPROTO;
4265
Linus Torvalds1da177e2005-04-16 15:20:36 -07004266 scid = __le16_to_cpu(rsp->scid);
4267 dcid = __le16_to_cpu(rsp->dcid);
4268
4269 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
4270
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004271 mutex_lock(&conn->chan_lock);
4272
4273 chan = __l2cap_get_chan_by_scid(conn, scid);
4274 if (!chan) {
4275 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004276 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004277 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004278
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004279 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004280
Mat Martineau61d6ef32012-04-27 16:50:50 -07004281 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004282 l2cap_chan_del(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004283
4284 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004285
Gustavo Padovan80b98022012-05-27 22:27:51 -03004286 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004287 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004288
4289 mutex_unlock(&conn->chan_lock);
4290
Linus Torvalds1da177e2005-04-16 15:20:36 -07004291 return 0;
4292}
4293
Gustavo Padovan2d792812012-10-06 10:07:01 +01004294static inline int l2cap_information_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004295 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4296 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004297{
4298 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004299 u16 type;
4300
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004301 if (cmd_len != sizeof(*req))
4302 return -EPROTO;
4303
Linus Torvalds1da177e2005-04-16 15:20:36 -07004304 type = __le16_to_cpu(req->type);
4305
4306 BT_DBG("type 0x%4.4x", type);
4307
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004308 if (type == L2CAP_IT_FEAT_MASK) {
4309 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07004310 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004311 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004312 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
4313 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03004314 if (!disable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004315 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
Gustavo Padovan2d792812012-10-06 10:07:01 +01004316 | L2CAP_FEAT_FCS;
Marcel Holtmann848566b2013-10-01 22:59:22 -07004317 if (conn->hs_enabled)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03004318 feat_mask |= L2CAP_FEAT_EXT_FLOW
Gustavo Padovan2d792812012-10-06 10:07:01 +01004319 | L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03004320
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03004321 put_unaligned_le32(feat_mask, rsp->data);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004322 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4323 buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004324 } else if (type == L2CAP_IT_FIXED_CHAN) {
4325 u8 buf[12];
4326 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Mat Martineau50a147c2011-11-02 16:18:34 -07004327
Marcel Holtmann848566b2013-10-01 22:59:22 -07004328 if (conn->hs_enabled)
Mat Martineau50a147c2011-11-02 16:18:34 -07004329 l2cap_fixed_chan[0] |= L2CAP_FC_A2MP;
4330 else
4331 l2cap_fixed_chan[0] &= ~L2CAP_FC_A2MP;
4332
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004333 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
4334 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Andrei Emeltchenkoc6337ea2011-10-20 17:02:44 +03004335 memcpy(rsp->data, l2cap_fixed_chan, sizeof(l2cap_fixed_chan));
Gustavo Padovan2d792812012-10-06 10:07:01 +01004336 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4337 buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004338 } else {
4339 struct l2cap_info_rsp rsp;
4340 rsp.type = cpu_to_le16(type);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004341 rsp.result = __constant_cpu_to_le16(L2CAP_IR_NOTSUPP);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004342 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(rsp),
4343 &rsp);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004344 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004345
4346 return 0;
4347}
4348
Gustavo Padovan2d792812012-10-06 10:07:01 +01004349static inline int l2cap_information_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004350 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4351 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004352{
4353 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
4354 u16 type, result;
4355
Jaganath Kanakkassery3f6fa3d2013-06-21 19:55:11 +05304356 if (cmd_len < sizeof(*rsp))
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004357 return -EPROTO;
4358
Linus Torvalds1da177e2005-04-16 15:20:36 -07004359 type = __le16_to_cpu(rsp->type);
4360 result = __le16_to_cpu(rsp->result);
4361
4362 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
4363
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004364 /* L2CAP Info req/rsp are unbound to channels, add extra checks */
4365 if (cmd->ident != conn->info_ident ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01004366 conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004367 return 0;
4368
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02004369 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004370
Ville Tervoadb08ed2010-08-04 09:43:33 +03004371 if (result != L2CAP_IR_SUCCESS) {
4372 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4373 conn->info_ident = 0;
4374
4375 l2cap_conn_start(conn);
4376
4377 return 0;
4378 }
4379
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004380 switch (type) {
4381 case L2CAP_IT_FEAT_MASK:
Harvey Harrison83985312008-05-02 16:25:46 -07004382 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004383
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07004384 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004385 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004386 req.type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004387
4388 conn->info_ident = l2cap_get_ident(conn);
4389
4390 l2cap_send_cmd(conn, conn->info_ident,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004391 L2CAP_INFO_REQ, sizeof(req), &req);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004392 } else {
4393 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4394 conn->info_ident = 0;
4395
4396 l2cap_conn_start(conn);
4397 }
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004398 break;
4399
4400 case L2CAP_IT_FIXED_CHAN:
4401 conn->fixed_chan_mask = rsp->data[0];
Marcel Holtmann984947d2009-02-06 23:35:19 +01004402 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004403 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004404
4405 l2cap_conn_start(conn);
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004406 break;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004407 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004408
Linus Torvalds1da177e2005-04-16 15:20:36 -07004409 return 0;
4410}
4411
Mat Martineau17009152012-10-23 15:24:07 -07004412static int l2cap_create_channel_req(struct l2cap_conn *conn,
4413 struct l2cap_cmd_hdr *cmd,
4414 u16 cmd_len, void *data)
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004415{
4416 struct l2cap_create_chan_req *req = data;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004417 struct l2cap_create_chan_rsp rsp;
Mat Martineau17009152012-10-23 15:24:07 -07004418 struct l2cap_chan *chan;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004419 struct hci_dev *hdev;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004420 u16 psm, scid;
4421
4422 if (cmd_len != sizeof(*req))
4423 return -EPROTO;
4424
Marcel Holtmann848566b2013-10-01 22:59:22 -07004425 if (!conn->hs_enabled)
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004426 return -EINVAL;
4427
4428 psm = le16_to_cpu(req->psm);
4429 scid = le16_to_cpu(req->scid);
4430
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004431 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 -07004432
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004433 /* For controller id 0 make BR/EDR connection */
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004434 if (req->amp_id == AMP_ID_BREDR) {
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004435 l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4436 req->amp_id);
4437 return 0;
4438 }
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004439
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004440 /* Validate AMP controller id */
4441 hdev = hci_dev_get(req->amp_id);
4442 if (!hdev)
4443 goto error;
Mat Martineau17009152012-10-23 15:24:07 -07004444
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004445 if (hdev->dev_type != HCI_AMP || !test_bit(HCI_UP, &hdev->flags)) {
Mat Martineau17009152012-10-23 15:24:07 -07004446 hci_dev_put(hdev);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004447 goto error;
Mat Martineau17009152012-10-23 15:24:07 -07004448 }
4449
4450 chan = l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4451 req->amp_id);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004452 if (chan) {
4453 struct amp_mgr *mgr = conn->hcon->amp_mgr;
4454 struct hci_conn *hs_hcon;
4455
Marcel Holtmann98e0f7e2013-10-13 02:23:40 -07004456 hs_hcon = hci_conn_hash_lookup_ba(hdev, AMP_LINK,
4457 &conn->hcon->dst);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004458 if (!hs_hcon) {
4459 hci_dev_put(hdev);
Johan Hedberg662d6522013-10-16 11:20:47 +03004460 cmd_reject_invalid_cid(conn, cmd->ident, chan->scid,
4461 chan->dcid);
4462 return 0;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004463 }
4464
4465 BT_DBG("mgr %p bredr_chan %p hs_hcon %p", mgr, chan, hs_hcon);
4466
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004467 mgr->bredr_chan = chan;
4468 chan->hs_hcon = hs_hcon;
Andrei Emeltchenkofd45bf42012-11-20 17:16:22 +02004469 chan->fcs = L2CAP_FCS_NONE;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004470 conn->mtu = hdev->block_mtu;
4471 }
4472
4473 hci_dev_put(hdev);
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004474
4475 return 0;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004476
4477error:
4478 rsp.dcid = 0;
4479 rsp.scid = cpu_to_le16(scid);
4480 rsp.result = __constant_cpu_to_le16(L2CAP_CR_BAD_AMP);
4481 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
4482
4483 l2cap_send_cmd(conn, cmd->ident, L2CAP_CREATE_CHAN_RSP,
4484 sizeof(rsp), &rsp);
4485
Johan Hedbergdc280802013-09-16 13:05:13 +03004486 return 0;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004487}
4488
Mat Martineau8eb200b2012-10-23 15:24:17 -07004489static void l2cap_send_move_chan_req(struct l2cap_chan *chan, u8 dest_amp_id)
4490{
4491 struct l2cap_move_chan_req req;
4492 u8 ident;
4493
4494 BT_DBG("chan %p, dest_amp_id %d", chan, dest_amp_id);
4495
4496 ident = l2cap_get_ident(chan->conn);
4497 chan->ident = ident;
4498
4499 req.icid = cpu_to_le16(chan->scid);
4500 req.dest_amp_id = dest_amp_id;
4501
4502 l2cap_send_cmd(chan->conn, ident, L2CAP_MOVE_CHAN_REQ, sizeof(req),
4503 &req);
4504
4505 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4506}
4507
Mat Martineau1500109b2012-10-23 15:24:15 -07004508static void l2cap_send_move_chan_rsp(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004509{
4510 struct l2cap_move_chan_rsp rsp;
4511
Mat Martineau1500109b2012-10-23 15:24:15 -07004512 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004513
Mat Martineau1500109b2012-10-23 15:24:15 -07004514 rsp.icid = cpu_to_le16(chan->dcid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004515 rsp.result = cpu_to_le16(result);
4516
Mat Martineau1500109b2012-10-23 15:24:15 -07004517 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_RSP,
4518 sizeof(rsp), &rsp);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004519}
4520
Mat Martineau5b155ef2012-10-23 15:24:14 -07004521static void l2cap_send_move_chan_cfm(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004522{
4523 struct l2cap_move_chan_cfm cfm;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004524
Mat Martineau5b155ef2012-10-23 15:24:14 -07004525 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004526
Mat Martineau5b155ef2012-10-23 15:24:14 -07004527 chan->ident = l2cap_get_ident(chan->conn);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004528
Mat Martineau5b155ef2012-10-23 15:24:14 -07004529 cfm.icid = cpu_to_le16(chan->scid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004530 cfm.result = cpu_to_le16(result);
4531
Mat Martineau5b155ef2012-10-23 15:24:14 -07004532 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_CFM,
4533 sizeof(cfm), &cfm);
4534
4535 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4536}
4537
4538static void l2cap_send_move_chan_cfm_icid(struct l2cap_conn *conn, u16 icid)
4539{
4540 struct l2cap_move_chan_cfm cfm;
4541
4542 BT_DBG("conn %p, icid 0x%4.4x", conn, icid);
4543
4544 cfm.icid = cpu_to_le16(icid);
4545 cfm.result = __constant_cpu_to_le16(L2CAP_MC_UNCONFIRMED);
4546
4547 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_MOVE_CHAN_CFM,
4548 sizeof(cfm), &cfm);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004549}
4550
4551static void l2cap_send_move_chan_cfm_rsp(struct l2cap_conn *conn, u8 ident,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004552 u16 icid)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004553{
4554 struct l2cap_move_chan_cfm_rsp rsp;
4555
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004556 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004557
4558 rsp.icid = cpu_to_le16(icid);
4559 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM_RSP, sizeof(rsp), &rsp);
4560}
4561
Mat Martineau5f3847a2012-10-23 15:24:12 -07004562static void __release_logical_link(struct l2cap_chan *chan)
4563{
4564 chan->hs_hchan = NULL;
4565 chan->hs_hcon = NULL;
4566
4567 /* Placeholder - release the logical link */
4568}
4569
Mat Martineau1500109b2012-10-23 15:24:15 -07004570static void l2cap_logical_fail(struct l2cap_chan *chan)
4571{
4572 /* Logical link setup failed */
4573 if (chan->state != BT_CONNECTED) {
4574 /* Create channel failure, disconnect */
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004575 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineau1500109b2012-10-23 15:24:15 -07004576 return;
4577 }
4578
4579 switch (chan->move_role) {
4580 case L2CAP_MOVE_ROLE_RESPONDER:
4581 l2cap_move_done(chan);
4582 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_SUPP);
4583 break;
4584 case L2CAP_MOVE_ROLE_INITIATOR:
4585 if (chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_COMP ||
4586 chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_CFM) {
4587 /* Remote has only sent pending or
4588 * success responses, clean up
4589 */
4590 l2cap_move_done(chan);
4591 }
4592
4593 /* Other amp move states imply that the move
4594 * has already aborted
4595 */
4596 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4597 break;
4598 }
4599}
4600
4601static void l2cap_logical_finish_create(struct l2cap_chan *chan,
4602 struct hci_chan *hchan)
4603{
4604 struct l2cap_conf_rsp rsp;
Mat Martineau1500109b2012-10-23 15:24:15 -07004605
Andrei Emeltchenko336178a2012-10-31 15:46:27 +02004606 chan->hs_hchan = hchan;
Mat Martineau1500109b2012-10-23 15:24:15 -07004607 chan->hs_hcon->l2cap_data = chan->conn;
4608
Andrei Emeltchenko35ba9562012-10-25 15:20:43 +03004609 l2cap_send_efs_conf_rsp(chan, &rsp, chan->ident, 0);
Mat Martineau1500109b2012-10-23 15:24:15 -07004610
4611 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Andrei Emeltchenkofe79c6f2012-10-25 15:20:42 +03004612 int err;
Mat Martineau1500109b2012-10-23 15:24:15 -07004613
4614 set_default_fcs(chan);
4615
4616 err = l2cap_ertm_init(chan);
4617 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004618 l2cap_send_disconn_req(chan, -err);
Mat Martineau1500109b2012-10-23 15:24:15 -07004619 else
4620 l2cap_chan_ready(chan);
4621 }
4622}
4623
4624static void l2cap_logical_finish_move(struct l2cap_chan *chan,
4625 struct hci_chan *hchan)
4626{
4627 chan->hs_hcon = hchan->conn;
4628 chan->hs_hcon->l2cap_data = chan->conn;
4629
4630 BT_DBG("move_state %d", chan->move_state);
4631
4632 switch (chan->move_state) {
4633 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
4634 /* Move confirm will be sent after a success
4635 * response is received
4636 */
4637 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4638 break;
4639 case L2CAP_MOVE_WAIT_LOGICAL_CFM:
4640 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4641 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4642 } else if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
4643 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
4644 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4645 } else if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
4646 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4647 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
4648 }
4649 break;
4650 default:
4651 /* Move was not in expected state, free the channel */
4652 __release_logical_link(chan);
4653
4654 chan->move_state = L2CAP_MOVE_STABLE;
4655 }
4656}
4657
4658/* Call with chan locked */
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03004659void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan,
4660 u8 status)
Mat Martineau5b155ef2012-10-23 15:24:14 -07004661{
Mat Martineau1500109b2012-10-23 15:24:15 -07004662 BT_DBG("chan %p, hchan %p, status %d", chan, hchan, status);
4663
4664 if (status) {
4665 l2cap_logical_fail(chan);
4666 __release_logical_link(chan);
4667 return;
4668 }
4669
4670 if (chan->state != BT_CONNECTED) {
4671 /* Ignore logical link if channel is on BR/EDR */
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004672 if (chan->local_amp_id != AMP_ID_BREDR)
Mat Martineau1500109b2012-10-23 15:24:15 -07004673 l2cap_logical_finish_create(chan, hchan);
4674 } else {
4675 l2cap_logical_finish_move(chan, hchan);
4676 }
Mat Martineau5b155ef2012-10-23 15:24:14 -07004677}
4678
Mat Martineau3f7a56c2012-10-23 15:24:23 -07004679void l2cap_move_start(struct l2cap_chan *chan)
4680{
4681 BT_DBG("chan %p", chan);
4682
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004683 if (chan->local_amp_id == AMP_ID_BREDR) {
Mat Martineau3f7a56c2012-10-23 15:24:23 -07004684 if (chan->chan_policy != BT_CHANNEL_POLICY_AMP_PREFERRED)
4685 return;
4686 chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
4687 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
4688 /* Placeholder - start physical link setup */
4689 } else {
4690 chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
4691 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4692 chan->move_id = 0;
4693 l2cap_move_setup(chan);
4694 l2cap_send_move_chan_req(chan, 0);
4695 }
4696}
4697
Mat Martineau8eb200b2012-10-23 15:24:17 -07004698static void l2cap_do_create(struct l2cap_chan *chan, int result,
4699 u8 local_amp_id, u8 remote_amp_id)
4700{
Andrei Emeltchenko62748ca2012-11-20 17:16:19 +02004701 BT_DBG("chan %p state %s %u -> %u", chan, state_to_string(chan->state),
4702 local_amp_id, remote_amp_id);
4703
Andrei Emeltchenko12d6cc62012-11-14 17:39:31 +02004704 chan->fcs = L2CAP_FCS_NONE;
4705
Andrei Emeltchenko62748ca2012-11-20 17:16:19 +02004706 /* Outgoing channel on AMP */
4707 if (chan->state == BT_CONNECT) {
4708 if (result == L2CAP_CR_SUCCESS) {
4709 chan->local_amp_id = local_amp_id;
4710 l2cap_send_create_chan_req(chan, remote_amp_id);
4711 } else {
4712 /* Revert to BR/EDR connect */
4713 l2cap_send_conn_req(chan);
4714 }
4715
4716 return;
4717 }
4718
4719 /* Incoming channel on AMP */
4720 if (__l2cap_no_conn_pending(chan)) {
Mat Martineau8eb200b2012-10-23 15:24:17 -07004721 struct l2cap_conn_rsp rsp;
4722 char buf[128];
4723 rsp.scid = cpu_to_le16(chan->dcid);
4724 rsp.dcid = cpu_to_le16(chan->scid);
4725
Mat Martineau8eb200b2012-10-23 15:24:17 -07004726 if (result == L2CAP_CR_SUCCESS) {
4727 /* Send successful response */
Andrei Emeltchenko62cd50e2012-11-14 17:39:32 +02004728 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
4729 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004730 } else {
4731 /* Send negative response */
Andrei Emeltchenko62cd50e2012-11-14 17:39:32 +02004732 rsp.result = __constant_cpu_to_le16(L2CAP_CR_NO_MEM);
4733 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004734 }
4735
4736 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_RSP,
4737 sizeof(rsp), &rsp);
4738
4739 if (result == L2CAP_CR_SUCCESS) {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02004740 l2cap_state_change(chan, BT_CONFIG);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004741 set_bit(CONF_REQ_SENT, &chan->conf_state);
4742 l2cap_send_cmd(chan->conn, l2cap_get_ident(chan->conn),
4743 L2CAP_CONF_REQ,
4744 l2cap_build_conf_req(chan, buf), buf);
4745 chan->num_conf_req++;
4746 }
Mat Martineau8eb200b2012-10-23 15:24:17 -07004747 }
4748}
4749
4750static void l2cap_do_move_initiate(struct l2cap_chan *chan, u8 local_amp_id,
4751 u8 remote_amp_id)
4752{
4753 l2cap_move_setup(chan);
4754 chan->move_id = local_amp_id;
4755 chan->move_state = L2CAP_MOVE_WAIT_RSP;
4756
4757 l2cap_send_move_chan_req(chan, remote_amp_id);
4758}
4759
4760static void l2cap_do_move_respond(struct l2cap_chan *chan, int result)
4761{
4762 struct hci_chan *hchan = NULL;
4763
4764 /* Placeholder - get hci_chan for logical link */
4765
4766 if (hchan) {
4767 if (hchan->state == BT_CONNECTED) {
4768 /* Logical link is ready to go */
4769 chan->hs_hcon = hchan->conn;
4770 chan->hs_hcon->l2cap_data = chan->conn;
4771 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4772 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
4773
4774 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
4775 } else {
4776 /* Wait for logical link to be ready */
4777 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4778 }
4779 } else {
4780 /* Logical link not available */
4781 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_ALLOWED);
4782 }
4783}
4784
4785static void l2cap_do_move_cancel(struct l2cap_chan *chan, int result)
4786{
4787 if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
4788 u8 rsp_result;
4789 if (result == -EINVAL)
4790 rsp_result = L2CAP_MR_BAD_ID;
4791 else
4792 rsp_result = L2CAP_MR_NOT_ALLOWED;
4793
4794 l2cap_send_move_chan_rsp(chan, rsp_result);
4795 }
4796
4797 chan->move_role = L2CAP_MOVE_ROLE_NONE;
4798 chan->move_state = L2CAP_MOVE_STABLE;
4799
4800 /* Restart data transmission */
4801 l2cap_ertm_send(chan);
4802}
4803
Andrei Emeltchenkoa514b172012-11-14 17:39:30 +02004804/* Invoke with locked chan */
4805void __l2cap_physical_cfm(struct l2cap_chan *chan, int result)
Mat Martineau8eb200b2012-10-23 15:24:17 -07004806{
Andrei Emeltchenko770bfef2012-10-31 15:46:29 +02004807 u8 local_amp_id = chan->local_amp_id;
Andrei Emeltchenkofffadc02012-11-01 15:37:03 +02004808 u8 remote_amp_id = chan->remote_amp_id;
Andrei Emeltchenko770bfef2012-10-31 15:46:29 +02004809
Mat Martineau8eb200b2012-10-23 15:24:17 -07004810 BT_DBG("chan %p, result %d, local_amp_id %d, remote_amp_id %d",
4811 chan, result, local_amp_id, remote_amp_id);
4812
Mat Martineau8eb200b2012-10-23 15:24:17 -07004813 if (chan->state == BT_DISCONN || chan->state == BT_CLOSED) {
4814 l2cap_chan_unlock(chan);
4815 return;
4816 }
4817
4818 if (chan->state != BT_CONNECTED) {
4819 l2cap_do_create(chan, result, local_amp_id, remote_amp_id);
4820 } else if (result != L2CAP_MR_SUCCESS) {
4821 l2cap_do_move_cancel(chan, result);
4822 } else {
4823 switch (chan->move_role) {
4824 case L2CAP_MOVE_ROLE_INITIATOR:
4825 l2cap_do_move_initiate(chan, local_amp_id,
4826 remote_amp_id);
4827 break;
4828 case L2CAP_MOVE_ROLE_RESPONDER:
4829 l2cap_do_move_respond(chan, result);
4830 break;
4831 default:
4832 l2cap_do_move_cancel(chan, result);
4833 break;
4834 }
4835 }
Mat Martineau8eb200b2012-10-23 15:24:17 -07004836}
4837
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004838static inline int l2cap_move_channel_req(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004839 struct l2cap_cmd_hdr *cmd,
4840 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004841{
4842 struct l2cap_move_chan_req *req = data;
Mat Martineau1500109b2012-10-23 15:24:15 -07004843 struct l2cap_move_chan_rsp rsp;
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004844 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004845 u16 icid = 0;
4846 u16 result = L2CAP_MR_NOT_ALLOWED;
4847
4848 if (cmd_len != sizeof(*req))
4849 return -EPROTO;
4850
4851 icid = le16_to_cpu(req->icid);
4852
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004853 BT_DBG("icid 0x%4.4x, dest_amp_id %d", icid, req->dest_amp_id);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004854
Marcel Holtmann848566b2013-10-01 22:59:22 -07004855 if (!conn->hs_enabled)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004856 return -EINVAL;
4857
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004858 chan = l2cap_get_chan_by_dcid(conn, icid);
4859 if (!chan) {
Mat Martineau1500109b2012-10-23 15:24:15 -07004860 rsp.icid = cpu_to_le16(icid);
4861 rsp.result = __constant_cpu_to_le16(L2CAP_MR_NOT_ALLOWED);
4862 l2cap_send_cmd(conn, cmd->ident, L2CAP_MOVE_CHAN_RSP,
4863 sizeof(rsp), &rsp);
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004864 return 0;
4865 }
4866
Mat Martineau1500109b2012-10-23 15:24:15 -07004867 chan->ident = cmd->ident;
4868
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004869 if (chan->scid < L2CAP_CID_DYN_START ||
4870 chan->chan_policy == BT_CHANNEL_POLICY_BREDR_ONLY ||
4871 (chan->mode != L2CAP_MODE_ERTM &&
4872 chan->mode != L2CAP_MODE_STREAMING)) {
4873 result = L2CAP_MR_NOT_ALLOWED;
4874 goto send_move_response;
4875 }
4876
4877 if (chan->local_amp_id == req->dest_amp_id) {
4878 result = L2CAP_MR_SAME_ID;
4879 goto send_move_response;
4880 }
4881
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004882 if (req->dest_amp_id != AMP_ID_BREDR) {
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004883 struct hci_dev *hdev;
4884 hdev = hci_dev_get(req->dest_amp_id);
4885 if (!hdev || hdev->dev_type != HCI_AMP ||
4886 !test_bit(HCI_UP, &hdev->flags)) {
4887 if (hdev)
4888 hci_dev_put(hdev);
4889
4890 result = L2CAP_MR_BAD_ID;
4891 goto send_move_response;
4892 }
4893 hci_dev_put(hdev);
4894 }
4895
4896 /* Detect a move collision. Only send a collision response
4897 * if this side has "lost", otherwise proceed with the move.
4898 * The winner has the larger bd_addr.
4899 */
4900 if ((__chan_is_moving(chan) ||
4901 chan->move_role != L2CAP_MOVE_ROLE_NONE) &&
Marcel Holtmann6f59b902013-10-13 05:24:01 -07004902 bacmp(&conn->hcon->src, &conn->hcon->dst) > 0) {
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004903 result = L2CAP_MR_COLLISION;
4904 goto send_move_response;
4905 }
4906
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004907 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
4908 l2cap_move_setup(chan);
4909 chan->move_id = req->dest_amp_id;
4910 icid = chan->dcid;
4911
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004912 if (req->dest_amp_id == AMP_ID_BREDR) {
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004913 /* Moving to BR/EDR */
4914 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4915 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4916 result = L2CAP_MR_PEND;
4917 } else {
4918 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4919 result = L2CAP_MR_SUCCESS;
4920 }
4921 } else {
4922 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
4923 /* Placeholder - uncomment when amp functions are available */
4924 /*amp_accept_physical(chan, req->dest_amp_id);*/
4925 result = L2CAP_MR_PEND;
4926 }
4927
4928send_move_response:
Mat Martineau1500109b2012-10-23 15:24:15 -07004929 l2cap_send_move_chan_rsp(chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004930
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004931 l2cap_chan_unlock(chan);
4932
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004933 return 0;
4934}
4935
Mat Martineau5b155ef2012-10-23 15:24:14 -07004936static void l2cap_move_continue(struct l2cap_conn *conn, u16 icid, u16 result)
4937{
4938 struct l2cap_chan *chan;
4939 struct hci_chan *hchan = NULL;
4940
4941 chan = l2cap_get_chan_by_scid(conn, icid);
4942 if (!chan) {
4943 l2cap_send_move_chan_cfm_icid(conn, icid);
4944 return;
4945 }
4946
4947 __clear_chan_timer(chan);
4948 if (result == L2CAP_MR_PEND)
4949 __set_chan_timer(chan, L2CAP_MOVE_ERTX_TIMEOUT);
4950
4951 switch (chan->move_state) {
4952 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
4953 /* Move confirm will be sent when logical link
4954 * is complete.
4955 */
4956 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4957 break;
4958 case L2CAP_MOVE_WAIT_RSP_SUCCESS:
4959 if (result == L2CAP_MR_PEND) {
4960 break;
4961 } else if (test_bit(CONN_LOCAL_BUSY,
4962 &chan->conn_state)) {
4963 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4964 } else {
4965 /* Logical link is up or moving to BR/EDR,
4966 * proceed with move
4967 */
4968 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
4969 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4970 }
4971 break;
4972 case L2CAP_MOVE_WAIT_RSP:
4973 /* Moving to AMP */
4974 if (result == L2CAP_MR_SUCCESS) {
4975 /* Remote is ready, send confirm immediately
4976 * after logical link is ready
4977 */
4978 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4979 } else {
4980 /* Both logical link and move success
4981 * are required to confirm
4982 */
4983 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_COMP;
4984 }
4985
4986 /* Placeholder - get hci_chan for logical link */
4987 if (!hchan) {
4988 /* Logical link not available */
4989 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4990 break;
4991 }
4992
4993 /* If the logical link is not yet connected, do not
4994 * send confirmation.
4995 */
4996 if (hchan->state != BT_CONNECTED)
4997 break;
4998
4999 /* Logical link is already ready to go */
5000
5001 chan->hs_hcon = hchan->conn;
5002 chan->hs_hcon->l2cap_data = chan->conn;
5003
5004 if (result == L2CAP_MR_SUCCESS) {
5005 /* Can confirm now */
5006 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
5007 } else {
5008 /* Now only need move success
5009 * to confirm
5010 */
5011 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
5012 }
5013
5014 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
5015 break;
5016 default:
5017 /* Any other amp move state means the move failed. */
5018 chan->move_id = chan->local_amp_id;
5019 l2cap_move_done(chan);
5020 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
5021 }
5022
5023 l2cap_chan_unlock(chan);
5024}
5025
5026static void l2cap_move_fail(struct l2cap_conn *conn, u8 ident, u16 icid,
5027 u16 result)
5028{
5029 struct l2cap_chan *chan;
5030
5031 chan = l2cap_get_chan_by_ident(conn, ident);
5032 if (!chan) {
5033 /* Could not locate channel, icid is best guess */
5034 l2cap_send_move_chan_cfm_icid(conn, icid);
5035 return;
5036 }
5037
5038 __clear_chan_timer(chan);
5039
5040 if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
5041 if (result == L2CAP_MR_COLLISION) {
5042 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
5043 } else {
5044 /* Cleanup - cancel move */
5045 chan->move_id = chan->local_amp_id;
5046 l2cap_move_done(chan);
5047 }
5048 }
5049
5050 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
5051
5052 l2cap_chan_unlock(chan);
5053}
5054
5055static int l2cap_move_channel_rsp(struct l2cap_conn *conn,
5056 struct l2cap_cmd_hdr *cmd,
5057 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005058{
5059 struct l2cap_move_chan_rsp *rsp = data;
5060 u16 icid, result;
5061
5062 if (cmd_len != sizeof(*rsp))
5063 return -EPROTO;
5064
5065 icid = le16_to_cpu(rsp->icid);
5066 result = le16_to_cpu(rsp->result);
5067
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005068 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005069
Mat Martineau5b155ef2012-10-23 15:24:14 -07005070 if (result == L2CAP_MR_SUCCESS || result == L2CAP_MR_PEND)
5071 l2cap_move_continue(conn, icid, result);
5072 else
5073 l2cap_move_fail(conn, cmd->ident, icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005074
5075 return 0;
5076}
5077
Mat Martineau5f3847a2012-10-23 15:24:12 -07005078static int l2cap_move_channel_confirm(struct l2cap_conn *conn,
5079 struct l2cap_cmd_hdr *cmd,
5080 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005081{
5082 struct l2cap_move_chan_cfm *cfm = data;
Mat Martineau5f3847a2012-10-23 15:24:12 -07005083 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005084 u16 icid, result;
5085
5086 if (cmd_len != sizeof(*cfm))
5087 return -EPROTO;
5088
5089 icid = le16_to_cpu(cfm->icid);
5090 result = le16_to_cpu(cfm->result);
5091
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005092 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005093
Mat Martineau5f3847a2012-10-23 15:24:12 -07005094 chan = l2cap_get_chan_by_dcid(conn, icid);
5095 if (!chan) {
5096 /* Spec requires a response even if the icid was not found */
5097 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
5098 return 0;
5099 }
5100
5101 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM) {
5102 if (result == L2CAP_MC_CONFIRMED) {
5103 chan->local_amp_id = chan->move_id;
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07005104 if (chan->local_amp_id == AMP_ID_BREDR)
Mat Martineau5f3847a2012-10-23 15:24:12 -07005105 __release_logical_link(chan);
5106 } else {
5107 chan->move_id = chan->local_amp_id;
5108 }
5109
5110 l2cap_move_done(chan);
5111 }
5112
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005113 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
5114
Mat Martineau5f3847a2012-10-23 15:24:12 -07005115 l2cap_chan_unlock(chan);
5116
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005117 return 0;
5118}
5119
5120static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005121 struct l2cap_cmd_hdr *cmd,
5122 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005123{
5124 struct l2cap_move_chan_cfm_rsp *rsp = data;
Mat Martineau3fd71a02012-10-23 15:24:16 -07005125 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005126 u16 icid;
5127
5128 if (cmd_len != sizeof(*rsp))
5129 return -EPROTO;
5130
5131 icid = le16_to_cpu(rsp->icid);
5132
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005133 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005134
Mat Martineau3fd71a02012-10-23 15:24:16 -07005135 chan = l2cap_get_chan_by_scid(conn, icid);
5136 if (!chan)
5137 return 0;
5138
5139 __clear_chan_timer(chan);
5140
5141 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM_RSP) {
5142 chan->local_amp_id = chan->move_id;
5143
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07005144 if (chan->local_amp_id == AMP_ID_BREDR && chan->hs_hchan)
Mat Martineau3fd71a02012-10-23 15:24:16 -07005145 __release_logical_link(chan);
5146
5147 l2cap_move_done(chan);
5148 }
5149
5150 l2cap_chan_unlock(chan);
5151
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005152 return 0;
5153}
5154
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03005155static inline int l2cap_check_conn_param(u16 min, u16 max, u16 latency,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005156 u16 to_multiplier)
Claudio Takahaside731152011-02-11 19:28:55 -02005157{
5158 u16 max_latency;
5159
5160 if (min > max || min < 6 || max > 3200)
5161 return -EINVAL;
5162
5163 if (to_multiplier < 10 || to_multiplier > 3200)
5164 return -EINVAL;
5165
5166 if (max >= to_multiplier * 8)
5167 return -EINVAL;
5168
5169 max_latency = (to_multiplier * 8 / max) - 1;
5170 if (latency > 499 || latency > max_latency)
5171 return -EINVAL;
5172
5173 return 0;
5174}
5175
5176static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005177 struct l2cap_cmd_hdr *cmd,
Johan Hedberg203e6392013-05-15 10:07:15 +03005178 u16 cmd_len, u8 *data)
Claudio Takahaside731152011-02-11 19:28:55 -02005179{
5180 struct hci_conn *hcon = conn->hcon;
5181 struct l2cap_conn_param_update_req *req;
5182 struct l2cap_conn_param_update_rsp rsp;
Johan Hedberg203e6392013-05-15 10:07:15 +03005183 u16 min, max, latency, to_multiplier;
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005184 int err;
Claudio Takahaside731152011-02-11 19:28:55 -02005185
5186 if (!(hcon->link_mode & HCI_LM_MASTER))
5187 return -EINVAL;
5188
Claudio Takahaside731152011-02-11 19:28:55 -02005189 if (cmd_len != sizeof(struct l2cap_conn_param_update_req))
5190 return -EPROTO;
5191
5192 req = (struct l2cap_conn_param_update_req *) data;
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03005193 min = __le16_to_cpu(req->min);
5194 max = __le16_to_cpu(req->max);
Claudio Takahaside731152011-02-11 19:28:55 -02005195 latency = __le16_to_cpu(req->latency);
5196 to_multiplier = __le16_to_cpu(req->to_multiplier);
5197
5198 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 +01005199 min, max, latency, to_multiplier);
Claudio Takahaside731152011-02-11 19:28:55 -02005200
5201 memset(&rsp, 0, sizeof(rsp));
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005202
5203 err = l2cap_check_conn_param(min, max, latency, to_multiplier);
5204 if (err)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005205 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
Claudio Takahaside731152011-02-11 19:28:55 -02005206 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005207 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED);
Claudio Takahaside731152011-02-11 19:28:55 -02005208
5209 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005210 sizeof(rsp), &rsp);
Claudio Takahaside731152011-02-11 19:28:55 -02005211
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005212 if (!err)
5213 hci_le_conn_update(hcon, min, max, latency, to_multiplier);
5214
Claudio Takahaside731152011-02-11 19:28:55 -02005215 return 0;
5216}
5217
Johan Hedbergf1496de2013-05-13 14:15:56 +03005218static int l2cap_le_connect_rsp(struct l2cap_conn *conn,
5219 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5220 u8 *data)
5221{
5222 struct l2cap_le_conn_rsp *rsp = (struct l2cap_le_conn_rsp *) data;
5223 u16 dcid, mtu, mps, credits, result;
5224 struct l2cap_chan *chan;
5225 int err;
5226
5227 if (cmd_len < sizeof(*rsp))
5228 return -EPROTO;
5229
5230 dcid = __le16_to_cpu(rsp->dcid);
5231 mtu = __le16_to_cpu(rsp->mtu);
5232 mps = __le16_to_cpu(rsp->mps);
5233 credits = __le16_to_cpu(rsp->credits);
5234 result = __le16_to_cpu(rsp->result);
5235
5236 if (result == L2CAP_CR_SUCCESS && (mtu < 23 || mps < 23))
5237 return -EPROTO;
5238
5239 BT_DBG("dcid 0x%4.4x mtu %u mps %u credits %u result 0x%2.2x",
5240 dcid, mtu, mps, credits, result);
5241
5242 mutex_lock(&conn->chan_lock);
5243
5244 chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
5245 if (!chan) {
5246 err = -EBADSLT;
5247 goto unlock;
5248 }
5249
5250 err = 0;
5251
5252 l2cap_chan_lock(chan);
5253
5254 switch (result) {
5255 case L2CAP_CR_SUCCESS:
5256 chan->ident = 0;
5257 chan->dcid = dcid;
5258 chan->omtu = mtu;
5259 chan->remote_mps = mps;
Johan Hedberg0cd75f72013-05-17 13:09:05 +03005260 chan->tx_credits = credits;
Johan Hedbergf1496de2013-05-13 14:15:56 +03005261 l2cap_chan_ready(chan);
5262 break;
5263
5264 default:
5265 l2cap_chan_del(chan, ECONNREFUSED);
5266 break;
5267 }
5268
5269 l2cap_chan_unlock(chan);
5270
5271unlock:
5272 mutex_unlock(&conn->chan_lock);
5273
5274 return err;
5275}
5276
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005277static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005278 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5279 u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005280{
5281 int err = 0;
5282
5283 switch (cmd->code) {
5284 case L2CAP_COMMAND_REJ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005285 l2cap_command_rej(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005286 break;
5287
5288 case L2CAP_CONN_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005289 err = l2cap_connect_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005290 break;
5291
5292 case L2CAP_CONN_RSP:
Mat Martineauf5a25982012-10-11 17:48:21 +03005293 case L2CAP_CREATE_CHAN_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005294 l2cap_connect_create_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005295 break;
5296
5297 case L2CAP_CONF_REQ:
5298 err = l2cap_config_req(conn, cmd, cmd_len, data);
5299 break;
5300
5301 case L2CAP_CONF_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005302 l2cap_config_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005303 break;
5304
5305 case L2CAP_DISCONN_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005306 err = l2cap_disconnect_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005307 break;
5308
5309 case L2CAP_DISCONN_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005310 l2cap_disconnect_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005311 break;
5312
5313 case L2CAP_ECHO_REQ:
5314 l2cap_send_cmd(conn, cmd->ident, L2CAP_ECHO_RSP, cmd_len, data);
5315 break;
5316
5317 case L2CAP_ECHO_RSP:
5318 break;
5319
5320 case L2CAP_INFO_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005321 err = l2cap_information_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005322 break;
5323
5324 case L2CAP_INFO_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005325 l2cap_information_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005326 break;
5327
Mat Martineauf94ff6f2011-11-02 16:18:32 -07005328 case L2CAP_CREATE_CHAN_REQ:
5329 err = l2cap_create_channel_req(conn, cmd, cmd_len, data);
5330 break;
5331
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005332 case L2CAP_MOVE_CHAN_REQ:
5333 err = l2cap_move_channel_req(conn, cmd, cmd_len, data);
5334 break;
5335
5336 case L2CAP_MOVE_CHAN_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005337 l2cap_move_channel_rsp(conn, cmd, cmd_len, data);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005338 break;
5339
5340 case L2CAP_MOVE_CHAN_CFM:
5341 err = l2cap_move_channel_confirm(conn, cmd, cmd_len, data);
5342 break;
5343
5344 case L2CAP_MOVE_CHAN_CFM_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005345 l2cap_move_channel_confirm_rsp(conn, cmd, cmd_len, data);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005346 break;
5347
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005348 default:
5349 BT_ERR("Unknown BR/EDR signaling command 0x%2.2x", cmd->code);
5350 err = -EINVAL;
5351 break;
5352 }
5353
5354 return err;
5355}
5356
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005357static int l2cap_le_connect_req(struct l2cap_conn *conn,
5358 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5359 u8 *data)
5360{
5361 struct l2cap_le_conn_req *req = (struct l2cap_le_conn_req *) data;
5362 struct l2cap_le_conn_rsp rsp;
5363 struct l2cap_chan *chan, *pchan;
Johan Hedberg0cd75f72013-05-17 13:09:05 +03005364 u16 dcid, scid, credits, mtu, mps;
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005365 __le16 psm;
5366 u8 result;
5367
5368 if (cmd_len != sizeof(*req))
5369 return -EPROTO;
5370
5371 scid = __le16_to_cpu(req->scid);
5372 mtu = __le16_to_cpu(req->mtu);
5373 mps = __le16_to_cpu(req->mps);
5374 psm = req->psm;
5375 dcid = 0;
Johan Hedberg0cd75f72013-05-17 13:09:05 +03005376 credits = 0;
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005377
5378 if (mtu < 23 || mps < 23)
5379 return -EPROTO;
5380
5381 BT_DBG("psm 0x%2.2x scid 0x%4.4x mtu %u mps %u", __le16_to_cpu(psm),
5382 scid, mtu, mps);
5383
5384 /* Check if we have socket listening on psm */
5385 pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, &conn->hcon->src,
5386 &conn->hcon->dst, LE_LINK);
5387 if (!pchan) {
5388 result = L2CAP_CR_BAD_PSM;
5389 chan = NULL;
5390 goto response;
5391 }
5392
5393 mutex_lock(&conn->chan_lock);
5394 l2cap_chan_lock(pchan);
5395
5396 if (!smp_sufficient_security(conn->hcon, pchan->sec_level)) {
5397 result = L2CAP_CR_AUTHENTICATION;
5398 chan = NULL;
5399 goto response_unlock;
5400 }
5401
5402 /* Check if we already have channel with that dcid */
5403 if (__l2cap_get_chan_by_dcid(conn, scid)) {
5404 result = L2CAP_CR_NO_MEM;
5405 chan = NULL;
5406 goto response_unlock;
5407 }
5408
5409 chan = pchan->ops->new_connection(pchan);
5410 if (!chan) {
5411 result = L2CAP_CR_NO_MEM;
5412 goto response_unlock;
5413 }
5414
Johan Hedberg0ce43ce2013-12-05 14:55:33 +02005415 l2cap_le_flowctl_init(chan);
5416
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005417 bacpy(&chan->src, &conn->hcon->src);
5418 bacpy(&chan->dst, &conn->hcon->dst);
5419 chan->src_type = bdaddr_type(conn->hcon, conn->hcon->src_type);
5420 chan->dst_type = bdaddr_type(conn->hcon, conn->hcon->dst_type);
5421 chan->psm = psm;
5422 chan->dcid = scid;
5423 chan->omtu = mtu;
5424 chan->remote_mps = mps;
Johan Hedberg0cd75f72013-05-17 13:09:05 +03005425 chan->tx_credits = __le16_to_cpu(req->credits);
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005426
5427 __l2cap_chan_add(conn, chan);
5428 dcid = chan->scid;
Johan Hedberg0cd75f72013-05-17 13:09:05 +03005429 credits = chan->rx_credits;
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005430
5431 __set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
5432
5433 chan->ident = cmd->ident;
5434
5435 if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
5436 l2cap_state_change(chan, BT_CONNECT2);
5437 result = L2CAP_CR_PEND;
5438 chan->ops->defer(chan);
5439 } else {
5440 l2cap_chan_ready(chan);
5441 result = L2CAP_CR_SUCCESS;
5442 }
5443
5444response_unlock:
5445 l2cap_chan_unlock(pchan);
5446 mutex_unlock(&conn->chan_lock);
5447
5448 if (result == L2CAP_CR_PEND)
5449 return 0;
5450
5451response:
5452 if (chan) {
5453 rsp.mtu = cpu_to_le16(chan->imtu);
Johan Hedberg3916aed2013-10-07 15:35:26 +02005454 rsp.mps = cpu_to_le16(chan->mps);
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005455 } else {
5456 rsp.mtu = 0;
5457 rsp.mps = 0;
5458 }
5459
5460 rsp.dcid = cpu_to_le16(dcid);
Johan Hedberg0cd75f72013-05-17 13:09:05 +03005461 rsp.credits = cpu_to_le16(credits);
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005462 rsp.result = cpu_to_le16(result);
5463
5464 l2cap_send_cmd(conn, cmd->ident, L2CAP_LE_CONN_RSP, sizeof(rsp), &rsp);
5465
5466 return 0;
5467}
5468
Johan Hedbergfad5fc892013-12-05 09:45:01 +02005469static inline int l2cap_le_credits(struct l2cap_conn *conn,
5470 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5471 u8 *data)
5472{
5473 struct l2cap_le_credits *pkt;
5474 struct l2cap_chan *chan;
Johan Hedberg0f1bfe42014-01-27 15:11:35 -08005475 u16 cid, credits, max_credits;
Johan Hedbergfad5fc892013-12-05 09:45:01 +02005476
5477 if (cmd_len != sizeof(*pkt))
5478 return -EPROTO;
5479
5480 pkt = (struct l2cap_le_credits *) data;
5481 cid = __le16_to_cpu(pkt->cid);
5482 credits = __le16_to_cpu(pkt->credits);
5483
5484 BT_DBG("cid 0x%4.4x credits 0x%4.4x", cid, credits);
5485
5486 chan = l2cap_get_chan_by_dcid(conn, cid);
5487 if (!chan)
5488 return -EBADSLT;
5489
Johan Hedberg0f1bfe42014-01-27 15:11:35 -08005490 max_credits = LE_FLOWCTL_MAX_CREDITS - chan->tx_credits;
5491 if (credits > max_credits) {
5492 BT_ERR("LE credits overflow");
5493 l2cap_send_disconn_req(chan, ECONNRESET);
5494
5495 /* Return 0 so that we don't trigger an unnecessary
5496 * command reject packet.
5497 */
5498 return 0;
5499 }
5500
Johan Hedbergfad5fc892013-12-05 09:45:01 +02005501 chan->tx_credits += credits;
5502
5503 while (chan->tx_credits && !skb_queue_empty(&chan->tx_q)) {
5504 l2cap_do_send(chan, skb_dequeue(&chan->tx_q));
5505 chan->tx_credits--;
5506 }
5507
5508 if (chan->tx_credits)
5509 chan->ops->resume(chan);
5510
5511 l2cap_chan_unlock(chan);
5512
5513 return 0;
5514}
5515
Johan Hedberg71fb4192013-12-10 10:52:48 +02005516static inline int l2cap_le_command_rej(struct l2cap_conn *conn,
5517 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5518 u8 *data)
5519{
5520 struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data;
5521 struct l2cap_chan *chan;
5522
5523 if (cmd_len < sizeof(*rej))
5524 return -EPROTO;
5525
5526 mutex_lock(&conn->chan_lock);
5527
5528 chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
5529 if (!chan)
5530 goto done;
5531
5532 l2cap_chan_lock(chan);
5533 l2cap_chan_del(chan, ECONNREFUSED);
5534 l2cap_chan_unlock(chan);
5535
5536done:
5537 mutex_unlock(&conn->chan_lock);
5538 return 0;
5539}
5540
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005541static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn,
Johan Hedberg203e6392013-05-15 10:07:15 +03005542 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5543 u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005544{
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005545 int err = 0;
5546
Johan Hedberg3af8ace2013-12-03 09:51:51 +02005547 if (!enable_lecoc) {
5548 switch (cmd->code) {
5549 case L2CAP_LE_CONN_REQ:
5550 case L2CAP_LE_CONN_RSP:
5551 case L2CAP_LE_CREDITS:
5552 case L2CAP_DISCONN_REQ:
5553 case L2CAP_DISCONN_RSP:
5554 return -EINVAL;
5555 }
5556 }
5557
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005558 switch (cmd->code) {
5559 case L2CAP_COMMAND_REJ:
Johan Hedberg71fb4192013-12-10 10:52:48 +02005560 l2cap_le_command_rej(conn, cmd, cmd_len, data);
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005561 break;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005562
5563 case L2CAP_CONN_PARAM_UPDATE_REQ:
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005564 err = l2cap_conn_param_update_req(conn, cmd, cmd_len, data);
5565 break;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005566
5567 case L2CAP_CONN_PARAM_UPDATE_RSP:
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005568 break;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005569
Johan Hedbergf1496de2013-05-13 14:15:56 +03005570 case L2CAP_LE_CONN_RSP:
5571 l2cap_le_connect_rsp(conn, cmd, cmd_len, data);
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005572 break;
Johan Hedbergf1496de2013-05-13 14:15:56 +03005573
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005574 case L2CAP_LE_CONN_REQ:
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005575 err = l2cap_le_connect_req(conn, cmd, cmd_len, data);
5576 break;
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005577
Johan Hedbergfad5fc892013-12-05 09:45:01 +02005578 case L2CAP_LE_CREDITS:
5579 err = l2cap_le_credits(conn, cmd, cmd_len, data);
5580 break;
5581
Johan Hedberg3defe012013-05-15 10:16:06 +03005582 case L2CAP_DISCONN_REQ:
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005583 err = l2cap_disconnect_req(conn, cmd, cmd_len, data);
5584 break;
Johan Hedberg3defe012013-05-15 10:16:06 +03005585
5586 case L2CAP_DISCONN_RSP:
5587 l2cap_disconnect_rsp(conn, cmd, cmd_len, data);
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005588 break;
Johan Hedberg3defe012013-05-15 10:16:06 +03005589
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005590 default:
5591 BT_ERR("Unknown LE signaling command 0x%2.2x", cmd->code);
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005592 err = -EINVAL;
5593 break;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005594 }
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005595
5596 return err;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005597}
5598
Johan Hedbergc5623552013-04-29 19:35:33 +03005599static inline void l2cap_le_sig_channel(struct l2cap_conn *conn,
5600 struct sk_buff *skb)
5601{
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005602 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005603 struct l2cap_cmd_hdr *cmd;
5604 u16 len;
Johan Hedbergc5623552013-04-29 19:35:33 +03005605 int err;
5606
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005607 if (hcon->type != LE_LINK)
Marcel Holtmann3b166292013-10-02 08:28:21 -07005608 goto drop;
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005609
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005610 if (skb->len < L2CAP_CMD_HDR_SIZE)
5611 goto drop;
Johan Hedbergc5623552013-04-29 19:35:33 +03005612
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005613 cmd = (void *) skb->data;
5614 skb_pull(skb, L2CAP_CMD_HDR_SIZE);
Johan Hedbergc5623552013-04-29 19:35:33 +03005615
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005616 len = le16_to_cpu(cmd->len);
Johan Hedbergc5623552013-04-29 19:35:33 +03005617
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005618 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd->code, len, cmd->ident);
Johan Hedbergc5623552013-04-29 19:35:33 +03005619
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005620 if (len != skb->len || !cmd->ident) {
5621 BT_DBG("corrupted command");
5622 goto drop;
5623 }
Johan Hedbergc5623552013-04-29 19:35:33 +03005624
Johan Hedberg203e6392013-05-15 10:07:15 +03005625 err = l2cap_le_sig_cmd(conn, cmd, len, skb->data);
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005626 if (err) {
5627 struct l2cap_cmd_rej_unk rej;
Johan Hedbergc5623552013-04-29 19:35:33 +03005628
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005629 BT_ERR("Wrong link type (%d)", err);
Johan Hedbergc5623552013-04-29 19:35:33 +03005630
Johan Hedberga5211492013-10-16 11:20:49 +03005631 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005632 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
5633 sizeof(rej), &rej);
Johan Hedbergc5623552013-04-29 19:35:33 +03005634 }
5635
Marcel Holtmann3b166292013-10-02 08:28:21 -07005636drop:
Johan Hedbergc5623552013-04-29 19:35:33 +03005637 kfree_skb(skb);
5638}
5639
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005640static inline void l2cap_sig_channel(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005641 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005642{
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005643 struct hci_conn *hcon = conn->hcon;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005644 u8 *data = skb->data;
5645 int len = skb->len;
5646 struct l2cap_cmd_hdr cmd;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005647 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005648
5649 l2cap_raw_recv(conn, skb);
5650
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005651 if (hcon->type != ACL_LINK)
Marcel Holtmann3b166292013-10-02 08:28:21 -07005652 goto drop;
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005653
Linus Torvalds1da177e2005-04-16 15:20:36 -07005654 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07005655 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005656 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
5657 data += L2CAP_CMD_HDR_SIZE;
5658 len -= L2CAP_CMD_HDR_SIZE;
5659
Al Viro88219a02007-07-29 00:17:25 -07005660 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005661
Gustavo Padovan2d792812012-10-06 10:07:01 +01005662 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len,
5663 cmd.ident);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005664
Al Viro88219a02007-07-29 00:17:25 -07005665 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005666 BT_DBG("corrupted command");
5667 break;
5668 }
5669
Johan Hedbergc5623552013-04-29 19:35:33 +03005670 err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005671 if (err) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03005672 struct l2cap_cmd_rej_unk rej;
Gustavo F. Padovan2c6d1a22011-03-23 14:38:32 -03005673
5674 BT_ERR("Wrong link type (%d)", err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005675
Johan Hedberga5211492013-10-16 11:20:49 +03005676 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
Gustavo Padovan2d792812012-10-06 10:07:01 +01005677 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ,
5678 sizeof(rej), &rej);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005679 }
5680
Al Viro88219a02007-07-29 00:17:25 -07005681 data += cmd_len;
5682 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005683 }
5684
Marcel Holtmann3b166292013-10-02 08:28:21 -07005685drop:
Linus Torvalds1da177e2005-04-16 15:20:36 -07005686 kfree_skb(skb);
5687}
5688
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005689static int l2cap_check_fcs(struct l2cap_chan *chan, struct sk_buff *skb)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005690{
5691 u16 our_fcs, rcv_fcs;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03005692 int hdr_size;
5693
5694 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
5695 hdr_size = L2CAP_EXT_HDR_SIZE;
5696 else
5697 hdr_size = L2CAP_ENH_HDR_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005698
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005699 if (chan->fcs == L2CAP_FCS_CRC16) {
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005700 skb_trim(skb, skb->len - L2CAP_FCS_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005701 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
5702 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
5703
5704 if (our_fcs != rcv_fcs)
João Paulo Rechi Vita7a560e52010-06-22 13:56:27 -03005705 return -EBADMSG;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005706 }
5707 return 0;
5708}
5709
Mat Martineau6ea00482012-05-17 20:53:52 -07005710static void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan)
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005711{
Mat Martineaue31f7632012-05-17 20:53:41 -07005712 struct l2cap_ctrl control;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005713
Mat Martineaue31f7632012-05-17 20:53:41 -07005714 BT_DBG("chan %p", chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005715
Mat Martineaue31f7632012-05-17 20:53:41 -07005716 memset(&control, 0, sizeof(control));
5717 control.sframe = 1;
5718 control.final = 1;
5719 control.reqseq = chan->buffer_seq;
5720 set_bit(CONN_SEND_FBIT, &chan->conn_state);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005721
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03005722 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
Mat Martineaue31f7632012-05-17 20:53:41 -07005723 control.super = L2CAP_SUPER_RNR;
5724 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005725 }
5726
Mat Martineaue31f7632012-05-17 20:53:41 -07005727 if (test_and_clear_bit(CONN_REMOTE_BUSY, &chan->conn_state) &&
5728 chan->unacked_frames > 0)
5729 __set_retrans_timer(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005730
Mat Martineaue31f7632012-05-17 20:53:41 -07005731 /* Send pending iframes */
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03005732 l2cap_ertm_send(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005733
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03005734 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
Mat Martineaue31f7632012-05-17 20:53:41 -07005735 test_bit(CONN_SEND_FBIT, &chan->conn_state)) {
5736 /* F-bit wasn't sent in an s-frame or i-frame yet, so
5737 * send it now.
5738 */
5739 control.super = L2CAP_SUPER_RR;
5740 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005741 }
5742}
5743
Gustavo Padovan2d792812012-10-06 10:07:01 +01005744static void append_skb_frag(struct sk_buff *skb, struct sk_buff *new_frag,
5745 struct sk_buff **last_frag)
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005746{
Mat Martineau84084a32011-07-22 14:54:00 -07005747 /* skb->len reflects data in skb as well as all fragments
5748 * skb->data_len reflects only data in fragments
5749 */
5750 if (!skb_has_frag_list(skb))
5751 skb_shinfo(skb)->frag_list = new_frag;
5752
5753 new_frag->next = NULL;
5754
5755 (*last_frag)->next = new_frag;
5756 *last_frag = new_frag;
5757
5758 skb->len += new_frag->len;
5759 skb->data_len += new_frag->len;
5760 skb->truesize += new_frag->truesize;
5761}
5762
Mat Martineau4b51dae92012-05-17 20:53:37 -07005763static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb,
5764 struct l2cap_ctrl *control)
Mat Martineau84084a32011-07-22 14:54:00 -07005765{
5766 int err = -EINVAL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005767
Mat Martineau4b51dae92012-05-17 20:53:37 -07005768 switch (control->sar) {
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005769 case L2CAP_SAR_UNSEGMENTED:
Mat Martineau84084a32011-07-22 14:54:00 -07005770 if (chan->sdu)
5771 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005772
Gustavo Padovan80b98022012-05-27 22:27:51 -03005773 err = chan->ops->recv(chan, skb);
Mat Martineau84084a32011-07-22 14:54:00 -07005774 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005775
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005776 case L2CAP_SAR_START:
Mat Martineau84084a32011-07-22 14:54:00 -07005777 if (chan->sdu)
5778 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005779
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005780 chan->sdu_len = get_unaligned_le16(skb->data);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005781 skb_pull(skb, L2CAP_SDULEN_SIZE);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005782
Mat Martineau84084a32011-07-22 14:54:00 -07005783 if (chan->sdu_len > chan->imtu) {
5784 err = -EMSGSIZE;
5785 break;
5786 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005787
Mat Martineau84084a32011-07-22 14:54:00 -07005788 if (skb->len >= chan->sdu_len)
5789 break;
5790
5791 chan->sdu = skb;
5792 chan->sdu_last_frag = skb;
5793
5794 skb = NULL;
5795 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005796 break;
5797
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005798 case L2CAP_SAR_CONTINUE:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005799 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07005800 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005801
Mat Martineau84084a32011-07-22 14:54:00 -07005802 append_skb_frag(chan->sdu, skb,
5803 &chan->sdu_last_frag);
5804 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005805
Mat Martineau84084a32011-07-22 14:54:00 -07005806 if (chan->sdu->len >= chan->sdu_len)
5807 break;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03005808
Mat Martineau84084a32011-07-22 14:54:00 -07005809 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005810 break;
5811
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005812 case L2CAP_SAR_END:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005813 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07005814 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005815
Mat Martineau84084a32011-07-22 14:54:00 -07005816 append_skb_frag(chan->sdu, skb,
5817 &chan->sdu_last_frag);
5818 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005819
Mat Martineau84084a32011-07-22 14:54:00 -07005820 if (chan->sdu->len != chan->sdu_len)
5821 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005822
Gustavo Padovan80b98022012-05-27 22:27:51 -03005823 err = chan->ops->recv(chan, chan->sdu);
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03005824
Mat Martineau84084a32011-07-22 14:54:00 -07005825 if (!err) {
5826 /* Reassembly complete */
5827 chan->sdu = NULL;
5828 chan->sdu_last_frag = NULL;
5829 chan->sdu_len = 0;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03005830 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005831 break;
5832 }
5833
Mat Martineau84084a32011-07-22 14:54:00 -07005834 if (err) {
5835 kfree_skb(skb);
5836 kfree_skb(chan->sdu);
5837 chan->sdu = NULL;
5838 chan->sdu_last_frag = NULL;
5839 chan->sdu_len = 0;
5840 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005841
Mat Martineau84084a32011-07-22 14:54:00 -07005842 return err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005843}
5844
Mat Martineau32b32732012-10-23 15:24:11 -07005845static int l2cap_resegment(struct l2cap_chan *chan)
5846{
5847 /* Placeholder */
5848 return 0;
5849}
5850
Mat Martineaue3281402011-07-07 09:39:02 -07005851void l2cap_chan_busy(struct l2cap_chan *chan, int busy)
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03005852{
Mat Martineau61aa4f52012-05-17 20:53:40 -07005853 u8 event;
5854
5855 if (chan->mode != L2CAP_MODE_ERTM)
5856 return;
5857
5858 event = busy ? L2CAP_EV_LOCAL_BUSY_DETECTED : L2CAP_EV_LOCAL_BUSY_CLEAR;
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03005859 l2cap_tx(chan, NULL, NULL, event);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03005860}
5861
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005862static int l2cap_rx_queued_iframes(struct l2cap_chan *chan)
5863{
Mat Martineau63838722012-05-17 20:53:45 -07005864 int err = 0;
5865 /* Pass sequential frames to l2cap_reassemble_sdu()
5866 * until a gap is encountered.
5867 */
5868
5869 BT_DBG("chan %p", chan);
5870
5871 while (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5872 struct sk_buff *skb;
5873 BT_DBG("Searching for skb with txseq %d (queue len %d)",
5874 chan->buffer_seq, skb_queue_len(&chan->srej_q));
5875
5876 skb = l2cap_ertm_seq_in_queue(&chan->srej_q, chan->buffer_seq);
5877
5878 if (!skb)
5879 break;
5880
5881 skb_unlink(skb, &chan->srej_q);
5882 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
5883 err = l2cap_reassemble_sdu(chan, skb, &bt_cb(skb)->control);
5884 if (err)
5885 break;
5886 }
5887
5888 if (skb_queue_empty(&chan->srej_q)) {
5889 chan->rx_state = L2CAP_RX_STATE_RECV;
5890 l2cap_send_ack(chan);
5891 }
5892
5893 return err;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005894}
5895
5896static void l2cap_handle_srej(struct l2cap_chan *chan,
5897 struct l2cap_ctrl *control)
5898{
Mat Martineauf80842a2012-05-17 20:53:46 -07005899 struct sk_buff *skb;
5900
5901 BT_DBG("chan %p, control %p", chan, control);
5902
5903 if (control->reqseq == chan->next_tx_seq) {
5904 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005905 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineauf80842a2012-05-17 20:53:46 -07005906 return;
5907 }
5908
5909 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
5910
5911 if (skb == NULL) {
5912 BT_DBG("Seq %d not available for retransmission",
5913 control->reqseq);
5914 return;
5915 }
5916
5917 if (chan->max_tx != 0 && bt_cb(skb)->control.retries >= chan->max_tx) {
5918 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005919 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineauf80842a2012-05-17 20:53:46 -07005920 return;
5921 }
5922
5923 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5924
5925 if (control->poll) {
5926 l2cap_pass_to_tx(chan, control);
5927
5928 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5929 l2cap_retransmit(chan, control);
5930 l2cap_ertm_send(chan);
5931
5932 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
5933 set_bit(CONN_SREJ_ACT, &chan->conn_state);
5934 chan->srej_save_reqseq = control->reqseq;
5935 }
5936 } else {
5937 l2cap_pass_to_tx_fbit(chan, control);
5938
5939 if (control->final) {
5940 if (chan->srej_save_reqseq != control->reqseq ||
5941 !test_and_clear_bit(CONN_SREJ_ACT,
5942 &chan->conn_state))
5943 l2cap_retransmit(chan, control);
5944 } else {
5945 l2cap_retransmit(chan, control);
5946 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
5947 set_bit(CONN_SREJ_ACT, &chan->conn_state);
5948 chan->srej_save_reqseq = control->reqseq;
5949 }
5950 }
5951 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005952}
5953
5954static void l2cap_handle_rej(struct l2cap_chan *chan,
5955 struct l2cap_ctrl *control)
5956{
Mat Martineaufcd289d2012-05-17 20:53:47 -07005957 struct sk_buff *skb;
5958
5959 BT_DBG("chan %p, control %p", chan, control);
5960
5961 if (control->reqseq == chan->next_tx_seq) {
5962 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005963 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaufcd289d2012-05-17 20:53:47 -07005964 return;
5965 }
5966
5967 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
5968
5969 if (chan->max_tx && skb &&
5970 bt_cb(skb)->control.retries >= chan->max_tx) {
5971 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005972 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaufcd289d2012-05-17 20:53:47 -07005973 return;
5974 }
5975
5976 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5977
5978 l2cap_pass_to_tx(chan, control);
5979
5980 if (control->final) {
5981 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state))
5982 l2cap_retransmit_all(chan, control);
5983 } else {
5984 l2cap_retransmit_all(chan, control);
5985 l2cap_ertm_send(chan);
5986 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F)
5987 set_bit(CONN_REJ_ACT, &chan->conn_state);
5988 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005989}
5990
Mat Martineau4b51dae92012-05-17 20:53:37 -07005991static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq)
5992{
5993 BT_DBG("chan %p, txseq %d", chan, txseq);
5994
5995 BT_DBG("last_acked_seq %d, expected_tx_seq %d", chan->last_acked_seq,
5996 chan->expected_tx_seq);
5997
5998 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
5999 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
Gustavo Padovan2d792812012-10-06 10:07:01 +01006000 chan->tx_win) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07006001 /* See notes below regarding "double poll" and
6002 * invalid packets.
6003 */
6004 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
6005 BT_DBG("Invalid/Ignore - after SREJ");
6006 return L2CAP_TXSEQ_INVALID_IGNORE;
6007 } else {
6008 BT_DBG("Invalid - in window after SREJ sent");
6009 return L2CAP_TXSEQ_INVALID;
6010 }
6011 }
6012
6013 if (chan->srej_list.head == txseq) {
6014 BT_DBG("Expected SREJ");
6015 return L2CAP_TXSEQ_EXPECTED_SREJ;
6016 }
6017
6018 if (l2cap_ertm_seq_in_queue(&chan->srej_q, txseq)) {
6019 BT_DBG("Duplicate SREJ - txseq already stored");
6020 return L2CAP_TXSEQ_DUPLICATE_SREJ;
6021 }
6022
6023 if (l2cap_seq_list_contains(&chan->srej_list, txseq)) {
6024 BT_DBG("Unexpected SREJ - not requested");
6025 return L2CAP_TXSEQ_UNEXPECTED_SREJ;
6026 }
6027 }
6028
6029 if (chan->expected_tx_seq == txseq) {
6030 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
6031 chan->tx_win) {
6032 BT_DBG("Invalid - txseq outside tx window");
6033 return L2CAP_TXSEQ_INVALID;
6034 } else {
6035 BT_DBG("Expected");
6036 return L2CAP_TXSEQ_EXPECTED;
6037 }
6038 }
6039
6040 if (__seq_offset(chan, txseq, chan->last_acked_seq) <
Gustavo Padovan2d792812012-10-06 10:07:01 +01006041 __seq_offset(chan, chan->expected_tx_seq, chan->last_acked_seq)) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07006042 BT_DBG("Duplicate - expected_tx_seq later than txseq");
6043 return L2CAP_TXSEQ_DUPLICATE;
6044 }
6045
6046 if (__seq_offset(chan, txseq, chan->last_acked_seq) >= chan->tx_win) {
6047 /* A source of invalid packets is a "double poll" condition,
6048 * where delays cause us to send multiple poll packets. If
6049 * the remote stack receives and processes both polls,
6050 * sequence numbers can wrap around in such a way that a
6051 * resent frame has a sequence number that looks like new data
6052 * with a sequence gap. This would trigger an erroneous SREJ
6053 * request.
6054 *
6055 * Fortunately, this is impossible with a tx window that's
6056 * less than half of the maximum sequence number, which allows
6057 * invalid frames to be safely ignored.
6058 *
6059 * With tx window sizes greater than half of the tx window
6060 * maximum, the frame is invalid and cannot be ignored. This
6061 * causes a disconnect.
6062 */
6063
6064 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
6065 BT_DBG("Invalid/Ignore - txseq outside tx window");
6066 return L2CAP_TXSEQ_INVALID_IGNORE;
6067 } else {
6068 BT_DBG("Invalid - txseq outside tx window");
6069 return L2CAP_TXSEQ_INVALID;
6070 }
6071 } else {
6072 BT_DBG("Unexpected - txseq indicates missing frames");
6073 return L2CAP_TXSEQ_UNEXPECTED;
6074 }
6075}
6076
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006077static int l2cap_rx_state_recv(struct l2cap_chan *chan,
6078 struct l2cap_ctrl *control,
6079 struct sk_buff *skb, u8 event)
6080{
6081 int err = 0;
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006082 bool skb_in_use = false;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006083
6084 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
6085 event);
6086
6087 switch (event) {
6088 case L2CAP_EV_RECV_IFRAME:
6089 switch (l2cap_classify_txseq(chan, control->txseq)) {
6090 case L2CAP_TXSEQ_EXPECTED:
6091 l2cap_pass_to_tx(chan, control);
6092
6093 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
6094 BT_DBG("Busy, discarding expected seq %d",
6095 control->txseq);
6096 break;
6097 }
6098
6099 chan->expected_tx_seq = __next_seq(chan,
6100 control->txseq);
6101
6102 chan->buffer_seq = chan->expected_tx_seq;
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006103 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006104
6105 err = l2cap_reassemble_sdu(chan, skb, control);
6106 if (err)
6107 break;
6108
6109 if (control->final) {
6110 if (!test_and_clear_bit(CONN_REJ_ACT,
6111 &chan->conn_state)) {
6112 control->final = 0;
6113 l2cap_retransmit_all(chan, control);
6114 l2cap_ertm_send(chan);
6115 }
6116 }
6117
6118 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
6119 l2cap_send_ack(chan);
6120 break;
6121 case L2CAP_TXSEQ_UNEXPECTED:
6122 l2cap_pass_to_tx(chan, control);
6123
6124 /* Can't issue SREJ frames in the local busy state.
6125 * Drop this frame, it will be seen as missing
6126 * when local busy is exited.
6127 */
6128 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
6129 BT_DBG("Busy, discarding unexpected seq %d",
6130 control->txseq);
6131 break;
6132 }
6133
6134 /* There was a gap in the sequence, so an SREJ
6135 * must be sent for each missing frame. The
6136 * current frame is stored for later use.
6137 */
6138 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006139 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006140 BT_DBG("Queued %p (queue len %d)", skb,
6141 skb_queue_len(&chan->srej_q));
6142
6143 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
6144 l2cap_seq_list_clear(&chan->srej_list);
6145 l2cap_send_srej(chan, control->txseq);
6146
6147 chan->rx_state = L2CAP_RX_STATE_SREJ_SENT;
6148 break;
6149 case L2CAP_TXSEQ_DUPLICATE:
6150 l2cap_pass_to_tx(chan, control);
6151 break;
6152 case L2CAP_TXSEQ_INVALID_IGNORE:
6153 break;
6154 case L2CAP_TXSEQ_INVALID:
6155 default:
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006156 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006157 break;
6158 }
6159 break;
6160 case L2CAP_EV_RECV_RR:
6161 l2cap_pass_to_tx(chan, control);
6162 if (control->final) {
6163 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6164
Mat Martineaue6a3ee62012-10-23 15:24:22 -07006165 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state) &&
6166 !__chan_is_moving(chan)) {
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006167 control->final = 0;
6168 l2cap_retransmit_all(chan, control);
6169 }
6170
6171 l2cap_ertm_send(chan);
6172 } else if (control->poll) {
6173 l2cap_send_i_or_rr_or_rnr(chan);
6174 } else {
6175 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6176 &chan->conn_state) &&
6177 chan->unacked_frames)
6178 __set_retrans_timer(chan);
6179
6180 l2cap_ertm_send(chan);
6181 }
6182 break;
6183 case L2CAP_EV_RECV_RNR:
6184 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6185 l2cap_pass_to_tx(chan, control);
6186 if (control && control->poll) {
6187 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6188 l2cap_send_rr_or_rnr(chan, 0);
6189 }
6190 __clear_retrans_timer(chan);
6191 l2cap_seq_list_clear(&chan->retrans_list);
6192 break;
6193 case L2CAP_EV_RECV_REJ:
6194 l2cap_handle_rej(chan, control);
6195 break;
6196 case L2CAP_EV_RECV_SREJ:
6197 l2cap_handle_srej(chan, control);
6198 break;
6199 default:
6200 break;
6201 }
6202
6203 if (skb && !skb_in_use) {
6204 BT_DBG("Freeing %p", skb);
6205 kfree_skb(skb);
6206 }
6207
6208 return err;
6209}
6210
6211static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan,
6212 struct l2cap_ctrl *control,
6213 struct sk_buff *skb, u8 event)
6214{
6215 int err = 0;
6216 u16 txseq = control->txseq;
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006217 bool skb_in_use = false;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006218
6219 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
6220 event);
6221
6222 switch (event) {
6223 case L2CAP_EV_RECV_IFRAME:
6224 switch (l2cap_classify_txseq(chan, txseq)) {
6225 case L2CAP_TXSEQ_EXPECTED:
6226 /* Keep frame for reassembly later */
6227 l2cap_pass_to_tx(chan, control);
6228 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006229 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006230 BT_DBG("Queued %p (queue len %d)", skb,
6231 skb_queue_len(&chan->srej_q));
6232
6233 chan->expected_tx_seq = __next_seq(chan, txseq);
6234 break;
6235 case L2CAP_TXSEQ_EXPECTED_SREJ:
6236 l2cap_seq_list_pop(&chan->srej_list);
6237
6238 l2cap_pass_to_tx(chan, control);
6239 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006240 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006241 BT_DBG("Queued %p (queue len %d)", skb,
6242 skb_queue_len(&chan->srej_q));
6243
6244 err = l2cap_rx_queued_iframes(chan);
6245 if (err)
6246 break;
6247
6248 break;
6249 case L2CAP_TXSEQ_UNEXPECTED:
6250 /* Got a frame that can't be reassembled yet.
6251 * Save it for later, and send SREJs to cover
6252 * the missing frames.
6253 */
6254 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006255 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006256 BT_DBG("Queued %p (queue len %d)", skb,
6257 skb_queue_len(&chan->srej_q));
6258
6259 l2cap_pass_to_tx(chan, control);
6260 l2cap_send_srej(chan, control->txseq);
6261 break;
6262 case L2CAP_TXSEQ_UNEXPECTED_SREJ:
6263 /* This frame was requested with an SREJ, but
6264 * some expected retransmitted frames are
6265 * missing. Request retransmission of missing
6266 * SREJ'd frames.
6267 */
6268 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006269 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006270 BT_DBG("Queued %p (queue len %d)", skb,
6271 skb_queue_len(&chan->srej_q));
6272
6273 l2cap_pass_to_tx(chan, control);
6274 l2cap_send_srej_list(chan, control->txseq);
6275 break;
6276 case L2CAP_TXSEQ_DUPLICATE_SREJ:
6277 /* We've already queued this frame. Drop this copy. */
6278 l2cap_pass_to_tx(chan, control);
6279 break;
6280 case L2CAP_TXSEQ_DUPLICATE:
6281 /* Expecting a later sequence number, so this frame
6282 * was already received. Ignore it completely.
6283 */
6284 break;
6285 case L2CAP_TXSEQ_INVALID_IGNORE:
6286 break;
6287 case L2CAP_TXSEQ_INVALID:
6288 default:
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006289 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006290 break;
6291 }
6292 break;
6293 case L2CAP_EV_RECV_RR:
6294 l2cap_pass_to_tx(chan, control);
6295 if (control->final) {
6296 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6297
6298 if (!test_and_clear_bit(CONN_REJ_ACT,
6299 &chan->conn_state)) {
6300 control->final = 0;
6301 l2cap_retransmit_all(chan, control);
6302 }
6303
6304 l2cap_ertm_send(chan);
6305 } else if (control->poll) {
6306 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6307 &chan->conn_state) &&
6308 chan->unacked_frames) {
6309 __set_retrans_timer(chan);
6310 }
6311
6312 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6313 l2cap_send_srej_tail(chan);
6314 } else {
6315 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6316 &chan->conn_state) &&
6317 chan->unacked_frames)
6318 __set_retrans_timer(chan);
6319
6320 l2cap_send_ack(chan);
6321 }
6322 break;
6323 case L2CAP_EV_RECV_RNR:
6324 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6325 l2cap_pass_to_tx(chan, control);
6326 if (control->poll) {
6327 l2cap_send_srej_tail(chan);
6328 } else {
6329 struct l2cap_ctrl rr_control;
6330 memset(&rr_control, 0, sizeof(rr_control));
6331 rr_control.sframe = 1;
6332 rr_control.super = L2CAP_SUPER_RR;
6333 rr_control.reqseq = chan->buffer_seq;
6334 l2cap_send_sframe(chan, &rr_control);
6335 }
6336
6337 break;
6338 case L2CAP_EV_RECV_REJ:
6339 l2cap_handle_rej(chan, control);
6340 break;
6341 case L2CAP_EV_RECV_SREJ:
6342 l2cap_handle_srej(chan, control);
6343 break;
6344 }
6345
6346 if (skb && !skb_in_use) {
6347 BT_DBG("Freeing %p", skb);
6348 kfree_skb(skb);
6349 }
6350
6351 return err;
6352}
6353
Mat Martineau32b32732012-10-23 15:24:11 -07006354static int l2cap_finish_move(struct l2cap_chan *chan)
6355{
6356 BT_DBG("chan %p", chan);
6357
6358 chan->rx_state = L2CAP_RX_STATE_RECV;
6359
6360 if (chan->hs_hcon)
6361 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
6362 else
6363 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
6364
6365 return l2cap_resegment(chan);
6366}
6367
6368static int l2cap_rx_state_wait_p(struct l2cap_chan *chan,
6369 struct l2cap_ctrl *control,
6370 struct sk_buff *skb, u8 event)
6371{
6372 int err;
6373
6374 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
6375 event);
6376
6377 if (!control->poll)
6378 return -EPROTO;
6379
6380 l2cap_process_reqseq(chan, control->reqseq);
6381
6382 if (!skb_queue_empty(&chan->tx_q))
6383 chan->tx_send_head = skb_peek(&chan->tx_q);
6384 else
6385 chan->tx_send_head = NULL;
6386
6387 /* Rewind next_tx_seq to the point expected
6388 * by the receiver.
6389 */
6390 chan->next_tx_seq = control->reqseq;
6391 chan->unacked_frames = 0;
6392
6393 err = l2cap_finish_move(chan);
6394 if (err)
6395 return err;
6396
6397 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6398 l2cap_send_i_or_rr_or_rnr(chan);
6399
6400 if (event == L2CAP_EV_RECV_IFRAME)
6401 return -EPROTO;
6402
6403 return l2cap_rx_state_recv(chan, control, NULL, event);
6404}
6405
6406static int l2cap_rx_state_wait_f(struct l2cap_chan *chan,
6407 struct l2cap_ctrl *control,
6408 struct sk_buff *skb, u8 event)
6409{
6410 int err;
6411
6412 if (!control->final)
6413 return -EPROTO;
6414
6415 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6416
6417 chan->rx_state = L2CAP_RX_STATE_RECV;
6418 l2cap_process_reqseq(chan, control->reqseq);
6419
6420 if (!skb_queue_empty(&chan->tx_q))
6421 chan->tx_send_head = skb_peek(&chan->tx_q);
6422 else
6423 chan->tx_send_head = NULL;
6424
6425 /* Rewind next_tx_seq to the point expected
6426 * by the receiver.
6427 */
6428 chan->next_tx_seq = control->reqseq;
6429 chan->unacked_frames = 0;
6430
6431 if (chan->hs_hcon)
6432 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
6433 else
6434 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
6435
6436 err = l2cap_resegment(chan);
6437
6438 if (!err)
6439 err = l2cap_rx_state_recv(chan, control, skb, event);
6440
6441 return err;
6442}
6443
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006444static bool __valid_reqseq(struct l2cap_chan *chan, u16 reqseq)
6445{
6446 /* Make sure reqseq is for a packet that has been sent but not acked */
6447 u16 unacked;
6448
6449 unacked = __seq_offset(chan, chan->next_tx_seq, chan->expected_ack_seq);
6450 return __seq_offset(chan, chan->next_tx_seq, reqseq) <= unacked;
6451}
6452
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006453static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
6454 struct sk_buff *skb, u8 event)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006455{
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006456 int err = 0;
6457
6458 BT_DBG("chan %p, control %p, skb %p, event %d, state %d", chan,
6459 control, skb, event, chan->rx_state);
6460
6461 if (__valid_reqseq(chan, control->reqseq)) {
6462 switch (chan->rx_state) {
6463 case L2CAP_RX_STATE_RECV:
6464 err = l2cap_rx_state_recv(chan, control, skb, event);
6465 break;
6466 case L2CAP_RX_STATE_SREJ_SENT:
6467 err = l2cap_rx_state_srej_sent(chan, control, skb,
6468 event);
6469 break;
Mat Martineau32b32732012-10-23 15:24:11 -07006470 case L2CAP_RX_STATE_WAIT_P:
6471 err = l2cap_rx_state_wait_p(chan, control, skb, event);
6472 break;
6473 case L2CAP_RX_STATE_WAIT_F:
6474 err = l2cap_rx_state_wait_f(chan, control, skb, event);
6475 break;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006476 default:
6477 /* shut it down */
6478 break;
6479 }
6480 } else {
6481 BT_DBG("Invalid reqseq %d (next_tx_seq %d, expected_ack_seq %d",
6482 control->reqseq, chan->next_tx_seq,
6483 chan->expected_ack_seq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006484 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006485 }
6486
6487 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006488}
6489
6490static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
6491 struct sk_buff *skb)
6492{
Mat Martineau4b51dae92012-05-17 20:53:37 -07006493 int err = 0;
6494
6495 BT_DBG("chan %p, control %p, skb %p, state %d", chan, control, skb,
6496 chan->rx_state);
6497
6498 if (l2cap_classify_txseq(chan, control->txseq) ==
6499 L2CAP_TXSEQ_EXPECTED) {
6500 l2cap_pass_to_tx(chan, control);
6501
6502 BT_DBG("buffer_seq %d->%d", chan->buffer_seq,
6503 __next_seq(chan, chan->buffer_seq));
6504
6505 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
6506
6507 l2cap_reassemble_sdu(chan, skb, control);
6508 } else {
6509 if (chan->sdu) {
6510 kfree_skb(chan->sdu);
6511 chan->sdu = NULL;
6512 }
6513 chan->sdu_last_frag = NULL;
6514 chan->sdu_len = 0;
6515
6516 if (skb) {
6517 BT_DBG("Freeing %p", skb);
6518 kfree_skb(skb);
6519 }
6520 }
6521
6522 chan->last_acked_seq = control->txseq;
6523 chan->expected_tx_seq = __next_seq(chan, control->txseq);
6524
6525 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006526}
6527
6528static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
6529{
6530 struct l2cap_ctrl *control = &bt_cb(skb)->control;
6531 u16 len;
6532 u8 event;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006533
Mat Martineaub76bbd62012-04-11 10:48:43 -07006534 __unpack_control(chan, skb);
6535
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006536 len = skb->len;
6537
6538 /*
6539 * We can just drop the corrupted I-frame here.
6540 * Receiver will miss it and start proper recovery
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006541 * procedures and ask for retransmission.
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006542 */
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006543 if (l2cap_check_fcs(chan, skb))
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006544 goto drop;
6545
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006546 if (!control->sframe && control->sar == L2CAP_SAR_START)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03006547 len -= L2CAP_SDULEN_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006548
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006549 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03006550 len -= L2CAP_FCS_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006551
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006552 if (len > chan->mps) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006553 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006554 goto drop;
6555 }
6556
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006557 if (!control->sframe) {
6558 int err;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006559
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006560 BT_DBG("iframe sar %d, reqseq %d, final %d, txseq %d",
6561 control->sar, control->reqseq, control->final,
6562 control->txseq);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03006563
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006564 /* Validate F-bit - F=0 always valid, F=1 only
6565 * valid in TX WAIT_F
6566 */
6567 if (control->final && chan->tx_state != L2CAP_TX_STATE_WAIT_F)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006568 goto drop;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006569
6570 if (chan->mode != L2CAP_MODE_STREAMING) {
6571 event = L2CAP_EV_RECV_IFRAME;
6572 err = l2cap_rx(chan, control, skb, event);
6573 } else {
6574 err = l2cap_stream_rx(chan, control, skb);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006575 }
6576
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006577 if (err)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006578 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006579 } else {
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006580 const u8 rx_func_to_event[4] = {
6581 L2CAP_EV_RECV_RR, L2CAP_EV_RECV_REJ,
6582 L2CAP_EV_RECV_RNR, L2CAP_EV_RECV_SREJ
6583 };
6584
6585 /* Only I-frames are expected in streaming mode */
6586 if (chan->mode == L2CAP_MODE_STREAMING)
6587 goto drop;
6588
6589 BT_DBG("sframe reqseq %d, final %d, poll %d, super %d",
6590 control->reqseq, control->final, control->poll,
6591 control->super);
6592
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006593 if (len != 0) {
Andrei Emeltchenko1bb166e2012-11-20 17:16:21 +02006594 BT_ERR("Trailing bytes: %d in sframe", len);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006595 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006596 goto drop;
6597 }
6598
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006599 /* Validate F and P bits */
6600 if (control->final && (control->poll ||
6601 chan->tx_state != L2CAP_TX_STATE_WAIT_F))
6602 goto drop;
6603
6604 event = rx_func_to_event[control->super];
6605 if (l2cap_rx(chan, control, skb, event))
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006606 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006607 }
6608
6609 return 0;
6610
6611drop:
6612 kfree_skb(skb);
6613 return 0;
6614}
6615
Johan Hedbergb1c325c2013-12-05 09:43:34 +02006616static void l2cap_chan_le_send_credits(struct l2cap_chan *chan)
6617{
6618 struct l2cap_conn *conn = chan->conn;
6619 struct l2cap_le_credits pkt;
6620 u16 return_credits;
6621
6622 /* We return more credits to the sender only after the amount of
6623 * credits falls below half of the initial amount.
6624 */
Johan Hedbergf15b8ec2013-12-03 15:08:25 +02006625 if (chan->rx_credits >= (le_max_credits + 1) / 2)
Johan Hedbergb1c325c2013-12-05 09:43:34 +02006626 return;
6627
Johan Hedbergf15b8ec2013-12-03 15:08:25 +02006628 return_credits = le_max_credits - chan->rx_credits;
Johan Hedbergb1c325c2013-12-05 09:43:34 +02006629
6630 BT_DBG("chan %p returning %u credits to sender", chan, return_credits);
6631
6632 chan->rx_credits += return_credits;
6633
6634 pkt.cid = cpu_to_le16(chan->scid);
6635 pkt.credits = cpu_to_le16(return_credits);
6636
6637 chan->ident = l2cap_get_ident(conn);
6638
6639 l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CREDITS, sizeof(pkt), &pkt);
6640}
6641
Johan Hedbergfad5fc892013-12-05 09:45:01 +02006642static int l2cap_le_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
6643{
Johan Hedbergaac23bf2013-06-01 10:14:57 +03006644 int err;
Johan Hedbergfad5fc892013-12-05 09:45:01 +02006645
Johan Hedbergaac23bf2013-06-01 10:14:57 +03006646 if (!chan->rx_credits) {
6647 BT_ERR("No credits to receive LE L2CAP data");
Johan Hedbergdfd97742014-01-27 15:11:34 -08006648 l2cap_send_disconn_req(chan, ECONNRESET);
Johan Hedbergfad5fc892013-12-05 09:45:01 +02006649 return -ENOBUFS;
Johan Hedbergaac23bf2013-06-01 10:14:57 +03006650 }
6651
6652 if (chan->imtu < skb->len) {
6653 BT_ERR("Too big LE L2CAP PDU");
6654 return -ENOBUFS;
6655 }
Johan Hedbergfad5fc892013-12-05 09:45:01 +02006656
6657 chan->rx_credits--;
6658 BT_DBG("rx_credits %u -> %u", chan->rx_credits + 1, chan->rx_credits);
6659
6660 l2cap_chan_le_send_credits(chan);
6661
Johan Hedbergaac23bf2013-06-01 10:14:57 +03006662 err = 0;
6663
6664 if (!chan->sdu) {
6665 u16 sdu_len;
6666
6667 sdu_len = get_unaligned_le16(skb->data);
6668 skb_pull(skb, L2CAP_SDULEN_SIZE);
6669
6670 BT_DBG("Start of new SDU. sdu_len %u skb->len %u imtu %u",
6671 sdu_len, skb->len, chan->imtu);
6672
6673 if (sdu_len > chan->imtu) {
6674 BT_ERR("Too big LE L2CAP SDU length received");
6675 err = -EMSGSIZE;
6676 goto failed;
6677 }
6678
6679 if (skb->len > sdu_len) {
6680 BT_ERR("Too much LE L2CAP data received");
6681 err = -EINVAL;
6682 goto failed;
6683 }
6684
6685 if (skb->len == sdu_len)
6686 return chan->ops->recv(chan, skb);
6687
6688 chan->sdu = skb;
6689 chan->sdu_len = sdu_len;
6690 chan->sdu_last_frag = skb;
6691
6692 return 0;
6693 }
6694
6695 BT_DBG("SDU fragment. chan->sdu->len %u skb->len %u chan->sdu_len %u",
6696 chan->sdu->len, skb->len, chan->sdu_len);
6697
6698 if (chan->sdu->len + skb->len > chan->sdu_len) {
6699 BT_ERR("Too much LE L2CAP data received");
6700 err = -EINVAL;
6701 goto failed;
6702 }
6703
6704 append_skb_frag(chan->sdu, skb, &chan->sdu_last_frag);
6705 skb = NULL;
6706
6707 if (chan->sdu->len == chan->sdu_len) {
6708 err = chan->ops->recv(chan, chan->sdu);
6709 if (!err) {
6710 chan->sdu = NULL;
6711 chan->sdu_last_frag = NULL;
6712 chan->sdu_len = 0;
6713 }
6714 }
6715
6716failed:
6717 if (err) {
6718 kfree_skb(skb);
6719 kfree_skb(chan->sdu);
6720 chan->sdu = NULL;
6721 chan->sdu_last_frag = NULL;
6722 chan->sdu_len = 0;
6723 }
6724
6725 /* We can't return an error here since we took care of the skb
6726 * freeing internally. An error return would cause the caller to
6727 * do a double-free of the skb.
6728 */
6729 return 0;
Johan Hedbergfad5fc892013-12-05 09:45:01 +02006730}
6731
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006732static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid,
6733 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006734{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006735 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006736
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03006737 chan = l2cap_get_chan_by_scid(conn, cid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006738 if (!chan) {
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006739 if (cid == L2CAP_CID_A2MP) {
6740 chan = a2mp_channel_create(conn, skb);
6741 if (!chan) {
6742 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006743 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006744 }
6745
6746 l2cap_chan_lock(chan);
6747 } else {
6748 BT_DBG("unknown cid 0x%4.4x", cid);
6749 /* Drop packet and return */
6750 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006751 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006752 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006753 }
6754
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03006755 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006756
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006757 if (chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006758 goto drop;
6759
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006760 switch (chan->mode) {
Johan Hedberg38319712013-05-17 12:49:23 +03006761 case L2CAP_MODE_LE_FLOWCTL:
Johan Hedbergfad5fc892013-12-05 09:45:01 +02006762 if (l2cap_le_data_rcv(chan, skb) < 0)
6763 goto drop;
6764
6765 goto done;
6766
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006767 case L2CAP_MODE_BASIC:
6768 /* If socket recv buffers overflows we drop data here
6769 * which is *bad* because L2CAP has to be reliable.
6770 * But we don't have any other choice. L2CAP doesn't
6771 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006772
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006773 if (chan->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006774 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006775
Gustavo Padovan80b98022012-05-27 22:27:51 -03006776 if (!chan->ops->recv(chan, skb))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006777 goto done;
6778 break;
6779
6780 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03006781 case L2CAP_MODE_STREAMING:
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006782 l2cap_data_rcv(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03006783 goto done;
6784
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006785 default:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006786 BT_DBG("chan %p: bad mode 0x%2.2x", chan, chan->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006787 break;
6788 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006789
6790drop:
6791 kfree_skb(skb);
6792
6793done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006794 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006795}
6796
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03006797static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm,
6798 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006799{
Marcel Holtmannae4fd2d2013-10-03 00:03:39 -07006800 struct hci_conn *hcon = conn->hcon;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006801 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006802
Marcel Holtmannae4fd2d2013-10-03 00:03:39 -07006803 if (hcon->type != ACL_LINK)
6804 goto drop;
6805
Johan Hedbergbf20fd42013-05-14 13:23:13 +03006806 chan = l2cap_global_chan_by_psm(0, psm, &hcon->src, &hcon->dst,
6807 ACL_LINK);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006808 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006809 goto drop;
6810
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02006811 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006812
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006813 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006814 goto drop;
6815
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03006816 if (chan->imtu < skb->len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006817 goto drop;
6818
Marcel Holtmann2edf8702013-10-13 12:55:29 -07006819 /* Store remote BD_ADDR and PSM for msg_name */
Marcel Holtmann06ae3312013-10-18 03:43:00 -07006820 bacpy(&bt_cb(skb)->bdaddr, &hcon->dst);
Marcel Holtmann2edf8702013-10-13 12:55:29 -07006821 bt_cb(skb)->psm = psm;
6822
Gustavo Padovan80b98022012-05-27 22:27:51 -03006823 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03006824 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006825
6826drop:
6827 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006828}
6829
Marcel Holtmann72f78352013-04-23 00:59:00 -07006830static void l2cap_att_channel(struct l2cap_conn *conn,
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03006831 struct sk_buff *skb)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006832{
Marcel Holtmannb99707d2013-10-03 02:54:11 -07006833 struct hci_conn *hcon = conn->hcon;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006834 struct l2cap_chan *chan;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006835
Marcel Holtmannb99707d2013-10-03 02:54:11 -07006836 if (hcon->type != LE_LINK)
6837 goto drop;
6838
Johan Hedbergaf1c0132013-04-29 19:35:42 +03006839 chan = l2cap_global_chan_by_scid(BT_CONNECTED, L2CAP_CID_ATT,
Marcel Holtmann06ae3312013-10-18 03:43:00 -07006840 &hcon->src, &hcon->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006841 if (!chan)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006842 goto drop;
6843
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02006844 BT_DBG("chan %p, len %d", chan, skb->len);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006845
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07006846 if (hci_blacklist_lookup(hcon->hdev, &hcon->dst, hcon->dst_type))
6847 goto drop;
6848
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03006849 if (chan->imtu < skb->len)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006850 goto drop;
6851
Gustavo Padovan80b98022012-05-27 22:27:51 -03006852 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03006853 return;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006854
6855drop:
6856 kfree_skb(skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006857}
6858
Linus Torvalds1da177e2005-04-16 15:20:36 -07006859static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
6860{
6861 struct l2cap_hdr *lh = (void *) skb->data;
Johan Hedberg61a939c2014-01-17 20:45:11 +02006862 struct hci_conn *hcon = conn->hcon;
Al Viro8e036fc2007-07-29 00:16:36 -07006863 u16 cid, len;
6864 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006865
Johan Hedberg61a939c2014-01-17 20:45:11 +02006866 if (hcon->state != BT_CONNECTED) {
6867 BT_DBG("queueing pending rx skb");
6868 skb_queue_tail(&conn->pending_rx, skb);
6869 return;
6870 }
6871
Linus Torvalds1da177e2005-04-16 15:20:36 -07006872 skb_pull(skb, L2CAP_HDR_SIZE);
6873 cid = __le16_to_cpu(lh->cid);
6874 len = __le16_to_cpu(lh->len);
6875
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006876 if (len != skb->len) {
6877 kfree_skb(skb);
6878 return;
6879 }
6880
Linus Torvalds1da177e2005-04-16 15:20:36 -07006881 BT_DBG("len %d, cid 0x%4.4x", len, cid);
6882
6883 switch (cid) {
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03006884 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006885 l2cap_sig_channel(conn, skb);
6886 break;
6887
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03006888 case L2CAP_CID_CONN_LESS:
Andrei Emeltchenko097db762012-03-09 14:16:17 +02006889 psm = get_unaligned((__le16 *) skb->data);
Andrei Emeltchenko0181a702012-05-29 10:04:05 +03006890 skb_pull(skb, L2CAP_PSMLEN_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006891 l2cap_conless_channel(conn, psm, skb);
6892 break;
6893
Johan Hedberg073d1cf2013-04-29 19:35:35 +03006894 case L2CAP_CID_ATT:
Marcel Holtmann72f78352013-04-23 00:59:00 -07006895 l2cap_att_channel(conn, skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006896 break;
6897
Marcel Holtmanna2877622013-10-02 23:46:54 -07006898 case L2CAP_CID_LE_SIGNALING:
6899 l2cap_le_sig_channel(conn, skb);
6900 break;
6901
Anderson Brigliab501d6a2011-06-07 18:46:31 -03006902 case L2CAP_CID_SMP:
6903 if (smp_sig_channel(conn, skb))
6904 l2cap_conn_del(conn->hcon, EACCES);
6905 break;
6906
Jukka Rissanen18722c22013-12-11 17:05:37 +02006907 case L2CAP_FC_6LOWPAN:
6908 bt_6lowpan_recv(conn, skb);
6909 break;
6910
Linus Torvalds1da177e2005-04-16 15:20:36 -07006911 default:
6912 l2cap_data_channel(conn, cid, skb);
6913 break;
6914 }
6915}
6916
Johan Hedberg61a939c2014-01-17 20:45:11 +02006917static void process_pending_rx(struct work_struct *work)
6918{
6919 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
6920 pending_rx_work);
6921 struct sk_buff *skb;
6922
6923 BT_DBG("");
6924
6925 while ((skb = skb_dequeue(&conn->pending_rx)))
6926 l2cap_recv_frame(conn, skb);
6927}
6928
Johan Hedberg162b49e2014-01-17 20:45:10 +02006929static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon)
6930{
6931 struct l2cap_conn *conn = hcon->l2cap_data;
6932 struct hci_chan *hchan;
6933
6934 if (conn)
6935 return conn;
6936
6937 hchan = hci_chan_create(hcon);
6938 if (!hchan)
6939 return NULL;
6940
6941 conn = kzalloc(sizeof(struct l2cap_conn), GFP_KERNEL);
6942 if (!conn) {
6943 hci_chan_del(hchan);
6944 return NULL;
6945 }
6946
6947 kref_init(&conn->ref);
6948 hcon->l2cap_data = conn;
6949 conn->hcon = hcon;
6950 hci_conn_get(conn->hcon);
6951 conn->hchan = hchan;
6952
6953 BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan);
6954
6955 switch (hcon->type) {
6956 case LE_LINK:
6957 if (hcon->hdev->le_mtu) {
6958 conn->mtu = hcon->hdev->le_mtu;
6959 break;
6960 }
6961 /* fall through */
6962 default:
6963 conn->mtu = hcon->hdev->acl_mtu;
6964 break;
6965 }
6966
6967 conn->feat_mask = 0;
6968
6969 if (hcon->type == ACL_LINK)
6970 conn->hs_enabled = test_bit(HCI_HS_ENABLED,
6971 &hcon->hdev->dev_flags);
6972
6973 spin_lock_init(&conn->lock);
6974 mutex_init(&conn->chan_lock);
6975
6976 INIT_LIST_HEAD(&conn->chan_l);
6977 INIT_LIST_HEAD(&conn->users);
6978
6979 if (hcon->type == LE_LINK)
6980 INIT_DELAYED_WORK(&conn->security_timer, security_timeout);
6981 else
6982 INIT_DELAYED_WORK(&conn->info_timer, l2cap_info_timeout);
6983
Johan Hedberg61a939c2014-01-17 20:45:11 +02006984 skb_queue_head_init(&conn->pending_rx);
6985 INIT_WORK(&conn->pending_rx_work, process_pending_rx);
6986
Johan Hedberg162b49e2014-01-17 20:45:10 +02006987 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
6988
6989 return conn;
6990}
6991
6992static bool is_valid_psm(u16 psm, u8 dst_type) {
6993 if (!psm)
6994 return false;
6995
6996 if (bdaddr_type_is_le(dst_type))
6997 return (psm <= 0x00ff);
6998
6999 /* PSM must be odd and lsb of upper byte must be 0 */
7000 return ((psm & 0x0101) == 0x0001);
7001}
7002
7003int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
7004 bdaddr_t *dst, u8 dst_type)
7005{
7006 struct l2cap_conn *conn;
7007 struct hci_conn *hcon;
7008 struct hci_dev *hdev;
7009 __u8 auth_type;
7010 int err;
7011
7012 BT_DBG("%pMR -> %pMR (type %u) psm 0x%2.2x", &chan->src, dst,
7013 dst_type, __le16_to_cpu(psm));
7014
7015 hdev = hci_get_route(dst, &chan->src);
7016 if (!hdev)
7017 return -EHOSTUNREACH;
7018
7019 hci_dev_lock(hdev);
7020
7021 l2cap_chan_lock(chan);
7022
7023 if (!is_valid_psm(__le16_to_cpu(psm), dst_type) && !cid &&
7024 chan->chan_type != L2CAP_CHAN_RAW) {
7025 err = -EINVAL;
7026 goto done;
7027 }
7028
Johan Hedberg21626e62014-01-24 10:35:41 +02007029 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && !psm) {
7030 err = -EINVAL;
7031 goto done;
7032 }
7033
7034 if (chan->chan_type == L2CAP_CHAN_FIXED && !cid) {
Johan Hedberg162b49e2014-01-17 20:45:10 +02007035 err = -EINVAL;
7036 goto done;
7037 }
7038
7039 switch (chan->mode) {
7040 case L2CAP_MODE_BASIC:
7041 break;
7042 case L2CAP_MODE_LE_FLOWCTL:
7043 l2cap_le_flowctl_init(chan);
7044 break;
7045 case L2CAP_MODE_ERTM:
7046 case L2CAP_MODE_STREAMING:
7047 if (!disable_ertm)
7048 break;
7049 /* fall through */
7050 default:
7051 err = -ENOTSUPP;
7052 goto done;
7053 }
7054
7055 switch (chan->state) {
7056 case BT_CONNECT:
7057 case BT_CONNECT2:
7058 case BT_CONFIG:
7059 /* Already connecting */
7060 err = 0;
7061 goto done;
7062
7063 case BT_CONNECTED:
7064 /* Already connected */
7065 err = -EISCONN;
7066 goto done;
7067
7068 case BT_OPEN:
7069 case BT_BOUND:
7070 /* Can connect */
7071 break;
7072
7073 default:
7074 err = -EBADFD;
7075 goto done;
7076 }
7077
7078 /* Set destination address and psm */
7079 bacpy(&chan->dst, dst);
7080 chan->dst_type = dst_type;
7081
7082 chan->psm = psm;
7083 chan->dcid = cid;
7084
7085 auth_type = l2cap_get_auth_type(chan);
7086
7087 if (bdaddr_type_is_le(dst_type))
7088 hcon = hci_connect(hdev, LE_LINK, dst, dst_type,
7089 chan->sec_level, auth_type);
7090 else
7091 hcon = hci_connect(hdev, ACL_LINK, dst, dst_type,
7092 chan->sec_level, auth_type);
7093
7094 if (IS_ERR(hcon)) {
7095 err = PTR_ERR(hcon);
7096 goto done;
7097 }
7098
7099 conn = l2cap_conn_add(hcon);
7100 if (!conn) {
7101 hci_conn_drop(hcon);
7102 err = -ENOMEM;
7103 goto done;
7104 }
7105
7106 if (cid && __l2cap_get_chan_by_dcid(conn, cid)) {
7107 hci_conn_drop(hcon);
7108 err = -EBUSY;
7109 goto done;
7110 }
7111
7112 /* Update source addr of the socket */
7113 bacpy(&chan->src, &hcon->src);
7114 chan->src_type = bdaddr_type(hcon, hcon->src_type);
7115
7116 l2cap_chan_unlock(chan);
7117 l2cap_chan_add(conn, chan);
7118 l2cap_chan_lock(chan);
7119
7120 /* l2cap_chan_add takes its own ref so we can drop this one */
7121 hci_conn_drop(hcon);
7122
7123 l2cap_state_change(chan, BT_CONNECT);
7124 __set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
7125
Johan Hedberg61202e42014-01-28 15:16:48 -08007126 /* Release chan->sport so that it can be reused by other
7127 * sockets (as it's only used for listening sockets).
7128 */
7129 write_lock(&chan_list_lock);
7130 chan->sport = 0;
7131 write_unlock(&chan_list_lock);
7132
Johan Hedberg162b49e2014-01-17 20:45:10 +02007133 if (hcon->state == BT_CONNECTED) {
7134 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
7135 __clear_chan_timer(chan);
7136 if (l2cap_chan_check_security(chan))
7137 l2cap_state_change(chan, BT_CONNECTED);
7138 } else
7139 l2cap_do_start(chan);
7140 }
7141
7142 err = 0;
7143
7144done:
7145 l2cap_chan_unlock(chan);
7146 hci_dev_unlock(hdev);
7147 hci_dev_put(hdev);
7148 return err;
7149}
7150
Linus Torvalds1da177e2005-04-16 15:20:36 -07007151/* ---- L2CAP interface with lower layer (HCI) ---- */
7152
Ulisses Furquim686ebf22011-12-21 10:11:33 -02007153int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007154{
7155 int exact = 0, lm1 = 0, lm2 = 0;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007156 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007157
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03007158 BT_DBG("hdev %s, bdaddr %pMR", hdev->name, bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007159
7160 /* Find listening sockets and check their link_mode */
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007161 read_lock(&chan_list_lock);
7162 list_for_each_entry(c, &chan_list, global_l) {
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03007163 if (c->state != BT_LISTEN)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007164 continue;
7165
Marcel Holtmann7eafc592013-10-13 08:12:47 -07007166 if (!bacmp(&c->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01007167 lm1 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03007168 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01007169 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007170 exact++;
Marcel Holtmann7eafc592013-10-13 08:12:47 -07007171 } else if (!bacmp(&c->src, BDADDR_ANY)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01007172 lm2 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03007173 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01007174 lm2 |= HCI_LM_MASTER;
7175 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07007176 }
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007177 read_unlock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007178
7179 return exact ? lm1 : lm2;
7180}
7181
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03007182void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007183{
Marcel Holtmann01394182006-07-03 10:02:46 +02007184 struct l2cap_conn *conn;
7185
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03007186 BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007187
Linus Torvalds1da177e2005-04-16 15:20:36 -07007188 if (!status) {
Claudio Takahasibaf43252013-04-11 13:55:50 -03007189 conn = l2cap_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007190 if (conn)
7191 l2cap_conn_ready(conn);
Andrei Emeltchenkoba6fc312012-10-31 15:46:26 +02007192 } else {
Joe Perchese1750722011-06-29 18:18:29 -07007193 l2cap_conn_del(hcon, bt_to_errno(status));
Andrei Emeltchenkoba6fc312012-10-31 15:46:26 +02007194 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07007195}
7196
Ulisses Furquim686ebf22011-12-21 10:11:33 -02007197int l2cap_disconn_ind(struct hci_conn *hcon)
Marcel Holtmann2950f212009-02-12 14:02:50 +01007198{
7199 struct l2cap_conn *conn = hcon->l2cap_data;
7200
7201 BT_DBG("hcon %p", hcon);
7202
Ulisses Furquim686ebf22011-12-21 10:11:33 -02007203 if (!conn)
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02007204 return HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01007205 return conn->disc_reason;
7206}
7207
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03007208void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007209{
7210 BT_DBG("hcon %p reason %d", hcon, reason);
7211
Jukka Rissanen18722c22013-12-11 17:05:37 +02007212 bt_6lowpan_del_conn(hcon->l2cap_data);
7213
Joe Perchese1750722011-06-29 18:18:29 -07007214 l2cap_conn_del(hcon, bt_to_errno(reason));
Linus Torvalds1da177e2005-04-16 15:20:36 -07007215}
7216
Gustavo F. Padovan43434782011-04-12 18:31:57 -03007217static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
Marcel Holtmannf62e4322009-01-15 21:58:44 +01007218{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03007219 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED)
Marcel Holtmann255c7602009-02-04 21:07:19 +01007220 return;
7221
Marcel Holtmannf62e4322009-01-15 21:58:44 +01007222 if (encrypt == 0x00) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03007223 if (chan->sec_level == BT_SECURITY_MEDIUM) {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08007224 __set_chan_timer(chan, L2CAP_ENC_TIMEOUT);
Marcel Holtmann7d513e92014-01-15 22:37:40 -08007225 } else if (chan->sec_level == BT_SECURITY_HIGH ||
7226 chan->sec_level == BT_SECURITY_FIPS)
Gustavo F. Padovan0f852722011-05-04 19:42:50 -03007227 l2cap_chan_close(chan, ECONNREFUSED);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01007228 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03007229 if (chan->sec_level == BT_SECURITY_MEDIUM)
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03007230 __clear_chan_timer(chan);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01007231 }
7232}
7233
Ulisses Furquim686ebf22011-12-21 10:11:33 -02007234int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007235{
Marcel Holtmann40be4922008-07-14 20:13:50 +02007236 struct l2cap_conn *conn = hcon->l2cap_data;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03007237 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007238
Marcel Holtmann01394182006-07-03 10:02:46 +02007239 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007240 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02007241
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03007242 BT_DBG("conn %p status 0x%2.2x encrypt %u", conn, status, encrypt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007243
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03007244 if (hcon->type == LE_LINK) {
Hemant Gupta35d4adcc2012-04-18 14:46:26 +05307245 if (!status && encrypt)
7246 smp_distribute_keys(conn, 0);
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02007247 cancel_delayed_work(&conn->security_timer);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03007248 }
7249
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02007250 mutex_lock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007251
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02007252 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02007253 l2cap_chan_lock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007254
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03007255 BT_DBG("chan %p scid 0x%4.4x state %s", chan, chan->scid,
7256 state_to_string(chan->state));
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03007257
Johan Hedberg2338a7e2014-01-24 10:35:40 +02007258 if (chan->scid == L2CAP_CID_A2MP) {
Andrei Emeltchenko78eb2f92012-07-19 17:03:47 +03007259 l2cap_chan_unlock(chan);
7260 continue;
7261 }
7262
Johan Hedberg073d1cf2013-04-29 19:35:35 +03007263 if (chan->scid == L2CAP_CID_ATT) {
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03007264 if (!status && encrypt) {
7265 chan->sec_level = hcon->sec_level;
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02007266 l2cap_chan_ready(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03007267 }
7268
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02007269 l2cap_chan_unlock(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03007270 continue;
7271 }
7272
Andrei Emeltchenko96eff462012-11-15 18:14:53 +02007273 if (!__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02007274 l2cap_chan_unlock(chan);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01007275 continue;
7276 }
7277
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03007278 if (!status && (chan->state == BT_CONNECTED ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01007279 chan->state == BT_CONFIG)) {
Marcel Holtmannd97c8992013-10-14 02:53:54 -07007280 chan->ops->resume(chan);
Gustavo F. Padovan43434782011-04-12 18:31:57 -03007281 l2cap_check_encryption(chan, encrypt);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02007282 l2cap_chan_unlock(chan);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02007283 continue;
7284 }
7285
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03007286 if (chan->state == BT_CONNECT) {
Johan Hedberg6d3c15d2013-12-02 22:13:24 +02007287 if (!status)
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03007288 l2cap_start_connection(chan);
Johan Hedberg6d3c15d2013-12-02 22:13:24 +02007289 else
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08007290 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03007291 } else if (chan->state == BT_CONNECT2) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +02007292 struct l2cap_conn_rsp rsp;
Johan Hedbergdf3c3932011-06-14 12:48:19 +03007293 __u16 res, stat;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02007294
7295 if (!status) {
Marcel Holtmannbdc25782013-10-14 02:45:34 -07007296 if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
Johan Hedbergdf3c3932011-06-14 12:48:19 +03007297 res = L2CAP_CR_PEND;
7298 stat = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08007299 chan->ops->defer(chan);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03007300 } else {
Gustavo Padovanacdcabf2013-10-21 14:21:39 -02007301 l2cap_state_change(chan, BT_CONFIG);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03007302 res = L2CAP_CR_SUCCESS;
7303 stat = L2CAP_CS_NO_INFO;
7304 }
Marcel Holtmannb1235d72008-07-14 20:13:54 +02007305 } else {
Gustavo Padovanacdcabf2013-10-21 14:21:39 -02007306 l2cap_state_change(chan, BT_DISCONN);
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08007307 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03007308 res = L2CAP_CR_SEC_BLOCK;
7309 stat = L2CAP_CS_NO_INFO;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02007310 }
7311
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03007312 rsp.scid = cpu_to_le16(chan->dcid);
7313 rsp.dcid = cpu_to_le16(chan->scid);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03007314 rsp.result = cpu_to_le16(res);
7315 rsp.status = cpu_to_le16(stat);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03007316 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01007317 sizeof(rsp), &rsp);
Mat Martineau2d369352012-05-23 14:59:30 -07007318
7319 if (!test_bit(CONF_REQ_SENT, &chan->conf_state) &&
7320 res == L2CAP_CR_SUCCESS) {
7321 char buf[128];
7322 set_bit(CONF_REQ_SENT, &chan->conf_state);
7323 l2cap_send_cmd(conn, l2cap_get_ident(conn),
7324 L2CAP_CONF_REQ,
7325 l2cap_build_conf_req(chan, buf),
7326 buf);
7327 chan->num_conf_req++;
7328 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07007329 }
7330
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02007331 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007332 }
7333
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02007334 mutex_unlock(&conn->chan_lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02007335
Linus Torvalds1da177e2005-04-16 15:20:36 -07007336 return 0;
7337}
7338
Ulisses Furquim686ebf22011-12-21 10:11:33 -02007339int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007340{
7341 struct l2cap_conn *conn = hcon->l2cap_data;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03007342 struct l2cap_hdr *hdr;
7343 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007344
Andrei Emeltchenko1d13a252012-10-15 11:58:41 +03007345 /* For AMP controller do not create l2cap conn */
7346 if (!conn && hcon->hdev->dev_type != HCI_BREDR)
7347 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007348
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02007349 if (!conn)
Claudio Takahasibaf43252013-04-11 13:55:50 -03007350 conn = l2cap_conn_add(hcon);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02007351
7352 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007353 goto drop;
7354
7355 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
7356
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03007357 switch (flags) {
7358 case ACL_START:
7359 case ACL_START_NO_FLUSH:
7360 case ACL_COMPLETE:
Linus Torvalds1da177e2005-04-16 15:20:36 -07007361 if (conn->rx_len) {
7362 BT_ERR("Unexpected start frame (len %d)", skb->len);
7363 kfree_skb(conn->rx_skb);
7364 conn->rx_skb = NULL;
7365 conn->rx_len = 0;
7366 l2cap_conn_unreliable(conn, ECOMM);
7367 }
7368
Andrei Emeltchenkoaae7fe22010-09-15 14:28:43 +03007369 /* Start fragment always begin with Basic L2CAP header */
7370 if (skb->len < L2CAP_HDR_SIZE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07007371 BT_ERR("Frame is too short (len %d)", skb->len);
7372 l2cap_conn_unreliable(conn, ECOMM);
7373 goto drop;
7374 }
7375
7376 hdr = (struct l2cap_hdr *) skb->data;
7377 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
7378
7379 if (len == skb->len) {
7380 /* Complete frame received */
7381 l2cap_recv_frame(conn, skb);
7382 return 0;
7383 }
7384
7385 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
7386
7387 if (skb->len > len) {
7388 BT_ERR("Frame is too long (len %d, expected len %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01007389 skb->len, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007390 l2cap_conn_unreliable(conn, ECOMM);
7391 goto drop;
7392 }
7393
7394 /* Allocate skb for the complete frame (with header) */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03007395 conn->rx_skb = bt_skb_alloc(len, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03007396 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007397 goto drop;
7398
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03007399 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01007400 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007401 conn->rx_len = len - skb->len;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03007402 break;
7403
7404 case ACL_CONT:
Linus Torvalds1da177e2005-04-16 15:20:36 -07007405 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
7406
7407 if (!conn->rx_len) {
7408 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
7409 l2cap_conn_unreliable(conn, ECOMM);
7410 goto drop;
7411 }
7412
7413 if (skb->len > conn->rx_len) {
7414 BT_ERR("Fragment is too long (len %d, expected %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01007415 skb->len, conn->rx_len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007416 kfree_skb(conn->rx_skb);
7417 conn->rx_skb = NULL;
7418 conn->rx_len = 0;
7419 l2cap_conn_unreliable(conn, ECOMM);
7420 goto drop;
7421 }
7422
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03007423 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01007424 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007425 conn->rx_len -= skb->len;
7426
7427 if (!conn->rx_len) {
Johan Hedbergc4e5baf2013-10-10 13:33:37 +02007428 /* Complete frame received. l2cap_recv_frame
7429 * takes ownership of the skb so set the global
7430 * rx_skb pointer to NULL first.
7431 */
7432 struct sk_buff *rx_skb = conn->rx_skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007433 conn->rx_skb = NULL;
Johan Hedbergc4e5baf2013-10-10 13:33:37 +02007434 l2cap_recv_frame(conn, rx_skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007435 }
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03007436 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007437 }
7438
7439drop:
7440 kfree_skb(skb);
7441 return 0;
7442}
7443
Marcel Holtmannaef7d972010-03-21 05:27:45 +01007444static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007445{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007446 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007447
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02007448 read_lock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007449
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007450 list_for_each_entry(c, &chan_list, global_l) {
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +03007451 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 -07007452 &c->src, &c->dst,
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +03007453 c->state, __le16_to_cpu(c->psm),
7454 c->scid, c->dcid, c->imtu, c->omtu,
7455 c->sec_level, c->mode);
Andrei Emeltchenko61e1b4b2012-01-19 11:19:50 +02007456 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07007457
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02007458 read_unlock(&chan_list_lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08007459
Marcel Holtmannaef7d972010-03-21 05:27:45 +01007460 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007461}
7462
Marcel Holtmannaef7d972010-03-21 05:27:45 +01007463static int l2cap_debugfs_open(struct inode *inode, struct file *file)
7464{
7465 return single_open(file, l2cap_debugfs_show, inode->i_private);
7466}
7467
7468static const struct file_operations l2cap_debugfs_fops = {
7469 .open = l2cap_debugfs_open,
7470 .read = seq_read,
7471 .llseek = seq_lseek,
7472 .release = single_release,
7473};
7474
7475static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007476
Gustavo F. Padovan64274512011-02-07 20:08:52 -02007477int __init l2cap_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007478{
7479 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08007480
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02007481 err = l2cap_init_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07007482 if (err < 0)
7483 return err;
7484
Marcel Holtmann1120e4b2013-10-17 17:24:16 -07007485 if (IS_ERR_OR_NULL(bt_debugfs))
7486 return 0;
7487
7488 l2cap_debugfs = debugfs_create_file("l2cap", 0444, bt_debugfs,
7489 NULL, &l2cap_debugfs_fops);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007490
Johan Hedbergf15b8ec2013-12-03 15:08:25 +02007491 debugfs_create_u16("l2cap_le_max_credits", 0466, bt_debugfs,
7492 &le_max_credits);
7493 debugfs_create_u16("l2cap_le_default_mps", 0466, bt_debugfs,
7494 &le_default_mps);
7495
Jukka Rissanen18722c22013-12-11 17:05:37 +02007496 bt_6lowpan_init();
7497
Linus Torvalds1da177e2005-04-16 15:20:36 -07007498 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007499}
7500
Gustavo F. Padovan64274512011-02-07 20:08:52 -02007501void l2cap_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007502{
Jukka Rissanen18722c22013-12-11 17:05:37 +02007503 bt_6lowpan_cleanup();
Marcel Holtmannaef7d972010-03-21 05:27:45 +01007504 debugfs_remove(l2cap_debugfs);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02007505 l2cap_cleanup_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07007506}
7507
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03007508module_param(disable_ertm, bool, 0644);
7509MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode");