blob: 5a30fc72f4ba0a05d9c9abb75490e1c5561b7b43 [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
Mat Martineaud1de6d42012-05-17 20:53:55 -070045bool disable_ertm;
Marcel Holtmannf0709e02007-10-20 13:38:51 +020046
Marcel Holtmann547d1032013-10-12 08:18:19 -070047static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN | L2CAP_FEAT_UCD;
Marcel Holtmannd40bffb2013-10-12 08:18:18 -070048static u8 l2cap_fixed_chan[8] = { L2CAP_FC_L2CAP | L2CAP_FC_CONNLESS, };
Linus Torvalds1da177e2005-04-16 15:20:36 -070049
Johannes Bergb5ad8b72011-06-01 08:54:45 +020050static LIST_HEAD(chan_list);
51static DEFINE_RWLOCK(chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -070052
Johan Hedbergf15b8ec2013-12-03 15:08:25 +020053static u16 le_max_credits = L2CAP_LE_MAX_CREDITS;
54static u16 le_default_mps = L2CAP_LE_DEFAULT_MPS;
55
Linus Torvalds1da177e2005-04-16 15:20:36 -070056static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +010057 u8 code, u8 ident, u16 dlen, void *data);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -030058static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
Gustavo Padovan2d792812012-10-06 10:07:01 +010059 void *data);
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -030060static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +020061static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err);
Linus Torvalds1da177e2005-04-16 15:20:36 -070062
Gustavo Padovand6603662012-05-21 13:58:22 -030063static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
Gustavo Padovan2d792812012-10-06 10:07:01 +010064 struct sk_buff_head *skbs, u8 event);
Mat Martineau608bcc62012-05-17 20:53:32 -070065
Marcel Holtmann4f1654e2013-10-13 08:50:41 -070066static inline __u8 bdaddr_type(struct hci_conn *hcon, __u8 type)
67{
68 if (hcon->type == LE_LINK) {
69 if (type == ADDR_LE_DEV_PUBLIC)
70 return BDADDR_LE_PUBLIC;
71 else
72 return BDADDR_LE_RANDOM;
73 }
74
75 return BDADDR_BREDR;
76}
77
Marcel Holtmann01394182006-07-03 10:02:46 +020078/* ---- L2CAP channels ---- */
Gustavo F. Padovan71ba0e52011-05-17 14:34:52 -030079
Gustavo Padovan2d792812012-10-06 10:07:01 +010080static struct l2cap_chan *__l2cap_get_chan_by_dcid(struct l2cap_conn *conn,
81 u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +020082{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020083 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030084
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020085 list_for_each_entry(c, &conn->chan_l, list) {
86 if (c->dcid == cid)
87 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +020088 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020089 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +020090}
91
Gustavo Padovan2d792812012-10-06 10:07:01 +010092static struct l2cap_chan *__l2cap_get_chan_by_scid(struct l2cap_conn *conn,
93 u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +020094{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020095 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030096
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020097 list_for_each_entry(c, &conn->chan_l, list) {
98 if (c->scid == cid)
99 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +0200100 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200101 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200102}
103
104/* Find channel with given SCID.
Mat Martineauef191ad2012-05-02 09:42:00 -0700105 * Returns locked channel. */
Gustavo Padovan2d792812012-10-06 10:07:01 +0100106static struct l2cap_chan *l2cap_get_chan_by_scid(struct l2cap_conn *conn,
107 u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +0200108{
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300109 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300110
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200111 mutex_lock(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300112 c = __l2cap_get_chan_by_scid(conn, cid);
Mat Martineauef191ad2012-05-02 09:42:00 -0700113 if (c)
114 l2cap_chan_lock(c);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200115 mutex_unlock(&conn->chan_lock);
116
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300117 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +0200118}
119
Mat Martineaub1a130b2012-10-23 15:24:09 -0700120/* Find channel with given DCID.
121 * Returns locked channel.
122 */
123static struct l2cap_chan *l2cap_get_chan_by_dcid(struct l2cap_conn *conn,
124 u16 cid)
125{
126 struct l2cap_chan *c;
127
128 mutex_lock(&conn->chan_lock);
129 c = __l2cap_get_chan_by_dcid(conn, cid);
130 if (c)
131 l2cap_chan_lock(c);
132 mutex_unlock(&conn->chan_lock);
133
134 return c;
135}
136
Gustavo Padovan2d792812012-10-06 10:07:01 +0100137static struct l2cap_chan *__l2cap_get_chan_by_ident(struct l2cap_conn *conn,
138 u8 ident)
Marcel Holtmann01394182006-07-03 10:02:46 +0200139{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200140 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300141
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200142 list_for_each_entry(c, &conn->chan_l, list) {
143 if (c->ident == ident)
144 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +0200145 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200146 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200147}
148
Mat Martineau5b155ef2012-10-23 15:24:14 -0700149static struct l2cap_chan *l2cap_get_chan_by_ident(struct l2cap_conn *conn,
150 u8 ident)
151{
152 struct l2cap_chan *c;
153
154 mutex_lock(&conn->chan_lock);
155 c = __l2cap_get_chan_by_ident(conn, ident);
156 if (c)
157 l2cap_chan_lock(c);
158 mutex_unlock(&conn->chan_lock);
159
160 return c;
161}
162
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300163static struct l2cap_chan *__l2cap_global_chan_by_addr(__le16 psm, bdaddr_t *src)
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300164{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300165 struct l2cap_chan *c;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300166
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300167 list_for_each_entry(c, &chan_list, global_l) {
Marcel Holtmann7eafc592013-10-13 08:12:47 -0700168 if (c->sport == psm && !bacmp(&c->src, src))
Szymon Janc250938c2011-11-16 09:32:22 +0100169 return c;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300170 }
Szymon Janc250938c2011-11-16 09:32:22 +0100171 return NULL;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300172}
173
174int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm)
175{
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300176 int err;
177
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200178 write_lock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300179
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300180 if (psm && __l2cap_global_chan_by_addr(psm, src)) {
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300181 err = -EADDRINUSE;
182 goto done;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300183 }
184
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300185 if (psm) {
186 chan->psm = psm;
187 chan->sport = psm;
188 err = 0;
189 } else {
190 u16 p;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300191
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300192 err = -EINVAL;
193 for (p = 0x1001; p < 0x1100; p += 2)
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300194 if (!__l2cap_global_chan_by_addr(cpu_to_le16(p), src)) {
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300195 chan->psm = cpu_to_le16(p);
196 chan->sport = cpu_to_le16(p);
197 err = 0;
198 break;
199 }
200 }
201
202done:
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200203 write_unlock(&chan_list_lock);
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300204 return err;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300205}
206
207int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid)
208{
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200209 write_lock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300210
211 chan->scid = scid;
212
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200213 write_unlock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300214
215 return 0;
216}
217
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300218static u16 l2cap_alloc_cid(struct l2cap_conn *conn)
Marcel Holtmann01394182006-07-03 10:02:46 +0200219{
Johan Hedberge77af752013-10-08 10:31:00 +0200220 u16 cid, dyn_end;
Marcel Holtmann01394182006-07-03 10:02:46 +0200221
Johan Hedberge77af752013-10-08 10:31:00 +0200222 if (conn->hcon->type == LE_LINK)
223 dyn_end = L2CAP_CID_LE_DYN_END;
224 else
225 dyn_end = L2CAP_CID_DYN_END;
226
227 for (cid = L2CAP_CID_DYN_START; cid < dyn_end; cid++) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300228 if (!__l2cap_get_chan_by_scid(conn, cid))
Marcel Holtmann01394182006-07-03 10:02:46 +0200229 return cid;
230 }
231
232 return 0;
233}
234
Gustavo Padovanf93fa272013-10-21 14:21:40 -0200235static void l2cap_state_change(struct l2cap_chan *chan, int state)
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300236{
Andrei Emeltchenko42d2d872012-02-17 11:40:57 +0200237 BT_DBG("chan %p %s -> %s", chan, state_to_string(chan->state),
Gustavo Padovan2d792812012-10-06 10:07:01 +0100238 state_to_string(state));
Gustavo F. Padovanbadaaa02011-11-23 20:11:46 -0200239
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300240 chan->state = state;
Gustavo Padovan53f52122013-10-15 19:24:45 -0300241 chan->ops->state_change(chan, state, 0);
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300242}
243
Gustavo Padovanf8e73012013-10-15 19:24:46 -0300244static inline void l2cap_state_change_and_error(struct l2cap_chan *chan,
245 int state, int err)
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +0200246{
Gustavo Padovanf8e73012013-10-15 19:24:46 -0300247 chan->state = state;
Gustavo Padovan53f52122013-10-15 19:24:45 -0300248 chan->ops->state_change(chan, chan->state, err);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +0200249}
250
251static inline void l2cap_chan_set_err(struct l2cap_chan *chan, int err)
252{
Gustavo Padovanf8e73012013-10-15 19:24:46 -0300253 chan->ops->state_change(chan, chan->state, err);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +0200254}
255
Mat Martineau4239d162012-05-17 20:53:49 -0700256static void __set_retrans_timer(struct l2cap_chan *chan)
257{
258 if (!delayed_work_pending(&chan->monitor_timer) &&
259 chan->retrans_timeout) {
260 l2cap_set_timer(chan, &chan->retrans_timer,
261 msecs_to_jiffies(chan->retrans_timeout));
262 }
263}
264
265static void __set_monitor_timer(struct l2cap_chan *chan)
266{
267 __clear_retrans_timer(chan);
268 if (chan->monitor_timeout) {
269 l2cap_set_timer(chan, &chan->monitor_timer,
270 msecs_to_jiffies(chan->monitor_timeout));
271 }
272}
273
Mat Martineau608bcc62012-05-17 20:53:32 -0700274static struct sk_buff *l2cap_ertm_seq_in_queue(struct sk_buff_head *head,
275 u16 seq)
276{
277 struct sk_buff *skb;
278
279 skb_queue_walk(head, skb) {
280 if (bt_cb(skb)->control.txseq == seq)
281 return skb;
282 }
283
284 return NULL;
285}
286
Mat Martineau3c588192012-04-11 10:48:42 -0700287/* ---- L2CAP sequence number lists ---- */
288
289/* For ERTM, ordered lists of sequence numbers must be tracked for
290 * SREJ requests that are received and for frames that are to be
291 * retransmitted. These seq_list functions implement a singly-linked
292 * list in an array, where membership in the list can also be checked
293 * in constant time. Items can also be added to the tail of the list
294 * and removed from the head in constant time, without further memory
295 * allocs or frees.
296 */
297
298static int l2cap_seq_list_init(struct l2cap_seq_list *seq_list, u16 size)
299{
300 size_t alloc_size, i;
301
302 /* Allocated size is a power of 2 to map sequence numbers
303 * (which may be up to 14 bits) in to a smaller array that is
304 * sized for the negotiated ERTM transmit windows.
305 */
306 alloc_size = roundup_pow_of_two(size);
307
308 seq_list->list = kmalloc(sizeof(u16) * alloc_size, GFP_KERNEL);
309 if (!seq_list->list)
310 return -ENOMEM;
311
312 seq_list->mask = alloc_size - 1;
313 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
314 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
315 for (i = 0; i < alloc_size; i++)
316 seq_list->list[i] = L2CAP_SEQ_LIST_CLEAR;
317
318 return 0;
319}
320
321static inline void l2cap_seq_list_free(struct l2cap_seq_list *seq_list)
322{
323 kfree(seq_list->list);
324}
325
326static inline bool l2cap_seq_list_contains(struct l2cap_seq_list *seq_list,
327 u16 seq)
328{
329 /* Constant-time check for list membership */
330 return seq_list->list[seq & seq_list->mask] != L2CAP_SEQ_LIST_CLEAR;
331}
332
Mat Martineau3c588192012-04-11 10:48:42 -0700333static inline u16 l2cap_seq_list_pop(struct l2cap_seq_list *seq_list)
334{
Johan Hedberg03a0c5d2014-01-18 21:32:59 +0200335 u16 seq = seq_list->head;
336 u16 mask = seq_list->mask;
337
338 seq_list->head = seq_list->list[seq & mask];
339 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_CLEAR;
340
341 if (seq_list->head == L2CAP_SEQ_LIST_TAIL) {
342 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
343 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
344 }
345
346 return seq;
Mat Martineau3c588192012-04-11 10:48:42 -0700347}
348
349static void l2cap_seq_list_clear(struct l2cap_seq_list *seq_list)
350{
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300351 u16 i;
Mat Martineau3c588192012-04-11 10:48:42 -0700352
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300353 if (seq_list->head == L2CAP_SEQ_LIST_CLEAR)
354 return;
355
356 for (i = 0; i <= seq_list->mask; i++)
357 seq_list->list[i] = L2CAP_SEQ_LIST_CLEAR;
358
359 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
360 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
Mat Martineau3c588192012-04-11 10:48:42 -0700361}
362
363static void l2cap_seq_list_append(struct l2cap_seq_list *seq_list, u16 seq)
364{
365 u16 mask = seq_list->mask;
366
367 /* All appends happen in constant time */
368
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300369 if (seq_list->list[seq & mask] != L2CAP_SEQ_LIST_CLEAR)
370 return;
Mat Martineau3c588192012-04-11 10:48:42 -0700371
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300372 if (seq_list->tail == L2CAP_SEQ_LIST_CLEAR)
373 seq_list->head = seq;
374 else
375 seq_list->list[seq_list->tail & mask] = seq;
376
377 seq_list->tail = seq;
378 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_TAIL;
Mat Martineau3c588192012-04-11 10:48:42 -0700379}
380
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300381static void l2cap_chan_timeout(struct work_struct *work)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300382{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300383 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100384 chan_timer.work);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200385 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300386 int reason;
387
Andrei Emeltchenkoe05dcc32012-02-17 11:40:56 +0200388 BT_DBG("chan %p state %s", chan, state_to_string(chan->state));
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300389
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200390 mutex_lock(&conn->chan_lock);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200391 l2cap_chan_lock(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300392
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300393 if (chan->state == BT_CONNECTED || chan->state == BT_CONFIG)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300394 reason = ECONNREFUSED;
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300395 else if (chan->state == BT_CONNECT &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100396 chan->sec_level != BT_SECURITY_SDP)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300397 reason = ECONNREFUSED;
398 else
399 reason = ETIMEDOUT;
400
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300401 l2cap_chan_close(chan, reason);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300402
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200403 l2cap_chan_unlock(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300404
Gustavo Padovan80b98022012-05-27 22:27:51 -0300405 chan->ops->close(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200406 mutex_unlock(&conn->chan_lock);
407
Ulisses Furquim371fd832011-12-21 20:02:36 -0200408 l2cap_chan_put(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300409}
410
Gustavo Padovaneef1d9b2012-03-25 13:59:16 -0300411struct l2cap_chan *l2cap_chan_create(void)
Marcel Holtmann01394182006-07-03 10:02:46 +0200412{
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300413 struct l2cap_chan *chan;
Marcel Holtmann01394182006-07-03 10:02:46 +0200414
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300415 chan = kzalloc(sizeof(*chan), GFP_ATOMIC);
416 if (!chan)
417 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200418
Andrei Emeltchenkoc03b3552012-02-21 12:54:56 +0200419 mutex_init(&chan->lock);
420
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200421 write_lock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300422 list_add(&chan->global_l, &chan_list);
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200423 write_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300424
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300425 INIT_DELAYED_WORK(&chan->chan_timer, l2cap_chan_timeout);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300426
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300427 chan->state = BT_OPEN;
428
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530429 kref_init(&chan->kref);
Gustavo F. Padovan71ba0e52011-05-17 14:34:52 -0300430
Mat Martineau28270112012-05-17 21:14:09 -0700431 /* This flag is cleared in l2cap_chan_ready() */
432 set_bit(CONF_NOT_COMPLETE, &chan->conf_state);
433
Gustavo Padovaneef1d9b2012-03-25 13:59:16 -0300434 BT_DBG("chan %p", chan);
Szymon Jancabc545b2011-11-03 16:05:44 +0100435
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300436 return chan;
Marcel Holtmann01394182006-07-03 10:02:46 +0200437}
438
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530439static void l2cap_chan_destroy(struct kref *kref)
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300440{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530441 struct l2cap_chan *chan = container_of(kref, struct l2cap_chan, kref);
442
Jaganath Kanakkassery4af66c62012-07-13 18:17:55 +0530443 BT_DBG("chan %p", chan);
444
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200445 write_lock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300446 list_del(&chan->global_l);
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200447 write_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300448
Jaganath Kanakkassery4af66c62012-07-13 18:17:55 +0530449 kfree(chan);
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300450}
451
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530452void l2cap_chan_hold(struct l2cap_chan *c)
453{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530454 BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->kref.refcount));
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530455
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530456 kref_get(&c->kref);
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530457}
458
459void l2cap_chan_put(struct l2cap_chan *c)
460{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530461 BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->kref.refcount));
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530462
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530463 kref_put(&c->kref, l2cap_chan_destroy);
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530464}
465
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +0300466void l2cap_chan_set_defaults(struct l2cap_chan *chan)
467{
468 chan->fcs = L2CAP_FCS_CRC16;
469 chan->max_tx = L2CAP_DEFAULT_MAX_TX;
470 chan->tx_win = L2CAP_DEFAULT_TX_WINDOW;
471 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
Mat Martineauc20f8e32012-07-10 05:47:07 -0700472 chan->ack_win = L2CAP_DEFAULT_TX_WINDOW;
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +0300473 chan->sec_level = BT_SECURITY_LOW;
474
475 set_bit(FLAG_FORCE_ACTIVE, &chan->flags);
476}
477
Johan Hedberg0ce43ce2013-12-05 14:55:33 +0200478static void l2cap_le_flowctl_init(struct l2cap_chan *chan)
Johan Hedberg38319712013-05-17 12:49:23 +0300479{
Johan Hedberg0ce43ce2013-12-05 14:55:33 +0200480 chan->sdu = NULL;
481 chan->sdu_last_frag = NULL;
482 chan->sdu_len = 0;
Johan Hedberg0cd75f72013-05-17 13:09:05 +0300483 chan->tx_credits = 0;
Johan Hedbergf15b8ec2013-12-03 15:08:25 +0200484 chan->rx_credits = le_max_credits;
Johan Hedbergd1d79412014-01-27 15:11:33 -0800485 chan->mps = min_t(u16, chan->imtu, le_default_mps);
Johan Hedberg0ce43ce2013-12-05 14:55:33 +0200486
487 skb_queue_head_init(&chan->tx_q);
Johan Hedberg38319712013-05-17 12:49:23 +0300488}
489
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +0300490void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Marcel Holtmann01394182006-07-03 10:02:46 +0200491{
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300492 BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
Andrei Emeltchenko097db762012-03-09 14:16:17 +0200493 __le16_to_cpu(chan->psm), chan->dcid);
Marcel Holtmann01394182006-07-03 10:02:46 +0200494
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +0200495 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +0100496
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300497 chan->conn = conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200498
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200499 switch (chan->chan_type) {
500 case L2CAP_CHAN_CONN_ORIENTED:
Johan Hedberg21626e62014-01-24 10:35:41 +0200501 /* Alloc CID for connection-oriented socket */
502 chan->scid = l2cap_alloc_cid(conn);
503 if (conn->hcon->type == ACL_LINK)
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300504 chan->omtu = L2CAP_DEFAULT_MTU;
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200505 break;
506
507 case L2CAP_CHAN_CONN_LESS:
Marcel Holtmann01394182006-07-03 10:02:46 +0200508 /* Connectionless socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300509 chan->scid = L2CAP_CID_CONN_LESS;
510 chan->dcid = L2CAP_CID_CONN_LESS;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300511 chan->omtu = L2CAP_DEFAULT_MTU;
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200512 break;
513
Johan Hedberg2338a7e2014-01-24 10:35:40 +0200514 case L2CAP_CHAN_FIXED:
515 /* Caller will set CID and CID specific MTU values */
Andrei Emeltchenko416fa752012-05-29 13:59:16 +0300516 break;
517
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200518 default:
Marcel Holtmann01394182006-07-03 10:02:46 +0200519 /* Raw socket can send/recv signalling messages only */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300520 chan->scid = L2CAP_CID_SIGNALING;
521 chan->dcid = L2CAP_CID_SIGNALING;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300522 chan->omtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann01394182006-07-03 10:02:46 +0200523 }
524
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300525 chan->local_id = L2CAP_BESTEFFORT_ID;
526 chan->local_stype = L2CAP_SERV_BESTEFFORT;
527 chan->local_msdu = L2CAP_DEFAULT_MAX_SDU_SIZE;
528 chan->local_sdu_itime = L2CAP_DEFAULT_SDU_ITIME;
529 chan->local_acc_lat = L2CAP_DEFAULT_ACC_LAT;
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +0300530 chan->local_flush_to = L2CAP_EFS_DEFAULT_FLUSH_TO;
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300531
Ulisses Furquim371fd832011-12-21 20:02:36 -0200532 l2cap_chan_hold(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300533
Johan Hedberg5ee98912013-04-29 19:35:43 +0300534 hci_conn_hold(conn->hcon);
535
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200536 list_add(&chan->list, &conn->chan_l);
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200537}
538
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300539void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200540{
541 mutex_lock(&conn->chan_lock);
542 __l2cap_chan_add(conn, chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200543 mutex_unlock(&conn->chan_lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200544}
545
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300546void l2cap_chan_del(struct l2cap_chan *chan, int err)
Marcel Holtmann01394182006-07-03 10:02:46 +0200547{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300548 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200549
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300550 __clear_chan_timer(chan);
Marcel Holtmann01394182006-07-03 10:02:46 +0200551
Gustavo F. Padovan49208c92011-04-04 15:59:54 -0300552 BT_DBG("chan %p, conn %p, err %d", chan, conn, err);
Marcel Holtmann01394182006-07-03 10:02:46 +0200553
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900554 if (conn) {
Andrei Emeltchenko56f60982012-10-15 11:58:44 +0300555 struct amp_mgr *mgr = conn->hcon->amp_mgr;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300556 /* Delete from channel list */
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200557 list_del(&chan->list);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -0200558
Ulisses Furquim371fd832011-12-21 20:02:36 -0200559 l2cap_chan_put(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300560
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300561 chan->conn = NULL;
Andrei Emeltchenko3cabbfd2012-05-31 11:01:37 +0300562
Johan Hedberg2338a7e2014-01-24 10:35:40 +0200563 if (chan->scid != L2CAP_CID_A2MP)
David Herrmann76a68ba2013-04-06 20:28:37 +0200564 hci_conn_drop(conn->hcon);
Andrei Emeltchenko56f60982012-10-15 11:58:44 +0300565
566 if (mgr && mgr->bredr_chan == chan)
567 mgr->bredr_chan = NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200568 }
569
Andrei Emeltchenko419e08c2012-10-31 15:46:34 +0200570 if (chan->hs_hchan) {
571 struct hci_chan *hs_hchan = chan->hs_hchan;
572
573 BT_DBG("chan %p disconnect hs_hchan %p", chan, hs_hchan);
574 amp_disconnect_logical_link(hs_hchan);
575 }
576
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100577 chan->ops->teardown(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200578
Mat Martineau28270112012-05-17 21:14:09 -0700579 if (test_bit(CONF_NOT_COMPLETE, &chan->conf_state))
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300580 return;
Gustavo F. Padovan2ead70b2011-04-01 15:13:36 -0300581
Gustavo Padovanee556f62012-05-18 20:22:38 -0300582 switch(chan->mode) {
583 case L2CAP_MODE_BASIC:
584 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300585
Johan Hedberg38319712013-05-17 12:49:23 +0300586 case L2CAP_MODE_LE_FLOWCTL:
Johan Hedberg177f8f22013-05-31 17:54:51 +0300587 skb_queue_purge(&chan->tx_q);
Johan Hedberg38319712013-05-17 12:49:23 +0300588 break;
589
Gustavo Padovanee556f62012-05-18 20:22:38 -0300590 case L2CAP_MODE_ERTM:
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -0300591 __clear_retrans_timer(chan);
592 __clear_monitor_timer(chan);
593 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300594
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -0300595 skb_queue_purge(&chan->srej_q);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300596
Mat Martineau3c588192012-04-11 10:48:42 -0700597 l2cap_seq_list_free(&chan->srej_list);
598 l2cap_seq_list_free(&chan->retrans_list);
Gustavo Padovanee556f62012-05-18 20:22:38 -0300599
600 /* fall through */
601
602 case L2CAP_MODE_STREAMING:
603 skb_queue_purge(&chan->tx_q);
604 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300605 }
Gustavo Padovanee556f62012-05-18 20:22:38 -0300606
607 return;
Marcel Holtmann01394182006-07-03 10:02:46 +0200608}
609
Johan Hedberg27e2d4c2013-05-14 13:27:21 +0300610static void l2cap_chan_le_connect_reject(struct l2cap_chan *chan)
611{
612 struct l2cap_conn *conn = chan->conn;
613 struct l2cap_le_conn_rsp rsp;
614 u16 result;
615
616 if (test_bit(FLAG_DEFER_SETUP, &chan->flags))
617 result = L2CAP_CR_AUTHORIZATION;
618 else
619 result = L2CAP_CR_BAD_PSM;
620
621 l2cap_state_change(chan, BT_DISCONN);
622
623 rsp.dcid = cpu_to_le16(chan->scid);
624 rsp.mtu = cpu_to_le16(chan->imtu);
Johan Hedberg3916aed2013-10-07 15:35:26 +0200625 rsp.mps = cpu_to_le16(chan->mps);
Johan Hedberg0cd75f72013-05-17 13:09:05 +0300626 rsp.credits = cpu_to_le16(chan->rx_credits);
Johan Hedberg27e2d4c2013-05-14 13:27:21 +0300627 rsp.result = cpu_to_le16(result);
628
629 l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CONN_RSP, sizeof(rsp),
630 &rsp);
631}
632
Johan Hedberg791d60f2013-05-14 22:24:44 +0300633static void l2cap_chan_connect_reject(struct l2cap_chan *chan)
634{
635 struct l2cap_conn *conn = chan->conn;
636 struct l2cap_conn_rsp rsp;
637 u16 result;
638
639 if (test_bit(FLAG_DEFER_SETUP, &chan->flags))
640 result = L2CAP_CR_SEC_BLOCK;
641 else
642 result = L2CAP_CR_BAD_PSM;
643
644 l2cap_state_change(chan, BT_DISCONN);
645
646 rsp.scid = cpu_to_le16(chan->dcid);
647 rsp.dcid = cpu_to_le16(chan->scid);
648 rsp.result = cpu_to_le16(result);
649 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
650
651 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
652}
653
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300654void l2cap_chan_close(struct l2cap_chan *chan, int reason)
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300655{
656 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300657
Marcel Holtmann7eafc592013-10-13 08:12:47 -0700658 BT_DBG("chan %p state %s", chan, state_to_string(chan->state));
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300659
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300660 switch (chan->state) {
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300661 case BT_LISTEN:
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100662 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300663 break;
664
665 case BT_CONNECTED:
666 case BT_CONFIG:
Johan Hedbergcea04ce32013-05-14 22:46:01 +0300667 /* ATT uses L2CAP_CHAN_CONN_ORIENTED so we must also
668 * check for chan->psm.
669 */
670 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && chan->psm) {
Gustavo Padovan8d836d72013-10-15 19:24:47 -0300671 __set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +0200672 l2cap_send_disconn_req(chan, reason);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300673 } else
674 l2cap_chan_del(chan, reason);
675 break;
676
677 case BT_CONNECT2:
Johan Hedberg791d60f2013-05-14 22:24:44 +0300678 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED) {
679 if (conn->hcon->type == ACL_LINK)
680 l2cap_chan_connect_reject(chan);
Johan Hedberg27e2d4c2013-05-14 13:27:21 +0300681 else if (conn->hcon->type == LE_LINK)
682 l2cap_chan_le_connect_reject(chan);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300683 }
684
685 l2cap_chan_del(chan, reason);
686 break;
687
688 case BT_CONNECT:
689 case BT_DISCONN:
690 l2cap_chan_del(chan, reason);
691 break;
692
693 default:
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100694 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300695 break;
696 }
697}
698
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300699static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530700{
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700701 switch (chan->chan_type) {
702 case L2CAP_CHAN_RAW:
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300703 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530704 case BT_SECURITY_HIGH:
Marcel Holtmann7d513e92014-01-15 22:37:40 -0800705 case BT_SECURITY_FIPS:
Johan Hedberg8556edd32011-01-19 12:06:50 +0530706 return HCI_AT_DEDICATED_BONDING_MITM;
707 case BT_SECURITY_MEDIUM:
708 return HCI_AT_DEDICATED_BONDING;
709 default:
710 return HCI_AT_NO_BONDING;
711 }
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700712 break;
Marcel Holtmann3124b842013-10-12 07:19:32 -0700713 case L2CAP_CHAN_CONN_LESS:
714 if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_3DSP)) {
715 if (chan->sec_level == BT_SECURITY_LOW)
716 chan->sec_level = BT_SECURITY_SDP;
717 }
Marcel Holtmann7d513e92014-01-15 22:37:40 -0800718 if (chan->sec_level == BT_SECURITY_HIGH ||
719 chan->sec_level == BT_SECURITY_FIPS)
Marcel Holtmann3124b842013-10-12 07:19:32 -0700720 return HCI_AT_NO_BONDING_MITM;
721 else
722 return HCI_AT_NO_BONDING;
723 break;
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700724 case L2CAP_CHAN_CONN_ORIENTED:
725 if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_SDP)) {
726 if (chan->sec_level == BT_SECURITY_LOW)
727 chan->sec_level = BT_SECURITY_SDP;
Johan Hedberg8556edd32011-01-19 12:06:50 +0530728
Marcel Holtmann7d513e92014-01-15 22:37:40 -0800729 if (chan->sec_level == BT_SECURITY_HIGH ||
730 chan->sec_level == BT_SECURITY_FIPS)
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700731 return HCI_AT_NO_BONDING_MITM;
732 else
733 return HCI_AT_NO_BONDING;
734 }
735 /* fall through */
736 default:
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300737 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530738 case BT_SECURITY_HIGH:
Marcel Holtmann7d513e92014-01-15 22:37:40 -0800739 case BT_SECURITY_FIPS:
Johan Hedberg8556edd32011-01-19 12:06:50 +0530740 return HCI_AT_GENERAL_BONDING_MITM;
741 case BT_SECURITY_MEDIUM:
742 return HCI_AT_GENERAL_BONDING;
743 default:
744 return HCI_AT_NO_BONDING;
745 }
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700746 break;
Johan Hedberg8556edd32011-01-19 12:06:50 +0530747 }
748}
749
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200750/* Service level security */
Gustavo F. Padovand45fc422011-11-05 19:54:24 -0200751int l2cap_chan_check_security(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200752{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300753 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100754 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200755
Johan Hedberga17de2f2013-05-14 13:25:37 +0300756 if (conn->hcon->type == LE_LINK)
757 return smp_conn_security(conn->hcon, chan->sec_level);
758
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300759 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100760
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300761 return hci_conn_security(conn->hcon, chan->sec_level, auth_type);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200762}
763
Johannes Bergb5ad8b72011-06-01 08:54:45 +0200764static u8 l2cap_get_ident(struct l2cap_conn *conn)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200765{
766 u8 id;
767
768 /* Get next available identificator.
769 * 1 - 128 are used by kernel.
770 * 129 - 199 are reserved.
771 * 200 - 254 are used by utilities like l2ping, etc.
772 */
773
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200774 spin_lock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200775
776 if (++conn->tx_ident > 128)
777 conn->tx_ident = 1;
778
779 id = conn->tx_ident;
780
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200781 spin_unlock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200782
783 return id;
784}
785
Gustavo Padovan2d792812012-10-06 10:07:01 +0100786static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
787 void *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200788{
789 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200790 u8 flags;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200791
792 BT_DBG("code 0x%2.2x", code);
793
794 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300795 return;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200796
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200797 if (lmp_no_flush_capable(conn->hcon->hdev))
798 flags = ACL_START_NO_FLUSH;
799 else
800 flags = ACL_START;
801
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700802 bt_cb(skb)->force_active = BT_POWER_FORCE_ACTIVE_ON;
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +0200803 skb->priority = HCI_PRIO_MAX;
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700804
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200805 hci_send_acl(conn->hchan, skb, flags);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200806}
807
Mat Martineau02b0fbb2012-10-23 15:24:10 -0700808static bool __chan_is_moving(struct l2cap_chan *chan)
809{
810 return chan->move_state != L2CAP_MOVE_STABLE &&
811 chan->move_state != L2CAP_MOVE_WAIT_PREPARE;
812}
813
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200814static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb)
815{
816 struct hci_conn *hcon = chan->conn->hcon;
817 u16 flags;
818
819 BT_DBG("chan %p, skb %p len %d priority %u", chan, skb, skb->len,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100820 skb->priority);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200821
Mat Martineaud5f8a752012-10-23 15:24:18 -0700822 if (chan->hs_hcon && !__chan_is_moving(chan)) {
823 if (chan->hs_hchan)
824 hci_send_acl(chan->hs_hchan, skb, ACL_COMPLETE);
825 else
826 kfree_skb(skb);
827
828 return;
829 }
830
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200831 if (!test_bit(FLAG_FLUSHABLE, &chan->flags) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100832 lmp_no_flush_capable(hcon->hdev))
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200833 flags = ACL_START_NO_FLUSH;
834 else
835 flags = ACL_START;
836
837 bt_cb(skb)->force_active = test_bit(FLAG_FORCE_ACTIVE, &chan->flags);
838 hci_send_acl(chan->conn->hchan, skb, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700839}
840
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700841static void __unpack_enhanced_control(u16 enh, struct l2cap_ctrl *control)
842{
843 control->reqseq = (enh & L2CAP_CTRL_REQSEQ) >> L2CAP_CTRL_REQSEQ_SHIFT;
844 control->final = (enh & L2CAP_CTRL_FINAL) >> L2CAP_CTRL_FINAL_SHIFT;
845
846 if (enh & L2CAP_CTRL_FRAME_TYPE) {
847 /* S-Frame */
848 control->sframe = 1;
849 control->poll = (enh & L2CAP_CTRL_POLL) >> L2CAP_CTRL_POLL_SHIFT;
850 control->super = (enh & L2CAP_CTRL_SUPERVISE) >> L2CAP_CTRL_SUPER_SHIFT;
851
852 control->sar = 0;
853 control->txseq = 0;
854 } else {
855 /* I-Frame */
856 control->sframe = 0;
857 control->sar = (enh & L2CAP_CTRL_SAR) >> L2CAP_CTRL_SAR_SHIFT;
858 control->txseq = (enh & L2CAP_CTRL_TXSEQ) >> L2CAP_CTRL_TXSEQ_SHIFT;
859
860 control->poll = 0;
861 control->super = 0;
862 }
863}
864
865static void __unpack_extended_control(u32 ext, struct l2cap_ctrl *control)
866{
867 control->reqseq = (ext & L2CAP_EXT_CTRL_REQSEQ) >> L2CAP_EXT_CTRL_REQSEQ_SHIFT;
868 control->final = (ext & L2CAP_EXT_CTRL_FINAL) >> L2CAP_EXT_CTRL_FINAL_SHIFT;
869
870 if (ext & L2CAP_EXT_CTRL_FRAME_TYPE) {
871 /* S-Frame */
872 control->sframe = 1;
873 control->poll = (ext & L2CAP_EXT_CTRL_POLL) >> L2CAP_EXT_CTRL_POLL_SHIFT;
874 control->super = (ext & L2CAP_EXT_CTRL_SUPERVISE) >> L2CAP_EXT_CTRL_SUPER_SHIFT;
875
876 control->sar = 0;
877 control->txseq = 0;
878 } else {
879 /* I-Frame */
880 control->sframe = 0;
881 control->sar = (ext & L2CAP_EXT_CTRL_SAR) >> L2CAP_EXT_CTRL_SAR_SHIFT;
882 control->txseq = (ext & L2CAP_EXT_CTRL_TXSEQ) >> L2CAP_EXT_CTRL_TXSEQ_SHIFT;
883
884 control->poll = 0;
885 control->super = 0;
886 }
887}
888
889static inline void __unpack_control(struct l2cap_chan *chan,
890 struct sk_buff *skb)
891{
892 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
893 __unpack_extended_control(get_unaligned_le32(skb->data),
894 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700895 skb_pull(skb, L2CAP_EXT_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700896 } else {
897 __unpack_enhanced_control(get_unaligned_le16(skb->data),
898 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700899 skb_pull(skb, L2CAP_ENH_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700900 }
901}
902
903static u32 __pack_extended_control(struct l2cap_ctrl *control)
904{
905 u32 packed;
906
907 packed = control->reqseq << L2CAP_EXT_CTRL_REQSEQ_SHIFT;
908 packed |= control->final << L2CAP_EXT_CTRL_FINAL_SHIFT;
909
910 if (control->sframe) {
911 packed |= control->poll << L2CAP_EXT_CTRL_POLL_SHIFT;
912 packed |= control->super << L2CAP_EXT_CTRL_SUPER_SHIFT;
913 packed |= L2CAP_EXT_CTRL_FRAME_TYPE;
914 } else {
915 packed |= control->sar << L2CAP_EXT_CTRL_SAR_SHIFT;
916 packed |= control->txseq << L2CAP_EXT_CTRL_TXSEQ_SHIFT;
917 }
918
919 return packed;
920}
921
922static u16 __pack_enhanced_control(struct l2cap_ctrl *control)
923{
924 u16 packed;
925
926 packed = control->reqseq << L2CAP_CTRL_REQSEQ_SHIFT;
927 packed |= control->final << L2CAP_CTRL_FINAL_SHIFT;
928
929 if (control->sframe) {
930 packed |= control->poll << L2CAP_CTRL_POLL_SHIFT;
931 packed |= control->super << L2CAP_CTRL_SUPER_SHIFT;
932 packed |= L2CAP_CTRL_FRAME_TYPE;
933 } else {
934 packed |= control->sar << L2CAP_CTRL_SAR_SHIFT;
935 packed |= control->txseq << L2CAP_CTRL_TXSEQ_SHIFT;
936 }
937
938 return packed;
939}
940
941static inline void __pack_control(struct l2cap_chan *chan,
942 struct l2cap_ctrl *control,
943 struct sk_buff *skb)
944{
945 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
946 put_unaligned_le32(__pack_extended_control(control),
947 skb->data + L2CAP_HDR_SIZE);
948 } else {
949 put_unaligned_le16(__pack_enhanced_control(control),
950 skb->data + L2CAP_HDR_SIZE);
951 }
952}
953
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300954static inline unsigned int __ertm_hdr_size(struct l2cap_chan *chan)
955{
956 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
957 return L2CAP_EXT_HDR_SIZE;
958 else
959 return L2CAP_ENH_HDR_SIZE;
960}
961
Mat Martineaua67d7f62012-05-17 20:53:35 -0700962static struct sk_buff *l2cap_create_sframe_pdu(struct l2cap_chan *chan,
963 u32 control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300964{
965 struct sk_buff *skb;
966 struct l2cap_hdr *lh;
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300967 int hlen = __ertm_hdr_size(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300968
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300969 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300970 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300971
Mat Martineaua67d7f62012-05-17 20:53:35 -0700972 skb = bt_skb_alloc(hlen, GFP_KERNEL);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300973
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300974 if (!skb)
Mat Martineaua67d7f62012-05-17 20:53:35 -0700975 return ERR_PTR(-ENOMEM);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300976
977 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300978 lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300979 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +0300980
Mat Martineaua67d7f62012-05-17 20:53:35 -0700981 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
982 put_unaligned_le32(control, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
983 else
984 put_unaligned_le16(control, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300985
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -0300986 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineaua67d7f62012-05-17 20:53:35 -0700987 u16 fcs = crc16(0, (u8 *)skb->data, skb->len);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300988 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300989 }
990
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200991 skb->priority = HCI_PRIO_MAX;
Mat Martineaua67d7f62012-05-17 20:53:35 -0700992 return skb;
993}
994
995static void l2cap_send_sframe(struct l2cap_chan *chan,
996 struct l2cap_ctrl *control)
997{
998 struct sk_buff *skb;
999 u32 control_field;
1000
1001 BT_DBG("chan %p, control %p", chan, control);
1002
1003 if (!control->sframe)
1004 return;
1005
Mat Martineaub99e13a2012-10-23 15:24:19 -07001006 if (__chan_is_moving(chan))
1007 return;
1008
Mat Martineaua67d7f62012-05-17 20:53:35 -07001009 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state) &&
1010 !control->poll)
1011 control->final = 1;
1012
1013 if (control->super == L2CAP_SUPER_RR)
1014 clear_bit(CONN_RNR_SENT, &chan->conn_state);
1015 else if (control->super == L2CAP_SUPER_RNR)
1016 set_bit(CONN_RNR_SENT, &chan->conn_state);
1017
1018 if (control->super != L2CAP_SUPER_SREJ) {
1019 chan->last_acked_seq = control->reqseq;
1020 __clear_ack_timer(chan);
1021 }
1022
1023 BT_DBG("reqseq %d, final %d, poll %d, super %d", control->reqseq,
1024 control->final, control->poll, control->super);
1025
1026 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
1027 control_field = __pack_extended_control(control);
1028 else
1029 control_field = __pack_enhanced_control(control);
1030
1031 skb = l2cap_create_sframe_pdu(chan, control_field);
1032 if (!IS_ERR(skb))
1033 l2cap_do_send(chan, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001034}
1035
Mat Martineauc9e3d5e2012-05-17 20:53:48 -07001036static void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, bool poll)
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001037{
Mat Martineauc9e3d5e2012-05-17 20:53:48 -07001038 struct l2cap_ctrl control;
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001039
Mat Martineauc9e3d5e2012-05-17 20:53:48 -07001040 BT_DBG("chan %p, poll %d", chan, poll);
1041
1042 memset(&control, 0, sizeof(control));
1043 control.sframe = 1;
1044 control.poll = poll;
1045
1046 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
1047 control.super = L2CAP_SUPER_RNR;
1048 else
1049 control.super = L2CAP_SUPER_RR;
1050
1051 control.reqseq = chan->buffer_seq;
1052 l2cap_send_sframe(chan, &control);
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001053}
1054
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03001055static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan)
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03001056{
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001057 return !test_bit(CONF_CONNECT_PEND, &chan->conf_state);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03001058}
1059
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001060static bool __amp_capable(struct l2cap_chan *chan)
1061{
1062 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann1df7b172013-10-05 11:47:49 -07001063 struct hci_dev *hdev;
1064 bool amp_available = false;
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001065
Marcel Holtmann1df7b172013-10-05 11:47:49 -07001066 if (!conn->hs_enabled)
1067 return false;
1068
1069 if (!(conn->fixed_chan_mask & L2CAP_FC_A2MP))
1070 return false;
1071
1072 read_lock(&hci_dev_list_lock);
1073 list_for_each_entry(hdev, &hci_dev_list, list) {
1074 if (hdev->amp_type != AMP_TYPE_BREDR &&
1075 test_bit(HCI_UP, &hdev->flags)) {
1076 amp_available = true;
1077 break;
1078 }
1079 }
1080 read_unlock(&hci_dev_list_lock);
1081
1082 if (chan->chan_policy == BT_CHANNEL_POLICY_AMP_PREFERRED)
1083 return amp_available;
Marcel Holtmann848566b2013-10-01 22:59:22 -07001084
1085 return false;
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001086}
1087
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +02001088static bool l2cap_check_efs(struct l2cap_chan *chan)
1089{
1090 /* Check EFS parameters */
1091 return true;
1092}
1093
Andrei Emeltchenko2766be42012-09-27 17:26:21 +03001094void l2cap_send_conn_req(struct l2cap_chan *chan)
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +02001095{
1096 struct l2cap_conn *conn = chan->conn;
1097 struct l2cap_conn_req req;
1098
1099 req.scid = cpu_to_le16(chan->scid);
1100 req.psm = chan->psm;
1101
1102 chan->ident = l2cap_get_ident(conn);
1103
1104 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
1105
1106 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, sizeof(req), &req);
1107}
1108
Mat Martineau8eb200b2012-10-23 15:24:17 -07001109static void l2cap_send_create_chan_req(struct l2cap_chan *chan, u8 amp_id)
1110{
1111 struct l2cap_create_chan_req req;
1112 req.scid = cpu_to_le16(chan->scid);
1113 req.psm = chan->psm;
1114 req.amp_id = amp_id;
1115
1116 chan->ident = l2cap_get_ident(chan->conn);
1117
1118 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_REQ,
1119 sizeof(req), &req);
1120}
1121
Mat Martineau02b0fbb2012-10-23 15:24:10 -07001122static void l2cap_move_setup(struct l2cap_chan *chan)
1123{
1124 struct sk_buff *skb;
1125
1126 BT_DBG("chan %p", chan);
1127
1128 if (chan->mode != L2CAP_MODE_ERTM)
1129 return;
1130
1131 __clear_retrans_timer(chan);
1132 __clear_monitor_timer(chan);
1133 __clear_ack_timer(chan);
1134
1135 chan->retry_count = 0;
1136 skb_queue_walk(&chan->tx_q, skb) {
1137 if (bt_cb(skb)->control.retries)
1138 bt_cb(skb)->control.retries = 1;
1139 else
1140 break;
1141 }
1142
1143 chan->expected_tx_seq = chan->buffer_seq;
1144
1145 clear_bit(CONN_REJ_ACT, &chan->conn_state);
1146 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
1147 l2cap_seq_list_clear(&chan->retrans_list);
1148 l2cap_seq_list_clear(&chan->srej_list);
1149 skb_queue_purge(&chan->srej_q);
1150
1151 chan->tx_state = L2CAP_TX_STATE_XMIT;
1152 chan->rx_state = L2CAP_RX_STATE_MOVE;
1153
1154 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
1155}
1156
Mat Martineau5f3847a2012-10-23 15:24:12 -07001157static void l2cap_move_done(struct l2cap_chan *chan)
1158{
1159 u8 move_role = chan->move_role;
1160 BT_DBG("chan %p", chan);
1161
1162 chan->move_state = L2CAP_MOVE_STABLE;
1163 chan->move_role = L2CAP_MOVE_ROLE_NONE;
1164
1165 if (chan->mode != L2CAP_MODE_ERTM)
1166 return;
1167
1168 switch (move_role) {
1169 case L2CAP_MOVE_ROLE_INITIATOR:
1170 l2cap_tx(chan, NULL, NULL, L2CAP_EV_EXPLICIT_POLL);
1171 chan->rx_state = L2CAP_RX_STATE_WAIT_F;
1172 break;
1173 case L2CAP_MOVE_ROLE_RESPONDER:
1174 chan->rx_state = L2CAP_RX_STATE_WAIT_P;
1175 break;
1176 }
1177}
1178
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001179static void l2cap_chan_ready(struct l2cap_chan *chan)
1180{
Mat Martineau28270112012-05-17 21:14:09 -07001181 /* This clears all conf flags, including CONF_NOT_COMPLETE */
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001182 chan->conf_state = 0;
1183 __clear_chan_timer(chan);
1184
Johan Hedberg0ce43ce2013-12-05 14:55:33 +02001185 if (chan->mode == L2CAP_MODE_LE_FLOWCTL && !chan->tx_credits)
1186 chan->ops->suspend(chan);
Johan Hedberg177f8f22013-05-31 17:54:51 +03001187
Andrei Emeltchenko54a59aa2012-05-27 22:27:53 -03001188 chan->state = BT_CONNECTED;
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001189
Andrei Emeltchenkofd83e2c2012-05-30 09:55:32 +03001190 chan->ops->ready(chan);
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001191}
1192
Johan Hedbergf1496de2013-05-13 14:15:56 +03001193static void l2cap_le_connect(struct l2cap_chan *chan)
1194{
1195 struct l2cap_conn *conn = chan->conn;
1196 struct l2cap_le_conn_req req;
1197
Johan Hedberg595177f2013-12-02 22:12:22 +02001198 if (test_and_set_bit(FLAG_LE_CONN_REQ_SENT, &chan->flags))
1199 return;
1200
Johan Hedbergf1496de2013-05-13 14:15:56 +03001201 req.psm = chan->psm;
1202 req.scid = cpu_to_le16(chan->scid);
1203 req.mtu = cpu_to_le16(chan->imtu);
Johan Hedberg3916aed2013-10-07 15:35:26 +02001204 req.mps = cpu_to_le16(chan->mps);
Johan Hedberg0cd75f72013-05-17 13:09:05 +03001205 req.credits = cpu_to_le16(chan->rx_credits);
Johan Hedbergf1496de2013-05-13 14:15:56 +03001206
1207 chan->ident = l2cap_get_ident(conn);
1208
1209 l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CONN_REQ,
1210 sizeof(req), &req);
1211}
1212
1213static void l2cap_le_start(struct l2cap_chan *chan)
1214{
1215 struct l2cap_conn *conn = chan->conn;
1216
1217 if (!smp_conn_security(conn->hcon, chan->sec_level))
1218 return;
1219
1220 if (!chan->psm) {
1221 l2cap_chan_ready(chan);
1222 return;
1223 }
1224
1225 if (chan->state == BT_CONNECT)
1226 l2cap_le_connect(chan);
1227}
1228
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001229static void l2cap_start_connection(struct l2cap_chan *chan)
1230{
1231 if (__amp_capable(chan)) {
1232 BT_DBG("chan %p AMP capable: discover AMPs", chan);
1233 a2mp_discover_amp(chan);
Johan Hedbergf1496de2013-05-13 14:15:56 +03001234 } else if (chan->conn->hcon->type == LE_LINK) {
1235 l2cap_le_start(chan);
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001236 } else {
1237 l2cap_send_conn_req(chan);
1238 }
1239}
1240
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001241static void l2cap_do_start(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001242{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001243 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001244
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001245 if (conn->hcon->type == LE_LINK) {
Johan Hedberg96ac34f2013-05-13 11:15:07 +03001246 l2cap_le_start(chan);
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001247 return;
1248 }
1249
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001250 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01001251 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
1252 return;
1253
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001254 if (l2cap_chan_check_security(chan) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01001255 __l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001256 l2cap_start_connection(chan);
1257 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001258 } else {
1259 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001260 req.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001261
1262 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
1263 conn->info_ident = l2cap_get_ident(conn);
1264
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08001265 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001266
Gustavo Padovan2d792812012-10-06 10:07:01 +01001267 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
1268 sizeof(req), &req);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001269 }
1270}
1271
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001272static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
1273{
1274 u32 local_feat_mask = l2cap_feat_mask;
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03001275 if (!disable_ertm)
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001276 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
1277
1278 switch (mode) {
1279 case L2CAP_MODE_ERTM:
1280 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
1281 case L2CAP_MODE_STREAMING:
1282 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
1283 default:
1284 return 0x00;
1285 }
1286}
1287
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02001288static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err)
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001289{
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02001290 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001291 struct l2cap_disconn_req req;
1292
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001293 if (!conn)
1294 return;
1295
Andrei Emeltchenkoaad3d0e2012-09-06 15:05:42 +03001296 if (chan->mode == L2CAP_MODE_ERTM && chan->state == BT_CONNECTED) {
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03001297 __clear_retrans_timer(chan);
1298 __clear_monitor_timer(chan);
1299 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001300 }
1301
Johan Hedberg2338a7e2014-01-24 10:35:40 +02001302 if (chan->scid == L2CAP_CID_A2MP) {
Gustavo Padovand1177732012-10-06 11:47:38 +01001303 l2cap_state_change(chan, BT_DISCONN);
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001304 return;
1305 }
1306
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001307 req.dcid = cpu_to_le16(chan->dcid);
1308 req.scid = cpu_to_le16(chan->scid);
Gustavo Padovan2d792812012-10-06 10:07:01 +01001309 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_DISCONN_REQ,
1310 sizeof(req), &req);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001311
Gustavo Padovanf8e73012013-10-15 19:24:46 -03001312 l2cap_state_change_and_error(chan, BT_DISCONN, err);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001313}
1314
Linus Torvalds1da177e2005-04-16 15:20:36 -07001315/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001316static void l2cap_conn_start(struct l2cap_conn *conn)
1317{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001318 struct l2cap_chan *chan, *tmp;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001319
1320 BT_DBG("conn %p", conn);
1321
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001322 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001323
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001324 list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001325 l2cap_chan_lock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001326
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001327 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001328 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001329 continue;
1330 }
1331
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001332 if (chan->state == BT_CONNECT) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001333 if (!l2cap_chan_check_security(chan) ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001334 !__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001335 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001336 continue;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02001337 }
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001338
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001339 if (!l2cap_mode_supported(chan->mode, conn->feat_mask)
Gustavo Padovan2d792812012-10-06 10:07:01 +01001340 && test_bit(CONF_STATE2_DEVICE,
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001341 &chan->conf_state)) {
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001342 l2cap_chan_close(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001343 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001344 continue;
1345 }
1346
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001347 l2cap_start_connection(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001348
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001349 } else if (chan->state == BT_CONNECT2) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001350 struct l2cap_conn_rsp rsp;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001351 char buf[128];
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001352 rsp.scid = cpu_to_le16(chan->dcid);
1353 rsp.dcid = cpu_to_le16(chan->scid);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001354
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001355 if (l2cap_chan_check_security(chan)) {
Marcel Holtmannbdc25782013-10-14 02:45:34 -07001356 if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001357 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1358 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08001359 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001360
1361 } else {
Gustavo Padovanacdcabf2013-10-21 14:21:39 -02001362 l2cap_state_change(chan, BT_CONFIG);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001363 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
1364 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001365 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001366 } else {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001367 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1368 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001369 }
1370
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001371 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001372 sizeof(rsp), &rsp);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001373
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001374 if (test_bit(CONF_REQ_SENT, &chan->conf_state) ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001375 rsp.result != L2CAP_CR_SUCCESS) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001376 l2cap_chan_unlock(chan);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001377 continue;
1378 }
1379
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001380 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001381 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001382 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03001383 chan->num_conf_req++;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001384 }
1385
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001386 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001387 }
1388
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001389 mutex_unlock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001390}
1391
Ido Yarivc2287682012-04-20 15:46:07 -03001392/* Find socket with cid and source/destination bdaddr.
Ville Tervob62f3282011-02-10 22:38:50 -03001393 * Returns closest match, locked.
1394 */
Andrei Emeltchenkod9b88702012-03-12 12:13:08 +02001395static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid,
Ido Yarivc2287682012-04-20 15:46:07 -03001396 bdaddr_t *src,
1397 bdaddr_t *dst)
Ville Tervob62f3282011-02-10 22:38:50 -03001398{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001399 struct l2cap_chan *c, *c1 = NULL;
Ville Tervob62f3282011-02-10 22:38:50 -03001400
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001401 read_lock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001402
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001403 list_for_each_entry(c, &chan_list, global_l) {
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001404 if (state && c->state != state)
Ville Tervob62f3282011-02-10 22:38:50 -03001405 continue;
1406
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001407 if (c->scid == cid) {
Ido Yarivc2287682012-04-20 15:46:07 -03001408 int src_match, dst_match;
1409 int src_any, dst_any;
1410
Ville Tervob62f3282011-02-10 22:38:50 -03001411 /* Exact match. */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001412 src_match = !bacmp(&c->src, src);
1413 dst_match = !bacmp(&c->dst, dst);
Ido Yarivc2287682012-04-20 15:46:07 -03001414 if (src_match && dst_match) {
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001415 read_unlock(&chan_list_lock);
1416 return c;
1417 }
Ville Tervob62f3282011-02-10 22:38:50 -03001418
1419 /* Closest match */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001420 src_any = !bacmp(&c->src, BDADDR_ANY);
1421 dst_any = !bacmp(&c->dst, BDADDR_ANY);
Ido Yarivc2287682012-04-20 15:46:07 -03001422 if ((src_match && dst_any) || (src_any && dst_match) ||
1423 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001424 c1 = c;
Ville Tervob62f3282011-02-10 22:38:50 -03001425 }
1426 }
Gustavo F. Padovan280f2942011-04-13 19:01:22 -03001427
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001428 read_unlock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001429
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001430 return c1;
Ville Tervob62f3282011-02-10 22:38:50 -03001431}
1432
1433static void l2cap_le_conn_ready(struct l2cap_conn *conn)
1434{
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001435 struct hci_conn *hcon = conn->hcon;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001436 struct l2cap_chan *chan, *pchan;
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001437 u8 dst_type;
Ville Tervob62f3282011-02-10 22:38:50 -03001438
1439 BT_DBG("");
1440
Jukka Rissanen18722c22013-12-11 17:05:37 +02001441 bt_6lowpan_add_conn(conn);
1442
Ville Tervob62f3282011-02-10 22:38:50 -03001443 /* Check if we have socket listening on cid */
Johan Hedberg073d1cf2013-04-29 19:35:35 +03001444 pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_ATT,
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001445 &hcon->src, &hcon->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001446 if (!pchan)
Ville Tervob62f3282011-02-10 22:38:50 -03001447 return;
1448
Johan Hedberg44f3b0f2013-04-29 19:35:45 +03001449 /* Client ATT sockets should override the server one */
1450 if (__l2cap_get_chan_by_dcid(conn, L2CAP_CID_ATT))
1451 return;
1452
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001453 dst_type = bdaddr_type(hcon, hcon->dst_type);
1454
1455 /* If device is blocked, do not create a channel for it */
1456 if (hci_blacklist_lookup(hcon->hdev, &hcon->dst, dst_type))
1457 return;
1458
Gustavo Padovan8ffb9292013-10-21 14:21:41 -02001459 l2cap_chan_lock(pchan);
Gustavo F. Padovan62f3a2c2011-04-14 18:34:34 -03001460
Gustavo Padovan80b98022012-05-27 22:27:51 -03001461 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001462 if (!chan)
Ville Tervob62f3282011-02-10 22:38:50 -03001463 goto clean;
1464
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001465 bacpy(&chan->src, &hcon->src);
1466 bacpy(&chan->dst, &hcon->dst);
1467 chan->src_type = bdaddr_type(hcon, hcon->src_type);
1468 chan->dst_type = dst_type;
Ville Tervob62f3282011-02-10 22:38:50 -03001469
Johan Hedberg44f3b0f2013-04-29 19:35:45 +03001470 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001471
Ville Tervob62f3282011-02-10 22:38:50 -03001472clean:
Gustavo Padovan8ffb9292013-10-21 14:21:41 -02001473 l2cap_chan_unlock(pchan);
Ville Tervob62f3282011-02-10 22:38:50 -03001474}
1475
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001476static void l2cap_conn_ready(struct l2cap_conn *conn)
1477{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001478 struct l2cap_chan *chan;
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001479 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001480
1481 BT_DBG("conn %p", conn);
1482
Johan Hedbergd8729922013-04-29 19:35:39 +03001483 /* For outgoing pairing which doesn't necessarily have an
1484 * associated socket (e.g. mgmt_pair_device).
1485 */
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001486 if (hcon->out && hcon->type == LE_LINK)
1487 smp_conn_security(hcon, hcon->pending_sec_level);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03001488
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001489 mutex_lock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001490
Johan Hedberg44f3b0f2013-04-29 19:35:45 +03001491 if (hcon->type == LE_LINK)
1492 l2cap_le_conn_ready(conn);
1493
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001494 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001495
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001496 l2cap_chan_lock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001497
Johan Hedberg2338a7e2014-01-24 10:35:40 +02001498 if (chan->scid == L2CAP_CID_A2MP) {
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001499 l2cap_chan_unlock(chan);
1500 continue;
1501 }
1502
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001503 if (hcon->type == LE_LINK) {
Johan Hedbergf1496de2013-05-13 14:15:56 +03001504 l2cap_le_start(chan);
Vinicius Costa Gomes63128452011-06-17 22:46:26 -03001505 } else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Gustavo Padovan74e75742013-10-15 19:24:51 -03001506 l2cap_chan_ready(chan);
Anderson Brigliab501d6a2011-06-07 18:46:31 -03001507
Gustavo Padovan1c244f72012-12-07 03:29:10 -02001508 } else if (chan->state == BT_CONNECT) {
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001509 l2cap_do_start(chan);
Gustavo Padovan1c244f72012-12-07 03:29:10 -02001510 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001511
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001512 l2cap_chan_unlock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001513 }
1514
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001515 mutex_unlock(&conn->chan_lock);
Johan Hedberg61a939c2014-01-17 20:45:11 +02001516
1517 queue_work(hcon->hdev->workqueue, &conn->pending_rx_work);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001518}
1519
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001520/* Notify sockets that we cannot guaranty reliability anymore */
1521static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
1522{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001523 struct l2cap_chan *chan;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001524
1525 BT_DBG("conn %p", conn);
1526
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001527 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001528
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001529 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenkoecf61bd2011-10-11 14:04:32 +03001530 if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags))
Gustavo Padovan1d8b1fd2012-10-06 11:34:52 +01001531 l2cap_chan_set_err(chan, err);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001532 }
1533
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001534 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001535}
1536
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001537static void l2cap_info_timeout(struct work_struct *work)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001538{
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001539 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001540 info_timer.work);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001541
Marcel Holtmann984947d2009-02-06 23:35:19 +01001542 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01001543 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01001544
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001545 l2cap_conn_start(conn);
1546}
1547
David Herrmann2c8e1412013-04-06 20:28:45 +02001548/*
1549 * l2cap_user
1550 * External modules can register l2cap_user objects on l2cap_conn. The ->probe
1551 * callback is called during registration. The ->remove callback is called
1552 * during unregistration.
1553 * An l2cap_user object can either be explicitly unregistered or when the
1554 * underlying l2cap_conn object is deleted. This guarantees that l2cap->hcon,
1555 * l2cap->hchan, .. are valid as long as the remove callback hasn't been called.
1556 * External modules must own a reference to the l2cap_conn object if they intend
1557 * to call l2cap_unregister_user(). The l2cap_conn object might get destroyed at
1558 * any time if they don't.
1559 */
1560
1561int l2cap_register_user(struct l2cap_conn *conn, struct l2cap_user *user)
1562{
1563 struct hci_dev *hdev = conn->hcon->hdev;
1564 int ret;
1565
1566 /* We need to check whether l2cap_conn is registered. If it is not, we
1567 * must not register the l2cap_user. l2cap_conn_del() is unregisters
1568 * l2cap_conn objects, but doesn't provide its own locking. Instead, it
1569 * relies on the parent hci_conn object to be locked. This itself relies
1570 * on the hci_dev object to be locked. So we must lock the hci device
1571 * here, too. */
1572
1573 hci_dev_lock(hdev);
1574
1575 if (user->list.next || user->list.prev) {
1576 ret = -EINVAL;
1577 goto out_unlock;
1578 }
1579
1580 /* conn->hchan is NULL after l2cap_conn_del() was called */
1581 if (!conn->hchan) {
1582 ret = -ENODEV;
1583 goto out_unlock;
1584 }
1585
1586 ret = user->probe(conn, user);
1587 if (ret)
1588 goto out_unlock;
1589
1590 list_add(&user->list, &conn->users);
1591 ret = 0;
1592
1593out_unlock:
1594 hci_dev_unlock(hdev);
1595 return ret;
1596}
1597EXPORT_SYMBOL(l2cap_register_user);
1598
1599void l2cap_unregister_user(struct l2cap_conn *conn, struct l2cap_user *user)
1600{
1601 struct hci_dev *hdev = conn->hcon->hdev;
1602
1603 hci_dev_lock(hdev);
1604
1605 if (!user->list.next || !user->list.prev)
1606 goto out_unlock;
1607
1608 list_del(&user->list);
1609 user->list.next = NULL;
1610 user->list.prev = NULL;
1611 user->remove(conn, user);
1612
1613out_unlock:
1614 hci_dev_unlock(hdev);
1615}
1616EXPORT_SYMBOL(l2cap_unregister_user);
1617
1618static void l2cap_unregister_all_users(struct l2cap_conn *conn)
1619{
1620 struct l2cap_user *user;
1621
1622 while (!list_empty(&conn->users)) {
1623 user = list_first_entry(&conn->users, struct l2cap_user, list);
1624 list_del(&user->list);
1625 user->list.next = NULL;
1626 user->list.prev = NULL;
1627 user->remove(conn, user);
1628 }
1629}
1630
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001631static void l2cap_conn_del(struct hci_conn *hcon, int err)
1632{
1633 struct l2cap_conn *conn = hcon->l2cap_data;
1634 struct l2cap_chan *chan, *l;
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001635
1636 if (!conn)
1637 return;
1638
1639 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
1640
1641 kfree_skb(conn->rx_skb);
1642
Johan Hedberg61a939c2014-01-17 20:45:11 +02001643 skb_queue_purge(&conn->pending_rx);
1644 flush_work(&conn->pending_rx_work);
1645
David Herrmann2c8e1412013-04-06 20:28:45 +02001646 l2cap_unregister_all_users(conn);
1647
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001648 mutex_lock(&conn->chan_lock);
1649
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001650 /* Kill channels */
1651 list_for_each_entry_safe(chan, l, &conn->chan_l, list) {
Mat Martineau61d6ef32012-04-27 16:50:50 -07001652 l2cap_chan_hold(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001653 l2cap_chan_lock(chan);
1654
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001655 l2cap_chan_del(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001656
1657 l2cap_chan_unlock(chan);
1658
Gustavo Padovan80b98022012-05-27 22:27:51 -03001659 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07001660 l2cap_chan_put(chan);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001661 }
1662
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001663 mutex_unlock(&conn->chan_lock);
1664
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001665 hci_chan_del(conn->hchan);
1666
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001667 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
Ulisses Furquim127074b2012-01-30 18:26:29 -02001668 cancel_delayed_work_sync(&conn->info_timer);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001669
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001670 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) {
Ulisses Furquim127074b2012-01-30 18:26:29 -02001671 cancel_delayed_work_sync(&conn->security_timer);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -03001672 smp_chan_destroy(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001673 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001674
1675 hcon->l2cap_data = NULL;
David Herrmann9c903e32013-04-06 20:28:44 +02001676 conn->hchan = NULL;
1677 l2cap_conn_put(conn);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001678}
1679
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001680static void security_timeout(struct work_struct *work)
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001681{
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001682 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001683 security_timer.work);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001684
Johan Hedbergd06cc412012-06-06 18:44:11 +08001685 BT_DBG("conn %p", conn);
1686
1687 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) {
1688 smp_chan_destroy(conn);
1689 l2cap_conn_del(conn->hcon, ETIMEDOUT);
1690 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001691}
1692
David Herrmann9c903e32013-04-06 20:28:44 +02001693static void l2cap_conn_free(struct kref *ref)
1694{
1695 struct l2cap_conn *conn = container_of(ref, struct l2cap_conn, ref);
1696
1697 hci_conn_put(conn->hcon);
1698 kfree(conn);
1699}
1700
1701void l2cap_conn_get(struct l2cap_conn *conn)
1702{
1703 kref_get(&conn->ref);
1704}
1705EXPORT_SYMBOL(l2cap_conn_get);
1706
1707void l2cap_conn_put(struct l2cap_conn *conn)
1708{
1709 kref_put(&conn->ref, l2cap_conn_free);
1710}
1711EXPORT_SYMBOL(l2cap_conn_put);
1712
Linus Torvalds1da177e2005-04-16 15:20:36 -07001713/* ---- Socket interface ---- */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001714
Ido Yarivc2287682012-04-20 15:46:07 -03001715/* Find socket with psm and source / destination bdaddr.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001716 * Returns closest match.
1717 */
Ido Yarivc2287682012-04-20 15:46:07 -03001718static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
1719 bdaddr_t *src,
Johan Hedbergbf20fd42013-05-14 13:23:13 +03001720 bdaddr_t *dst,
1721 u8 link_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001722{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001723 struct l2cap_chan *c, *c1 = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001724
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001725 read_lock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001726
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001727 list_for_each_entry(c, &chan_list, global_l) {
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001728 if (state && c->state != state)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001729 continue;
1730
Johan Hedbergbf20fd42013-05-14 13:23:13 +03001731 if (link_type == ACL_LINK && c->src_type != BDADDR_BREDR)
1732 continue;
1733
1734 if (link_type == LE_LINK && c->src_type == BDADDR_BREDR)
1735 continue;
1736
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001737 if (c->psm == psm) {
Ido Yarivc2287682012-04-20 15:46:07 -03001738 int src_match, dst_match;
1739 int src_any, dst_any;
1740
Linus Torvalds1da177e2005-04-16 15:20:36 -07001741 /* Exact match. */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001742 src_match = !bacmp(&c->src, src);
1743 dst_match = !bacmp(&c->dst, dst);
Ido Yarivc2287682012-04-20 15:46:07 -03001744 if (src_match && dst_match) {
Johannes Berga7567b22011-06-01 08:29:54 +02001745 read_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001746 return c;
1747 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001748
1749 /* Closest match */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001750 src_any = !bacmp(&c->src, BDADDR_ANY);
1751 dst_any = !bacmp(&c->dst, BDADDR_ANY);
Ido Yarivc2287682012-04-20 15:46:07 -03001752 if ((src_match && dst_any) || (src_any && dst_match) ||
1753 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001754 c1 = c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001755 }
1756 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001757
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001758 read_unlock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001759
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001760 return c1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001761}
1762
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001763static void l2cap_monitor_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001764{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001765 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001766 monitor_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001767
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03001768 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001769
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001770 l2cap_chan_lock(chan);
1771
Mat Martineau80909e02012-05-17 20:53:50 -07001772 if (!chan->conn) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001773 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001774 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001775 return;
1776 }
1777
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001778 l2cap_tx(chan, NULL, NULL, L2CAP_EV_MONITOR_TO);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001779
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001780 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001781 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001782}
1783
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001784static void l2cap_retrans_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001785{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001786 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001787 retrans_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001788
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03001789 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001790
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001791 l2cap_chan_lock(chan);
1792
Mat Martineau80909e02012-05-17 20:53:50 -07001793 if (!chan->conn) {
1794 l2cap_chan_unlock(chan);
1795 l2cap_chan_put(chan);
1796 return;
1797 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001798
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001799 l2cap_tx(chan, NULL, NULL, L2CAP_EV_RETRANS_TO);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001800 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001801 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001802}
1803
Gustavo Padovand6603662012-05-21 13:58:22 -03001804static void l2cap_streaming_send(struct l2cap_chan *chan,
1805 struct sk_buff_head *skbs)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001806{
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001807 struct sk_buff *skb;
Mat Martineau37339372012-05-17 20:53:33 -07001808 struct l2cap_ctrl *control;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001809
Mat Martineau37339372012-05-17 20:53:33 -07001810 BT_DBG("chan %p, skbs %p", chan, skbs);
1811
Mat Martineaub99e13a2012-10-23 15:24:19 -07001812 if (__chan_is_moving(chan))
1813 return;
1814
Mat Martineau37339372012-05-17 20:53:33 -07001815 skb_queue_splice_tail_init(skbs, &chan->tx_q);
1816
1817 while (!skb_queue_empty(&chan->tx_q)) {
1818
1819 skb = skb_dequeue(&chan->tx_q);
1820
1821 bt_cb(skb)->control.retries = 1;
1822 control = &bt_cb(skb)->control;
1823
1824 control->reqseq = 0;
1825 control->txseq = chan->next_tx_seq;
1826
1827 __pack_control(chan, control, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001828
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001829 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau37339372012-05-17 20:53:33 -07001830 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
1831 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001832 }
1833
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001834 l2cap_do_send(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001835
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001836 BT_DBG("Sent txseq %u", control->txseq);
Mat Martineau37339372012-05-17 20:53:33 -07001837
Andrei Emeltchenko836be932011-10-17 12:19:57 +03001838 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau37339372012-05-17 20:53:33 -07001839 chan->frames_sent++;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001840 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001841}
1842
Szymon Janc67c9e842011-07-28 16:24:33 +02001843static int l2cap_ertm_send(struct l2cap_chan *chan)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001844{
1845 struct sk_buff *skb, *tx_skb;
Mat Martineau18a48e72012-05-17 20:53:34 -07001846 struct l2cap_ctrl *control;
1847 int sent = 0;
1848
1849 BT_DBG("chan %p", chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001850
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001851 if (chan->state != BT_CONNECTED)
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001852 return -ENOTCONN;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001853
Mat Martineau94122bb2012-05-02 09:42:02 -07001854 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1855 return 0;
1856
Mat Martineaub99e13a2012-10-23 15:24:19 -07001857 if (__chan_is_moving(chan))
1858 return 0;
1859
Mat Martineau18a48e72012-05-17 20:53:34 -07001860 while (chan->tx_send_head &&
1861 chan->unacked_frames < chan->remote_tx_win &&
1862 chan->tx_state == L2CAP_TX_STATE_XMIT) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001863
Mat Martineau18a48e72012-05-17 20:53:34 -07001864 skb = chan->tx_send_head;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001865
Mat Martineau18a48e72012-05-17 20:53:34 -07001866 bt_cb(skb)->control.retries = 1;
1867 control = &bt_cb(skb)->control;
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03001868
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03001869 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
Mat Martineau18a48e72012-05-17 20:53:34 -07001870 control->final = 1;
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03001871
Mat Martineau18a48e72012-05-17 20:53:34 -07001872 control->reqseq = chan->buffer_seq;
1873 chan->last_acked_seq = chan->buffer_seq;
1874 control->txseq = chan->next_tx_seq;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001875
Mat Martineau18a48e72012-05-17 20:53:34 -07001876 __pack_control(chan, control, skb);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001877
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001878 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau18a48e72012-05-17 20:53:34 -07001879 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
1880 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001881 }
1882
Mat Martineau18a48e72012-05-17 20:53:34 -07001883 /* Clone after data has been modified. Data is assumed to be
1884 read-only (for locking purposes) on cloned sk_buffs.
1885 */
1886 tx_skb = skb_clone(skb, GFP_KERNEL);
1887
1888 if (!tx_skb)
1889 break;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001890
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03001891 __set_retrans_timer(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001892
Andrei Emeltchenko836be932011-10-17 12:19:57 +03001893 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau18a48e72012-05-17 20:53:34 -07001894 chan->unacked_frames++;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03001895 chan->frames_sent++;
Mat Martineau18a48e72012-05-17 20:53:34 -07001896 sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001897
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03001898 if (skb_queue_is_last(&chan->tx_q, skb))
1899 chan->tx_send_head = NULL;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001900 else
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03001901 chan->tx_send_head = skb_queue_next(&chan->tx_q, skb);
Mat Martineau18a48e72012-05-17 20:53:34 -07001902
1903 l2cap_do_send(chan, tx_skb);
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001904 BT_DBG("Sent txseq %u", control->txseq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001905 }
1906
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001907 BT_DBG("Sent %d, %u unacked, %u in ERTM queue", sent,
1908 chan->unacked_frames, skb_queue_len(&chan->tx_q));
Mat Martineau18a48e72012-05-17 20:53:34 -07001909
1910 return sent;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001911}
1912
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001913static void l2cap_ertm_resend(struct l2cap_chan *chan)
1914{
1915 struct l2cap_ctrl control;
1916 struct sk_buff *skb;
1917 struct sk_buff *tx_skb;
1918 u16 seq;
1919
1920 BT_DBG("chan %p", chan);
1921
1922 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1923 return;
1924
Mat Martineaub99e13a2012-10-23 15:24:19 -07001925 if (__chan_is_moving(chan))
1926 return;
1927
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001928 while (chan->retrans_list.head != L2CAP_SEQ_LIST_CLEAR) {
1929 seq = l2cap_seq_list_pop(&chan->retrans_list);
1930
1931 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, seq);
1932 if (!skb) {
1933 BT_DBG("Error: Can't retransmit seq %d, frame missing",
Gustavo Padovan2d792812012-10-06 10:07:01 +01001934 seq);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001935 continue;
1936 }
1937
1938 bt_cb(skb)->control.retries++;
1939 control = bt_cb(skb)->control;
1940
1941 if (chan->max_tx != 0 &&
1942 bt_cb(skb)->control.retries > chan->max_tx) {
1943 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02001944 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001945 l2cap_seq_list_clear(&chan->retrans_list);
1946 break;
1947 }
1948
1949 control.reqseq = chan->buffer_seq;
1950 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
1951 control.final = 1;
1952 else
1953 control.final = 0;
1954
1955 if (skb_cloned(skb)) {
1956 /* Cloned sk_buffs are read-only, so we need a
1957 * writeable copy
1958 */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03001959 tx_skb = skb_copy(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001960 } else {
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03001961 tx_skb = skb_clone(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001962 }
1963
1964 if (!tx_skb) {
1965 l2cap_seq_list_clear(&chan->retrans_list);
1966 break;
1967 }
1968
1969 /* Update skb contents */
1970 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
1971 put_unaligned_le32(__pack_extended_control(&control),
1972 tx_skb->data + L2CAP_HDR_SIZE);
1973 } else {
1974 put_unaligned_le16(__pack_enhanced_control(&control),
1975 tx_skb->data + L2CAP_HDR_SIZE);
1976 }
1977
1978 if (chan->fcs == L2CAP_FCS_CRC16) {
1979 u16 fcs = crc16(0, (u8 *) tx_skb->data, tx_skb->len);
1980 put_unaligned_le16(fcs, skb_put(tx_skb,
1981 L2CAP_FCS_SIZE));
1982 }
1983
1984 l2cap_do_send(chan, tx_skb);
1985
1986 BT_DBG("Resent txseq %d", control.txseq);
1987
1988 chan->last_acked_seq = chan->buffer_seq;
1989 }
1990}
1991
Mat Martineauf80842a2012-05-17 20:53:46 -07001992static void l2cap_retransmit(struct l2cap_chan *chan,
1993 struct l2cap_ctrl *control)
1994{
1995 BT_DBG("chan %p, control %p", chan, control);
1996
1997 l2cap_seq_list_append(&chan->retrans_list, control->reqseq);
1998 l2cap_ertm_resend(chan);
1999}
2000
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002001static void l2cap_retransmit_all(struct l2cap_chan *chan,
2002 struct l2cap_ctrl *control)
2003{
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002004 struct sk_buff *skb;
2005
2006 BT_DBG("chan %p, control %p", chan, control);
2007
2008 if (control->poll)
2009 set_bit(CONN_SEND_FBIT, &chan->conn_state);
2010
2011 l2cap_seq_list_clear(&chan->retrans_list);
2012
2013 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2014 return;
2015
2016 if (chan->unacked_frames) {
2017 skb_queue_walk(&chan->tx_q, skb) {
2018 if (bt_cb(skb)->control.txseq == control->reqseq ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01002019 skb == chan->tx_send_head)
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002020 break;
2021 }
2022
2023 skb_queue_walk_from(&chan->tx_q, skb) {
2024 if (skb == chan->tx_send_head)
2025 break;
2026
2027 l2cap_seq_list_append(&chan->retrans_list,
2028 bt_cb(skb)->control.txseq);
2029 }
2030
2031 l2cap_ertm_resend(chan);
2032 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002033}
2034
Szymon Jancb17e73b2012-01-11 10:59:47 +01002035static void l2cap_send_ack(struct l2cap_chan *chan)
2036{
Mat Martineau0a0aba42012-05-17 20:53:39 -07002037 struct l2cap_ctrl control;
2038 u16 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
2039 chan->last_acked_seq);
2040 int threshold;
2041
2042 BT_DBG("chan %p last_acked_seq %d buffer_seq %d",
2043 chan, chan->last_acked_seq, chan->buffer_seq);
2044
2045 memset(&control, 0, sizeof(control));
2046 control.sframe = 1;
2047
2048 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
2049 chan->rx_state == L2CAP_RX_STATE_RECV) {
2050 __clear_ack_timer(chan);
2051 control.super = L2CAP_SUPER_RNR;
2052 control.reqseq = chan->buffer_seq;
2053 l2cap_send_sframe(chan, &control);
2054 } else {
2055 if (!test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) {
2056 l2cap_ertm_send(chan);
2057 /* If any i-frames were sent, they included an ack */
2058 if (chan->buffer_seq == chan->last_acked_seq)
2059 frames_to_ack = 0;
2060 }
2061
Mat Martineauc20f8e32012-07-10 05:47:07 -07002062 /* Ack now if the window is 3/4ths full.
Mat Martineau0a0aba42012-05-17 20:53:39 -07002063 * Calculate without mul or div
2064 */
Mat Martineauc20f8e32012-07-10 05:47:07 -07002065 threshold = chan->ack_win;
Mat Martineau0a0aba42012-05-17 20:53:39 -07002066 threshold += threshold << 1;
2067 threshold >>= 2;
2068
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002069 BT_DBG("frames_to_ack %u, threshold %d", frames_to_ack,
Mat Martineau0a0aba42012-05-17 20:53:39 -07002070 threshold);
2071
2072 if (frames_to_ack >= threshold) {
2073 __clear_ack_timer(chan);
2074 control.super = L2CAP_SUPER_RR;
2075 control.reqseq = chan->buffer_seq;
2076 l2cap_send_sframe(chan, &control);
2077 frames_to_ack = 0;
2078 }
2079
2080 if (frames_to_ack)
2081 __set_ack_timer(chan);
2082 }
Szymon Jancb17e73b2012-01-11 10:59:47 +01002083}
2084
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002085static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
2086 struct msghdr *msg, int len,
2087 int count, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002088{
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002089 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002090 struct sk_buff **frag;
Gustavo Padovan90338942012-04-06 20:15:47 -03002091 int sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002092
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03002093 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002094 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002095
2096 sent += count;
2097 len -= count;
2098
2099 /* Continuation fragments (no L2CAP header) */
2100 frag = &skb_shinfo(skb)->frag_list;
2101 while (len) {
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002102 struct sk_buff *tmp;
2103
Linus Torvalds1da177e2005-04-16 15:20:36 -07002104 count = min_t(unsigned int, conn->mtu, len);
2105
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002106 tmp = chan->ops->alloc_skb(chan, count,
2107 msg->msg_flags & MSG_DONTWAIT);
2108 if (IS_ERR(tmp))
2109 return PTR_ERR(tmp);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002110
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002111 *frag = tmp;
2112
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002113 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
2114 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002115
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002116 (*frag)->priority = skb->priority;
2117
Linus Torvalds1da177e2005-04-16 15:20:36 -07002118 sent += count;
2119 len -= count;
2120
Gustavo Padovan2d0ed3d2012-05-11 13:16:12 -03002121 skb->len += (*frag)->len;
2122 skb->data_len += (*frag)->len;
2123
Linus Torvalds1da177e2005-04-16 15:20:36 -07002124 frag = &(*frag)->next;
2125 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002126
2127 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002128}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002129
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002130static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002131 struct msghdr *msg, size_t len,
2132 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002133{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002134 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002135 struct sk_buff *skb;
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002136 int err, count, hlen = L2CAP_HDR_SIZE + L2CAP_PSMLEN_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002137 struct l2cap_hdr *lh;
2138
Marcel Holtmann43b1b8d2013-10-12 06:01:26 -07002139 BT_DBG("chan %p psm 0x%2.2x len %zu priority %u", chan,
2140 __le16_to_cpu(chan->psm), len, priority);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002141
2142 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002143
2144 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002145 msg->msg_flags & MSG_DONTWAIT);
2146 if (IS_ERR(skb))
2147 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002148
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002149 skb->priority = priority;
2150
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002151 /* Create L2CAP header */
2152 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002153 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenkodaf6a78c2012-05-03 10:55:52 +03002154 lh->len = cpu_to_le16(len + L2CAP_PSMLEN_SIZE);
Marcel Holtmann43b1b8d2013-10-12 06:01:26 -07002155 put_unaligned(chan->psm, (__le16 *) skb_put(skb, L2CAP_PSMLEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002156
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002157 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002158 if (unlikely(err < 0)) {
2159 kfree_skb(skb);
2160 return ERR_PTR(err);
2161 }
2162 return skb;
2163}
2164
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002165static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002166 struct msghdr *msg, size_t len,
2167 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002168{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002169 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002170 struct sk_buff *skb;
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002171 int err, count;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002172 struct l2cap_hdr *lh;
2173
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002174 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002175
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002176 count = min_t(unsigned int, (conn->mtu - L2CAP_HDR_SIZE), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002177
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002178 skb = chan->ops->alloc_skb(chan, count + L2CAP_HDR_SIZE,
Gustavo Padovan90338942012-04-06 20:15:47 -03002179 msg->msg_flags & MSG_DONTWAIT);
2180 if (IS_ERR(skb))
2181 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002182
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002183 skb->priority = priority;
2184
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002185 /* Create L2CAP header */
2186 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002187 lh->cid = cpu_to_le16(chan->dcid);
Gustavo Padovan6ff9b5e2012-05-02 11:56:17 -03002188 lh->len = cpu_to_le16(len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002189
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002190 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002191 if (unlikely(err < 0)) {
2192 kfree_skb(skb);
2193 return ERR_PTR(err);
2194 }
2195 return skb;
2196}
2197
Luiz Augusto von Dentzab0ff762011-09-12 20:00:50 +03002198static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002199 struct msghdr *msg, size_t len,
2200 u16 sdulen)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002201{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002202 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002203 struct sk_buff *skb;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002204 int err, count, hlen;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002205 struct l2cap_hdr *lh;
2206
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002207 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002208
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03002209 if (!conn)
2210 return ERR_PTR(-ENOTCONN);
2211
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002212 hlen = __ertm_hdr_size(chan);
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002213
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002214 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002215 hlen += L2CAP_SDULEN_SIZE;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002216
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002217 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002218 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002219
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002220 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002221
2222 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002223 msg->msg_flags & MSG_DONTWAIT);
2224 if (IS_ERR(skb))
2225 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002226
2227 /* Create L2CAP header */
2228 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002229 lh->cid = cpu_to_le16(chan->dcid);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002230 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002231
Mat Martineau18a48e72012-05-17 20:53:34 -07002232 /* Control header is populated later */
2233 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
2234 put_unaligned_le32(0, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
2235 else
2236 put_unaligned_le16(0, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002237
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002238 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002239 put_unaligned_le16(sdulen, skb_put(skb, L2CAP_SDULEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002240
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002241 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002242 if (unlikely(err < 0)) {
2243 kfree_skb(skb);
2244 return ERR_PTR(err);
2245 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002246
Mat Martineau18a48e72012-05-17 20:53:34 -07002247 bt_cb(skb)->control.fcs = chan->fcs;
Mat Martineau3ce35142012-04-25 16:36:14 -07002248 bt_cb(skb)->control.retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002249 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002250}
2251
Mat Martineau94122bb2012-05-02 09:42:02 -07002252static int l2cap_segment_sdu(struct l2cap_chan *chan,
2253 struct sk_buff_head *seg_queue,
2254 struct msghdr *msg, size_t len)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002255{
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002256 struct sk_buff *skb;
Mat Martineau94122bb2012-05-02 09:42:02 -07002257 u16 sdu_len;
2258 size_t pdu_len;
Mat Martineau94122bb2012-05-02 09:42:02 -07002259 u8 sar;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002260
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002261 BT_DBG("chan %p, msg %p, len %zu", chan, msg, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002262
Mat Martineau94122bb2012-05-02 09:42:02 -07002263 /* It is critical that ERTM PDUs fit in a single HCI fragment,
2264 * so fragmented skbs are not used. The HCI layer's handling
2265 * of fragmented skbs is not compatible with ERTM's queueing.
2266 */
2267
2268 /* PDU size is derived from the HCI MTU */
2269 pdu_len = chan->conn->mtu;
2270
Mat Martineaua5495742012-10-23 15:24:21 -07002271 /* Constrain PDU size for BR/EDR connections */
2272 if (!chan->hs_hcon)
2273 pdu_len = min_t(size_t, pdu_len, L2CAP_BREDR_MAX_PAYLOAD);
Mat Martineau94122bb2012-05-02 09:42:02 -07002274
2275 /* Adjust for largest possible L2CAP overhead. */
Gustavo Padovan35d401d2012-05-25 18:57:05 -03002276 if (chan->fcs)
2277 pdu_len -= L2CAP_FCS_SIZE;
2278
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002279 pdu_len -= __ertm_hdr_size(chan);
Mat Martineau94122bb2012-05-02 09:42:02 -07002280
2281 /* Remote device may have requested smaller PDUs */
2282 pdu_len = min_t(size_t, pdu_len, chan->remote_mps);
2283
2284 if (len <= pdu_len) {
2285 sar = L2CAP_SAR_UNSEGMENTED;
2286 sdu_len = 0;
2287 pdu_len = len;
2288 } else {
2289 sar = L2CAP_SAR_START;
2290 sdu_len = len;
2291 pdu_len -= L2CAP_SDULEN_SIZE;
2292 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002293
2294 while (len > 0) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002295 skb = l2cap_create_iframe_pdu(chan, msg, pdu_len, sdu_len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002296
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002297 if (IS_ERR(skb)) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002298 __skb_queue_purge(seg_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002299 return PTR_ERR(skb);
2300 }
2301
Mat Martineau94122bb2012-05-02 09:42:02 -07002302 bt_cb(skb)->control.sar = sar;
2303 __skb_queue_tail(seg_queue, skb);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002304
Mat Martineau94122bb2012-05-02 09:42:02 -07002305 len -= pdu_len;
2306 if (sdu_len) {
2307 sdu_len = 0;
2308 pdu_len += L2CAP_SDULEN_SIZE;
2309 }
2310
2311 if (len <= pdu_len) {
2312 sar = L2CAP_SAR_END;
2313 pdu_len = len;
2314 } else {
2315 sar = L2CAP_SAR_CONTINUE;
2316 }
2317 }
2318
Gustavo Padovanf0f62792012-05-29 13:29:17 -03002319 return 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002320}
2321
Johan Hedberg177f8f22013-05-31 17:54:51 +03002322static struct sk_buff *l2cap_create_le_flowctl_pdu(struct l2cap_chan *chan,
2323 struct msghdr *msg,
2324 size_t len, u16 sdulen)
2325{
2326 struct l2cap_conn *conn = chan->conn;
2327 struct sk_buff *skb;
2328 int err, count, hlen;
2329 struct l2cap_hdr *lh;
2330
2331 BT_DBG("chan %p len %zu", chan, len);
2332
2333 if (!conn)
2334 return ERR_PTR(-ENOTCONN);
2335
2336 hlen = L2CAP_HDR_SIZE;
2337
2338 if (sdulen)
2339 hlen += L2CAP_SDULEN_SIZE;
2340
2341 count = min_t(unsigned int, (conn->mtu - hlen), len);
2342
2343 skb = chan->ops->alloc_skb(chan, count + hlen,
2344 msg->msg_flags & MSG_DONTWAIT);
2345 if (IS_ERR(skb))
2346 return skb;
2347
2348 /* Create L2CAP header */
2349 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
2350 lh->cid = cpu_to_le16(chan->dcid);
2351 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
2352
2353 if (sdulen)
2354 put_unaligned_le16(sdulen, skb_put(skb, L2CAP_SDULEN_SIZE));
2355
2356 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
2357 if (unlikely(err < 0)) {
2358 kfree_skb(skb);
2359 return ERR_PTR(err);
2360 }
2361
2362 return skb;
2363}
2364
2365static int l2cap_segment_le_sdu(struct l2cap_chan *chan,
2366 struct sk_buff_head *seg_queue,
2367 struct msghdr *msg, size_t len)
2368{
2369 struct sk_buff *skb;
2370 size_t pdu_len;
2371 u16 sdu_len;
2372
2373 BT_DBG("chan %p, msg %p, len %zu", chan, msg, len);
2374
2375 pdu_len = chan->conn->mtu - L2CAP_HDR_SIZE;
2376
2377 pdu_len = min_t(size_t, pdu_len, chan->remote_mps);
2378
2379 sdu_len = len;
2380 pdu_len -= L2CAP_SDULEN_SIZE;
2381
2382 while (len > 0) {
2383 if (len <= pdu_len)
2384 pdu_len = len;
2385
2386 skb = l2cap_create_le_flowctl_pdu(chan, msg, pdu_len, sdu_len);
2387 if (IS_ERR(skb)) {
2388 __skb_queue_purge(seg_queue);
2389 return PTR_ERR(skb);
2390 }
2391
2392 __skb_queue_tail(seg_queue, skb);
2393
2394 len -= pdu_len;
2395
2396 if (sdu_len) {
2397 sdu_len = 0;
2398 pdu_len += L2CAP_SDULEN_SIZE;
2399 }
2400 }
2401
2402 return 0;
2403}
2404
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002405int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01002406 u32 priority)
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002407{
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002408 struct sk_buff *skb;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002409 int err;
Mat Martineau94122bb2012-05-02 09:42:02 -07002410 struct sk_buff_head seg_queue;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002411
Seung-Woo Kim31e8ce82013-11-05 18:46:33 +09002412 if (!chan->conn)
2413 return -ENOTCONN;
2414
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002415 /* Connectionless channel */
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002416 if (chan->chan_type == L2CAP_CHAN_CONN_LESS) {
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002417 skb = l2cap_create_connless_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002418 if (IS_ERR(skb))
2419 return PTR_ERR(skb);
2420
2421 l2cap_do_send(chan, skb);
2422 return len;
2423 }
2424
2425 switch (chan->mode) {
Johan Hedberg38319712013-05-17 12:49:23 +03002426 case L2CAP_MODE_LE_FLOWCTL:
Johan Hedberg177f8f22013-05-31 17:54:51 +03002427 /* Check outgoing MTU */
2428 if (len > chan->omtu)
2429 return -EMSGSIZE;
2430
Johan Hedbergfad5fc892013-12-05 09:45:01 +02002431 if (!chan->tx_credits)
2432 return -EAGAIN;
2433
Johan Hedberg177f8f22013-05-31 17:54:51 +03002434 __skb_queue_head_init(&seg_queue);
2435
2436 err = l2cap_segment_le_sdu(chan, &seg_queue, msg, len);
2437
2438 if (chan->state != BT_CONNECTED) {
2439 __skb_queue_purge(&seg_queue);
2440 err = -ENOTCONN;
2441 }
2442
2443 if (err)
2444 return err;
2445
2446 skb_queue_splice_tail_init(&seg_queue, &chan->tx_q);
2447
2448 while (chan->tx_credits && !skb_queue_empty(&chan->tx_q)) {
2449 l2cap_do_send(chan, skb_dequeue(&chan->tx_q));
2450 chan->tx_credits--;
2451 }
2452
2453 if (!chan->tx_credits)
2454 chan->ops->suspend(chan);
2455
2456 err = len;
2457
2458 break;
2459
Johan Hedbergfad5fc892013-12-05 09:45:01 +02002460 case L2CAP_MODE_BASIC:
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002461 /* Check outgoing MTU */
2462 if (len > chan->omtu)
2463 return -EMSGSIZE;
2464
2465 /* Create a basic PDU */
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002466 skb = l2cap_create_basic_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002467 if (IS_ERR(skb))
2468 return PTR_ERR(skb);
2469
2470 l2cap_do_send(chan, skb);
2471 err = len;
2472 break;
2473
2474 case L2CAP_MODE_ERTM:
2475 case L2CAP_MODE_STREAMING:
Mat Martineau94122bb2012-05-02 09:42:02 -07002476 /* Check outgoing MTU */
2477 if (len > chan->omtu) {
2478 err = -EMSGSIZE;
2479 break;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002480 }
2481
Mat Martineau94122bb2012-05-02 09:42:02 -07002482 __skb_queue_head_init(&seg_queue);
2483
2484 /* Do segmentation before calling in to the state machine,
2485 * since it's possible to block while waiting for memory
2486 * allocation.
2487 */
2488 err = l2cap_segment_sdu(chan, &seg_queue, msg, len);
2489
2490 /* The channel could have been closed while segmenting,
2491 * check that it is still connected.
2492 */
2493 if (chan->state != BT_CONNECTED) {
2494 __skb_queue_purge(&seg_queue);
2495 err = -ENOTCONN;
2496 }
2497
2498 if (err)
2499 break;
2500
Mat Martineau37339372012-05-17 20:53:33 -07002501 if (chan->mode == L2CAP_MODE_ERTM)
Gustavo Padovand6603662012-05-21 13:58:22 -03002502 l2cap_tx(chan, NULL, &seg_queue, L2CAP_EV_DATA_REQUEST);
Mat Martineau37339372012-05-17 20:53:33 -07002503 else
Gustavo Padovand6603662012-05-21 13:58:22 -03002504 l2cap_streaming_send(chan, &seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002505
Gustavo Padovand6603662012-05-21 13:58:22 -03002506 err = len;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002507
Mat Martineau94122bb2012-05-02 09:42:02 -07002508 /* If the skbs were not queued for sending, they'll still be in
2509 * seg_queue and need to be purged.
2510 */
2511 __skb_queue_purge(&seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002512 break;
2513
2514 default:
2515 BT_DBG("bad state %1.1x", chan->mode);
2516 err = -EBADFD;
2517 }
2518
2519 return err;
2520}
2521
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002522static void l2cap_send_srej(struct l2cap_chan *chan, u16 txseq)
2523{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002524 struct l2cap_ctrl control;
2525 u16 seq;
2526
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002527 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002528
2529 memset(&control, 0, sizeof(control));
2530 control.sframe = 1;
2531 control.super = L2CAP_SUPER_SREJ;
2532
2533 for (seq = chan->expected_tx_seq; seq != txseq;
2534 seq = __next_seq(chan, seq)) {
2535 if (!l2cap_ertm_seq_in_queue(&chan->srej_q, seq)) {
2536 control.reqseq = seq;
2537 l2cap_send_sframe(chan, &control);
2538 l2cap_seq_list_append(&chan->srej_list, seq);
2539 }
2540 }
2541
2542 chan->expected_tx_seq = __next_seq(chan, txseq);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002543}
2544
2545static void l2cap_send_srej_tail(struct l2cap_chan *chan)
2546{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002547 struct l2cap_ctrl control;
2548
2549 BT_DBG("chan %p", chan);
2550
2551 if (chan->srej_list.tail == L2CAP_SEQ_LIST_CLEAR)
2552 return;
2553
2554 memset(&control, 0, sizeof(control));
2555 control.sframe = 1;
2556 control.super = L2CAP_SUPER_SREJ;
2557 control.reqseq = chan->srej_list.tail;
2558 l2cap_send_sframe(chan, &control);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002559}
2560
2561static void l2cap_send_srej_list(struct l2cap_chan *chan, u16 txseq)
2562{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002563 struct l2cap_ctrl control;
2564 u16 initial_head;
2565 u16 seq;
2566
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002567 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002568
2569 memset(&control, 0, sizeof(control));
2570 control.sframe = 1;
2571 control.super = L2CAP_SUPER_SREJ;
2572
2573 /* Capture initial list head to allow only one pass through the list. */
2574 initial_head = chan->srej_list.head;
2575
2576 do {
2577 seq = l2cap_seq_list_pop(&chan->srej_list);
2578 if (seq == txseq || seq == L2CAP_SEQ_LIST_CLEAR)
2579 break;
2580
2581 control.reqseq = seq;
2582 l2cap_send_sframe(chan, &control);
2583 l2cap_seq_list_append(&chan->srej_list, seq);
2584 } while (chan->srej_list.head != initial_head);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002585}
2586
Mat Martineau608bcc62012-05-17 20:53:32 -07002587static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq)
2588{
2589 struct sk_buff *acked_skb;
2590 u16 ackseq;
2591
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002592 BT_DBG("chan %p, reqseq %u", chan, reqseq);
Mat Martineau608bcc62012-05-17 20:53:32 -07002593
2594 if (chan->unacked_frames == 0 || reqseq == chan->expected_ack_seq)
2595 return;
2596
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002597 BT_DBG("expected_ack_seq %u, unacked_frames %u",
Mat Martineau608bcc62012-05-17 20:53:32 -07002598 chan->expected_ack_seq, chan->unacked_frames);
2599
2600 for (ackseq = chan->expected_ack_seq; ackseq != reqseq;
2601 ackseq = __next_seq(chan, ackseq)) {
2602
2603 acked_skb = l2cap_ertm_seq_in_queue(&chan->tx_q, ackseq);
2604 if (acked_skb) {
2605 skb_unlink(acked_skb, &chan->tx_q);
2606 kfree_skb(acked_skb);
2607 chan->unacked_frames--;
2608 }
2609 }
2610
2611 chan->expected_ack_seq = reqseq;
2612
2613 if (chan->unacked_frames == 0)
2614 __clear_retrans_timer(chan);
2615
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002616 BT_DBG("unacked_frames %u", chan->unacked_frames);
Mat Martineau608bcc62012-05-17 20:53:32 -07002617}
2618
2619static void l2cap_abort_rx_srej_sent(struct l2cap_chan *chan)
2620{
2621 BT_DBG("chan %p", chan);
2622
2623 chan->expected_tx_seq = chan->buffer_seq;
2624 l2cap_seq_list_clear(&chan->srej_list);
2625 skb_queue_purge(&chan->srej_q);
2626 chan->rx_state = L2CAP_RX_STATE_RECV;
2627}
2628
Gustavo Padovand6603662012-05-21 13:58:22 -03002629static void l2cap_tx_state_xmit(struct l2cap_chan *chan,
2630 struct l2cap_ctrl *control,
2631 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002632{
Mat Martineau608bcc62012-05-17 20:53:32 -07002633 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2634 event);
2635
2636 switch (event) {
2637 case L2CAP_EV_DATA_REQUEST:
2638 if (chan->tx_send_head == NULL)
2639 chan->tx_send_head = skb_peek(skbs);
2640
2641 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2642 l2cap_ertm_send(chan);
2643 break;
2644 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2645 BT_DBG("Enter LOCAL_BUSY");
2646 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2647
2648 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2649 /* The SREJ_SENT state must be aborted if we are to
2650 * enter the LOCAL_BUSY state.
2651 */
2652 l2cap_abort_rx_srej_sent(chan);
2653 }
2654
2655 l2cap_send_ack(chan);
2656
2657 break;
2658 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2659 BT_DBG("Exit LOCAL_BUSY");
2660 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2661
2662 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2663 struct l2cap_ctrl local_control;
2664
2665 memset(&local_control, 0, sizeof(local_control));
2666 local_control.sframe = 1;
2667 local_control.super = L2CAP_SUPER_RR;
2668 local_control.poll = 1;
2669 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002670 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002671
2672 chan->retry_count = 1;
2673 __set_monitor_timer(chan);
2674 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2675 }
2676 break;
2677 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2678 l2cap_process_reqseq(chan, control->reqseq);
2679 break;
2680 case L2CAP_EV_EXPLICIT_POLL:
2681 l2cap_send_rr_or_rnr(chan, 1);
2682 chan->retry_count = 1;
2683 __set_monitor_timer(chan);
2684 __clear_ack_timer(chan);
2685 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2686 break;
2687 case L2CAP_EV_RETRANS_TO:
2688 l2cap_send_rr_or_rnr(chan, 1);
2689 chan->retry_count = 1;
2690 __set_monitor_timer(chan);
2691 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2692 break;
2693 case L2CAP_EV_RECV_FBIT:
2694 /* Nothing to process */
2695 break;
2696 default:
2697 break;
2698 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002699}
2700
Gustavo Padovand6603662012-05-21 13:58:22 -03002701static void l2cap_tx_state_wait_f(struct l2cap_chan *chan,
2702 struct l2cap_ctrl *control,
2703 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002704{
Mat Martineau608bcc62012-05-17 20:53:32 -07002705 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2706 event);
2707
2708 switch (event) {
2709 case L2CAP_EV_DATA_REQUEST:
2710 if (chan->tx_send_head == NULL)
2711 chan->tx_send_head = skb_peek(skbs);
2712 /* Queue data, but don't send. */
2713 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2714 break;
2715 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2716 BT_DBG("Enter LOCAL_BUSY");
2717 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2718
2719 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2720 /* The SREJ_SENT state must be aborted if we are to
2721 * enter the LOCAL_BUSY state.
2722 */
2723 l2cap_abort_rx_srej_sent(chan);
2724 }
2725
2726 l2cap_send_ack(chan);
2727
2728 break;
2729 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2730 BT_DBG("Exit LOCAL_BUSY");
2731 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2732
2733 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2734 struct l2cap_ctrl local_control;
2735 memset(&local_control, 0, sizeof(local_control));
2736 local_control.sframe = 1;
2737 local_control.super = L2CAP_SUPER_RR;
2738 local_control.poll = 1;
2739 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002740 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002741
2742 chan->retry_count = 1;
2743 __set_monitor_timer(chan);
2744 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2745 }
2746 break;
2747 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2748 l2cap_process_reqseq(chan, control->reqseq);
2749
2750 /* Fall through */
2751
2752 case L2CAP_EV_RECV_FBIT:
2753 if (control && control->final) {
2754 __clear_monitor_timer(chan);
2755 if (chan->unacked_frames > 0)
2756 __set_retrans_timer(chan);
2757 chan->retry_count = 0;
2758 chan->tx_state = L2CAP_TX_STATE_XMIT;
2759 BT_DBG("recv fbit tx_state 0x2.2%x", chan->tx_state);
2760 }
2761 break;
2762 case L2CAP_EV_EXPLICIT_POLL:
2763 /* Ignore */
2764 break;
2765 case L2CAP_EV_MONITOR_TO:
2766 if (chan->max_tx == 0 || chan->retry_count < chan->max_tx) {
2767 l2cap_send_rr_or_rnr(chan, 1);
2768 __set_monitor_timer(chan);
2769 chan->retry_count++;
2770 } else {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02002771 l2cap_send_disconn_req(chan, ECONNABORTED);
Mat Martineau608bcc62012-05-17 20:53:32 -07002772 }
2773 break;
2774 default:
2775 break;
2776 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002777}
2778
Gustavo Padovand6603662012-05-21 13:58:22 -03002779static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
2780 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002781{
Mat Martineau608bcc62012-05-17 20:53:32 -07002782 BT_DBG("chan %p, control %p, skbs %p, event %d, state %d",
2783 chan, control, skbs, event, chan->tx_state);
2784
2785 switch (chan->tx_state) {
2786 case L2CAP_TX_STATE_XMIT:
Gustavo Padovand6603662012-05-21 13:58:22 -03002787 l2cap_tx_state_xmit(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002788 break;
2789 case L2CAP_TX_STATE_WAIT_F:
Gustavo Padovand6603662012-05-21 13:58:22 -03002790 l2cap_tx_state_wait_f(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002791 break;
2792 default:
2793 /* Ignore event */
2794 break;
2795 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002796}
2797
Mat Martineau4b51dae92012-05-17 20:53:37 -07002798static void l2cap_pass_to_tx(struct l2cap_chan *chan,
2799 struct l2cap_ctrl *control)
2800{
2801 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002802 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_REQSEQ_AND_FBIT);
Mat Martineau4b51dae92012-05-17 20:53:37 -07002803}
2804
Mat Martineauf80842a2012-05-17 20:53:46 -07002805static void l2cap_pass_to_tx_fbit(struct l2cap_chan *chan,
2806 struct l2cap_ctrl *control)
2807{
2808 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002809 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_FBIT);
Mat Martineauf80842a2012-05-17 20:53:46 -07002810}
2811
Linus Torvalds1da177e2005-04-16 15:20:36 -07002812/* Copy frame to all raw sockets on that connection */
2813static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2814{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002815 struct sk_buff *nskb;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002816 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002817
2818 BT_DBG("conn %p", conn);
2819
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002820 mutex_lock(&conn->chan_lock);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002821
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002822 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002823 if (chan->chan_type != L2CAP_CHAN_RAW)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002824 continue;
2825
Gustavo Padovan7f5396a2013-10-21 18:22:25 -02002826 /* Don't send frame to the channel it came from */
2827 if (bt_cb(skb)->chan == chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002828 continue;
Gustavo Padovan7f5396a2013-10-21 18:22:25 -02002829
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002830 nskb = skb_clone(skb, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002831 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002832 continue;
Gustavo Padovan80b98022012-05-27 22:27:51 -03002833 if (chan->ops->recv(chan, nskb))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002834 kfree_skb(nskb);
2835 }
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002836
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002837 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002838}
2839
2840/* ---- L2CAP signalling commands ---- */
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002841static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code,
2842 u8 ident, u16 dlen, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002843{
2844 struct sk_buff *skb, **frag;
2845 struct l2cap_cmd_hdr *cmd;
2846 struct l2cap_hdr *lh;
2847 int len, count;
2848
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002849 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %u",
2850 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002851
Anderson Lizardo300b9622013-06-02 16:30:40 -04002852 if (conn->mtu < L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE)
2853 return NULL;
2854
Linus Torvalds1da177e2005-04-16 15:20:36 -07002855 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2856 count = min_t(unsigned int, conn->mtu, len);
2857
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002858 skb = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002859 if (!skb)
2860 return NULL;
2861
2862 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002863 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002864
2865 if (conn->hcon->type == LE_LINK)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002866 lh->cid = __constant_cpu_to_le16(L2CAP_CID_LE_SIGNALING);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002867 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002868 lh->cid = __constant_cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002869
2870 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2871 cmd->code = code;
2872 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002873 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002874
2875 if (dlen) {
2876 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2877 memcpy(skb_put(skb, count), data, count);
2878 data += count;
2879 }
2880
2881 len -= skb->len;
2882
2883 /* Continuation fragments (no L2CAP header) */
2884 frag = &skb_shinfo(skb)->frag_list;
2885 while (len) {
2886 count = min_t(unsigned int, conn->mtu, len);
2887
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002888 *frag = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002889 if (!*frag)
2890 goto fail;
2891
2892 memcpy(skb_put(*frag, count), data, count);
2893
2894 len -= count;
2895 data += count;
2896
2897 frag = &(*frag)->next;
2898 }
2899
2900 return skb;
2901
2902fail:
2903 kfree_skb(skb);
2904 return NULL;
2905}
2906
Gustavo Padovan2d792812012-10-06 10:07:01 +01002907static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen,
2908 unsigned long *val)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002909{
2910 struct l2cap_conf_opt *opt = *ptr;
2911 int len;
2912
2913 len = L2CAP_CONF_OPT_SIZE + opt->len;
2914 *ptr += len;
2915
2916 *type = opt->type;
2917 *olen = opt->len;
2918
2919 switch (opt->len) {
2920 case 1:
2921 *val = *((u8 *) opt->val);
2922 break;
2923
2924 case 2:
steven miaobfaaeb32010-10-16 18:29:47 -04002925 *val = get_unaligned_le16(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002926 break;
2927
2928 case 4:
steven miaobfaaeb32010-10-16 18:29:47 -04002929 *val = get_unaligned_le32(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002930 break;
2931
2932 default:
2933 *val = (unsigned long) opt->val;
2934 break;
2935 }
2936
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002937 BT_DBG("type 0x%2.2x len %u val 0x%lx", *type, opt->len, *val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002938 return len;
2939}
2940
Linus Torvalds1da177e2005-04-16 15:20:36 -07002941static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2942{
2943 struct l2cap_conf_opt *opt = *ptr;
2944
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002945 BT_DBG("type 0x%2.2x len %u val 0x%lx", type, len, val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002946
2947 opt->type = type;
2948 opt->len = len;
2949
2950 switch (len) {
2951 case 1:
2952 *((u8 *) opt->val) = val;
2953 break;
2954
2955 case 2:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002956 put_unaligned_le16(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002957 break;
2958
2959 case 4:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002960 put_unaligned_le32(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002961 break;
2962
2963 default:
2964 memcpy(opt->val, (void *) val, len);
2965 break;
2966 }
2967
2968 *ptr += L2CAP_CONF_OPT_SIZE + len;
2969}
2970
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002971static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan)
2972{
2973 struct l2cap_conf_efs efs;
2974
Szymon Janc1ec918c2011-11-16 09:32:21 +01002975 switch (chan->mode) {
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002976 case L2CAP_MODE_ERTM:
2977 efs.id = chan->local_id;
2978 efs.stype = chan->local_stype;
2979 efs.msdu = cpu_to_le16(chan->local_msdu);
2980 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002981 efs.acc_lat = __constant_cpu_to_le32(L2CAP_DEFAULT_ACC_LAT);
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03002982 efs.flush_to = __constant_cpu_to_le32(L2CAP_EFS_DEFAULT_FLUSH_TO);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002983 break;
2984
2985 case L2CAP_MODE_STREAMING:
2986 efs.id = 1;
2987 efs.stype = L2CAP_SERV_BESTEFFORT;
2988 efs.msdu = cpu_to_le16(chan->local_msdu);
2989 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
2990 efs.acc_lat = 0;
2991 efs.flush_to = 0;
2992 break;
2993
2994 default:
2995 return;
2996 }
2997
2998 l2cap_add_conf_opt(ptr, L2CAP_CONF_EFS, sizeof(efs),
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03002999 (unsigned long) &efs);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003000}
3001
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003002static void l2cap_ack_timeout(struct work_struct *work)
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003003{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003004 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau03625202012-05-17 20:53:51 -07003005 ack_timer.work);
3006 u16 frames_to_ack;
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003007
Gustavo F. Padovan2fb9b3d2011-12-22 16:56:05 -02003008 BT_DBG("chan %p", chan);
3009
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003010 l2cap_chan_lock(chan);
3011
Mat Martineau03625202012-05-17 20:53:51 -07003012 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
3013 chan->last_acked_seq);
3014
3015 if (frames_to_ack)
3016 l2cap_send_rr_or_rnr(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003017
3018 l2cap_chan_unlock(chan);
Szymon Janc09bfb2e2012-01-11 10:59:49 +01003019 l2cap_chan_put(chan);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003020}
3021
Andrei Emeltchenko466f8002012-05-29 13:59:01 +03003022int l2cap_ertm_init(struct l2cap_chan *chan)
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003023{
Mat Martineau3c588192012-04-11 10:48:42 -07003024 int err;
3025
Mat Martineau105bdf92012-04-27 16:50:48 -07003026 chan->next_tx_seq = 0;
3027 chan->expected_tx_seq = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03003028 chan->expected_ack_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03003029 chan->unacked_frames = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03003030 chan->buffer_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03003031 chan->frames_sent = 0;
Mat Martineau105bdf92012-04-27 16:50:48 -07003032 chan->last_acked_seq = 0;
3033 chan->sdu = NULL;
3034 chan->sdu_last_frag = NULL;
3035 chan->sdu_len = 0;
3036
Mat Martineaud34c34f2012-05-14 14:49:27 -07003037 skb_queue_head_init(&chan->tx_q);
3038
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003039 chan->local_amp_id = AMP_ID_BREDR;
3040 chan->move_id = AMP_ID_BREDR;
Mat Martineau08333282012-10-23 15:24:06 -07003041 chan->move_state = L2CAP_MOVE_STABLE;
3042 chan->move_role = L2CAP_MOVE_ROLE_NONE;
3043
Mat Martineau105bdf92012-04-27 16:50:48 -07003044 if (chan->mode != L2CAP_MODE_ERTM)
3045 return 0;
3046
3047 chan->rx_state = L2CAP_RX_STATE_RECV;
3048 chan->tx_state = L2CAP_TX_STATE_XMIT;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003049
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003050 INIT_DELAYED_WORK(&chan->retrans_timer, l2cap_retrans_timeout);
3051 INIT_DELAYED_WORK(&chan->monitor_timer, l2cap_monitor_timeout);
3052 INIT_DELAYED_WORK(&chan->ack_timer, l2cap_ack_timeout);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003053
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -03003054 skb_queue_head_init(&chan->srej_q);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003055
Mat Martineau3c588192012-04-11 10:48:42 -07003056 err = l2cap_seq_list_init(&chan->srej_list, chan->tx_win);
3057 if (err < 0)
3058 return err;
3059
Mat Martineau9dc9aff2012-05-17 16:20:14 -07003060 err = l2cap_seq_list_init(&chan->retrans_list, chan->remote_tx_win);
3061 if (err < 0)
3062 l2cap_seq_list_free(&chan->srej_list);
3063
3064 return err;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003065}
3066
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003067static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
3068{
3069 switch (mode) {
3070 case L2CAP_MODE_STREAMING:
3071 case L2CAP_MODE_ERTM:
3072 if (l2cap_mode_supported(mode, remote_feat_mask))
3073 return mode;
3074 /* fall through */
3075 default:
3076 return L2CAP_MODE_BASIC;
3077 }
3078}
3079
Marcel Holtmann848566b2013-10-01 22:59:22 -07003080static inline bool __l2cap_ews_supported(struct l2cap_conn *conn)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003081{
Marcel Holtmann848566b2013-10-01 22:59:22 -07003082 return conn->hs_enabled && conn->feat_mask & L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003083}
3084
Marcel Holtmann848566b2013-10-01 22:59:22 -07003085static inline bool __l2cap_efs_supported(struct l2cap_conn *conn)
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003086{
Marcel Holtmann848566b2013-10-01 22:59:22 -07003087 return conn->hs_enabled && conn->feat_mask & L2CAP_FEAT_EXT_FLOW;
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003088}
3089
Mat Martineau36c86c82012-10-23 15:24:20 -07003090static void __l2cap_set_ertm_timeouts(struct l2cap_chan *chan,
3091 struct l2cap_conf_rfc *rfc)
3092{
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003093 if (chan->local_amp_id != AMP_ID_BREDR && chan->hs_hcon) {
Mat Martineau36c86c82012-10-23 15:24:20 -07003094 u64 ertm_to = chan->hs_hcon->hdev->amp_be_flush_to;
3095
3096 /* Class 1 devices have must have ERTM timeouts
3097 * exceeding the Link Supervision Timeout. The
3098 * default Link Supervision Timeout for AMP
3099 * controllers is 10 seconds.
3100 *
3101 * Class 1 devices use 0xffffffff for their
3102 * best-effort flush timeout, so the clamping logic
3103 * will result in a timeout that meets the above
3104 * requirement. ERTM timeouts are 16-bit values, so
3105 * the maximum timeout is 65.535 seconds.
3106 */
3107
3108 /* Convert timeout to milliseconds and round */
3109 ertm_to = DIV_ROUND_UP_ULL(ertm_to, 1000);
3110
3111 /* This is the recommended formula for class 2 devices
3112 * that start ERTM timers when packets are sent to the
3113 * controller.
3114 */
3115 ertm_to = 3 * ertm_to + 500;
3116
3117 if (ertm_to > 0xffff)
3118 ertm_to = 0xffff;
3119
3120 rfc->retrans_timeout = cpu_to_le16((u16) ertm_to);
3121 rfc->monitor_timeout = rfc->retrans_timeout;
3122 } else {
3123 rfc->retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
3124 rfc->monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
3125 }
3126}
3127
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003128static inline void l2cap_txwin_setup(struct l2cap_chan *chan)
3129{
3130 if (chan->tx_win > L2CAP_DEFAULT_TX_WINDOW &&
Marcel Holtmann848566b2013-10-01 22:59:22 -07003131 __l2cap_ews_supported(chan->conn)) {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003132 /* use extended control field */
3133 set_bit(FLAG_EXT_CTRL, &chan->flags);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003134 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
3135 } else {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003136 chan->tx_win = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003137 L2CAP_DEFAULT_TX_WINDOW);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003138 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
3139 }
Mat Martineauc20f8e32012-07-10 05:47:07 -07003140 chan->ack_win = chan->tx_win;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003141}
3142
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003143static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003144{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003145 struct l2cap_conf_req *req = data;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003146 struct l2cap_conf_rfc rfc = { .mode = chan->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07003147 void *ptr = req->data;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003148 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003149
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03003150 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003151
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003152 if (chan->num_conf_req || chan->num_conf_rsp)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003153 goto done;
3154
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003155 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003156 case L2CAP_MODE_STREAMING:
3157 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003158 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state))
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003159 break;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003160
Marcel Holtmann848566b2013-10-01 22:59:22 -07003161 if (__l2cap_efs_supported(chan->conn))
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003162 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3163
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03003164 /* fall through */
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003165 default:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003166 chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003167 break;
3168 }
3169
3170done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003171 if (chan->imtu != L2CAP_DEFAULT_MTU)
3172 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovan7990681c2011-01-24 16:01:43 -02003173
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003174 switch (chan->mode) {
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003175 case L2CAP_MODE_BASIC:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003176 if (!(chan->conn->feat_mask & L2CAP_FEAT_ERTM) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003177 !(chan->conn->feat_mask & L2CAP_FEAT_STREAMING))
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003178 break;
3179
Gustavo F. Padovan62547752010-06-08 20:05:31 -03003180 rfc.mode = L2CAP_MODE_BASIC;
3181 rfc.txwin_size = 0;
3182 rfc.max_transmit = 0;
3183 rfc.retrans_timeout = 0;
3184 rfc.monitor_timeout = 0;
3185 rfc.max_pdu_size = 0;
3186
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003187 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003188 (unsigned long) &rfc);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003189 break;
3190
3191 case L2CAP_MODE_ERTM:
3192 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003193 rfc.max_transmit = chan->max_tx;
Mat Martineau36c86c82012-10-23 15:24:20 -07003194
3195 __l2cap_set_ertm_timeouts(chan, &rfc);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003196
3197 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003198 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3199 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003200 rfc.max_pdu_size = cpu_to_le16(size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003201
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003202 l2cap_txwin_setup(chan);
3203
3204 rfc.txwin_size = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003205 L2CAP_DEFAULT_TX_WINDOW);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003206
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003207 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003208 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003209
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003210 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3211 l2cap_add_opt_efs(&ptr, chan);
3212
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003213 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3214 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003215 chan->tx_win);
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003216
3217 if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
3218 if (chan->fcs == L2CAP_FCS_NONE ||
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003219 test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003220 chan->fcs = L2CAP_FCS_NONE;
3221 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
3222 chan->fcs);
3223 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003224 break;
3225
3226 case L2CAP_MODE_STREAMING:
Mat Martineau273759e2012-05-17 20:53:53 -07003227 l2cap_txwin_setup(chan);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003228 rfc.mode = L2CAP_MODE_STREAMING;
3229 rfc.txwin_size = 0;
3230 rfc.max_transmit = 0;
3231 rfc.retrans_timeout = 0;
3232 rfc.monitor_timeout = 0;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003233
3234 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003235 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3236 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003237 rfc.max_pdu_size = cpu_to_le16(size);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003238
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003239 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003240 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003241
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003242 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3243 l2cap_add_opt_efs(&ptr, chan);
3244
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003245 if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
3246 if (chan->fcs == L2CAP_FCS_NONE ||
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003247 test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003248 chan->fcs = L2CAP_FCS_NONE;
3249 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
3250 chan->fcs);
3251 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003252 break;
3253 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003254
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003255 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003256 req->flags = __constant_cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003257
3258 return ptr - data;
3259}
3260
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003261static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003262{
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003263 struct l2cap_conf_rsp *rsp = data;
3264 void *ptr = rsp->data;
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003265 void *req = chan->conf_req;
3266 int len = chan->conf_len;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003267 int type, hint, olen;
3268 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003269 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003270 struct l2cap_conf_efs efs;
3271 u8 remote_efs = 0;
Marcel Holtmann861d6882007-10-20 13:37:06 +02003272 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003273 u16 result = L2CAP_CONF_SUCCESS;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003274 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003275
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003276 BT_DBG("chan %p", chan);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01003277
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003278 while (len >= L2CAP_CONF_OPT_SIZE) {
3279 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003280
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03003281 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003282 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003283
3284 switch (type) {
3285 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02003286 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003287 break;
3288
3289 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003290 chan->flush_to = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003291 break;
3292
3293 case L2CAP_CONF_QOS:
3294 break;
3295
Marcel Holtmann6464f352007-10-20 13:39:51 +02003296 case L2CAP_CONF_RFC:
3297 if (olen == sizeof(rfc))
3298 memcpy(&rfc, (void *) val, olen);
3299 break;
3300
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003301 case L2CAP_CONF_FCS:
3302 if (val == L2CAP_FCS_NONE)
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003303 set_bit(CONF_RECV_NO_FCS, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003304 break;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003305
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003306 case L2CAP_CONF_EFS:
3307 remote_efs = 1;
3308 if (olen == sizeof(efs))
3309 memcpy(&efs, (void *) val, olen);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003310 break;
3311
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003312 case L2CAP_CONF_EWS:
Marcel Holtmann848566b2013-10-01 22:59:22 -07003313 if (!chan->conn->hs_enabled)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003314 return -ECONNREFUSED;
3315
3316 set_bit(FLAG_EXT_CTRL, &chan->flags);
3317 set_bit(CONF_EWS_RECV, &chan->conf_state);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003318 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003319 chan->remote_tx_win = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003320 break;
3321
3322 default:
3323 if (hint)
3324 break;
3325
3326 result = L2CAP_CONF_UNKNOWN;
3327 *((u8 *) ptr++) = type;
3328 break;
3329 }
3330 }
3331
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003332 if (chan->num_conf_rsp || chan->num_conf_req > 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003333 goto done;
3334
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003335 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003336 case L2CAP_MODE_STREAMING:
3337 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003338 if (!test_bit(CONF_STATE2_DEVICE, &chan->conf_state)) {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003339 chan->mode = l2cap_select_mode(rfc.mode,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003340 chan->conn->feat_mask);
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003341 break;
3342 }
3343
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003344 if (remote_efs) {
Marcel Holtmann848566b2013-10-01 22:59:22 -07003345 if (__l2cap_efs_supported(chan->conn))
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003346 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3347 else
3348 return -ECONNREFUSED;
3349 }
3350
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003351 if (chan->mode != rfc.mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003352 return -ECONNREFUSED;
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03003353
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003354 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003355 }
3356
3357done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003358 if (chan->mode != rfc.mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003359 result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003360 rfc.mode = chan->mode;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003361
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003362 if (chan->num_conf_rsp == 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003363 return -ECONNREFUSED;
3364
Gustavo Padovan2d792812012-10-06 10:07:01 +01003365 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3366 (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003367 }
3368
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003369 if (result == L2CAP_CONF_SUCCESS) {
3370 /* Configure output options and let the other side know
3371 * which ones we don't like. */
3372
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003373 if (mtu < L2CAP_DEFAULT_MIN_MTU)
3374 result = L2CAP_CONF_UNACCEPT;
3375 else {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003376 chan->omtu = mtu;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003377 set_bit(CONF_MTU_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003378 }
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003379 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003380
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003381 if (remote_efs) {
3382 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003383 efs.stype != L2CAP_SERV_NOTRAFIC &&
3384 efs.stype != chan->local_stype) {
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003385
3386 result = L2CAP_CONF_UNACCEPT;
3387
3388 if (chan->num_conf_req >= 1)
3389 return -ECONNREFUSED;
3390
3391 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003392 sizeof(efs),
3393 (unsigned long) &efs);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003394 } else {
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003395 /* Send PENDING Conf Rsp */
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003396 result = L2CAP_CONF_PENDING;
3397 set_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003398 }
3399 }
3400
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003401 switch (rfc.mode) {
3402 case L2CAP_MODE_BASIC:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003403 chan->fcs = L2CAP_FCS_NONE;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003404 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003405 break;
3406
3407 case L2CAP_MODE_ERTM:
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003408 if (!test_bit(CONF_EWS_RECV, &chan->conf_state))
3409 chan->remote_tx_win = rfc.txwin_size;
3410 else
3411 rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW;
3412
Gustavo F. Padovan2c03a7a2011-03-25 20:15:28 -03003413 chan->remote_max_tx = rfc.max_transmit;
Mat Martineau86b1b262010-08-05 15:54:22 -07003414
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003415 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003416 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3417 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003418 rfc.max_pdu_size = cpu_to_le16(size);
3419 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003420
Mat Martineau36c86c82012-10-23 15:24:20 -07003421 __l2cap_set_ertm_timeouts(chan, &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003422
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003423 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003424
3425 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003426 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003427
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003428 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3429 chan->remote_id = efs.id;
3430 chan->remote_stype = efs.stype;
3431 chan->remote_msdu = le16_to_cpu(efs.msdu);
3432 chan->remote_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003433 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003434 chan->remote_acc_lat =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003435 le32_to_cpu(efs.acc_lat);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003436 chan->remote_sdu_itime =
3437 le32_to_cpu(efs.sdu_itime);
3438 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003439 sizeof(efs),
3440 (unsigned long) &efs);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003441 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003442 break;
3443
3444 case L2CAP_MODE_STREAMING:
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003445 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003446 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3447 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003448 rfc.max_pdu_size = cpu_to_le16(size);
3449 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003450
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003451 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003452
Gustavo Padovan2d792812012-10-06 10:07:01 +01003453 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3454 (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003455
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003456 break;
3457
3458 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02003459 result = L2CAP_CONF_UNACCEPT;
3460
3461 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003462 rfc.mode = chan->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003463 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003464
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003465 if (result == L2CAP_CONF_SUCCESS)
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003466 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003467 }
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003468 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003469 rsp->result = cpu_to_le16(result);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003470 rsp->flags = __constant_cpu_to_le16(0);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003471
3472 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003473}
3474
Gustavo Padovan2d792812012-10-06 10:07:01 +01003475static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len,
3476 void *data, u16 *result)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003477{
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003478 struct l2cap_conf_req *req = data;
3479 void *ptr = req->data;
3480 int type, olen;
3481 unsigned long val;
Mat Martineau36e999a2011-12-08 17:23:21 -08003482 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003483 struct l2cap_conf_efs efs;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003484
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003485 BT_DBG("chan %p, rsp %p, len %d, req %p", chan, rsp, len, data);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003486
3487 while (len >= L2CAP_CONF_OPT_SIZE) {
3488 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3489
3490 switch (type) {
3491 case L2CAP_CONF_MTU:
3492 if (val < L2CAP_DEFAULT_MIN_MTU) {
3493 *result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003494 chan->imtu = L2CAP_DEFAULT_MIN_MTU;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003495 } else
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003496 chan->imtu = val;
3497 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003498 break;
3499
3500 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003501 chan->flush_to = val;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003502 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003503 2, chan->flush_to);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003504 break;
3505
3506 case L2CAP_CONF_RFC:
3507 if (olen == sizeof(rfc))
3508 memcpy(&rfc, (void *)val, olen);
3509
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003510 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003511 rfc.mode != chan->mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003512 return -ECONNREFUSED;
3513
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003514 chan->fcs = 0;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003515
3516 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003517 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003518 break;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003519
3520 case L2CAP_CONF_EWS:
Mat Martineauc20f8e32012-07-10 05:47:07 -07003521 chan->ack_win = min_t(u16, val, chan->ack_win);
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003522 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Mat Martineauc20f8e32012-07-10 05:47:07 -07003523 chan->tx_win);
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003524 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003525
3526 case L2CAP_CONF_EFS:
3527 if (olen == sizeof(efs))
3528 memcpy(&efs, (void *)val, olen);
3529
3530 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003531 efs.stype != L2CAP_SERV_NOTRAFIC &&
3532 efs.stype != chan->local_stype)
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003533 return -ECONNREFUSED;
3534
Gustavo Padovan2d792812012-10-06 10:07:01 +01003535 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs),
3536 (unsigned long) &efs);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003537 break;
Andrei Emeltchenkocbabee72012-11-29 17:46:07 +02003538
3539 case L2CAP_CONF_FCS:
3540 if (*result == L2CAP_CONF_PENDING)
3541 if (val == L2CAP_FCS_NONE)
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003542 set_bit(CONF_RECV_NO_FCS,
Andrei Emeltchenkocbabee72012-11-29 17:46:07 +02003543 &chan->conf_state);
3544 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003545 }
3546 }
3547
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003548 if (chan->mode == L2CAP_MODE_BASIC && chan->mode != rfc.mode)
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003549 return -ECONNREFUSED;
3550
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003551 chan->mode = rfc.mode;
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003552
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003553 if (*result == L2CAP_CONF_SUCCESS || *result == L2CAP_CONF_PENDING) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003554 switch (rfc.mode) {
3555 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003556 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3557 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
3558 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003559 if (!test_bit(FLAG_EXT_CTRL, &chan->flags))
3560 chan->ack_win = min_t(u16, chan->ack_win,
3561 rfc.txwin_size);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003562
3563 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3564 chan->local_msdu = le16_to_cpu(efs.msdu);
3565 chan->local_sdu_itime =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003566 le32_to_cpu(efs.sdu_itime);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003567 chan->local_acc_lat = le32_to_cpu(efs.acc_lat);
3568 chan->local_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003569 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003570 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003571 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003572
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003573 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003574 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003575 }
3576 }
3577
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003578 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003579 req->flags = __constant_cpu_to_le16(0);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003580
3581 return ptr - data;
3582}
3583
Gustavo Padovan2d792812012-10-06 10:07:01 +01003584static int l2cap_build_conf_rsp(struct l2cap_chan *chan, void *data,
3585 u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003586{
3587 struct l2cap_conf_rsp *rsp = data;
3588 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003589
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003590 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003591
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003592 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003593 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003594 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003595
3596 return ptr - data;
3597}
3598
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03003599void __l2cap_le_connect_rsp_defer(struct l2cap_chan *chan)
3600{
3601 struct l2cap_le_conn_rsp rsp;
3602 struct l2cap_conn *conn = chan->conn;
3603
3604 BT_DBG("chan %p", chan);
3605
3606 rsp.dcid = cpu_to_le16(chan->scid);
3607 rsp.mtu = cpu_to_le16(chan->imtu);
Johan Hedberg3916aed2013-10-07 15:35:26 +02003608 rsp.mps = cpu_to_le16(chan->mps);
Johan Hedberg0cd75f72013-05-17 13:09:05 +03003609 rsp.credits = cpu_to_le16(chan->rx_credits);
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03003610 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
3611
3612 l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CONN_RSP, sizeof(rsp),
3613 &rsp);
3614}
3615
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003616void __l2cap_connect_rsp_defer(struct l2cap_chan *chan)
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003617{
3618 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003619 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003620 u8 buf[128];
Andrei Emeltchenko439f34a2012-10-31 15:46:28 +02003621 u8 rsp_code;
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003622
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003623 rsp.scid = cpu_to_le16(chan->dcid);
3624 rsp.dcid = cpu_to_le16(chan->scid);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003625 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
3626 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Andrei Emeltchenko439f34a2012-10-31 15:46:28 +02003627
3628 if (chan->hs_hcon)
3629 rsp_code = L2CAP_CREATE_CHAN_RSP;
3630 else
3631 rsp_code = L2CAP_CONN_RSP;
3632
3633 BT_DBG("chan %p rsp_code %u", chan, rsp_code);
3634
3635 l2cap_send_cmd(conn, chan->ident, rsp_code, sizeof(rsp), &rsp);
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003636
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003637 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003638 return;
3639
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003640 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003641 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003642 chan->num_conf_req++;
3643}
3644
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003645static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003646{
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003647 int type, olen;
3648 unsigned long val;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003649 /* Use sane default values in case a misbehaving remote device
3650 * did not send an RFC or extended window size option.
3651 */
3652 u16 txwin_ext = chan->ack_win;
3653 struct l2cap_conf_rfc rfc = {
3654 .mode = chan->mode,
3655 .retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO),
3656 .monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO),
3657 .max_pdu_size = cpu_to_le16(chan->imtu),
3658 .txwin_size = min_t(u16, chan->ack_win, L2CAP_DEFAULT_TX_WINDOW),
3659 };
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003660
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003661 BT_DBG("chan %p, rsp %p, len %d", chan, rsp, len);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003662
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003663 if ((chan->mode != L2CAP_MODE_ERTM) && (chan->mode != L2CAP_MODE_STREAMING))
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003664 return;
3665
3666 while (len >= L2CAP_CONF_OPT_SIZE) {
3667 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3668
Mat Martineauc20f8e32012-07-10 05:47:07 -07003669 switch (type) {
3670 case L2CAP_CONF_RFC:
3671 if (olen == sizeof(rfc))
3672 memcpy(&rfc, (void *)val, olen);
Szymon Janc8f321f82012-06-08 11:33:33 +02003673 break;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003674 case L2CAP_CONF_EWS:
3675 txwin_ext = val;
3676 break;
3677 }
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003678 }
3679
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003680 switch (rfc.mode) {
3681 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003682 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3683 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003684 chan->mps = le16_to_cpu(rfc.max_pdu_size);
3685 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3686 chan->ack_win = min_t(u16, chan->ack_win, txwin_ext);
3687 else
3688 chan->ack_win = min_t(u16, chan->ack_win,
3689 rfc.txwin_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003690 break;
3691 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003692 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003693 }
3694}
3695
Gustavo Padovan2d792812012-10-06 10:07:01 +01003696static inline int l2cap_command_rej(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003697 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3698 u8 *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003699{
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003700 struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003701
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003702 if (cmd_len < sizeof(*rej))
3703 return -EPROTO;
3704
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003705 if (rej->reason != L2CAP_REJ_NOT_UNDERSTOOD)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003706 return 0;
3707
3708 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003709 cmd->ident == conn->info_ident) {
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02003710 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01003711
3712 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003713 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003714
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003715 l2cap_conn_start(conn);
3716 }
3717
3718 return 0;
3719}
3720
Mat Martineau17009152012-10-23 15:24:07 -07003721static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
3722 struct l2cap_cmd_hdr *cmd,
3723 u8 *data, u8 rsp_code, u8 amp_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003724{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003725 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
3726 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003727 struct l2cap_chan *chan = NULL, *pchan;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003728 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003729
3730 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003731 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003732
Andrei Emeltchenko097db762012-03-09 14:16:17 +02003733 BT_DBG("psm 0x%2.2x scid 0x%4.4x", __le16_to_cpu(psm), scid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003734
3735 /* Check if we have socket listening on psm */
Marcel Holtmann6f59b902013-10-13 05:24:01 -07003736 pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, &conn->hcon->src,
Johan Hedbergbf20fd42013-05-14 13:23:13 +03003737 &conn->hcon->dst, ACL_LINK);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003738 if (!pchan) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003739 result = L2CAP_CR_BAD_PSM;
3740 goto sendresp;
3741 }
3742
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003743 mutex_lock(&conn->chan_lock);
Gustavo Padovan8ffb9292013-10-21 14:21:41 -02003744 l2cap_chan_lock(pchan);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00003745
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003746 /* Check if the ACL is secure enough (if not SDP) */
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +03003747 if (psm != __constant_cpu_to_le16(L2CAP_PSM_SDP) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003748 !hci_conn_check_link_mode(conn->hcon)) {
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003749 conn->disc_reason = HCI_ERROR_AUTH_FAILURE;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003750 result = L2CAP_CR_SEC_BLOCK;
3751 goto response;
3752 }
3753
Linus Torvalds1da177e2005-04-16 15:20:36 -07003754 result = L2CAP_CR_NO_MEM;
3755
Gustavo Padovan2dfa1002012-05-27 22:27:58 -03003756 /* Check if we already have channel with that dcid */
3757 if (__l2cap_get_chan_by_dcid(conn, scid))
3758 goto response;
3759
Gustavo Padovan80b98022012-05-27 22:27:51 -03003760 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003761 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003762 goto response;
3763
Syam Sidhardhan330b6c12013-08-06 01:59:12 +09003764 /* For certain devices (ex: HID mouse), support for authentication,
3765 * pairing and bonding is optional. For such devices, inorder to avoid
3766 * the ACL alive for too long after L2CAP disconnection, reset the ACL
3767 * disc_timeout back to HCI_DISCONN_TIMEOUT during L2CAP connect.
3768 */
3769 conn->hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
3770
Marcel Holtmann7eafc592013-10-13 08:12:47 -07003771 bacpy(&chan->src, &conn->hcon->src);
3772 bacpy(&chan->dst, &conn->hcon->dst);
Marcel Holtmann4f1654e2013-10-13 08:50:41 -07003773 chan->src_type = bdaddr_type(conn->hcon, conn->hcon->src_type);
3774 chan->dst_type = bdaddr_type(conn->hcon, conn->hcon->dst_type);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003775 chan->psm = psm;
3776 chan->dcid = scid;
Mat Martineau17009152012-10-23 15:24:07 -07003777 chan->local_amp_id = amp_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003778
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003779 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003780
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003781 dcid = chan->scid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003782
Gustavo Padovan8d836d72013-10-15 19:24:47 -03003783 __set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003784
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003785 chan->ident = cmd->ident;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003786
Marcel Holtmann984947d2009-02-06 23:35:19 +01003787 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02003788 if (l2cap_chan_check_security(chan)) {
Marcel Holtmannbdc25782013-10-14 02:45:34 -07003789 if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02003790 l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003791 result = L2CAP_CR_PEND;
3792 status = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08003793 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003794 } else {
Mat Martineau17009152012-10-23 15:24:07 -07003795 /* Force pending result for AMP controllers.
3796 * The connection will succeed after the
3797 * physical link is up.
3798 */
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003799 if (amp_id == AMP_ID_BREDR) {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02003800 l2cap_state_change(chan, BT_CONFIG);
Mat Martineau17009152012-10-23 15:24:07 -07003801 result = L2CAP_CR_SUCCESS;
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003802 } else {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02003803 l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003804 result = L2CAP_CR_PEND;
Mat Martineau17009152012-10-23 15:24:07 -07003805 }
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003806 status = L2CAP_CS_NO_INFO;
3807 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003808 } else {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02003809 l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003810 result = L2CAP_CR_PEND;
3811 status = L2CAP_CS_AUTHEN_PEND;
3812 }
3813 } else {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02003814 l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003815 result = L2CAP_CR_PEND;
3816 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003817 }
3818
Linus Torvalds1da177e2005-04-16 15:20:36 -07003819response:
Gustavo Padovan8ffb9292013-10-21 14:21:41 -02003820 l2cap_chan_unlock(pchan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003821 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003822
3823sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003824 rsp.scid = cpu_to_le16(scid);
3825 rsp.dcid = cpu_to_le16(dcid);
3826 rsp.result = cpu_to_le16(result);
3827 rsp.status = cpu_to_le16(status);
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003828 l2cap_send_cmd(conn, cmd->ident, rsp_code, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003829
3830 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
3831 struct l2cap_info_req info;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003832 info.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003833
3834 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
3835 conn->info_ident = l2cap_get_ident(conn);
3836
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08003837 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003838
Gustavo Padovan2d792812012-10-06 10:07:01 +01003839 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
3840 sizeof(info), &info);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003841 }
3842
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003843 if (chan && !test_bit(CONF_REQ_SENT, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003844 result == L2CAP_CR_SUCCESS) {
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003845 u8 buf[128];
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003846 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003847 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003848 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003849 chan->num_conf_req++;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003850 }
Mat Martineau17009152012-10-23 15:24:07 -07003851
3852 return chan;
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003853}
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003854
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003855static int l2cap_connect_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003856 struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003857{
Jaganath Kanakkassery7b064ed2013-01-10 10:28:35 +05303858 struct hci_dev *hdev = conn->hcon->hdev;
3859 struct hci_conn *hcon = conn->hcon;
3860
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003861 if (cmd_len < sizeof(struct l2cap_conn_req))
3862 return -EPROTO;
3863
Jaganath Kanakkassery7b064ed2013-01-10 10:28:35 +05303864 hci_dev_lock(hdev);
3865 if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
3866 !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &hcon->flags))
3867 mgmt_device_connected(hdev, &hcon->dst, hcon->type,
3868 hcon->dst_type, 0, NULL, 0,
3869 hcon->dev_class);
3870 hci_dev_unlock(hdev);
3871
Gustavo Padovan300229f2012-10-12 19:40:40 +08003872 l2cap_connect(conn, cmd, data, L2CAP_CONN_RSP, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003873 return 0;
3874}
3875
Mat Martineau5909cf32012-10-23 15:24:08 -07003876static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003877 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3878 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003879{
3880 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
3881 u16 scid, dcid, result, status;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003882 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003883 u8 req[128];
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003884 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003885
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003886 if (cmd_len < sizeof(*rsp))
3887 return -EPROTO;
3888
Linus Torvalds1da177e2005-04-16 15:20:36 -07003889 scid = __le16_to_cpu(rsp->scid);
3890 dcid = __le16_to_cpu(rsp->dcid);
3891 result = __le16_to_cpu(rsp->result);
3892 status = __le16_to_cpu(rsp->status);
3893
Andrei Emeltchenko1b009c92012-02-21 12:54:54 +02003894 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 +01003895 dcid, scid, result, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003896
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003897 mutex_lock(&conn->chan_lock);
3898
Linus Torvalds1da177e2005-04-16 15:20:36 -07003899 if (scid) {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003900 chan = __l2cap_get_chan_by_scid(conn, scid);
3901 if (!chan) {
Johan Hedberg21870b52013-09-16 13:05:14 +03003902 err = -EBADSLT;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003903 goto unlock;
3904 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003905 } else {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003906 chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
3907 if (!chan) {
Johan Hedberg21870b52013-09-16 13:05:14 +03003908 err = -EBADSLT;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003909 goto unlock;
3910 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003911 }
3912
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003913 err = 0;
3914
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003915 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003916
Linus Torvalds1da177e2005-04-16 15:20:36 -07003917 switch (result) {
3918 case L2CAP_CR_SUCCESS:
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03003919 l2cap_state_change(chan, BT_CONFIG);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003920 chan->ident = 0;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003921 chan->dcid = dcid;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003922 clear_bit(CONF_CONNECT_PEND, &chan->conf_state);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003923
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003924 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003925 break;
3926
Linus Torvalds1da177e2005-04-16 15:20:36 -07003927 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003928 l2cap_build_conf_req(chan, req), req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003929 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003930 break;
3931
3932 case L2CAP_CR_PEND:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003933 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003934 break;
3935
3936 default:
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003937 l2cap_chan_del(chan, ECONNREFUSED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003938 break;
3939 }
3940
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003941 l2cap_chan_unlock(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003942
3943unlock:
3944 mutex_unlock(&conn->chan_lock);
3945
3946 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003947}
3948
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003949static inline void set_default_fcs(struct l2cap_chan *chan)
Mat Martineau8c462b62010-08-24 15:35:42 -07003950{
3951 /* FCS is enabled only in ERTM or streaming mode, if one or both
3952 * sides request it.
3953 */
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003954 if (chan->mode != L2CAP_MODE_ERTM && chan->mode != L2CAP_MODE_STREAMING)
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003955 chan->fcs = L2CAP_FCS_NONE;
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003956 else if (!test_bit(CONF_RECV_NO_FCS, &chan->conf_state))
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003957 chan->fcs = L2CAP_FCS_CRC16;
Mat Martineau8c462b62010-08-24 15:35:42 -07003958}
3959
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03003960static void l2cap_send_efs_conf_rsp(struct l2cap_chan *chan, void *data,
3961 u8 ident, u16 flags)
3962{
3963 struct l2cap_conn *conn = chan->conn;
3964
3965 BT_DBG("conn %p chan %p ident %d flags 0x%4.4x", conn, chan, ident,
3966 flags);
3967
3968 clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
3969 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
3970
3971 l2cap_send_cmd(conn, ident, L2CAP_CONF_RSP,
3972 l2cap_build_conf_rsp(chan, data,
3973 L2CAP_CONF_SUCCESS, flags), data);
3974}
3975
Johan Hedberg662d6522013-10-16 11:20:47 +03003976static void cmd_reject_invalid_cid(struct l2cap_conn *conn, u8 ident,
3977 u16 scid, u16 dcid)
3978{
3979 struct l2cap_cmd_rej_cid rej;
3980
3981 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_INVALID_CID);
3982 rej.scid = __cpu_to_le16(scid);
3983 rej.dcid = __cpu_to_le16(dcid);
3984
3985 l2cap_send_cmd(conn, ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
3986}
3987
Gustavo Padovan2d792812012-10-06 10:07:01 +01003988static inline int l2cap_config_req(struct l2cap_conn *conn,
3989 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3990 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003991{
3992 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
3993 u16 dcid, flags;
3994 u8 rsp[64];
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003995 struct l2cap_chan *chan;
Mat Martineau3c588192012-04-11 10:48:42 -07003996 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003997
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003998 if (cmd_len < sizeof(*req))
3999 return -EPROTO;
4000
Linus Torvalds1da177e2005-04-16 15:20:36 -07004001 dcid = __le16_to_cpu(req->dcid);
4002 flags = __le16_to_cpu(req->flags);
4003
4004 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
4005
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03004006 chan = l2cap_get_chan_by_scid(conn, dcid);
Johan Hedberg662d6522013-10-16 11:20:47 +03004007 if (!chan) {
4008 cmd_reject_invalid_cid(conn, cmd->ident, dcid, 0);
4009 return 0;
4010 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004011
David S. Miller033b1142011-07-21 13:38:42 -07004012 if (chan->state != BT_CONFIG && chan->state != BT_CONNECT2) {
Johan Hedberg662d6522013-10-16 11:20:47 +03004013 cmd_reject_invalid_cid(conn, cmd->ident, chan->scid,
4014 chan->dcid);
Marcel Holtmann354f60a2006-11-18 22:15:20 +01004015 goto unlock;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03004016 }
Marcel Holtmann354f60a2006-11-18 22:15:20 +01004017
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004018 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07004019 len = cmd_len - sizeof(*req);
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004020 if (chan->conf_len + len > sizeof(chan->conf_req)) {
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004021 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004022 l2cap_build_conf_rsp(chan, rsp,
4023 L2CAP_CONF_REJECT, flags), rsp);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004024 goto unlock;
4025 }
4026
4027 /* Store config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004028 memcpy(chan->conf_req + chan->conf_len, req->data, len);
4029 chan->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004030
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03004031 if (flags & L2CAP_CONF_FLAG_CONTINUATION) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004032 /* Incomplete config. Send empty response. */
4033 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004034 l2cap_build_conf_rsp(chan, rsp,
4035 L2CAP_CONF_SUCCESS, flags), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004036 goto unlock;
4037 }
4038
4039 /* Complete config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004040 len = l2cap_parse_conf_req(chan, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004041 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004042 l2cap_send_disconn_req(chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004043 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004044 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004045
Mat Martineau1500109b2012-10-23 15:24:15 -07004046 chan->ident = cmd->ident;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004047 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004048 chan->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004049
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004050 /* Reset config buffer. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004051 chan->conf_len = 0;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004052
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004053 if (!test_bit(CONF_OUTPUT_DONE, &chan->conf_state))
Marcel Holtmann876d9482007-10-20 13:35:42 +02004054 goto unlock;
4055
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004056 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004057 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004058
Mat Martineau105bdf92012-04-27 16:50:48 -07004059 if (chan->mode == L2CAP_MODE_ERTM ||
4060 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07004061 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03004062
Mat Martineau3c588192012-04-11 10:48:42 -07004063 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004064 l2cap_send_disconn_req(chan, -err);
Mat Martineau3c588192012-04-11 10:48:42 -07004065 else
4066 l2cap_chan_ready(chan);
4067
Marcel Holtmann876d9482007-10-20 13:35:42 +02004068 goto unlock;
4069 }
4070
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004071 if (!test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004072 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004073 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004074 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004075 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004076 }
4077
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004078 /* Got Conf Rsp PENDING from remote side and asume we sent
4079 Conf Rsp PENDING in the code above */
4080 if (test_bit(CONF_REM_CONF_PEND, &chan->conf_state) &&
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03004081 test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004082
4083 /* check compatibility */
4084
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004085 /* Send rsp for BR/EDR channel */
Andrei Emeltchenkof351bc72012-10-31 15:46:35 +02004086 if (!chan->hs_hcon)
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004087 l2cap_send_efs_conf_rsp(chan, rsp, cmd->ident, flags);
4088 else
4089 chan->ident = cmd->ident;
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004090 }
4091
Linus Torvalds1da177e2005-04-16 15:20:36 -07004092unlock:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004093 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07004094 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004095}
4096
Gustavo Padovan2d792812012-10-06 10:07:01 +01004097static inline int l2cap_config_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004098 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4099 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004100{
4101 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
4102 u16 scid, flags, result;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004103 struct l2cap_chan *chan;
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004104 int len = cmd_len - sizeof(*rsp);
Mat Martineau3c588192012-04-11 10:48:42 -07004105 int err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004106
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004107 if (cmd_len < sizeof(*rsp))
4108 return -EPROTO;
4109
Linus Torvalds1da177e2005-04-16 15:20:36 -07004110 scid = __le16_to_cpu(rsp->scid);
4111 flags = __le16_to_cpu(rsp->flags);
4112 result = __le16_to_cpu(rsp->result);
4113
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02004114 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x len %d", scid, flags,
4115 result, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004116
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03004117 chan = l2cap_get_chan_by_scid(conn, scid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004118 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004119 return 0;
4120
4121 switch (result) {
4122 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004123 l2cap_conf_rfc_get(chan, rsp->data, len);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004124 clear_bit(CONF_REM_CONF_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004125 break;
4126
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004127 case L2CAP_CONF_PENDING:
4128 set_bit(CONF_REM_CONF_PEND, &chan->conf_state);
4129
4130 if (test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
4131 char buf[64];
4132
4133 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004134 buf, &result);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004135 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004136 l2cap_send_disconn_req(chan, ECONNRESET);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004137 goto done;
4138 }
4139
Andrei Emeltchenkof351bc72012-10-31 15:46:35 +02004140 if (!chan->hs_hcon) {
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004141 l2cap_send_efs_conf_rsp(chan, buf, cmd->ident,
4142 0);
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +02004143 } else {
4144 if (l2cap_check_efs(chan)) {
4145 amp_create_logical_link(chan);
4146 chan->ident = cmd->ident;
4147 }
4148 }
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004149 }
4150 goto done;
4151
Linus Torvalds1da177e2005-04-16 15:20:36 -07004152 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004153 if (chan->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004154 char req[64];
4155
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02004156 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004157 l2cap_send_disconn_req(chan, ECONNRESET);
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02004158 goto done;
4159 }
4160
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004161 /* throw out any old stored conf requests */
4162 result = L2CAP_CONF_SUCCESS;
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03004163 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004164 req, &result);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004165 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004166 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004167 goto done;
4168 }
4169
4170 l2cap_send_cmd(conn, l2cap_get_ident(conn),
Gustavo Padovan2d792812012-10-06 10:07:01 +01004171 L2CAP_CONF_REQ, len, req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004172 chan->num_conf_req++;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004173 if (result != L2CAP_CONF_SUCCESS)
4174 goto done;
4175 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004176 }
4177
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09004178 default:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004179 l2cap_chan_set_err(chan, ECONNRESET);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02004180
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08004181 __set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004182 l2cap_send_disconn_req(chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004183 goto done;
4184 }
4185
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03004186 if (flags & L2CAP_CONF_FLAG_CONTINUATION)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004187 goto done;
4188
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004189 set_bit(CONF_INPUT_DONE, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004190
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004191 if (test_bit(CONF_OUTPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004192 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004193
Mat Martineau105bdf92012-04-27 16:50:48 -07004194 if (chan->mode == L2CAP_MODE_ERTM ||
4195 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07004196 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03004197
Mat Martineau3c588192012-04-11 10:48:42 -07004198 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004199 l2cap_send_disconn_req(chan, -err);
Mat Martineau3c588192012-04-11 10:48:42 -07004200 else
4201 l2cap_chan_ready(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004202 }
4203
4204done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004205 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07004206 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004207}
4208
Gustavo Padovan2d792812012-10-06 10:07:01 +01004209static inline int l2cap_disconnect_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004210 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4211 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004212{
4213 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
4214 struct l2cap_disconn_rsp rsp;
4215 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004216 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004217
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004218 if (cmd_len != sizeof(*req))
4219 return -EPROTO;
4220
Linus Torvalds1da177e2005-04-16 15:20:36 -07004221 scid = __le16_to_cpu(req->scid);
4222 dcid = __le16_to_cpu(req->dcid);
4223
4224 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
4225
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004226 mutex_lock(&conn->chan_lock);
4227
4228 chan = __l2cap_get_chan_by_scid(conn, dcid);
4229 if (!chan) {
4230 mutex_unlock(&conn->chan_lock);
Johan Hedberg662d6522013-10-16 11:20:47 +03004231 cmd_reject_invalid_cid(conn, cmd->ident, dcid, scid);
4232 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004233 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004234
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004235 l2cap_chan_lock(chan);
4236
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03004237 rsp.dcid = cpu_to_le16(chan->scid);
4238 rsp.scid = cpu_to_le16(chan->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004239 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
4240
Gustavo Padovan5ec1bbe2013-10-15 19:24:48 -03004241 chan->ops->set_shutdown(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004242
Mat Martineau61d6ef32012-04-27 16:50:50 -07004243 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004244 l2cap_chan_del(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004245
4246 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004247
Gustavo Padovan80b98022012-05-27 22:27:51 -03004248 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004249 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004250
4251 mutex_unlock(&conn->chan_lock);
4252
Linus Torvalds1da177e2005-04-16 15:20:36 -07004253 return 0;
4254}
4255
Gustavo Padovan2d792812012-10-06 10:07:01 +01004256static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004257 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4258 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004259{
4260 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
4261 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004262 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004263
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004264 if (cmd_len != sizeof(*rsp))
4265 return -EPROTO;
4266
Linus Torvalds1da177e2005-04-16 15:20:36 -07004267 scid = __le16_to_cpu(rsp->scid);
4268 dcid = __le16_to_cpu(rsp->dcid);
4269
4270 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
4271
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004272 mutex_lock(&conn->chan_lock);
4273
4274 chan = __l2cap_get_chan_by_scid(conn, scid);
4275 if (!chan) {
4276 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004277 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004278 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004279
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004280 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004281
Mat Martineau61d6ef32012-04-27 16:50:50 -07004282 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004283 l2cap_chan_del(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004284
4285 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004286
Gustavo Padovan80b98022012-05-27 22:27:51 -03004287 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004288 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004289
4290 mutex_unlock(&conn->chan_lock);
4291
Linus Torvalds1da177e2005-04-16 15:20:36 -07004292 return 0;
4293}
4294
Gustavo Padovan2d792812012-10-06 10:07:01 +01004295static inline int l2cap_information_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004296 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4297 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004298{
4299 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004300 u16 type;
4301
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004302 if (cmd_len != sizeof(*req))
4303 return -EPROTO;
4304
Linus Torvalds1da177e2005-04-16 15:20:36 -07004305 type = __le16_to_cpu(req->type);
4306
4307 BT_DBG("type 0x%4.4x", type);
4308
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004309 if (type == L2CAP_IT_FEAT_MASK) {
4310 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07004311 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004312 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004313 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
4314 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03004315 if (!disable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004316 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
Gustavo Padovan2d792812012-10-06 10:07:01 +01004317 | L2CAP_FEAT_FCS;
Marcel Holtmann848566b2013-10-01 22:59:22 -07004318 if (conn->hs_enabled)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03004319 feat_mask |= L2CAP_FEAT_EXT_FLOW
Gustavo Padovan2d792812012-10-06 10:07:01 +01004320 | L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03004321
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03004322 put_unaligned_le32(feat_mask, rsp->data);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004323 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4324 buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004325 } else if (type == L2CAP_IT_FIXED_CHAN) {
4326 u8 buf[12];
4327 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Mat Martineau50a147c2011-11-02 16:18:34 -07004328
Marcel Holtmann848566b2013-10-01 22:59:22 -07004329 if (conn->hs_enabled)
Mat Martineau50a147c2011-11-02 16:18:34 -07004330 l2cap_fixed_chan[0] |= L2CAP_FC_A2MP;
4331 else
4332 l2cap_fixed_chan[0] &= ~L2CAP_FC_A2MP;
4333
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004334 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
4335 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Andrei Emeltchenkoc6337ea2011-10-20 17:02:44 +03004336 memcpy(rsp->data, l2cap_fixed_chan, sizeof(l2cap_fixed_chan));
Gustavo Padovan2d792812012-10-06 10:07:01 +01004337 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4338 buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004339 } else {
4340 struct l2cap_info_rsp rsp;
4341 rsp.type = cpu_to_le16(type);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004342 rsp.result = __constant_cpu_to_le16(L2CAP_IR_NOTSUPP);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004343 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(rsp),
4344 &rsp);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004345 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004346
4347 return 0;
4348}
4349
Gustavo Padovan2d792812012-10-06 10:07:01 +01004350static inline int l2cap_information_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004351 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4352 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004353{
4354 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
4355 u16 type, result;
4356
Jaganath Kanakkassery3f6fa3d2013-06-21 19:55:11 +05304357 if (cmd_len < sizeof(*rsp))
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004358 return -EPROTO;
4359
Linus Torvalds1da177e2005-04-16 15:20:36 -07004360 type = __le16_to_cpu(rsp->type);
4361 result = __le16_to_cpu(rsp->result);
4362
4363 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
4364
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004365 /* L2CAP Info req/rsp are unbound to channels, add extra checks */
4366 if (cmd->ident != conn->info_ident ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01004367 conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004368 return 0;
4369
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02004370 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004371
Ville Tervoadb08ed2010-08-04 09:43:33 +03004372 if (result != L2CAP_IR_SUCCESS) {
4373 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4374 conn->info_ident = 0;
4375
4376 l2cap_conn_start(conn);
4377
4378 return 0;
4379 }
4380
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004381 switch (type) {
4382 case L2CAP_IT_FEAT_MASK:
Harvey Harrison83985312008-05-02 16:25:46 -07004383 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004384
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07004385 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004386 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004387 req.type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004388
4389 conn->info_ident = l2cap_get_ident(conn);
4390
4391 l2cap_send_cmd(conn, conn->info_ident,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004392 L2CAP_INFO_REQ, sizeof(req), &req);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004393 } else {
4394 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4395 conn->info_ident = 0;
4396
4397 l2cap_conn_start(conn);
4398 }
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004399 break;
4400
4401 case L2CAP_IT_FIXED_CHAN:
4402 conn->fixed_chan_mask = rsp->data[0];
Marcel Holtmann984947d2009-02-06 23:35:19 +01004403 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004404 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004405
4406 l2cap_conn_start(conn);
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004407 break;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004408 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004409
Linus Torvalds1da177e2005-04-16 15:20:36 -07004410 return 0;
4411}
4412
Mat Martineau17009152012-10-23 15:24:07 -07004413static int l2cap_create_channel_req(struct l2cap_conn *conn,
4414 struct l2cap_cmd_hdr *cmd,
4415 u16 cmd_len, void *data)
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004416{
4417 struct l2cap_create_chan_req *req = data;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004418 struct l2cap_create_chan_rsp rsp;
Mat Martineau17009152012-10-23 15:24:07 -07004419 struct l2cap_chan *chan;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004420 struct hci_dev *hdev;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004421 u16 psm, scid;
4422
4423 if (cmd_len != sizeof(*req))
4424 return -EPROTO;
4425
Marcel Holtmann848566b2013-10-01 22:59:22 -07004426 if (!conn->hs_enabled)
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004427 return -EINVAL;
4428
4429 psm = le16_to_cpu(req->psm);
4430 scid = le16_to_cpu(req->scid);
4431
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004432 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 -07004433
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004434 /* For controller id 0 make BR/EDR connection */
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004435 if (req->amp_id == AMP_ID_BREDR) {
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004436 l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4437 req->amp_id);
4438 return 0;
4439 }
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004440
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004441 /* Validate AMP controller id */
4442 hdev = hci_dev_get(req->amp_id);
4443 if (!hdev)
4444 goto error;
Mat Martineau17009152012-10-23 15:24:07 -07004445
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004446 if (hdev->dev_type != HCI_AMP || !test_bit(HCI_UP, &hdev->flags)) {
Mat Martineau17009152012-10-23 15:24:07 -07004447 hci_dev_put(hdev);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004448 goto error;
Mat Martineau17009152012-10-23 15:24:07 -07004449 }
4450
4451 chan = l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4452 req->amp_id);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004453 if (chan) {
4454 struct amp_mgr *mgr = conn->hcon->amp_mgr;
4455 struct hci_conn *hs_hcon;
4456
Marcel Holtmann98e0f7e2013-10-13 02:23:40 -07004457 hs_hcon = hci_conn_hash_lookup_ba(hdev, AMP_LINK,
4458 &conn->hcon->dst);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004459 if (!hs_hcon) {
4460 hci_dev_put(hdev);
Johan Hedberg662d6522013-10-16 11:20:47 +03004461 cmd_reject_invalid_cid(conn, cmd->ident, chan->scid,
4462 chan->dcid);
4463 return 0;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004464 }
4465
4466 BT_DBG("mgr %p bredr_chan %p hs_hcon %p", mgr, chan, hs_hcon);
4467
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004468 mgr->bredr_chan = chan;
4469 chan->hs_hcon = hs_hcon;
Andrei Emeltchenkofd45bf42012-11-20 17:16:22 +02004470 chan->fcs = L2CAP_FCS_NONE;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004471 conn->mtu = hdev->block_mtu;
4472 }
4473
4474 hci_dev_put(hdev);
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004475
4476 return 0;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004477
4478error:
4479 rsp.dcid = 0;
4480 rsp.scid = cpu_to_le16(scid);
4481 rsp.result = __constant_cpu_to_le16(L2CAP_CR_BAD_AMP);
4482 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
4483
4484 l2cap_send_cmd(conn, cmd->ident, L2CAP_CREATE_CHAN_RSP,
4485 sizeof(rsp), &rsp);
4486
Johan Hedbergdc280802013-09-16 13:05:13 +03004487 return 0;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004488}
4489
Mat Martineau8eb200b2012-10-23 15:24:17 -07004490static void l2cap_send_move_chan_req(struct l2cap_chan *chan, u8 dest_amp_id)
4491{
4492 struct l2cap_move_chan_req req;
4493 u8 ident;
4494
4495 BT_DBG("chan %p, dest_amp_id %d", chan, dest_amp_id);
4496
4497 ident = l2cap_get_ident(chan->conn);
4498 chan->ident = ident;
4499
4500 req.icid = cpu_to_le16(chan->scid);
4501 req.dest_amp_id = dest_amp_id;
4502
4503 l2cap_send_cmd(chan->conn, ident, L2CAP_MOVE_CHAN_REQ, sizeof(req),
4504 &req);
4505
4506 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4507}
4508
Mat Martineau1500109b2012-10-23 15:24:15 -07004509static void l2cap_send_move_chan_rsp(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004510{
4511 struct l2cap_move_chan_rsp rsp;
4512
Mat Martineau1500109b2012-10-23 15:24:15 -07004513 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004514
Mat Martineau1500109b2012-10-23 15:24:15 -07004515 rsp.icid = cpu_to_le16(chan->dcid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004516 rsp.result = cpu_to_le16(result);
4517
Mat Martineau1500109b2012-10-23 15:24:15 -07004518 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_RSP,
4519 sizeof(rsp), &rsp);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004520}
4521
Mat Martineau5b155ef2012-10-23 15:24:14 -07004522static void l2cap_send_move_chan_cfm(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004523{
4524 struct l2cap_move_chan_cfm cfm;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004525
Mat Martineau5b155ef2012-10-23 15:24:14 -07004526 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004527
Mat Martineau5b155ef2012-10-23 15:24:14 -07004528 chan->ident = l2cap_get_ident(chan->conn);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004529
Mat Martineau5b155ef2012-10-23 15:24:14 -07004530 cfm.icid = cpu_to_le16(chan->scid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004531 cfm.result = cpu_to_le16(result);
4532
Mat Martineau5b155ef2012-10-23 15:24:14 -07004533 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_CFM,
4534 sizeof(cfm), &cfm);
4535
4536 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4537}
4538
4539static void l2cap_send_move_chan_cfm_icid(struct l2cap_conn *conn, u16 icid)
4540{
4541 struct l2cap_move_chan_cfm cfm;
4542
4543 BT_DBG("conn %p, icid 0x%4.4x", conn, icid);
4544
4545 cfm.icid = cpu_to_le16(icid);
4546 cfm.result = __constant_cpu_to_le16(L2CAP_MC_UNCONFIRMED);
4547
4548 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_MOVE_CHAN_CFM,
4549 sizeof(cfm), &cfm);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004550}
4551
4552static void l2cap_send_move_chan_cfm_rsp(struct l2cap_conn *conn, u8 ident,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004553 u16 icid)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004554{
4555 struct l2cap_move_chan_cfm_rsp rsp;
4556
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004557 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004558
4559 rsp.icid = cpu_to_le16(icid);
4560 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM_RSP, sizeof(rsp), &rsp);
4561}
4562
Mat Martineau5f3847a2012-10-23 15:24:12 -07004563static void __release_logical_link(struct l2cap_chan *chan)
4564{
4565 chan->hs_hchan = NULL;
4566 chan->hs_hcon = NULL;
4567
4568 /* Placeholder - release the logical link */
4569}
4570
Mat Martineau1500109b2012-10-23 15:24:15 -07004571static void l2cap_logical_fail(struct l2cap_chan *chan)
4572{
4573 /* Logical link setup failed */
4574 if (chan->state != BT_CONNECTED) {
4575 /* Create channel failure, disconnect */
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004576 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineau1500109b2012-10-23 15:24:15 -07004577 return;
4578 }
4579
4580 switch (chan->move_role) {
4581 case L2CAP_MOVE_ROLE_RESPONDER:
4582 l2cap_move_done(chan);
4583 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_SUPP);
4584 break;
4585 case L2CAP_MOVE_ROLE_INITIATOR:
4586 if (chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_COMP ||
4587 chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_CFM) {
4588 /* Remote has only sent pending or
4589 * success responses, clean up
4590 */
4591 l2cap_move_done(chan);
4592 }
4593
4594 /* Other amp move states imply that the move
4595 * has already aborted
4596 */
4597 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4598 break;
4599 }
4600}
4601
4602static void l2cap_logical_finish_create(struct l2cap_chan *chan,
4603 struct hci_chan *hchan)
4604{
4605 struct l2cap_conf_rsp rsp;
Mat Martineau1500109b2012-10-23 15:24:15 -07004606
Andrei Emeltchenko336178a2012-10-31 15:46:27 +02004607 chan->hs_hchan = hchan;
Mat Martineau1500109b2012-10-23 15:24:15 -07004608 chan->hs_hcon->l2cap_data = chan->conn;
4609
Andrei Emeltchenko35ba9562012-10-25 15:20:43 +03004610 l2cap_send_efs_conf_rsp(chan, &rsp, chan->ident, 0);
Mat Martineau1500109b2012-10-23 15:24:15 -07004611
4612 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Andrei Emeltchenkofe79c6f2012-10-25 15:20:42 +03004613 int err;
Mat Martineau1500109b2012-10-23 15:24:15 -07004614
4615 set_default_fcs(chan);
4616
4617 err = l2cap_ertm_init(chan);
4618 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004619 l2cap_send_disconn_req(chan, -err);
Mat Martineau1500109b2012-10-23 15:24:15 -07004620 else
4621 l2cap_chan_ready(chan);
4622 }
4623}
4624
4625static void l2cap_logical_finish_move(struct l2cap_chan *chan,
4626 struct hci_chan *hchan)
4627{
4628 chan->hs_hcon = hchan->conn;
4629 chan->hs_hcon->l2cap_data = chan->conn;
4630
4631 BT_DBG("move_state %d", chan->move_state);
4632
4633 switch (chan->move_state) {
4634 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
4635 /* Move confirm will be sent after a success
4636 * response is received
4637 */
4638 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4639 break;
4640 case L2CAP_MOVE_WAIT_LOGICAL_CFM:
4641 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4642 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4643 } else if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
4644 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
4645 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4646 } else if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
4647 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4648 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
4649 }
4650 break;
4651 default:
4652 /* Move was not in expected state, free the channel */
4653 __release_logical_link(chan);
4654
4655 chan->move_state = L2CAP_MOVE_STABLE;
4656 }
4657}
4658
4659/* Call with chan locked */
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03004660void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan,
4661 u8 status)
Mat Martineau5b155ef2012-10-23 15:24:14 -07004662{
Mat Martineau1500109b2012-10-23 15:24:15 -07004663 BT_DBG("chan %p, hchan %p, status %d", chan, hchan, status);
4664
4665 if (status) {
4666 l2cap_logical_fail(chan);
4667 __release_logical_link(chan);
4668 return;
4669 }
4670
4671 if (chan->state != BT_CONNECTED) {
4672 /* Ignore logical link if channel is on BR/EDR */
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004673 if (chan->local_amp_id != AMP_ID_BREDR)
Mat Martineau1500109b2012-10-23 15:24:15 -07004674 l2cap_logical_finish_create(chan, hchan);
4675 } else {
4676 l2cap_logical_finish_move(chan, hchan);
4677 }
Mat Martineau5b155ef2012-10-23 15:24:14 -07004678}
4679
Mat Martineau3f7a56c2012-10-23 15:24:23 -07004680void l2cap_move_start(struct l2cap_chan *chan)
4681{
4682 BT_DBG("chan %p", chan);
4683
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004684 if (chan->local_amp_id == AMP_ID_BREDR) {
Mat Martineau3f7a56c2012-10-23 15:24:23 -07004685 if (chan->chan_policy != BT_CHANNEL_POLICY_AMP_PREFERRED)
4686 return;
4687 chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
4688 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
4689 /* Placeholder - start physical link setup */
4690 } else {
4691 chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
4692 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4693 chan->move_id = 0;
4694 l2cap_move_setup(chan);
4695 l2cap_send_move_chan_req(chan, 0);
4696 }
4697}
4698
Mat Martineau8eb200b2012-10-23 15:24:17 -07004699static void l2cap_do_create(struct l2cap_chan *chan, int result,
4700 u8 local_amp_id, u8 remote_amp_id)
4701{
Andrei Emeltchenko62748ca2012-11-20 17:16:19 +02004702 BT_DBG("chan %p state %s %u -> %u", chan, state_to_string(chan->state),
4703 local_amp_id, remote_amp_id);
4704
Andrei Emeltchenko12d6cc62012-11-14 17:39:31 +02004705 chan->fcs = L2CAP_FCS_NONE;
4706
Andrei Emeltchenko62748ca2012-11-20 17:16:19 +02004707 /* Outgoing channel on AMP */
4708 if (chan->state == BT_CONNECT) {
4709 if (result == L2CAP_CR_SUCCESS) {
4710 chan->local_amp_id = local_amp_id;
4711 l2cap_send_create_chan_req(chan, remote_amp_id);
4712 } else {
4713 /* Revert to BR/EDR connect */
4714 l2cap_send_conn_req(chan);
4715 }
4716
4717 return;
4718 }
4719
4720 /* Incoming channel on AMP */
4721 if (__l2cap_no_conn_pending(chan)) {
Mat Martineau8eb200b2012-10-23 15:24:17 -07004722 struct l2cap_conn_rsp rsp;
4723 char buf[128];
4724 rsp.scid = cpu_to_le16(chan->dcid);
4725 rsp.dcid = cpu_to_le16(chan->scid);
4726
Mat Martineau8eb200b2012-10-23 15:24:17 -07004727 if (result == L2CAP_CR_SUCCESS) {
4728 /* Send successful response */
Andrei Emeltchenko62cd50e2012-11-14 17:39:32 +02004729 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
4730 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004731 } else {
4732 /* Send negative response */
Andrei Emeltchenko62cd50e2012-11-14 17:39:32 +02004733 rsp.result = __constant_cpu_to_le16(L2CAP_CR_NO_MEM);
4734 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004735 }
4736
4737 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_RSP,
4738 sizeof(rsp), &rsp);
4739
4740 if (result == L2CAP_CR_SUCCESS) {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02004741 l2cap_state_change(chan, BT_CONFIG);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004742 set_bit(CONF_REQ_SENT, &chan->conf_state);
4743 l2cap_send_cmd(chan->conn, l2cap_get_ident(chan->conn),
4744 L2CAP_CONF_REQ,
4745 l2cap_build_conf_req(chan, buf), buf);
4746 chan->num_conf_req++;
4747 }
Mat Martineau8eb200b2012-10-23 15:24:17 -07004748 }
4749}
4750
4751static void l2cap_do_move_initiate(struct l2cap_chan *chan, u8 local_amp_id,
4752 u8 remote_amp_id)
4753{
4754 l2cap_move_setup(chan);
4755 chan->move_id = local_amp_id;
4756 chan->move_state = L2CAP_MOVE_WAIT_RSP;
4757
4758 l2cap_send_move_chan_req(chan, remote_amp_id);
4759}
4760
4761static void l2cap_do_move_respond(struct l2cap_chan *chan, int result)
4762{
4763 struct hci_chan *hchan = NULL;
4764
4765 /* Placeholder - get hci_chan for logical link */
4766
4767 if (hchan) {
4768 if (hchan->state == BT_CONNECTED) {
4769 /* Logical link is ready to go */
4770 chan->hs_hcon = hchan->conn;
4771 chan->hs_hcon->l2cap_data = chan->conn;
4772 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4773 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
4774
4775 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
4776 } else {
4777 /* Wait for logical link to be ready */
4778 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4779 }
4780 } else {
4781 /* Logical link not available */
4782 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_ALLOWED);
4783 }
4784}
4785
4786static void l2cap_do_move_cancel(struct l2cap_chan *chan, int result)
4787{
4788 if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
4789 u8 rsp_result;
4790 if (result == -EINVAL)
4791 rsp_result = L2CAP_MR_BAD_ID;
4792 else
4793 rsp_result = L2CAP_MR_NOT_ALLOWED;
4794
4795 l2cap_send_move_chan_rsp(chan, rsp_result);
4796 }
4797
4798 chan->move_role = L2CAP_MOVE_ROLE_NONE;
4799 chan->move_state = L2CAP_MOVE_STABLE;
4800
4801 /* Restart data transmission */
4802 l2cap_ertm_send(chan);
4803}
4804
Andrei Emeltchenkoa514b172012-11-14 17:39:30 +02004805/* Invoke with locked chan */
4806void __l2cap_physical_cfm(struct l2cap_chan *chan, int result)
Mat Martineau8eb200b2012-10-23 15:24:17 -07004807{
Andrei Emeltchenko770bfef2012-10-31 15:46:29 +02004808 u8 local_amp_id = chan->local_amp_id;
Andrei Emeltchenkofffadc02012-11-01 15:37:03 +02004809 u8 remote_amp_id = chan->remote_amp_id;
Andrei Emeltchenko770bfef2012-10-31 15:46:29 +02004810
Mat Martineau8eb200b2012-10-23 15:24:17 -07004811 BT_DBG("chan %p, result %d, local_amp_id %d, remote_amp_id %d",
4812 chan, result, local_amp_id, remote_amp_id);
4813
Mat Martineau8eb200b2012-10-23 15:24:17 -07004814 if (chan->state == BT_DISCONN || chan->state == BT_CLOSED) {
4815 l2cap_chan_unlock(chan);
4816 return;
4817 }
4818
4819 if (chan->state != BT_CONNECTED) {
4820 l2cap_do_create(chan, result, local_amp_id, remote_amp_id);
4821 } else if (result != L2CAP_MR_SUCCESS) {
4822 l2cap_do_move_cancel(chan, result);
4823 } else {
4824 switch (chan->move_role) {
4825 case L2CAP_MOVE_ROLE_INITIATOR:
4826 l2cap_do_move_initiate(chan, local_amp_id,
4827 remote_amp_id);
4828 break;
4829 case L2CAP_MOVE_ROLE_RESPONDER:
4830 l2cap_do_move_respond(chan, result);
4831 break;
4832 default:
4833 l2cap_do_move_cancel(chan, result);
4834 break;
4835 }
4836 }
Mat Martineau8eb200b2012-10-23 15:24:17 -07004837}
4838
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004839static inline int l2cap_move_channel_req(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004840 struct l2cap_cmd_hdr *cmd,
4841 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004842{
4843 struct l2cap_move_chan_req *req = data;
Mat Martineau1500109b2012-10-23 15:24:15 -07004844 struct l2cap_move_chan_rsp rsp;
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004845 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004846 u16 icid = 0;
4847 u16 result = L2CAP_MR_NOT_ALLOWED;
4848
4849 if (cmd_len != sizeof(*req))
4850 return -EPROTO;
4851
4852 icid = le16_to_cpu(req->icid);
4853
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004854 BT_DBG("icid 0x%4.4x, dest_amp_id %d", icid, req->dest_amp_id);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004855
Marcel Holtmann848566b2013-10-01 22:59:22 -07004856 if (!conn->hs_enabled)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004857 return -EINVAL;
4858
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004859 chan = l2cap_get_chan_by_dcid(conn, icid);
4860 if (!chan) {
Mat Martineau1500109b2012-10-23 15:24:15 -07004861 rsp.icid = cpu_to_le16(icid);
4862 rsp.result = __constant_cpu_to_le16(L2CAP_MR_NOT_ALLOWED);
4863 l2cap_send_cmd(conn, cmd->ident, L2CAP_MOVE_CHAN_RSP,
4864 sizeof(rsp), &rsp);
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004865 return 0;
4866 }
4867
Mat Martineau1500109b2012-10-23 15:24:15 -07004868 chan->ident = cmd->ident;
4869
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004870 if (chan->scid < L2CAP_CID_DYN_START ||
4871 chan->chan_policy == BT_CHANNEL_POLICY_BREDR_ONLY ||
4872 (chan->mode != L2CAP_MODE_ERTM &&
4873 chan->mode != L2CAP_MODE_STREAMING)) {
4874 result = L2CAP_MR_NOT_ALLOWED;
4875 goto send_move_response;
4876 }
4877
4878 if (chan->local_amp_id == req->dest_amp_id) {
4879 result = L2CAP_MR_SAME_ID;
4880 goto send_move_response;
4881 }
4882
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004883 if (req->dest_amp_id != AMP_ID_BREDR) {
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004884 struct hci_dev *hdev;
4885 hdev = hci_dev_get(req->dest_amp_id);
4886 if (!hdev || hdev->dev_type != HCI_AMP ||
4887 !test_bit(HCI_UP, &hdev->flags)) {
4888 if (hdev)
4889 hci_dev_put(hdev);
4890
4891 result = L2CAP_MR_BAD_ID;
4892 goto send_move_response;
4893 }
4894 hci_dev_put(hdev);
4895 }
4896
4897 /* Detect a move collision. Only send a collision response
4898 * if this side has "lost", otherwise proceed with the move.
4899 * The winner has the larger bd_addr.
4900 */
4901 if ((__chan_is_moving(chan) ||
4902 chan->move_role != L2CAP_MOVE_ROLE_NONE) &&
Marcel Holtmann6f59b902013-10-13 05:24:01 -07004903 bacmp(&conn->hcon->src, &conn->hcon->dst) > 0) {
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004904 result = L2CAP_MR_COLLISION;
4905 goto send_move_response;
4906 }
4907
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004908 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
4909 l2cap_move_setup(chan);
4910 chan->move_id = req->dest_amp_id;
4911 icid = chan->dcid;
4912
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004913 if (req->dest_amp_id == AMP_ID_BREDR) {
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004914 /* Moving to BR/EDR */
4915 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4916 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4917 result = L2CAP_MR_PEND;
4918 } else {
4919 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4920 result = L2CAP_MR_SUCCESS;
4921 }
4922 } else {
4923 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
4924 /* Placeholder - uncomment when amp functions are available */
4925 /*amp_accept_physical(chan, req->dest_amp_id);*/
4926 result = L2CAP_MR_PEND;
4927 }
4928
4929send_move_response:
Mat Martineau1500109b2012-10-23 15:24:15 -07004930 l2cap_send_move_chan_rsp(chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004931
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004932 l2cap_chan_unlock(chan);
4933
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004934 return 0;
4935}
4936
Mat Martineau5b155ef2012-10-23 15:24:14 -07004937static void l2cap_move_continue(struct l2cap_conn *conn, u16 icid, u16 result)
4938{
4939 struct l2cap_chan *chan;
4940 struct hci_chan *hchan = NULL;
4941
4942 chan = l2cap_get_chan_by_scid(conn, icid);
4943 if (!chan) {
4944 l2cap_send_move_chan_cfm_icid(conn, icid);
4945 return;
4946 }
4947
4948 __clear_chan_timer(chan);
4949 if (result == L2CAP_MR_PEND)
4950 __set_chan_timer(chan, L2CAP_MOVE_ERTX_TIMEOUT);
4951
4952 switch (chan->move_state) {
4953 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
4954 /* Move confirm will be sent when logical link
4955 * is complete.
4956 */
4957 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4958 break;
4959 case L2CAP_MOVE_WAIT_RSP_SUCCESS:
4960 if (result == L2CAP_MR_PEND) {
4961 break;
4962 } else if (test_bit(CONN_LOCAL_BUSY,
4963 &chan->conn_state)) {
4964 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4965 } else {
4966 /* Logical link is up or moving to BR/EDR,
4967 * proceed with move
4968 */
4969 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
4970 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4971 }
4972 break;
4973 case L2CAP_MOVE_WAIT_RSP:
4974 /* Moving to AMP */
4975 if (result == L2CAP_MR_SUCCESS) {
4976 /* Remote is ready, send confirm immediately
4977 * after logical link is ready
4978 */
4979 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4980 } else {
4981 /* Both logical link and move success
4982 * are required to confirm
4983 */
4984 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_COMP;
4985 }
4986
4987 /* Placeholder - get hci_chan for logical link */
4988 if (!hchan) {
4989 /* Logical link not available */
4990 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4991 break;
4992 }
4993
4994 /* If the logical link is not yet connected, do not
4995 * send confirmation.
4996 */
4997 if (hchan->state != BT_CONNECTED)
4998 break;
4999
5000 /* Logical link is already ready to go */
5001
5002 chan->hs_hcon = hchan->conn;
5003 chan->hs_hcon->l2cap_data = chan->conn;
5004
5005 if (result == L2CAP_MR_SUCCESS) {
5006 /* Can confirm now */
5007 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
5008 } else {
5009 /* Now only need move success
5010 * to confirm
5011 */
5012 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
5013 }
5014
5015 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
5016 break;
5017 default:
5018 /* Any other amp move state means the move failed. */
5019 chan->move_id = chan->local_amp_id;
5020 l2cap_move_done(chan);
5021 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
5022 }
5023
5024 l2cap_chan_unlock(chan);
5025}
5026
5027static void l2cap_move_fail(struct l2cap_conn *conn, u8 ident, u16 icid,
5028 u16 result)
5029{
5030 struct l2cap_chan *chan;
5031
5032 chan = l2cap_get_chan_by_ident(conn, ident);
5033 if (!chan) {
5034 /* Could not locate channel, icid is best guess */
5035 l2cap_send_move_chan_cfm_icid(conn, icid);
5036 return;
5037 }
5038
5039 __clear_chan_timer(chan);
5040
5041 if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
5042 if (result == L2CAP_MR_COLLISION) {
5043 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
5044 } else {
5045 /* Cleanup - cancel move */
5046 chan->move_id = chan->local_amp_id;
5047 l2cap_move_done(chan);
5048 }
5049 }
5050
5051 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
5052
5053 l2cap_chan_unlock(chan);
5054}
5055
5056static int l2cap_move_channel_rsp(struct l2cap_conn *conn,
5057 struct l2cap_cmd_hdr *cmd,
5058 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005059{
5060 struct l2cap_move_chan_rsp *rsp = data;
5061 u16 icid, result;
5062
5063 if (cmd_len != sizeof(*rsp))
5064 return -EPROTO;
5065
5066 icid = le16_to_cpu(rsp->icid);
5067 result = le16_to_cpu(rsp->result);
5068
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005069 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005070
Mat Martineau5b155ef2012-10-23 15:24:14 -07005071 if (result == L2CAP_MR_SUCCESS || result == L2CAP_MR_PEND)
5072 l2cap_move_continue(conn, icid, result);
5073 else
5074 l2cap_move_fail(conn, cmd->ident, icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005075
5076 return 0;
5077}
5078
Mat Martineau5f3847a2012-10-23 15:24:12 -07005079static int l2cap_move_channel_confirm(struct l2cap_conn *conn,
5080 struct l2cap_cmd_hdr *cmd,
5081 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005082{
5083 struct l2cap_move_chan_cfm *cfm = data;
Mat Martineau5f3847a2012-10-23 15:24:12 -07005084 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005085 u16 icid, result;
5086
5087 if (cmd_len != sizeof(*cfm))
5088 return -EPROTO;
5089
5090 icid = le16_to_cpu(cfm->icid);
5091 result = le16_to_cpu(cfm->result);
5092
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005093 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005094
Mat Martineau5f3847a2012-10-23 15:24:12 -07005095 chan = l2cap_get_chan_by_dcid(conn, icid);
5096 if (!chan) {
5097 /* Spec requires a response even if the icid was not found */
5098 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
5099 return 0;
5100 }
5101
5102 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM) {
5103 if (result == L2CAP_MC_CONFIRMED) {
5104 chan->local_amp_id = chan->move_id;
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07005105 if (chan->local_amp_id == AMP_ID_BREDR)
Mat Martineau5f3847a2012-10-23 15:24:12 -07005106 __release_logical_link(chan);
5107 } else {
5108 chan->move_id = chan->local_amp_id;
5109 }
5110
5111 l2cap_move_done(chan);
5112 }
5113
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005114 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
5115
Mat Martineau5f3847a2012-10-23 15:24:12 -07005116 l2cap_chan_unlock(chan);
5117
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005118 return 0;
5119}
5120
5121static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005122 struct l2cap_cmd_hdr *cmd,
5123 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005124{
5125 struct l2cap_move_chan_cfm_rsp *rsp = data;
Mat Martineau3fd71a02012-10-23 15:24:16 -07005126 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005127 u16 icid;
5128
5129 if (cmd_len != sizeof(*rsp))
5130 return -EPROTO;
5131
5132 icid = le16_to_cpu(rsp->icid);
5133
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005134 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005135
Mat Martineau3fd71a02012-10-23 15:24:16 -07005136 chan = l2cap_get_chan_by_scid(conn, icid);
5137 if (!chan)
5138 return 0;
5139
5140 __clear_chan_timer(chan);
5141
5142 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM_RSP) {
5143 chan->local_amp_id = chan->move_id;
5144
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07005145 if (chan->local_amp_id == AMP_ID_BREDR && chan->hs_hchan)
Mat Martineau3fd71a02012-10-23 15:24:16 -07005146 __release_logical_link(chan);
5147
5148 l2cap_move_done(chan);
5149 }
5150
5151 l2cap_chan_unlock(chan);
5152
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005153 return 0;
5154}
5155
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03005156static inline int l2cap_check_conn_param(u16 min, u16 max, u16 latency,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005157 u16 to_multiplier)
Claudio Takahaside731152011-02-11 19:28:55 -02005158{
5159 u16 max_latency;
5160
5161 if (min > max || min < 6 || max > 3200)
5162 return -EINVAL;
5163
5164 if (to_multiplier < 10 || to_multiplier > 3200)
5165 return -EINVAL;
5166
5167 if (max >= to_multiplier * 8)
5168 return -EINVAL;
5169
5170 max_latency = (to_multiplier * 8 / max) - 1;
5171 if (latency > 499 || latency > max_latency)
5172 return -EINVAL;
5173
5174 return 0;
5175}
5176
5177static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005178 struct l2cap_cmd_hdr *cmd,
Johan Hedberg203e6392013-05-15 10:07:15 +03005179 u16 cmd_len, u8 *data)
Claudio Takahaside731152011-02-11 19:28:55 -02005180{
5181 struct hci_conn *hcon = conn->hcon;
5182 struct l2cap_conn_param_update_req *req;
5183 struct l2cap_conn_param_update_rsp rsp;
Johan Hedberg203e6392013-05-15 10:07:15 +03005184 u16 min, max, latency, to_multiplier;
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005185 int err;
Claudio Takahaside731152011-02-11 19:28:55 -02005186
5187 if (!(hcon->link_mode & HCI_LM_MASTER))
5188 return -EINVAL;
5189
Claudio Takahaside731152011-02-11 19:28:55 -02005190 if (cmd_len != sizeof(struct l2cap_conn_param_update_req))
5191 return -EPROTO;
5192
5193 req = (struct l2cap_conn_param_update_req *) data;
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03005194 min = __le16_to_cpu(req->min);
5195 max = __le16_to_cpu(req->max);
Claudio Takahaside731152011-02-11 19:28:55 -02005196 latency = __le16_to_cpu(req->latency);
5197 to_multiplier = __le16_to_cpu(req->to_multiplier);
5198
5199 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 +01005200 min, max, latency, to_multiplier);
Claudio Takahaside731152011-02-11 19:28:55 -02005201
5202 memset(&rsp, 0, sizeof(rsp));
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005203
5204 err = l2cap_check_conn_param(min, max, latency, to_multiplier);
5205 if (err)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005206 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
Claudio Takahaside731152011-02-11 19:28:55 -02005207 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005208 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED);
Claudio Takahaside731152011-02-11 19:28:55 -02005209
5210 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005211 sizeof(rsp), &rsp);
Claudio Takahaside731152011-02-11 19:28:55 -02005212
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005213 if (!err)
5214 hci_le_conn_update(hcon, min, max, latency, to_multiplier);
5215
Claudio Takahaside731152011-02-11 19:28:55 -02005216 return 0;
5217}
5218
Johan Hedbergf1496de2013-05-13 14:15:56 +03005219static int l2cap_le_connect_rsp(struct l2cap_conn *conn,
5220 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5221 u8 *data)
5222{
5223 struct l2cap_le_conn_rsp *rsp = (struct l2cap_le_conn_rsp *) data;
5224 u16 dcid, mtu, mps, credits, result;
5225 struct l2cap_chan *chan;
5226 int err;
5227
5228 if (cmd_len < sizeof(*rsp))
5229 return -EPROTO;
5230
5231 dcid = __le16_to_cpu(rsp->dcid);
5232 mtu = __le16_to_cpu(rsp->mtu);
5233 mps = __le16_to_cpu(rsp->mps);
5234 credits = __le16_to_cpu(rsp->credits);
5235 result = __le16_to_cpu(rsp->result);
5236
5237 if (result == L2CAP_CR_SUCCESS && (mtu < 23 || mps < 23))
5238 return -EPROTO;
5239
5240 BT_DBG("dcid 0x%4.4x mtu %u mps %u credits %u result 0x%2.2x",
5241 dcid, mtu, mps, credits, result);
5242
5243 mutex_lock(&conn->chan_lock);
5244
5245 chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
5246 if (!chan) {
5247 err = -EBADSLT;
5248 goto unlock;
5249 }
5250
5251 err = 0;
5252
5253 l2cap_chan_lock(chan);
5254
5255 switch (result) {
5256 case L2CAP_CR_SUCCESS:
5257 chan->ident = 0;
5258 chan->dcid = dcid;
5259 chan->omtu = mtu;
5260 chan->remote_mps = mps;
Johan Hedberg0cd75f72013-05-17 13:09:05 +03005261 chan->tx_credits = credits;
Johan Hedbergf1496de2013-05-13 14:15:56 +03005262 l2cap_chan_ready(chan);
5263 break;
5264
5265 default:
5266 l2cap_chan_del(chan, ECONNREFUSED);
5267 break;
5268 }
5269
5270 l2cap_chan_unlock(chan);
5271
5272unlock:
5273 mutex_unlock(&conn->chan_lock);
5274
5275 return err;
5276}
5277
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005278static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005279 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5280 u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005281{
5282 int err = 0;
5283
5284 switch (cmd->code) {
5285 case L2CAP_COMMAND_REJ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005286 l2cap_command_rej(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005287 break;
5288
5289 case L2CAP_CONN_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005290 err = l2cap_connect_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005291 break;
5292
5293 case L2CAP_CONN_RSP:
Mat Martineauf5a25982012-10-11 17:48:21 +03005294 case L2CAP_CREATE_CHAN_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005295 l2cap_connect_create_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005296 break;
5297
5298 case L2CAP_CONF_REQ:
5299 err = l2cap_config_req(conn, cmd, cmd_len, data);
5300 break;
5301
5302 case L2CAP_CONF_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005303 l2cap_config_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005304 break;
5305
5306 case L2CAP_DISCONN_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005307 err = l2cap_disconnect_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005308 break;
5309
5310 case L2CAP_DISCONN_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005311 l2cap_disconnect_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005312 break;
5313
5314 case L2CAP_ECHO_REQ:
5315 l2cap_send_cmd(conn, cmd->ident, L2CAP_ECHO_RSP, cmd_len, data);
5316 break;
5317
5318 case L2CAP_ECHO_RSP:
5319 break;
5320
5321 case L2CAP_INFO_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005322 err = l2cap_information_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005323 break;
5324
5325 case L2CAP_INFO_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005326 l2cap_information_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005327 break;
5328
Mat Martineauf94ff6f2011-11-02 16:18:32 -07005329 case L2CAP_CREATE_CHAN_REQ:
5330 err = l2cap_create_channel_req(conn, cmd, cmd_len, data);
5331 break;
5332
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005333 case L2CAP_MOVE_CHAN_REQ:
5334 err = l2cap_move_channel_req(conn, cmd, cmd_len, data);
5335 break;
5336
5337 case L2CAP_MOVE_CHAN_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005338 l2cap_move_channel_rsp(conn, cmd, cmd_len, data);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005339 break;
5340
5341 case L2CAP_MOVE_CHAN_CFM:
5342 err = l2cap_move_channel_confirm(conn, cmd, cmd_len, data);
5343 break;
5344
5345 case L2CAP_MOVE_CHAN_CFM_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005346 l2cap_move_channel_confirm_rsp(conn, cmd, cmd_len, data);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005347 break;
5348
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005349 default:
5350 BT_ERR("Unknown BR/EDR signaling command 0x%2.2x", cmd->code);
5351 err = -EINVAL;
5352 break;
5353 }
5354
5355 return err;
5356}
5357
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005358static int l2cap_le_connect_req(struct l2cap_conn *conn,
5359 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5360 u8 *data)
5361{
5362 struct l2cap_le_conn_req *req = (struct l2cap_le_conn_req *) data;
5363 struct l2cap_le_conn_rsp rsp;
5364 struct l2cap_chan *chan, *pchan;
Johan Hedberg0cd75f72013-05-17 13:09:05 +03005365 u16 dcid, scid, credits, mtu, mps;
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005366 __le16 psm;
5367 u8 result;
5368
5369 if (cmd_len != sizeof(*req))
5370 return -EPROTO;
5371
5372 scid = __le16_to_cpu(req->scid);
5373 mtu = __le16_to_cpu(req->mtu);
5374 mps = __le16_to_cpu(req->mps);
5375 psm = req->psm;
5376 dcid = 0;
Johan Hedberg0cd75f72013-05-17 13:09:05 +03005377 credits = 0;
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005378
5379 if (mtu < 23 || mps < 23)
5380 return -EPROTO;
5381
5382 BT_DBG("psm 0x%2.2x scid 0x%4.4x mtu %u mps %u", __le16_to_cpu(psm),
5383 scid, mtu, mps);
5384
5385 /* Check if we have socket listening on psm */
5386 pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, &conn->hcon->src,
5387 &conn->hcon->dst, LE_LINK);
5388 if (!pchan) {
5389 result = L2CAP_CR_BAD_PSM;
5390 chan = NULL;
5391 goto response;
5392 }
5393
5394 mutex_lock(&conn->chan_lock);
5395 l2cap_chan_lock(pchan);
5396
5397 if (!smp_sufficient_security(conn->hcon, pchan->sec_level)) {
5398 result = L2CAP_CR_AUTHENTICATION;
5399 chan = NULL;
5400 goto response_unlock;
5401 }
5402
5403 /* Check if we already have channel with that dcid */
5404 if (__l2cap_get_chan_by_dcid(conn, scid)) {
5405 result = L2CAP_CR_NO_MEM;
5406 chan = NULL;
5407 goto response_unlock;
5408 }
5409
5410 chan = pchan->ops->new_connection(pchan);
5411 if (!chan) {
5412 result = L2CAP_CR_NO_MEM;
5413 goto response_unlock;
5414 }
5415
Johan Hedberg0ce43ce2013-12-05 14:55:33 +02005416 l2cap_le_flowctl_init(chan);
5417
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005418 bacpy(&chan->src, &conn->hcon->src);
5419 bacpy(&chan->dst, &conn->hcon->dst);
5420 chan->src_type = bdaddr_type(conn->hcon, conn->hcon->src_type);
5421 chan->dst_type = bdaddr_type(conn->hcon, conn->hcon->dst_type);
5422 chan->psm = psm;
5423 chan->dcid = scid;
5424 chan->omtu = mtu;
5425 chan->remote_mps = mps;
Johan Hedberg0cd75f72013-05-17 13:09:05 +03005426 chan->tx_credits = __le16_to_cpu(req->credits);
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005427
5428 __l2cap_chan_add(conn, chan);
5429 dcid = chan->scid;
Johan Hedberg0cd75f72013-05-17 13:09:05 +03005430 credits = chan->rx_credits;
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005431
5432 __set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
5433
5434 chan->ident = cmd->ident;
5435
5436 if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
5437 l2cap_state_change(chan, BT_CONNECT2);
5438 result = L2CAP_CR_PEND;
5439 chan->ops->defer(chan);
5440 } else {
5441 l2cap_chan_ready(chan);
5442 result = L2CAP_CR_SUCCESS;
5443 }
5444
5445response_unlock:
5446 l2cap_chan_unlock(pchan);
5447 mutex_unlock(&conn->chan_lock);
5448
5449 if (result == L2CAP_CR_PEND)
5450 return 0;
5451
5452response:
5453 if (chan) {
5454 rsp.mtu = cpu_to_le16(chan->imtu);
Johan Hedberg3916aed2013-10-07 15:35:26 +02005455 rsp.mps = cpu_to_le16(chan->mps);
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005456 } else {
5457 rsp.mtu = 0;
5458 rsp.mps = 0;
5459 }
5460
5461 rsp.dcid = cpu_to_le16(dcid);
Johan Hedberg0cd75f72013-05-17 13:09:05 +03005462 rsp.credits = cpu_to_le16(credits);
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005463 rsp.result = cpu_to_le16(result);
5464
5465 l2cap_send_cmd(conn, cmd->ident, L2CAP_LE_CONN_RSP, sizeof(rsp), &rsp);
5466
5467 return 0;
5468}
5469
Johan Hedbergfad5fc892013-12-05 09:45:01 +02005470static inline int l2cap_le_credits(struct l2cap_conn *conn,
5471 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5472 u8 *data)
5473{
5474 struct l2cap_le_credits *pkt;
5475 struct l2cap_chan *chan;
5476 u16 cid, credits;
5477
5478 if (cmd_len != sizeof(*pkt))
5479 return -EPROTO;
5480
5481 pkt = (struct l2cap_le_credits *) data;
5482 cid = __le16_to_cpu(pkt->cid);
5483 credits = __le16_to_cpu(pkt->credits);
5484
5485 BT_DBG("cid 0x%4.4x credits 0x%4.4x", cid, credits);
5486
5487 chan = l2cap_get_chan_by_dcid(conn, cid);
5488 if (!chan)
5489 return -EBADSLT;
5490
5491 chan->tx_credits += credits;
5492
5493 while (chan->tx_credits && !skb_queue_empty(&chan->tx_q)) {
5494 l2cap_do_send(chan, skb_dequeue(&chan->tx_q));
5495 chan->tx_credits--;
5496 }
5497
5498 if (chan->tx_credits)
5499 chan->ops->resume(chan);
5500
5501 l2cap_chan_unlock(chan);
5502
5503 return 0;
5504}
5505
Johan Hedberg71fb4192013-12-10 10:52:48 +02005506static inline int l2cap_le_command_rej(struct l2cap_conn *conn,
5507 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5508 u8 *data)
5509{
5510 struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data;
5511 struct l2cap_chan *chan;
5512
5513 if (cmd_len < sizeof(*rej))
5514 return -EPROTO;
5515
5516 mutex_lock(&conn->chan_lock);
5517
5518 chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
5519 if (!chan)
5520 goto done;
5521
5522 l2cap_chan_lock(chan);
5523 l2cap_chan_del(chan, ECONNREFUSED);
5524 l2cap_chan_unlock(chan);
5525
5526done:
5527 mutex_unlock(&conn->chan_lock);
5528 return 0;
5529}
5530
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005531static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn,
Johan Hedberg203e6392013-05-15 10:07:15 +03005532 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5533 u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005534{
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005535 int err = 0;
5536
Johan Hedberg3af8ace2013-12-03 09:51:51 +02005537 if (!enable_lecoc) {
5538 switch (cmd->code) {
5539 case L2CAP_LE_CONN_REQ:
5540 case L2CAP_LE_CONN_RSP:
5541 case L2CAP_LE_CREDITS:
5542 case L2CAP_DISCONN_REQ:
5543 case L2CAP_DISCONN_RSP:
5544 return -EINVAL;
5545 }
5546 }
5547
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005548 switch (cmd->code) {
5549 case L2CAP_COMMAND_REJ:
Johan Hedberg71fb4192013-12-10 10:52:48 +02005550 l2cap_le_command_rej(conn, cmd, cmd_len, data);
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005551 break;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005552
5553 case L2CAP_CONN_PARAM_UPDATE_REQ:
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005554 err = l2cap_conn_param_update_req(conn, cmd, cmd_len, data);
5555 break;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005556
5557 case L2CAP_CONN_PARAM_UPDATE_RSP:
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005558 break;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005559
Johan Hedbergf1496de2013-05-13 14:15:56 +03005560 case L2CAP_LE_CONN_RSP:
5561 l2cap_le_connect_rsp(conn, cmd, cmd_len, data);
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005562 break;
Johan Hedbergf1496de2013-05-13 14:15:56 +03005563
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005564 case L2CAP_LE_CONN_REQ:
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005565 err = l2cap_le_connect_req(conn, cmd, cmd_len, data);
5566 break;
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005567
Johan Hedbergfad5fc892013-12-05 09:45:01 +02005568 case L2CAP_LE_CREDITS:
5569 err = l2cap_le_credits(conn, cmd, cmd_len, data);
5570 break;
5571
Johan Hedberg3defe012013-05-15 10:16:06 +03005572 case L2CAP_DISCONN_REQ:
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005573 err = l2cap_disconnect_req(conn, cmd, cmd_len, data);
5574 break;
Johan Hedberg3defe012013-05-15 10:16:06 +03005575
5576 case L2CAP_DISCONN_RSP:
5577 l2cap_disconnect_rsp(conn, cmd, cmd_len, data);
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005578 break;
Johan Hedberg3defe012013-05-15 10:16:06 +03005579
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005580 default:
5581 BT_ERR("Unknown LE signaling command 0x%2.2x", cmd->code);
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005582 err = -EINVAL;
5583 break;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005584 }
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005585
5586 return err;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005587}
5588
Johan Hedbergc5623552013-04-29 19:35:33 +03005589static inline void l2cap_le_sig_channel(struct l2cap_conn *conn,
5590 struct sk_buff *skb)
5591{
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005592 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005593 struct l2cap_cmd_hdr *cmd;
5594 u16 len;
Johan Hedbergc5623552013-04-29 19:35:33 +03005595 int err;
5596
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005597 if (hcon->type != LE_LINK)
Marcel Holtmann3b166292013-10-02 08:28:21 -07005598 goto drop;
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005599
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005600 if (skb->len < L2CAP_CMD_HDR_SIZE)
5601 goto drop;
Johan Hedbergc5623552013-04-29 19:35:33 +03005602
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005603 cmd = (void *) skb->data;
5604 skb_pull(skb, L2CAP_CMD_HDR_SIZE);
Johan Hedbergc5623552013-04-29 19:35:33 +03005605
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005606 len = le16_to_cpu(cmd->len);
Johan Hedbergc5623552013-04-29 19:35:33 +03005607
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005608 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd->code, len, cmd->ident);
Johan Hedbergc5623552013-04-29 19:35:33 +03005609
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005610 if (len != skb->len || !cmd->ident) {
5611 BT_DBG("corrupted command");
5612 goto drop;
5613 }
Johan Hedbergc5623552013-04-29 19:35:33 +03005614
Johan Hedberg203e6392013-05-15 10:07:15 +03005615 err = l2cap_le_sig_cmd(conn, cmd, len, skb->data);
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005616 if (err) {
5617 struct l2cap_cmd_rej_unk rej;
Johan Hedbergc5623552013-04-29 19:35:33 +03005618
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005619 BT_ERR("Wrong link type (%d)", err);
Johan Hedbergc5623552013-04-29 19:35:33 +03005620
Johan Hedberga5211492013-10-16 11:20:49 +03005621 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005622 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
5623 sizeof(rej), &rej);
Johan Hedbergc5623552013-04-29 19:35:33 +03005624 }
5625
Marcel Holtmann3b166292013-10-02 08:28:21 -07005626drop:
Johan Hedbergc5623552013-04-29 19:35:33 +03005627 kfree_skb(skb);
5628}
5629
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005630static inline void l2cap_sig_channel(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005631 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005632{
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005633 struct hci_conn *hcon = conn->hcon;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005634 u8 *data = skb->data;
5635 int len = skb->len;
5636 struct l2cap_cmd_hdr cmd;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005637 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005638
5639 l2cap_raw_recv(conn, skb);
5640
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005641 if (hcon->type != ACL_LINK)
Marcel Holtmann3b166292013-10-02 08:28:21 -07005642 goto drop;
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005643
Linus Torvalds1da177e2005-04-16 15:20:36 -07005644 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07005645 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005646 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
5647 data += L2CAP_CMD_HDR_SIZE;
5648 len -= L2CAP_CMD_HDR_SIZE;
5649
Al Viro88219a02007-07-29 00:17:25 -07005650 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005651
Gustavo Padovan2d792812012-10-06 10:07:01 +01005652 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len,
5653 cmd.ident);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005654
Al Viro88219a02007-07-29 00:17:25 -07005655 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005656 BT_DBG("corrupted command");
5657 break;
5658 }
5659
Johan Hedbergc5623552013-04-29 19:35:33 +03005660 err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005661 if (err) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03005662 struct l2cap_cmd_rej_unk rej;
Gustavo F. Padovan2c6d1a22011-03-23 14:38:32 -03005663
5664 BT_ERR("Wrong link type (%d)", err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005665
Johan Hedberga5211492013-10-16 11:20:49 +03005666 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
Gustavo Padovan2d792812012-10-06 10:07:01 +01005667 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ,
5668 sizeof(rej), &rej);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005669 }
5670
Al Viro88219a02007-07-29 00:17:25 -07005671 data += cmd_len;
5672 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005673 }
5674
Marcel Holtmann3b166292013-10-02 08:28:21 -07005675drop:
Linus Torvalds1da177e2005-04-16 15:20:36 -07005676 kfree_skb(skb);
5677}
5678
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005679static int l2cap_check_fcs(struct l2cap_chan *chan, struct sk_buff *skb)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005680{
5681 u16 our_fcs, rcv_fcs;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03005682 int hdr_size;
5683
5684 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
5685 hdr_size = L2CAP_EXT_HDR_SIZE;
5686 else
5687 hdr_size = L2CAP_ENH_HDR_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005688
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005689 if (chan->fcs == L2CAP_FCS_CRC16) {
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005690 skb_trim(skb, skb->len - L2CAP_FCS_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005691 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
5692 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
5693
5694 if (our_fcs != rcv_fcs)
João Paulo Rechi Vita7a560e52010-06-22 13:56:27 -03005695 return -EBADMSG;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005696 }
5697 return 0;
5698}
5699
Mat Martineau6ea00482012-05-17 20:53:52 -07005700static void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan)
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005701{
Mat Martineaue31f7632012-05-17 20:53:41 -07005702 struct l2cap_ctrl control;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005703
Mat Martineaue31f7632012-05-17 20:53:41 -07005704 BT_DBG("chan %p", chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005705
Mat Martineaue31f7632012-05-17 20:53:41 -07005706 memset(&control, 0, sizeof(control));
5707 control.sframe = 1;
5708 control.final = 1;
5709 control.reqseq = chan->buffer_seq;
5710 set_bit(CONN_SEND_FBIT, &chan->conn_state);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005711
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03005712 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
Mat Martineaue31f7632012-05-17 20:53:41 -07005713 control.super = L2CAP_SUPER_RNR;
5714 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005715 }
5716
Mat Martineaue31f7632012-05-17 20:53:41 -07005717 if (test_and_clear_bit(CONN_REMOTE_BUSY, &chan->conn_state) &&
5718 chan->unacked_frames > 0)
5719 __set_retrans_timer(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005720
Mat Martineaue31f7632012-05-17 20:53:41 -07005721 /* Send pending iframes */
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03005722 l2cap_ertm_send(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005723
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03005724 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
Mat Martineaue31f7632012-05-17 20:53:41 -07005725 test_bit(CONN_SEND_FBIT, &chan->conn_state)) {
5726 /* F-bit wasn't sent in an s-frame or i-frame yet, so
5727 * send it now.
5728 */
5729 control.super = L2CAP_SUPER_RR;
5730 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005731 }
5732}
5733
Gustavo Padovan2d792812012-10-06 10:07:01 +01005734static void append_skb_frag(struct sk_buff *skb, struct sk_buff *new_frag,
5735 struct sk_buff **last_frag)
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005736{
Mat Martineau84084a32011-07-22 14:54:00 -07005737 /* skb->len reflects data in skb as well as all fragments
5738 * skb->data_len reflects only data in fragments
5739 */
5740 if (!skb_has_frag_list(skb))
5741 skb_shinfo(skb)->frag_list = new_frag;
5742
5743 new_frag->next = NULL;
5744
5745 (*last_frag)->next = new_frag;
5746 *last_frag = new_frag;
5747
5748 skb->len += new_frag->len;
5749 skb->data_len += new_frag->len;
5750 skb->truesize += new_frag->truesize;
5751}
5752
Mat Martineau4b51dae92012-05-17 20:53:37 -07005753static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb,
5754 struct l2cap_ctrl *control)
Mat Martineau84084a32011-07-22 14:54:00 -07005755{
5756 int err = -EINVAL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005757
Mat Martineau4b51dae92012-05-17 20:53:37 -07005758 switch (control->sar) {
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005759 case L2CAP_SAR_UNSEGMENTED:
Mat Martineau84084a32011-07-22 14:54:00 -07005760 if (chan->sdu)
5761 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005762
Gustavo Padovan80b98022012-05-27 22:27:51 -03005763 err = chan->ops->recv(chan, skb);
Mat Martineau84084a32011-07-22 14:54:00 -07005764 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005765
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005766 case L2CAP_SAR_START:
Mat Martineau84084a32011-07-22 14:54:00 -07005767 if (chan->sdu)
5768 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005769
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005770 chan->sdu_len = get_unaligned_le16(skb->data);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005771 skb_pull(skb, L2CAP_SDULEN_SIZE);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005772
Mat Martineau84084a32011-07-22 14:54:00 -07005773 if (chan->sdu_len > chan->imtu) {
5774 err = -EMSGSIZE;
5775 break;
5776 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005777
Mat Martineau84084a32011-07-22 14:54:00 -07005778 if (skb->len >= chan->sdu_len)
5779 break;
5780
5781 chan->sdu = skb;
5782 chan->sdu_last_frag = skb;
5783
5784 skb = NULL;
5785 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005786 break;
5787
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005788 case L2CAP_SAR_CONTINUE:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005789 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07005790 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005791
Mat Martineau84084a32011-07-22 14:54:00 -07005792 append_skb_frag(chan->sdu, skb,
5793 &chan->sdu_last_frag);
5794 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005795
Mat Martineau84084a32011-07-22 14:54:00 -07005796 if (chan->sdu->len >= chan->sdu_len)
5797 break;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03005798
Mat Martineau84084a32011-07-22 14:54:00 -07005799 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005800 break;
5801
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005802 case L2CAP_SAR_END:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005803 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07005804 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005805
Mat Martineau84084a32011-07-22 14:54:00 -07005806 append_skb_frag(chan->sdu, skb,
5807 &chan->sdu_last_frag);
5808 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005809
Mat Martineau84084a32011-07-22 14:54:00 -07005810 if (chan->sdu->len != chan->sdu_len)
5811 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005812
Gustavo Padovan80b98022012-05-27 22:27:51 -03005813 err = chan->ops->recv(chan, chan->sdu);
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03005814
Mat Martineau84084a32011-07-22 14:54:00 -07005815 if (!err) {
5816 /* Reassembly complete */
5817 chan->sdu = NULL;
5818 chan->sdu_last_frag = NULL;
5819 chan->sdu_len = 0;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03005820 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005821 break;
5822 }
5823
Mat Martineau84084a32011-07-22 14:54:00 -07005824 if (err) {
5825 kfree_skb(skb);
5826 kfree_skb(chan->sdu);
5827 chan->sdu = NULL;
5828 chan->sdu_last_frag = NULL;
5829 chan->sdu_len = 0;
5830 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005831
Mat Martineau84084a32011-07-22 14:54:00 -07005832 return err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005833}
5834
Mat Martineau32b32732012-10-23 15:24:11 -07005835static int l2cap_resegment(struct l2cap_chan *chan)
5836{
5837 /* Placeholder */
5838 return 0;
5839}
5840
Mat Martineaue3281402011-07-07 09:39:02 -07005841void l2cap_chan_busy(struct l2cap_chan *chan, int busy)
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03005842{
Mat Martineau61aa4f52012-05-17 20:53:40 -07005843 u8 event;
5844
5845 if (chan->mode != L2CAP_MODE_ERTM)
5846 return;
5847
5848 event = busy ? L2CAP_EV_LOCAL_BUSY_DETECTED : L2CAP_EV_LOCAL_BUSY_CLEAR;
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03005849 l2cap_tx(chan, NULL, NULL, event);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03005850}
5851
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005852static int l2cap_rx_queued_iframes(struct l2cap_chan *chan)
5853{
Mat Martineau63838722012-05-17 20:53:45 -07005854 int err = 0;
5855 /* Pass sequential frames to l2cap_reassemble_sdu()
5856 * until a gap is encountered.
5857 */
5858
5859 BT_DBG("chan %p", chan);
5860
5861 while (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5862 struct sk_buff *skb;
5863 BT_DBG("Searching for skb with txseq %d (queue len %d)",
5864 chan->buffer_seq, skb_queue_len(&chan->srej_q));
5865
5866 skb = l2cap_ertm_seq_in_queue(&chan->srej_q, chan->buffer_seq);
5867
5868 if (!skb)
5869 break;
5870
5871 skb_unlink(skb, &chan->srej_q);
5872 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
5873 err = l2cap_reassemble_sdu(chan, skb, &bt_cb(skb)->control);
5874 if (err)
5875 break;
5876 }
5877
5878 if (skb_queue_empty(&chan->srej_q)) {
5879 chan->rx_state = L2CAP_RX_STATE_RECV;
5880 l2cap_send_ack(chan);
5881 }
5882
5883 return err;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005884}
5885
5886static void l2cap_handle_srej(struct l2cap_chan *chan,
5887 struct l2cap_ctrl *control)
5888{
Mat Martineauf80842a2012-05-17 20:53:46 -07005889 struct sk_buff *skb;
5890
5891 BT_DBG("chan %p, control %p", chan, control);
5892
5893 if (control->reqseq == chan->next_tx_seq) {
5894 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005895 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineauf80842a2012-05-17 20:53:46 -07005896 return;
5897 }
5898
5899 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
5900
5901 if (skb == NULL) {
5902 BT_DBG("Seq %d not available for retransmission",
5903 control->reqseq);
5904 return;
5905 }
5906
5907 if (chan->max_tx != 0 && bt_cb(skb)->control.retries >= chan->max_tx) {
5908 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005909 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineauf80842a2012-05-17 20:53:46 -07005910 return;
5911 }
5912
5913 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5914
5915 if (control->poll) {
5916 l2cap_pass_to_tx(chan, control);
5917
5918 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5919 l2cap_retransmit(chan, control);
5920 l2cap_ertm_send(chan);
5921
5922 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
5923 set_bit(CONN_SREJ_ACT, &chan->conn_state);
5924 chan->srej_save_reqseq = control->reqseq;
5925 }
5926 } else {
5927 l2cap_pass_to_tx_fbit(chan, control);
5928
5929 if (control->final) {
5930 if (chan->srej_save_reqseq != control->reqseq ||
5931 !test_and_clear_bit(CONN_SREJ_ACT,
5932 &chan->conn_state))
5933 l2cap_retransmit(chan, control);
5934 } else {
5935 l2cap_retransmit(chan, control);
5936 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
5937 set_bit(CONN_SREJ_ACT, &chan->conn_state);
5938 chan->srej_save_reqseq = control->reqseq;
5939 }
5940 }
5941 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005942}
5943
5944static void l2cap_handle_rej(struct l2cap_chan *chan,
5945 struct l2cap_ctrl *control)
5946{
Mat Martineaufcd289d2012-05-17 20:53:47 -07005947 struct sk_buff *skb;
5948
5949 BT_DBG("chan %p, control %p", chan, control);
5950
5951 if (control->reqseq == chan->next_tx_seq) {
5952 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005953 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaufcd289d2012-05-17 20:53:47 -07005954 return;
5955 }
5956
5957 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
5958
5959 if (chan->max_tx && skb &&
5960 bt_cb(skb)->control.retries >= chan->max_tx) {
5961 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005962 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaufcd289d2012-05-17 20:53:47 -07005963 return;
5964 }
5965
5966 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5967
5968 l2cap_pass_to_tx(chan, control);
5969
5970 if (control->final) {
5971 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state))
5972 l2cap_retransmit_all(chan, control);
5973 } else {
5974 l2cap_retransmit_all(chan, control);
5975 l2cap_ertm_send(chan);
5976 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F)
5977 set_bit(CONN_REJ_ACT, &chan->conn_state);
5978 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005979}
5980
Mat Martineau4b51dae92012-05-17 20:53:37 -07005981static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq)
5982{
5983 BT_DBG("chan %p, txseq %d", chan, txseq);
5984
5985 BT_DBG("last_acked_seq %d, expected_tx_seq %d", chan->last_acked_seq,
5986 chan->expected_tx_seq);
5987
5988 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
5989 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
Gustavo Padovan2d792812012-10-06 10:07:01 +01005990 chan->tx_win) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07005991 /* See notes below regarding "double poll" and
5992 * invalid packets.
5993 */
5994 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
5995 BT_DBG("Invalid/Ignore - after SREJ");
5996 return L2CAP_TXSEQ_INVALID_IGNORE;
5997 } else {
5998 BT_DBG("Invalid - in window after SREJ sent");
5999 return L2CAP_TXSEQ_INVALID;
6000 }
6001 }
6002
6003 if (chan->srej_list.head == txseq) {
6004 BT_DBG("Expected SREJ");
6005 return L2CAP_TXSEQ_EXPECTED_SREJ;
6006 }
6007
6008 if (l2cap_ertm_seq_in_queue(&chan->srej_q, txseq)) {
6009 BT_DBG("Duplicate SREJ - txseq already stored");
6010 return L2CAP_TXSEQ_DUPLICATE_SREJ;
6011 }
6012
6013 if (l2cap_seq_list_contains(&chan->srej_list, txseq)) {
6014 BT_DBG("Unexpected SREJ - not requested");
6015 return L2CAP_TXSEQ_UNEXPECTED_SREJ;
6016 }
6017 }
6018
6019 if (chan->expected_tx_seq == txseq) {
6020 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
6021 chan->tx_win) {
6022 BT_DBG("Invalid - txseq outside tx window");
6023 return L2CAP_TXSEQ_INVALID;
6024 } else {
6025 BT_DBG("Expected");
6026 return L2CAP_TXSEQ_EXPECTED;
6027 }
6028 }
6029
6030 if (__seq_offset(chan, txseq, chan->last_acked_seq) <
Gustavo Padovan2d792812012-10-06 10:07:01 +01006031 __seq_offset(chan, chan->expected_tx_seq, chan->last_acked_seq)) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07006032 BT_DBG("Duplicate - expected_tx_seq later than txseq");
6033 return L2CAP_TXSEQ_DUPLICATE;
6034 }
6035
6036 if (__seq_offset(chan, txseq, chan->last_acked_seq) >= chan->tx_win) {
6037 /* A source of invalid packets is a "double poll" condition,
6038 * where delays cause us to send multiple poll packets. If
6039 * the remote stack receives and processes both polls,
6040 * sequence numbers can wrap around in such a way that a
6041 * resent frame has a sequence number that looks like new data
6042 * with a sequence gap. This would trigger an erroneous SREJ
6043 * request.
6044 *
6045 * Fortunately, this is impossible with a tx window that's
6046 * less than half of the maximum sequence number, which allows
6047 * invalid frames to be safely ignored.
6048 *
6049 * With tx window sizes greater than half of the tx window
6050 * maximum, the frame is invalid and cannot be ignored. This
6051 * causes a disconnect.
6052 */
6053
6054 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
6055 BT_DBG("Invalid/Ignore - txseq outside tx window");
6056 return L2CAP_TXSEQ_INVALID_IGNORE;
6057 } else {
6058 BT_DBG("Invalid - txseq outside tx window");
6059 return L2CAP_TXSEQ_INVALID;
6060 }
6061 } else {
6062 BT_DBG("Unexpected - txseq indicates missing frames");
6063 return L2CAP_TXSEQ_UNEXPECTED;
6064 }
6065}
6066
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006067static int l2cap_rx_state_recv(struct l2cap_chan *chan,
6068 struct l2cap_ctrl *control,
6069 struct sk_buff *skb, u8 event)
6070{
6071 int err = 0;
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006072 bool skb_in_use = false;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006073
6074 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
6075 event);
6076
6077 switch (event) {
6078 case L2CAP_EV_RECV_IFRAME:
6079 switch (l2cap_classify_txseq(chan, control->txseq)) {
6080 case L2CAP_TXSEQ_EXPECTED:
6081 l2cap_pass_to_tx(chan, control);
6082
6083 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
6084 BT_DBG("Busy, discarding expected seq %d",
6085 control->txseq);
6086 break;
6087 }
6088
6089 chan->expected_tx_seq = __next_seq(chan,
6090 control->txseq);
6091
6092 chan->buffer_seq = chan->expected_tx_seq;
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006093 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006094
6095 err = l2cap_reassemble_sdu(chan, skb, control);
6096 if (err)
6097 break;
6098
6099 if (control->final) {
6100 if (!test_and_clear_bit(CONN_REJ_ACT,
6101 &chan->conn_state)) {
6102 control->final = 0;
6103 l2cap_retransmit_all(chan, control);
6104 l2cap_ertm_send(chan);
6105 }
6106 }
6107
6108 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
6109 l2cap_send_ack(chan);
6110 break;
6111 case L2CAP_TXSEQ_UNEXPECTED:
6112 l2cap_pass_to_tx(chan, control);
6113
6114 /* Can't issue SREJ frames in the local busy state.
6115 * Drop this frame, it will be seen as missing
6116 * when local busy is exited.
6117 */
6118 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
6119 BT_DBG("Busy, discarding unexpected seq %d",
6120 control->txseq);
6121 break;
6122 }
6123
6124 /* There was a gap in the sequence, so an SREJ
6125 * must be sent for each missing frame. The
6126 * current frame is stored for later use.
6127 */
6128 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006129 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006130 BT_DBG("Queued %p (queue len %d)", skb,
6131 skb_queue_len(&chan->srej_q));
6132
6133 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
6134 l2cap_seq_list_clear(&chan->srej_list);
6135 l2cap_send_srej(chan, control->txseq);
6136
6137 chan->rx_state = L2CAP_RX_STATE_SREJ_SENT;
6138 break;
6139 case L2CAP_TXSEQ_DUPLICATE:
6140 l2cap_pass_to_tx(chan, control);
6141 break;
6142 case L2CAP_TXSEQ_INVALID_IGNORE:
6143 break;
6144 case L2CAP_TXSEQ_INVALID:
6145 default:
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006146 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006147 break;
6148 }
6149 break;
6150 case L2CAP_EV_RECV_RR:
6151 l2cap_pass_to_tx(chan, control);
6152 if (control->final) {
6153 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6154
Mat Martineaue6a3ee62012-10-23 15:24:22 -07006155 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state) &&
6156 !__chan_is_moving(chan)) {
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006157 control->final = 0;
6158 l2cap_retransmit_all(chan, control);
6159 }
6160
6161 l2cap_ertm_send(chan);
6162 } else if (control->poll) {
6163 l2cap_send_i_or_rr_or_rnr(chan);
6164 } else {
6165 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6166 &chan->conn_state) &&
6167 chan->unacked_frames)
6168 __set_retrans_timer(chan);
6169
6170 l2cap_ertm_send(chan);
6171 }
6172 break;
6173 case L2CAP_EV_RECV_RNR:
6174 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6175 l2cap_pass_to_tx(chan, control);
6176 if (control && control->poll) {
6177 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6178 l2cap_send_rr_or_rnr(chan, 0);
6179 }
6180 __clear_retrans_timer(chan);
6181 l2cap_seq_list_clear(&chan->retrans_list);
6182 break;
6183 case L2CAP_EV_RECV_REJ:
6184 l2cap_handle_rej(chan, control);
6185 break;
6186 case L2CAP_EV_RECV_SREJ:
6187 l2cap_handle_srej(chan, control);
6188 break;
6189 default:
6190 break;
6191 }
6192
6193 if (skb && !skb_in_use) {
6194 BT_DBG("Freeing %p", skb);
6195 kfree_skb(skb);
6196 }
6197
6198 return err;
6199}
6200
6201static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan,
6202 struct l2cap_ctrl *control,
6203 struct sk_buff *skb, u8 event)
6204{
6205 int err = 0;
6206 u16 txseq = control->txseq;
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006207 bool skb_in_use = false;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006208
6209 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
6210 event);
6211
6212 switch (event) {
6213 case L2CAP_EV_RECV_IFRAME:
6214 switch (l2cap_classify_txseq(chan, txseq)) {
6215 case L2CAP_TXSEQ_EXPECTED:
6216 /* Keep frame for reassembly later */
6217 l2cap_pass_to_tx(chan, control);
6218 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006219 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006220 BT_DBG("Queued %p (queue len %d)", skb,
6221 skb_queue_len(&chan->srej_q));
6222
6223 chan->expected_tx_seq = __next_seq(chan, txseq);
6224 break;
6225 case L2CAP_TXSEQ_EXPECTED_SREJ:
6226 l2cap_seq_list_pop(&chan->srej_list);
6227
6228 l2cap_pass_to_tx(chan, control);
6229 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006230 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006231 BT_DBG("Queued %p (queue len %d)", skb,
6232 skb_queue_len(&chan->srej_q));
6233
6234 err = l2cap_rx_queued_iframes(chan);
6235 if (err)
6236 break;
6237
6238 break;
6239 case L2CAP_TXSEQ_UNEXPECTED:
6240 /* Got a frame that can't be reassembled yet.
6241 * Save it for later, and send SREJs to cover
6242 * the missing frames.
6243 */
6244 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006245 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006246 BT_DBG("Queued %p (queue len %d)", skb,
6247 skb_queue_len(&chan->srej_q));
6248
6249 l2cap_pass_to_tx(chan, control);
6250 l2cap_send_srej(chan, control->txseq);
6251 break;
6252 case L2CAP_TXSEQ_UNEXPECTED_SREJ:
6253 /* This frame was requested with an SREJ, but
6254 * some expected retransmitted frames are
6255 * missing. Request retransmission of missing
6256 * SREJ'd frames.
6257 */
6258 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006259 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006260 BT_DBG("Queued %p (queue len %d)", skb,
6261 skb_queue_len(&chan->srej_q));
6262
6263 l2cap_pass_to_tx(chan, control);
6264 l2cap_send_srej_list(chan, control->txseq);
6265 break;
6266 case L2CAP_TXSEQ_DUPLICATE_SREJ:
6267 /* We've already queued this frame. Drop this copy. */
6268 l2cap_pass_to_tx(chan, control);
6269 break;
6270 case L2CAP_TXSEQ_DUPLICATE:
6271 /* Expecting a later sequence number, so this frame
6272 * was already received. Ignore it completely.
6273 */
6274 break;
6275 case L2CAP_TXSEQ_INVALID_IGNORE:
6276 break;
6277 case L2CAP_TXSEQ_INVALID:
6278 default:
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006279 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006280 break;
6281 }
6282 break;
6283 case L2CAP_EV_RECV_RR:
6284 l2cap_pass_to_tx(chan, control);
6285 if (control->final) {
6286 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6287
6288 if (!test_and_clear_bit(CONN_REJ_ACT,
6289 &chan->conn_state)) {
6290 control->final = 0;
6291 l2cap_retransmit_all(chan, control);
6292 }
6293
6294 l2cap_ertm_send(chan);
6295 } else if (control->poll) {
6296 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6297 &chan->conn_state) &&
6298 chan->unacked_frames) {
6299 __set_retrans_timer(chan);
6300 }
6301
6302 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6303 l2cap_send_srej_tail(chan);
6304 } else {
6305 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6306 &chan->conn_state) &&
6307 chan->unacked_frames)
6308 __set_retrans_timer(chan);
6309
6310 l2cap_send_ack(chan);
6311 }
6312 break;
6313 case L2CAP_EV_RECV_RNR:
6314 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6315 l2cap_pass_to_tx(chan, control);
6316 if (control->poll) {
6317 l2cap_send_srej_tail(chan);
6318 } else {
6319 struct l2cap_ctrl rr_control;
6320 memset(&rr_control, 0, sizeof(rr_control));
6321 rr_control.sframe = 1;
6322 rr_control.super = L2CAP_SUPER_RR;
6323 rr_control.reqseq = chan->buffer_seq;
6324 l2cap_send_sframe(chan, &rr_control);
6325 }
6326
6327 break;
6328 case L2CAP_EV_RECV_REJ:
6329 l2cap_handle_rej(chan, control);
6330 break;
6331 case L2CAP_EV_RECV_SREJ:
6332 l2cap_handle_srej(chan, control);
6333 break;
6334 }
6335
6336 if (skb && !skb_in_use) {
6337 BT_DBG("Freeing %p", skb);
6338 kfree_skb(skb);
6339 }
6340
6341 return err;
6342}
6343
Mat Martineau32b32732012-10-23 15:24:11 -07006344static int l2cap_finish_move(struct l2cap_chan *chan)
6345{
6346 BT_DBG("chan %p", chan);
6347
6348 chan->rx_state = L2CAP_RX_STATE_RECV;
6349
6350 if (chan->hs_hcon)
6351 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
6352 else
6353 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
6354
6355 return l2cap_resegment(chan);
6356}
6357
6358static int l2cap_rx_state_wait_p(struct l2cap_chan *chan,
6359 struct l2cap_ctrl *control,
6360 struct sk_buff *skb, u8 event)
6361{
6362 int err;
6363
6364 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
6365 event);
6366
6367 if (!control->poll)
6368 return -EPROTO;
6369
6370 l2cap_process_reqseq(chan, control->reqseq);
6371
6372 if (!skb_queue_empty(&chan->tx_q))
6373 chan->tx_send_head = skb_peek(&chan->tx_q);
6374 else
6375 chan->tx_send_head = NULL;
6376
6377 /* Rewind next_tx_seq to the point expected
6378 * by the receiver.
6379 */
6380 chan->next_tx_seq = control->reqseq;
6381 chan->unacked_frames = 0;
6382
6383 err = l2cap_finish_move(chan);
6384 if (err)
6385 return err;
6386
6387 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6388 l2cap_send_i_or_rr_or_rnr(chan);
6389
6390 if (event == L2CAP_EV_RECV_IFRAME)
6391 return -EPROTO;
6392
6393 return l2cap_rx_state_recv(chan, control, NULL, event);
6394}
6395
6396static int l2cap_rx_state_wait_f(struct l2cap_chan *chan,
6397 struct l2cap_ctrl *control,
6398 struct sk_buff *skb, u8 event)
6399{
6400 int err;
6401
6402 if (!control->final)
6403 return -EPROTO;
6404
6405 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6406
6407 chan->rx_state = L2CAP_RX_STATE_RECV;
6408 l2cap_process_reqseq(chan, control->reqseq);
6409
6410 if (!skb_queue_empty(&chan->tx_q))
6411 chan->tx_send_head = skb_peek(&chan->tx_q);
6412 else
6413 chan->tx_send_head = NULL;
6414
6415 /* Rewind next_tx_seq to the point expected
6416 * by the receiver.
6417 */
6418 chan->next_tx_seq = control->reqseq;
6419 chan->unacked_frames = 0;
6420
6421 if (chan->hs_hcon)
6422 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
6423 else
6424 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
6425
6426 err = l2cap_resegment(chan);
6427
6428 if (!err)
6429 err = l2cap_rx_state_recv(chan, control, skb, event);
6430
6431 return err;
6432}
6433
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006434static bool __valid_reqseq(struct l2cap_chan *chan, u16 reqseq)
6435{
6436 /* Make sure reqseq is for a packet that has been sent but not acked */
6437 u16 unacked;
6438
6439 unacked = __seq_offset(chan, chan->next_tx_seq, chan->expected_ack_seq);
6440 return __seq_offset(chan, chan->next_tx_seq, reqseq) <= unacked;
6441}
6442
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006443static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
6444 struct sk_buff *skb, u8 event)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006445{
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006446 int err = 0;
6447
6448 BT_DBG("chan %p, control %p, skb %p, event %d, state %d", chan,
6449 control, skb, event, chan->rx_state);
6450
6451 if (__valid_reqseq(chan, control->reqseq)) {
6452 switch (chan->rx_state) {
6453 case L2CAP_RX_STATE_RECV:
6454 err = l2cap_rx_state_recv(chan, control, skb, event);
6455 break;
6456 case L2CAP_RX_STATE_SREJ_SENT:
6457 err = l2cap_rx_state_srej_sent(chan, control, skb,
6458 event);
6459 break;
Mat Martineau32b32732012-10-23 15:24:11 -07006460 case L2CAP_RX_STATE_WAIT_P:
6461 err = l2cap_rx_state_wait_p(chan, control, skb, event);
6462 break;
6463 case L2CAP_RX_STATE_WAIT_F:
6464 err = l2cap_rx_state_wait_f(chan, control, skb, event);
6465 break;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006466 default:
6467 /* shut it down */
6468 break;
6469 }
6470 } else {
6471 BT_DBG("Invalid reqseq %d (next_tx_seq %d, expected_ack_seq %d",
6472 control->reqseq, chan->next_tx_seq,
6473 chan->expected_ack_seq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006474 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006475 }
6476
6477 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006478}
6479
6480static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
6481 struct sk_buff *skb)
6482{
Mat Martineau4b51dae92012-05-17 20:53:37 -07006483 int err = 0;
6484
6485 BT_DBG("chan %p, control %p, skb %p, state %d", chan, control, skb,
6486 chan->rx_state);
6487
6488 if (l2cap_classify_txseq(chan, control->txseq) ==
6489 L2CAP_TXSEQ_EXPECTED) {
6490 l2cap_pass_to_tx(chan, control);
6491
6492 BT_DBG("buffer_seq %d->%d", chan->buffer_seq,
6493 __next_seq(chan, chan->buffer_seq));
6494
6495 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
6496
6497 l2cap_reassemble_sdu(chan, skb, control);
6498 } else {
6499 if (chan->sdu) {
6500 kfree_skb(chan->sdu);
6501 chan->sdu = NULL;
6502 }
6503 chan->sdu_last_frag = NULL;
6504 chan->sdu_len = 0;
6505
6506 if (skb) {
6507 BT_DBG("Freeing %p", skb);
6508 kfree_skb(skb);
6509 }
6510 }
6511
6512 chan->last_acked_seq = control->txseq;
6513 chan->expected_tx_seq = __next_seq(chan, control->txseq);
6514
6515 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006516}
6517
6518static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
6519{
6520 struct l2cap_ctrl *control = &bt_cb(skb)->control;
6521 u16 len;
6522 u8 event;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006523
Mat Martineaub76bbd62012-04-11 10:48:43 -07006524 __unpack_control(chan, skb);
6525
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006526 len = skb->len;
6527
6528 /*
6529 * We can just drop the corrupted I-frame here.
6530 * Receiver will miss it and start proper recovery
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006531 * procedures and ask for retransmission.
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006532 */
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006533 if (l2cap_check_fcs(chan, skb))
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006534 goto drop;
6535
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006536 if (!control->sframe && control->sar == L2CAP_SAR_START)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03006537 len -= L2CAP_SDULEN_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006538
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006539 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03006540 len -= L2CAP_FCS_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006541
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006542 if (len > chan->mps) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006543 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006544 goto drop;
6545 }
6546
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006547 if (!control->sframe) {
6548 int err;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006549
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006550 BT_DBG("iframe sar %d, reqseq %d, final %d, txseq %d",
6551 control->sar, control->reqseq, control->final,
6552 control->txseq);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03006553
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006554 /* Validate F-bit - F=0 always valid, F=1 only
6555 * valid in TX WAIT_F
6556 */
6557 if (control->final && chan->tx_state != L2CAP_TX_STATE_WAIT_F)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006558 goto drop;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006559
6560 if (chan->mode != L2CAP_MODE_STREAMING) {
6561 event = L2CAP_EV_RECV_IFRAME;
6562 err = l2cap_rx(chan, control, skb, event);
6563 } else {
6564 err = l2cap_stream_rx(chan, control, skb);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006565 }
6566
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006567 if (err)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006568 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006569 } else {
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006570 const u8 rx_func_to_event[4] = {
6571 L2CAP_EV_RECV_RR, L2CAP_EV_RECV_REJ,
6572 L2CAP_EV_RECV_RNR, L2CAP_EV_RECV_SREJ
6573 };
6574
6575 /* Only I-frames are expected in streaming mode */
6576 if (chan->mode == L2CAP_MODE_STREAMING)
6577 goto drop;
6578
6579 BT_DBG("sframe reqseq %d, final %d, poll %d, super %d",
6580 control->reqseq, control->final, control->poll,
6581 control->super);
6582
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006583 if (len != 0) {
Andrei Emeltchenko1bb166e2012-11-20 17:16:21 +02006584 BT_ERR("Trailing bytes: %d in sframe", len);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006585 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006586 goto drop;
6587 }
6588
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006589 /* Validate F and P bits */
6590 if (control->final && (control->poll ||
6591 chan->tx_state != L2CAP_TX_STATE_WAIT_F))
6592 goto drop;
6593
6594 event = rx_func_to_event[control->super];
6595 if (l2cap_rx(chan, control, skb, event))
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006596 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006597 }
6598
6599 return 0;
6600
6601drop:
6602 kfree_skb(skb);
6603 return 0;
6604}
6605
Johan Hedbergb1c325c2013-12-05 09:43:34 +02006606static void l2cap_chan_le_send_credits(struct l2cap_chan *chan)
6607{
6608 struct l2cap_conn *conn = chan->conn;
6609 struct l2cap_le_credits pkt;
6610 u16 return_credits;
6611
6612 /* We return more credits to the sender only after the amount of
6613 * credits falls below half of the initial amount.
6614 */
Johan Hedbergf15b8ec2013-12-03 15:08:25 +02006615 if (chan->rx_credits >= (le_max_credits + 1) / 2)
Johan Hedbergb1c325c2013-12-05 09:43:34 +02006616 return;
6617
Johan Hedbergf15b8ec2013-12-03 15:08:25 +02006618 return_credits = le_max_credits - chan->rx_credits;
Johan Hedbergb1c325c2013-12-05 09:43:34 +02006619
6620 BT_DBG("chan %p returning %u credits to sender", chan, return_credits);
6621
6622 chan->rx_credits += return_credits;
6623
6624 pkt.cid = cpu_to_le16(chan->scid);
6625 pkt.credits = cpu_to_le16(return_credits);
6626
6627 chan->ident = l2cap_get_ident(conn);
6628
6629 l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CREDITS, sizeof(pkt), &pkt);
6630}
6631
Johan Hedbergfad5fc892013-12-05 09:45:01 +02006632static int l2cap_le_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
6633{
Johan Hedbergaac23bf2013-06-01 10:14:57 +03006634 int err;
Johan Hedbergfad5fc892013-12-05 09:45:01 +02006635
Johan Hedbergaac23bf2013-06-01 10:14:57 +03006636 if (!chan->rx_credits) {
6637 BT_ERR("No credits to receive LE L2CAP data");
Johan Hedbergfad5fc892013-12-05 09:45:01 +02006638 return -ENOBUFS;
Johan Hedbergaac23bf2013-06-01 10:14:57 +03006639 }
6640
6641 if (chan->imtu < skb->len) {
6642 BT_ERR("Too big LE L2CAP PDU");
6643 return -ENOBUFS;
6644 }
Johan Hedbergfad5fc892013-12-05 09:45:01 +02006645
6646 chan->rx_credits--;
6647 BT_DBG("rx_credits %u -> %u", chan->rx_credits + 1, chan->rx_credits);
6648
6649 l2cap_chan_le_send_credits(chan);
6650
Johan Hedbergaac23bf2013-06-01 10:14:57 +03006651 err = 0;
6652
6653 if (!chan->sdu) {
6654 u16 sdu_len;
6655
6656 sdu_len = get_unaligned_le16(skb->data);
6657 skb_pull(skb, L2CAP_SDULEN_SIZE);
6658
6659 BT_DBG("Start of new SDU. sdu_len %u skb->len %u imtu %u",
6660 sdu_len, skb->len, chan->imtu);
6661
6662 if (sdu_len > chan->imtu) {
6663 BT_ERR("Too big LE L2CAP SDU length received");
6664 err = -EMSGSIZE;
6665 goto failed;
6666 }
6667
6668 if (skb->len > sdu_len) {
6669 BT_ERR("Too much LE L2CAP data received");
6670 err = -EINVAL;
6671 goto failed;
6672 }
6673
6674 if (skb->len == sdu_len)
6675 return chan->ops->recv(chan, skb);
6676
6677 chan->sdu = skb;
6678 chan->sdu_len = sdu_len;
6679 chan->sdu_last_frag = skb;
6680
6681 return 0;
6682 }
6683
6684 BT_DBG("SDU fragment. chan->sdu->len %u skb->len %u chan->sdu_len %u",
6685 chan->sdu->len, skb->len, chan->sdu_len);
6686
6687 if (chan->sdu->len + skb->len > chan->sdu_len) {
6688 BT_ERR("Too much LE L2CAP data received");
6689 err = -EINVAL;
6690 goto failed;
6691 }
6692
6693 append_skb_frag(chan->sdu, skb, &chan->sdu_last_frag);
6694 skb = NULL;
6695
6696 if (chan->sdu->len == chan->sdu_len) {
6697 err = chan->ops->recv(chan, chan->sdu);
6698 if (!err) {
6699 chan->sdu = NULL;
6700 chan->sdu_last_frag = NULL;
6701 chan->sdu_len = 0;
6702 }
6703 }
6704
6705failed:
6706 if (err) {
6707 kfree_skb(skb);
6708 kfree_skb(chan->sdu);
6709 chan->sdu = NULL;
6710 chan->sdu_last_frag = NULL;
6711 chan->sdu_len = 0;
6712 }
6713
6714 /* We can't return an error here since we took care of the skb
6715 * freeing internally. An error return would cause the caller to
6716 * do a double-free of the skb.
6717 */
6718 return 0;
Johan Hedbergfad5fc892013-12-05 09:45:01 +02006719}
6720
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006721static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid,
6722 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006723{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006724 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006725
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03006726 chan = l2cap_get_chan_by_scid(conn, cid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006727 if (!chan) {
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006728 if (cid == L2CAP_CID_A2MP) {
6729 chan = a2mp_channel_create(conn, skb);
6730 if (!chan) {
6731 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006732 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006733 }
6734
6735 l2cap_chan_lock(chan);
6736 } else {
6737 BT_DBG("unknown cid 0x%4.4x", cid);
6738 /* Drop packet and return */
6739 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006740 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006741 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006742 }
6743
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03006744 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006745
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006746 if (chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006747 goto drop;
6748
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006749 switch (chan->mode) {
Johan Hedberg38319712013-05-17 12:49:23 +03006750 case L2CAP_MODE_LE_FLOWCTL:
Johan Hedbergfad5fc892013-12-05 09:45:01 +02006751 if (l2cap_le_data_rcv(chan, skb) < 0)
6752 goto drop;
6753
6754 goto done;
6755
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006756 case L2CAP_MODE_BASIC:
6757 /* If socket recv buffers overflows we drop data here
6758 * which is *bad* because L2CAP has to be reliable.
6759 * But we don't have any other choice. L2CAP doesn't
6760 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006761
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006762 if (chan->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006763 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006764
Gustavo Padovan80b98022012-05-27 22:27:51 -03006765 if (!chan->ops->recv(chan, skb))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006766 goto done;
6767 break;
6768
6769 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03006770 case L2CAP_MODE_STREAMING:
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006771 l2cap_data_rcv(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03006772 goto done;
6773
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006774 default:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006775 BT_DBG("chan %p: bad mode 0x%2.2x", chan, chan->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006776 break;
6777 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006778
6779drop:
6780 kfree_skb(skb);
6781
6782done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006783 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006784}
6785
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03006786static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm,
6787 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006788{
Marcel Holtmannae4fd2d2013-10-03 00:03:39 -07006789 struct hci_conn *hcon = conn->hcon;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006790 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006791
Marcel Holtmannae4fd2d2013-10-03 00:03:39 -07006792 if (hcon->type != ACL_LINK)
6793 goto drop;
6794
Johan Hedbergbf20fd42013-05-14 13:23:13 +03006795 chan = l2cap_global_chan_by_psm(0, psm, &hcon->src, &hcon->dst,
6796 ACL_LINK);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006797 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006798 goto drop;
6799
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02006800 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006801
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006802 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006803 goto drop;
6804
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03006805 if (chan->imtu < skb->len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006806 goto drop;
6807
Marcel Holtmann2edf8702013-10-13 12:55:29 -07006808 /* Store remote BD_ADDR and PSM for msg_name */
Marcel Holtmann06ae3312013-10-18 03:43:00 -07006809 bacpy(&bt_cb(skb)->bdaddr, &hcon->dst);
Marcel Holtmann2edf8702013-10-13 12:55:29 -07006810 bt_cb(skb)->psm = psm;
6811
Gustavo Padovan80b98022012-05-27 22:27:51 -03006812 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03006813 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006814
6815drop:
6816 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006817}
6818
Marcel Holtmann72f78352013-04-23 00:59:00 -07006819static void l2cap_att_channel(struct l2cap_conn *conn,
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03006820 struct sk_buff *skb)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006821{
Marcel Holtmannb99707d2013-10-03 02:54:11 -07006822 struct hci_conn *hcon = conn->hcon;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006823 struct l2cap_chan *chan;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006824
Marcel Holtmannb99707d2013-10-03 02:54:11 -07006825 if (hcon->type != LE_LINK)
6826 goto drop;
6827
Johan Hedbergaf1c0132013-04-29 19:35:42 +03006828 chan = l2cap_global_chan_by_scid(BT_CONNECTED, L2CAP_CID_ATT,
Marcel Holtmann06ae3312013-10-18 03:43:00 -07006829 &hcon->src, &hcon->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006830 if (!chan)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006831 goto drop;
6832
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02006833 BT_DBG("chan %p, len %d", chan, skb->len);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006834
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07006835 if (hci_blacklist_lookup(hcon->hdev, &hcon->dst, hcon->dst_type))
6836 goto drop;
6837
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03006838 if (chan->imtu < skb->len)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006839 goto drop;
6840
Gustavo Padovan80b98022012-05-27 22:27:51 -03006841 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03006842 return;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006843
6844drop:
6845 kfree_skb(skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006846}
6847
Linus Torvalds1da177e2005-04-16 15:20:36 -07006848static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
6849{
6850 struct l2cap_hdr *lh = (void *) skb->data;
Johan Hedberg61a939c2014-01-17 20:45:11 +02006851 struct hci_conn *hcon = conn->hcon;
Al Viro8e036fc2007-07-29 00:16:36 -07006852 u16 cid, len;
6853 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006854
Johan Hedberg61a939c2014-01-17 20:45:11 +02006855 if (hcon->state != BT_CONNECTED) {
6856 BT_DBG("queueing pending rx skb");
6857 skb_queue_tail(&conn->pending_rx, skb);
6858 return;
6859 }
6860
Linus Torvalds1da177e2005-04-16 15:20:36 -07006861 skb_pull(skb, L2CAP_HDR_SIZE);
6862 cid = __le16_to_cpu(lh->cid);
6863 len = __le16_to_cpu(lh->len);
6864
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006865 if (len != skb->len) {
6866 kfree_skb(skb);
6867 return;
6868 }
6869
Linus Torvalds1da177e2005-04-16 15:20:36 -07006870 BT_DBG("len %d, cid 0x%4.4x", len, cid);
6871
6872 switch (cid) {
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03006873 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006874 l2cap_sig_channel(conn, skb);
6875 break;
6876
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03006877 case L2CAP_CID_CONN_LESS:
Andrei Emeltchenko097db762012-03-09 14:16:17 +02006878 psm = get_unaligned((__le16 *) skb->data);
Andrei Emeltchenko0181a702012-05-29 10:04:05 +03006879 skb_pull(skb, L2CAP_PSMLEN_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006880 l2cap_conless_channel(conn, psm, skb);
6881 break;
6882
Johan Hedberg073d1cf2013-04-29 19:35:35 +03006883 case L2CAP_CID_ATT:
Marcel Holtmann72f78352013-04-23 00:59:00 -07006884 l2cap_att_channel(conn, skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006885 break;
6886
Marcel Holtmanna2877622013-10-02 23:46:54 -07006887 case L2CAP_CID_LE_SIGNALING:
6888 l2cap_le_sig_channel(conn, skb);
6889 break;
6890
Anderson Brigliab501d6a2011-06-07 18:46:31 -03006891 case L2CAP_CID_SMP:
6892 if (smp_sig_channel(conn, skb))
6893 l2cap_conn_del(conn->hcon, EACCES);
6894 break;
6895
Jukka Rissanen18722c22013-12-11 17:05:37 +02006896 case L2CAP_FC_6LOWPAN:
6897 bt_6lowpan_recv(conn, skb);
6898 break;
6899
Linus Torvalds1da177e2005-04-16 15:20:36 -07006900 default:
6901 l2cap_data_channel(conn, cid, skb);
6902 break;
6903 }
6904}
6905
Johan Hedberg61a939c2014-01-17 20:45:11 +02006906static void process_pending_rx(struct work_struct *work)
6907{
6908 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
6909 pending_rx_work);
6910 struct sk_buff *skb;
6911
6912 BT_DBG("");
6913
6914 while ((skb = skb_dequeue(&conn->pending_rx)))
6915 l2cap_recv_frame(conn, skb);
6916}
6917
Johan Hedberg162b49e2014-01-17 20:45:10 +02006918static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon)
6919{
6920 struct l2cap_conn *conn = hcon->l2cap_data;
6921 struct hci_chan *hchan;
6922
6923 if (conn)
6924 return conn;
6925
6926 hchan = hci_chan_create(hcon);
6927 if (!hchan)
6928 return NULL;
6929
6930 conn = kzalloc(sizeof(struct l2cap_conn), GFP_KERNEL);
6931 if (!conn) {
6932 hci_chan_del(hchan);
6933 return NULL;
6934 }
6935
6936 kref_init(&conn->ref);
6937 hcon->l2cap_data = conn;
6938 conn->hcon = hcon;
6939 hci_conn_get(conn->hcon);
6940 conn->hchan = hchan;
6941
6942 BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan);
6943
6944 switch (hcon->type) {
6945 case LE_LINK:
6946 if (hcon->hdev->le_mtu) {
6947 conn->mtu = hcon->hdev->le_mtu;
6948 break;
6949 }
6950 /* fall through */
6951 default:
6952 conn->mtu = hcon->hdev->acl_mtu;
6953 break;
6954 }
6955
6956 conn->feat_mask = 0;
6957
6958 if (hcon->type == ACL_LINK)
6959 conn->hs_enabled = test_bit(HCI_HS_ENABLED,
6960 &hcon->hdev->dev_flags);
6961
6962 spin_lock_init(&conn->lock);
6963 mutex_init(&conn->chan_lock);
6964
6965 INIT_LIST_HEAD(&conn->chan_l);
6966 INIT_LIST_HEAD(&conn->users);
6967
6968 if (hcon->type == LE_LINK)
6969 INIT_DELAYED_WORK(&conn->security_timer, security_timeout);
6970 else
6971 INIT_DELAYED_WORK(&conn->info_timer, l2cap_info_timeout);
6972
Johan Hedberg61a939c2014-01-17 20:45:11 +02006973 skb_queue_head_init(&conn->pending_rx);
6974 INIT_WORK(&conn->pending_rx_work, process_pending_rx);
6975
Johan Hedberg162b49e2014-01-17 20:45:10 +02006976 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
6977
6978 return conn;
6979}
6980
6981static bool is_valid_psm(u16 psm, u8 dst_type) {
6982 if (!psm)
6983 return false;
6984
6985 if (bdaddr_type_is_le(dst_type))
6986 return (psm <= 0x00ff);
6987
6988 /* PSM must be odd and lsb of upper byte must be 0 */
6989 return ((psm & 0x0101) == 0x0001);
6990}
6991
6992int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
6993 bdaddr_t *dst, u8 dst_type)
6994{
6995 struct l2cap_conn *conn;
6996 struct hci_conn *hcon;
6997 struct hci_dev *hdev;
6998 __u8 auth_type;
6999 int err;
7000
7001 BT_DBG("%pMR -> %pMR (type %u) psm 0x%2.2x", &chan->src, dst,
7002 dst_type, __le16_to_cpu(psm));
7003
7004 hdev = hci_get_route(dst, &chan->src);
7005 if (!hdev)
7006 return -EHOSTUNREACH;
7007
7008 hci_dev_lock(hdev);
7009
7010 l2cap_chan_lock(chan);
7011
7012 if (!is_valid_psm(__le16_to_cpu(psm), dst_type) && !cid &&
7013 chan->chan_type != L2CAP_CHAN_RAW) {
7014 err = -EINVAL;
7015 goto done;
7016 }
7017
Johan Hedberg21626e62014-01-24 10:35:41 +02007018 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && !psm) {
7019 err = -EINVAL;
7020 goto done;
7021 }
7022
7023 if (chan->chan_type == L2CAP_CHAN_FIXED && !cid) {
Johan Hedberg162b49e2014-01-17 20:45:10 +02007024 err = -EINVAL;
7025 goto done;
7026 }
7027
7028 switch (chan->mode) {
7029 case L2CAP_MODE_BASIC:
7030 break;
7031 case L2CAP_MODE_LE_FLOWCTL:
7032 l2cap_le_flowctl_init(chan);
7033 break;
7034 case L2CAP_MODE_ERTM:
7035 case L2CAP_MODE_STREAMING:
7036 if (!disable_ertm)
7037 break;
7038 /* fall through */
7039 default:
7040 err = -ENOTSUPP;
7041 goto done;
7042 }
7043
7044 switch (chan->state) {
7045 case BT_CONNECT:
7046 case BT_CONNECT2:
7047 case BT_CONFIG:
7048 /* Already connecting */
7049 err = 0;
7050 goto done;
7051
7052 case BT_CONNECTED:
7053 /* Already connected */
7054 err = -EISCONN;
7055 goto done;
7056
7057 case BT_OPEN:
7058 case BT_BOUND:
7059 /* Can connect */
7060 break;
7061
7062 default:
7063 err = -EBADFD;
7064 goto done;
7065 }
7066
7067 /* Set destination address and psm */
7068 bacpy(&chan->dst, dst);
7069 chan->dst_type = dst_type;
7070
7071 chan->psm = psm;
7072 chan->dcid = cid;
7073
7074 auth_type = l2cap_get_auth_type(chan);
7075
7076 if (bdaddr_type_is_le(dst_type))
7077 hcon = hci_connect(hdev, LE_LINK, dst, dst_type,
7078 chan->sec_level, auth_type);
7079 else
7080 hcon = hci_connect(hdev, ACL_LINK, dst, dst_type,
7081 chan->sec_level, auth_type);
7082
7083 if (IS_ERR(hcon)) {
7084 err = PTR_ERR(hcon);
7085 goto done;
7086 }
7087
7088 conn = l2cap_conn_add(hcon);
7089 if (!conn) {
7090 hci_conn_drop(hcon);
7091 err = -ENOMEM;
7092 goto done;
7093 }
7094
7095 if (cid && __l2cap_get_chan_by_dcid(conn, cid)) {
7096 hci_conn_drop(hcon);
7097 err = -EBUSY;
7098 goto done;
7099 }
7100
7101 /* Update source addr of the socket */
7102 bacpy(&chan->src, &hcon->src);
7103 chan->src_type = bdaddr_type(hcon, hcon->src_type);
7104
7105 l2cap_chan_unlock(chan);
7106 l2cap_chan_add(conn, chan);
7107 l2cap_chan_lock(chan);
7108
7109 /* l2cap_chan_add takes its own ref so we can drop this one */
7110 hci_conn_drop(hcon);
7111
7112 l2cap_state_change(chan, BT_CONNECT);
7113 __set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
7114
7115 if (hcon->state == BT_CONNECTED) {
7116 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
7117 __clear_chan_timer(chan);
7118 if (l2cap_chan_check_security(chan))
7119 l2cap_state_change(chan, BT_CONNECTED);
7120 } else
7121 l2cap_do_start(chan);
7122 }
7123
7124 err = 0;
7125
7126done:
7127 l2cap_chan_unlock(chan);
7128 hci_dev_unlock(hdev);
7129 hci_dev_put(hdev);
7130 return err;
7131}
7132
Linus Torvalds1da177e2005-04-16 15:20:36 -07007133/* ---- L2CAP interface with lower layer (HCI) ---- */
7134
Ulisses Furquim686ebf22011-12-21 10:11:33 -02007135int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007136{
7137 int exact = 0, lm1 = 0, lm2 = 0;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007138 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007139
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03007140 BT_DBG("hdev %s, bdaddr %pMR", hdev->name, bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007141
7142 /* Find listening sockets and check their link_mode */
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007143 read_lock(&chan_list_lock);
7144 list_for_each_entry(c, &chan_list, global_l) {
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03007145 if (c->state != BT_LISTEN)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007146 continue;
7147
Marcel Holtmann7eafc592013-10-13 08:12:47 -07007148 if (!bacmp(&c->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01007149 lm1 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03007150 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01007151 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007152 exact++;
Marcel Holtmann7eafc592013-10-13 08:12:47 -07007153 } else if (!bacmp(&c->src, BDADDR_ANY)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01007154 lm2 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03007155 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01007156 lm2 |= HCI_LM_MASTER;
7157 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07007158 }
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007159 read_unlock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007160
7161 return exact ? lm1 : lm2;
7162}
7163
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03007164void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007165{
Marcel Holtmann01394182006-07-03 10:02:46 +02007166 struct l2cap_conn *conn;
7167
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03007168 BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007169
Linus Torvalds1da177e2005-04-16 15:20:36 -07007170 if (!status) {
Claudio Takahasibaf43252013-04-11 13:55:50 -03007171 conn = l2cap_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007172 if (conn)
7173 l2cap_conn_ready(conn);
Andrei Emeltchenkoba6fc312012-10-31 15:46:26 +02007174 } else {
Joe Perchese1750722011-06-29 18:18:29 -07007175 l2cap_conn_del(hcon, bt_to_errno(status));
Andrei Emeltchenkoba6fc312012-10-31 15:46:26 +02007176 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07007177}
7178
Ulisses Furquim686ebf22011-12-21 10:11:33 -02007179int l2cap_disconn_ind(struct hci_conn *hcon)
Marcel Holtmann2950f212009-02-12 14:02:50 +01007180{
7181 struct l2cap_conn *conn = hcon->l2cap_data;
7182
7183 BT_DBG("hcon %p", hcon);
7184
Ulisses Furquim686ebf22011-12-21 10:11:33 -02007185 if (!conn)
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02007186 return HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01007187 return conn->disc_reason;
7188}
7189
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03007190void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007191{
7192 BT_DBG("hcon %p reason %d", hcon, reason);
7193
Jukka Rissanen18722c22013-12-11 17:05:37 +02007194 bt_6lowpan_del_conn(hcon->l2cap_data);
7195
Joe Perchese1750722011-06-29 18:18:29 -07007196 l2cap_conn_del(hcon, bt_to_errno(reason));
Linus Torvalds1da177e2005-04-16 15:20:36 -07007197}
7198
Gustavo F. Padovan43434782011-04-12 18:31:57 -03007199static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
Marcel Holtmannf62e4322009-01-15 21:58:44 +01007200{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03007201 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED)
Marcel Holtmann255c7602009-02-04 21:07:19 +01007202 return;
7203
Marcel Holtmannf62e4322009-01-15 21:58:44 +01007204 if (encrypt == 0x00) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03007205 if (chan->sec_level == BT_SECURITY_MEDIUM) {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08007206 __set_chan_timer(chan, L2CAP_ENC_TIMEOUT);
Marcel Holtmann7d513e92014-01-15 22:37:40 -08007207 } else if (chan->sec_level == BT_SECURITY_HIGH ||
7208 chan->sec_level == BT_SECURITY_FIPS)
Gustavo F. Padovan0f852722011-05-04 19:42:50 -03007209 l2cap_chan_close(chan, ECONNREFUSED);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01007210 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03007211 if (chan->sec_level == BT_SECURITY_MEDIUM)
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03007212 __clear_chan_timer(chan);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01007213 }
7214}
7215
Ulisses Furquim686ebf22011-12-21 10:11:33 -02007216int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007217{
Marcel Holtmann40be4922008-07-14 20:13:50 +02007218 struct l2cap_conn *conn = hcon->l2cap_data;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03007219 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007220
Marcel Holtmann01394182006-07-03 10:02:46 +02007221 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007222 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02007223
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03007224 BT_DBG("conn %p status 0x%2.2x encrypt %u", conn, status, encrypt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007225
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03007226 if (hcon->type == LE_LINK) {
Hemant Gupta35d4adcc2012-04-18 14:46:26 +05307227 if (!status && encrypt)
7228 smp_distribute_keys(conn, 0);
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02007229 cancel_delayed_work(&conn->security_timer);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03007230 }
7231
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02007232 mutex_lock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007233
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02007234 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02007235 l2cap_chan_lock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007236
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03007237 BT_DBG("chan %p scid 0x%4.4x state %s", chan, chan->scid,
7238 state_to_string(chan->state));
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03007239
Johan Hedberg2338a7e2014-01-24 10:35:40 +02007240 if (chan->scid == L2CAP_CID_A2MP) {
Andrei Emeltchenko78eb2f92012-07-19 17:03:47 +03007241 l2cap_chan_unlock(chan);
7242 continue;
7243 }
7244
Johan Hedberg073d1cf2013-04-29 19:35:35 +03007245 if (chan->scid == L2CAP_CID_ATT) {
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03007246 if (!status && encrypt) {
7247 chan->sec_level = hcon->sec_level;
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02007248 l2cap_chan_ready(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03007249 }
7250
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02007251 l2cap_chan_unlock(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03007252 continue;
7253 }
7254
Andrei Emeltchenko96eff462012-11-15 18:14:53 +02007255 if (!__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02007256 l2cap_chan_unlock(chan);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01007257 continue;
7258 }
7259
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03007260 if (!status && (chan->state == BT_CONNECTED ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01007261 chan->state == BT_CONFIG)) {
Marcel Holtmannd97c8992013-10-14 02:53:54 -07007262 chan->ops->resume(chan);
Gustavo F. Padovan43434782011-04-12 18:31:57 -03007263 l2cap_check_encryption(chan, encrypt);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02007264 l2cap_chan_unlock(chan);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02007265 continue;
7266 }
7267
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03007268 if (chan->state == BT_CONNECT) {
Johan Hedberg6d3c15d2013-12-02 22:13:24 +02007269 if (!status)
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03007270 l2cap_start_connection(chan);
Johan Hedberg6d3c15d2013-12-02 22:13:24 +02007271 else
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08007272 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03007273 } else if (chan->state == BT_CONNECT2) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +02007274 struct l2cap_conn_rsp rsp;
Johan Hedbergdf3c3932011-06-14 12:48:19 +03007275 __u16 res, stat;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02007276
7277 if (!status) {
Marcel Holtmannbdc25782013-10-14 02:45:34 -07007278 if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
Johan Hedbergdf3c3932011-06-14 12:48:19 +03007279 res = L2CAP_CR_PEND;
7280 stat = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08007281 chan->ops->defer(chan);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03007282 } else {
Gustavo Padovanacdcabf2013-10-21 14:21:39 -02007283 l2cap_state_change(chan, BT_CONFIG);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03007284 res = L2CAP_CR_SUCCESS;
7285 stat = L2CAP_CS_NO_INFO;
7286 }
Marcel Holtmannb1235d72008-07-14 20:13:54 +02007287 } else {
Gustavo Padovanacdcabf2013-10-21 14:21:39 -02007288 l2cap_state_change(chan, BT_DISCONN);
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08007289 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03007290 res = L2CAP_CR_SEC_BLOCK;
7291 stat = L2CAP_CS_NO_INFO;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02007292 }
7293
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03007294 rsp.scid = cpu_to_le16(chan->dcid);
7295 rsp.dcid = cpu_to_le16(chan->scid);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03007296 rsp.result = cpu_to_le16(res);
7297 rsp.status = cpu_to_le16(stat);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03007298 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01007299 sizeof(rsp), &rsp);
Mat Martineau2d369352012-05-23 14:59:30 -07007300
7301 if (!test_bit(CONF_REQ_SENT, &chan->conf_state) &&
7302 res == L2CAP_CR_SUCCESS) {
7303 char buf[128];
7304 set_bit(CONF_REQ_SENT, &chan->conf_state);
7305 l2cap_send_cmd(conn, l2cap_get_ident(conn),
7306 L2CAP_CONF_REQ,
7307 l2cap_build_conf_req(chan, buf),
7308 buf);
7309 chan->num_conf_req++;
7310 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07007311 }
7312
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02007313 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007314 }
7315
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02007316 mutex_unlock(&conn->chan_lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02007317
Linus Torvalds1da177e2005-04-16 15:20:36 -07007318 return 0;
7319}
7320
Ulisses Furquim686ebf22011-12-21 10:11:33 -02007321int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007322{
7323 struct l2cap_conn *conn = hcon->l2cap_data;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03007324 struct l2cap_hdr *hdr;
7325 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007326
Andrei Emeltchenko1d13a252012-10-15 11:58:41 +03007327 /* For AMP controller do not create l2cap conn */
7328 if (!conn && hcon->hdev->dev_type != HCI_BREDR)
7329 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007330
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02007331 if (!conn)
Claudio Takahasibaf43252013-04-11 13:55:50 -03007332 conn = l2cap_conn_add(hcon);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02007333
7334 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007335 goto drop;
7336
7337 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
7338
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03007339 switch (flags) {
7340 case ACL_START:
7341 case ACL_START_NO_FLUSH:
7342 case ACL_COMPLETE:
Linus Torvalds1da177e2005-04-16 15:20:36 -07007343 if (conn->rx_len) {
7344 BT_ERR("Unexpected start frame (len %d)", skb->len);
7345 kfree_skb(conn->rx_skb);
7346 conn->rx_skb = NULL;
7347 conn->rx_len = 0;
7348 l2cap_conn_unreliable(conn, ECOMM);
7349 }
7350
Andrei Emeltchenkoaae7fe22010-09-15 14:28:43 +03007351 /* Start fragment always begin with Basic L2CAP header */
7352 if (skb->len < L2CAP_HDR_SIZE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07007353 BT_ERR("Frame is too short (len %d)", skb->len);
7354 l2cap_conn_unreliable(conn, ECOMM);
7355 goto drop;
7356 }
7357
7358 hdr = (struct l2cap_hdr *) skb->data;
7359 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
7360
7361 if (len == skb->len) {
7362 /* Complete frame received */
7363 l2cap_recv_frame(conn, skb);
7364 return 0;
7365 }
7366
7367 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
7368
7369 if (skb->len > len) {
7370 BT_ERR("Frame is too long (len %d, expected len %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01007371 skb->len, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007372 l2cap_conn_unreliable(conn, ECOMM);
7373 goto drop;
7374 }
7375
7376 /* Allocate skb for the complete frame (with header) */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03007377 conn->rx_skb = bt_skb_alloc(len, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03007378 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007379 goto drop;
7380
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03007381 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01007382 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007383 conn->rx_len = len - skb->len;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03007384 break;
7385
7386 case ACL_CONT:
Linus Torvalds1da177e2005-04-16 15:20:36 -07007387 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
7388
7389 if (!conn->rx_len) {
7390 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
7391 l2cap_conn_unreliable(conn, ECOMM);
7392 goto drop;
7393 }
7394
7395 if (skb->len > conn->rx_len) {
7396 BT_ERR("Fragment is too long (len %d, expected %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01007397 skb->len, conn->rx_len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007398 kfree_skb(conn->rx_skb);
7399 conn->rx_skb = NULL;
7400 conn->rx_len = 0;
7401 l2cap_conn_unreliable(conn, ECOMM);
7402 goto drop;
7403 }
7404
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03007405 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01007406 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007407 conn->rx_len -= skb->len;
7408
7409 if (!conn->rx_len) {
Johan Hedbergc4e5baf2013-10-10 13:33:37 +02007410 /* Complete frame received. l2cap_recv_frame
7411 * takes ownership of the skb so set the global
7412 * rx_skb pointer to NULL first.
7413 */
7414 struct sk_buff *rx_skb = conn->rx_skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007415 conn->rx_skb = NULL;
Johan Hedbergc4e5baf2013-10-10 13:33:37 +02007416 l2cap_recv_frame(conn, rx_skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007417 }
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03007418 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007419 }
7420
7421drop:
7422 kfree_skb(skb);
7423 return 0;
7424}
7425
Marcel Holtmannaef7d972010-03-21 05:27:45 +01007426static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007427{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007428 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007429
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02007430 read_lock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007431
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007432 list_for_each_entry(c, &chan_list, global_l) {
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +03007433 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 -07007434 &c->src, &c->dst,
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +03007435 c->state, __le16_to_cpu(c->psm),
7436 c->scid, c->dcid, c->imtu, c->omtu,
7437 c->sec_level, c->mode);
Andrei Emeltchenko61e1b4b2012-01-19 11:19:50 +02007438 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07007439
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02007440 read_unlock(&chan_list_lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08007441
Marcel Holtmannaef7d972010-03-21 05:27:45 +01007442 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007443}
7444
Marcel Holtmannaef7d972010-03-21 05:27:45 +01007445static int l2cap_debugfs_open(struct inode *inode, struct file *file)
7446{
7447 return single_open(file, l2cap_debugfs_show, inode->i_private);
7448}
7449
7450static const struct file_operations l2cap_debugfs_fops = {
7451 .open = l2cap_debugfs_open,
7452 .read = seq_read,
7453 .llseek = seq_lseek,
7454 .release = single_release,
7455};
7456
7457static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007458
Gustavo F. Padovan64274512011-02-07 20:08:52 -02007459int __init l2cap_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007460{
7461 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08007462
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02007463 err = l2cap_init_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07007464 if (err < 0)
7465 return err;
7466
Marcel Holtmann1120e4b2013-10-17 17:24:16 -07007467 if (IS_ERR_OR_NULL(bt_debugfs))
7468 return 0;
7469
7470 l2cap_debugfs = debugfs_create_file("l2cap", 0444, bt_debugfs,
7471 NULL, &l2cap_debugfs_fops);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007472
Johan Hedbergf15b8ec2013-12-03 15:08:25 +02007473 debugfs_create_u16("l2cap_le_max_credits", 0466, bt_debugfs,
7474 &le_max_credits);
7475 debugfs_create_u16("l2cap_le_default_mps", 0466, bt_debugfs,
7476 &le_default_mps);
7477
Jukka Rissanen18722c22013-12-11 17:05:37 +02007478 bt_6lowpan_init();
7479
Linus Torvalds1da177e2005-04-16 15:20:36 -07007480 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007481}
7482
Gustavo F. Padovan64274512011-02-07 20:08:52 -02007483void l2cap_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007484{
Jukka Rissanen18722c22013-12-11 17:05:37 +02007485 bt_6lowpan_cleanup();
Marcel Holtmannaef7d972010-03-21 05:27:45 +01007486 debugfs_remove(l2cap_debugfs);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02007487 l2cap_cleanup_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07007488}
7489
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03007490module_param(disable_ertm, bool, 0644);
7491MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode");