blob: e0e7b82cff023595c0cc4fa70cadd17c46354987 [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.
Linus Torvalds1da177e2005-04-16 15:20:36 -07006
7 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License version 2 as
11 published by the Free Software Foundation;
12
13 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
14 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
16 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090017 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
18 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Linus Torvalds1da177e2005-04-16 15:20:36 -070020 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090022 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
23 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
Linus Torvalds1da177e2005-04-16 15:20:36 -070024 SOFTWARE IS DISCLAIMED.
25*/
26
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -020027/* Bluetooth L2CAP core. */
Linus Torvalds1da177e2005-04-16 15:20:36 -070028
Linus Torvalds1da177e2005-04-16 15:20:36 -070029#include <linux/module.h>
30
31#include <linux/types.h>
Randy Dunlap4fc268d2006-01-11 12:17:47 -080032#include <linux/capability.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070033#include <linux/errno.h>
34#include <linux/kernel.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070035#include <linux/sched.h>
36#include <linux/slab.h>
37#include <linux/poll.h>
38#include <linux/fcntl.h>
39#include <linux/init.h>
40#include <linux/interrupt.h>
41#include <linux/socket.h>
42#include <linux/skbuff.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070043#include <linux/list.h>
Marcel Holtmannbe9d1222005-11-08 09:57:38 -080044#include <linux/device.h>
Marcel Holtmannaef7d972010-03-21 05:27:45 +010045#include <linux/debugfs.h>
46#include <linux/seq_file.h>
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -030047#include <linux/uaccess.h>
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -030048#include <linux/crc16.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070049#include <net/sock.h>
50
51#include <asm/system.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070052#include <asm/unaligned.h>
53
54#include <net/bluetooth/bluetooth.h>
55#include <net/bluetooth/hci_core.h>
56#include <net/bluetooth/l2cap.h>
57
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -020058int disable_ertm;
Marcel Holtmannf0709e02007-10-20 13:38:51 +020059
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -070060static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN;
Marcel Holtmanne1027a72009-02-09 09:18:02 +010061static u8 l2cap_fixed_chan[8] = { 0x02, };
Linus Torvalds1da177e2005-04-16 15:20:36 -070062
Gustavo F. Padovan1890d362010-05-01 16:15:44 -030063static struct workqueue_struct *_busy_wq;
64
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -020065struct bt_sock_list l2cap_sk_list = {
Robert P. J. Dayd5fb2962008-03-28 16:17:38 -070066 .lock = __RW_LOCK_UNLOCKED(l2cap_sk_list.lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -070067};
68
Gustavo F. Padovan1890d362010-05-01 16:15:44 -030069static void l2cap_busy_work(struct work_struct *work);
70
Linus Torvalds1da177e2005-04-16 15:20:36 -070071static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
72 u8 code, u8 ident, u16 dlen, void *data);
73
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -030074static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb);
75
Marcel Holtmann01394182006-07-03 10:02:46 +020076/* ---- L2CAP channels ---- */
77static struct sock *__l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, u16 cid)
78{
79 struct sock *s;
80 for (s = l->head; s; s = l2cap_pi(s)->next_c) {
81 if (l2cap_pi(s)->dcid == cid)
82 break;
83 }
84 return s;
85}
86
87static struct sock *__l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid)
88{
89 struct sock *s;
90 for (s = l->head; s; s = l2cap_pi(s)->next_c) {
91 if (l2cap_pi(s)->scid == cid)
92 break;
93 }
94 return s;
95}
96
97/* Find channel with given SCID.
98 * Returns locked socket */
99static inline struct sock *l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid)
100{
101 struct sock *s;
102 read_lock(&l->lock);
103 s = __l2cap_get_chan_by_scid(l, cid);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300104 if (s)
105 bh_lock_sock(s);
Marcel Holtmann01394182006-07-03 10:02:46 +0200106 read_unlock(&l->lock);
107 return s;
108}
109
110static struct sock *__l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 ident)
111{
112 struct sock *s;
113 for (s = l->head; s; s = l2cap_pi(s)->next_c) {
114 if (l2cap_pi(s)->ident == ident)
115 break;
116 }
117 return s;
118}
119
120static inline struct sock *l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 ident)
121{
122 struct sock *s;
123 read_lock(&l->lock);
124 s = __l2cap_get_chan_by_ident(l, ident);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300125 if (s)
126 bh_lock_sock(s);
Marcel Holtmann01394182006-07-03 10:02:46 +0200127 read_unlock(&l->lock);
128 return s;
129}
130
131static u16 l2cap_alloc_cid(struct l2cap_chan_list *l)
132{
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300133 u16 cid = L2CAP_CID_DYN_START;
Marcel Holtmann01394182006-07-03 10:02:46 +0200134
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300135 for (; cid < L2CAP_CID_DYN_END; cid++) {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300136 if (!__l2cap_get_chan_by_scid(l, cid))
Marcel Holtmann01394182006-07-03 10:02:46 +0200137 return cid;
138 }
139
140 return 0;
141}
142
143static inline void __l2cap_chan_link(struct l2cap_chan_list *l, struct sock *sk)
144{
145 sock_hold(sk);
146
147 if (l->head)
148 l2cap_pi(l->head)->prev_c = sk;
149
150 l2cap_pi(sk)->next_c = l->head;
151 l2cap_pi(sk)->prev_c = NULL;
152 l->head = sk;
153}
154
155static inline void l2cap_chan_unlink(struct l2cap_chan_list *l, struct sock *sk)
156{
157 struct sock *next = l2cap_pi(sk)->next_c, *prev = l2cap_pi(sk)->prev_c;
158
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200159 write_lock_bh(&l->lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200160 if (sk == l->head)
161 l->head = next;
162
163 if (next)
164 l2cap_pi(next)->prev_c = prev;
165 if (prev)
166 l2cap_pi(prev)->next_c = next;
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200167 write_unlock_bh(&l->lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200168
169 __sock_put(sk);
170}
171
172static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
173{
174 struct l2cap_chan_list *l = &conn->chan_list;
175
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300176 BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
177 l2cap_pi(sk)->psm, l2cap_pi(sk)->dcid);
Marcel Holtmann01394182006-07-03 10:02:46 +0200178
Marcel Holtmann2950f212009-02-12 14:02:50 +0100179 conn->disc_reason = 0x13;
180
Marcel Holtmann01394182006-07-03 10:02:46 +0200181 l2cap_pi(sk)->conn = conn;
182
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300183 if (sk->sk_type == SOCK_SEQPACKET || sk->sk_type == SOCK_STREAM) {
Ville Tervob62f3282011-02-10 22:38:50 -0300184 if (conn->hcon->type == LE_LINK) {
185 /* LE connection */
186 l2cap_pi(sk)->omtu = L2CAP_LE_DEFAULT_MTU;
187 l2cap_pi(sk)->scid = L2CAP_CID_LE_DATA;
188 l2cap_pi(sk)->dcid = L2CAP_CID_LE_DATA;
189 } else {
190 /* Alloc CID for connection-oriented socket */
191 l2cap_pi(sk)->scid = l2cap_alloc_cid(l);
192 l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
193 }
Marcel Holtmann01394182006-07-03 10:02:46 +0200194 } else if (sk->sk_type == SOCK_DGRAM) {
195 /* Connectionless socket */
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300196 l2cap_pi(sk)->scid = L2CAP_CID_CONN_LESS;
197 l2cap_pi(sk)->dcid = L2CAP_CID_CONN_LESS;
Marcel Holtmann01394182006-07-03 10:02:46 +0200198 l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
199 } else {
200 /* Raw socket can send/recv signalling messages only */
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300201 l2cap_pi(sk)->scid = L2CAP_CID_SIGNALING;
202 l2cap_pi(sk)->dcid = L2CAP_CID_SIGNALING;
Marcel Holtmann01394182006-07-03 10:02:46 +0200203 l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
204 }
205
206 __l2cap_chan_link(l, sk);
207
208 if (parent)
209 bt_accept_enqueue(parent, sk);
210}
211
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900212/* Delete channel.
Marcel Holtmann01394182006-07-03 10:02:46 +0200213 * Must be called on the locked socket. */
Gustavo F. Padovan6de07022011-02-04 03:35:20 -0200214void l2cap_chan_del(struct sock *sk, int err)
Marcel Holtmann01394182006-07-03 10:02:46 +0200215{
216 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
217 struct sock *parent = bt_sk(sk)->parent;
218
219 l2cap_sock_clear_timer(sk);
220
221 BT_DBG("sk %p, conn %p, err %d", sk, conn, err);
222
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900223 if (conn) {
Marcel Holtmann01394182006-07-03 10:02:46 +0200224 /* Unlink from channel list */
225 l2cap_chan_unlink(&conn->chan_list, sk);
226 l2cap_pi(sk)->conn = NULL;
227 hci_conn_put(conn->hcon);
228 }
229
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200230 sk->sk_state = BT_CLOSED;
Marcel Holtmann01394182006-07-03 10:02:46 +0200231 sock_set_flag(sk, SOCK_ZAPPED);
232
233 if (err)
234 sk->sk_err = err;
235
236 if (parent) {
237 bt_accept_unlink(sk);
238 parent->sk_data_ready(parent, 0);
239 } else
240 sk->sk_state_change(sk);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300241
242 skb_queue_purge(TX_QUEUE(sk));
243
244 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
245 struct srej_list *l, *tmp;
246
247 del_timer(&l2cap_pi(sk)->retrans_timer);
248 del_timer(&l2cap_pi(sk)->monitor_timer);
249 del_timer(&l2cap_pi(sk)->ack_timer);
250
251 skb_queue_purge(SREJ_QUEUE(sk));
252 skb_queue_purge(BUSY_QUEUE(sk));
253
254 list_for_each_entry_safe(l, tmp, SREJ_LIST(sk), list) {
255 list_del(&l->list);
256 kfree(l);
257 }
258 }
Marcel Holtmann01394182006-07-03 10:02:46 +0200259}
260
Johan Hedberg8556edd32011-01-19 12:06:50 +0530261static inline u8 l2cap_get_auth_type(struct sock *sk)
262{
263 if (sk->sk_type == SOCK_RAW) {
264 switch (l2cap_pi(sk)->sec_level) {
265 case BT_SECURITY_HIGH:
266 return HCI_AT_DEDICATED_BONDING_MITM;
267 case BT_SECURITY_MEDIUM:
268 return HCI_AT_DEDICATED_BONDING;
269 default:
270 return HCI_AT_NO_BONDING;
271 }
272 } else if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) {
273 if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW)
274 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
275
276 if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
277 return HCI_AT_NO_BONDING_MITM;
278 else
279 return HCI_AT_NO_BONDING;
280 } else {
281 switch (l2cap_pi(sk)->sec_level) {
282 case BT_SECURITY_HIGH:
283 return HCI_AT_GENERAL_BONDING_MITM;
284 case BT_SECURITY_MEDIUM:
285 return HCI_AT_GENERAL_BONDING;
286 default:
287 return HCI_AT_NO_BONDING;
288 }
289 }
290}
291
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200292/* Service level security */
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100293static inline int l2cap_check_security(struct sock *sk)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200294{
295 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100296 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200297
Johan Hedberg8556edd32011-01-19 12:06:50 +0530298 auth_type = l2cap_get_auth_type(sk);
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100299
300 return hci_conn_security(conn->hcon, l2cap_pi(sk)->sec_level,
301 auth_type);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200302}
303
Gustavo F. Padovan68983252011-02-04 03:02:31 -0200304u8 l2cap_get_ident(struct l2cap_conn *conn)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200305{
306 u8 id;
307
308 /* Get next available identificator.
309 * 1 - 128 are used by kernel.
310 * 129 - 199 are reserved.
311 * 200 - 254 are used by utilities like l2ping, etc.
312 */
313
314 spin_lock_bh(&conn->lock);
315
316 if (++conn->tx_ident > 128)
317 conn->tx_ident = 1;
318
319 id = conn->tx_ident;
320
321 spin_unlock_bh(&conn->lock);
322
323 return id;
324}
325
Gustavo F. Padovan68983252011-02-04 03:02:31 -0200326void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200327{
328 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200329 u8 flags;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200330
331 BT_DBG("code 0x%2.2x", code);
332
333 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300334 return;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200335
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200336 if (lmp_no_flush_capable(conn->hcon->hdev))
337 flags = ACL_START_NO_FLUSH;
338 else
339 flags = ACL_START;
340
341 hci_send_acl(conn->hcon, skb, flags);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200342}
343
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300344static inline void l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300345{
346 struct sk_buff *skb;
347 struct l2cap_hdr *lh;
348 struct l2cap_conn *conn = pi->conn;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300349 struct sock *sk = (struct sock *)pi;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300350 int count, hlen = L2CAP_HDR_SIZE + 2;
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200351 u8 flags;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300352
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300353 if (sk->sk_state != BT_CONNECTED)
354 return;
355
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300356 if (pi->fcs == L2CAP_FCS_CRC16)
357 hlen += 2;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300358
359 BT_DBG("pi %p, control 0x%2.2x", pi, control);
360
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300361 count = min_t(unsigned int, conn->mtu, hlen);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300362 control |= L2CAP_CTRL_FRAME_TYPE;
363
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -0300364 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
365 control |= L2CAP_CTRL_FINAL;
366 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
367 }
368
Gustavo F. Padovanf0946cc2010-05-01 16:15:37 -0300369 if (pi->conn_state & L2CAP_CONN_SEND_PBIT) {
370 control |= L2CAP_CTRL_POLL;
371 pi->conn_state &= ~L2CAP_CONN_SEND_PBIT;
372 }
373
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300374 skb = bt_skb_alloc(count, GFP_ATOMIC);
375 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300376 return;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300377
378 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300379 lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300380 lh->cid = cpu_to_le16(pi->dcid);
381 put_unaligned_le16(control, skb_put(skb, 2));
382
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300383 if (pi->fcs == L2CAP_FCS_CRC16) {
384 u16 fcs = crc16(0, (u8 *)lh, count - 2);
385 put_unaligned_le16(fcs, skb_put(skb, 2));
386 }
387
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200388 if (lmp_no_flush_capable(conn->hcon->hdev))
389 flags = ACL_START_NO_FLUSH;
390 else
391 flags = ACL_START;
392
393 hci_send_acl(pi->conn->hcon, skb, flags);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300394}
395
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300396static inline void l2cap_send_rr_or_rnr(struct l2cap_pinfo *pi, u16 control)
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300397{
Gustavo F. Padovan1890d362010-05-01 16:15:44 -0300398 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300399 control |= L2CAP_SUPER_RCV_NOT_READY;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -0300400 pi->conn_state |= L2CAP_CONN_RNR_SENT;
401 } else
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300402 control |= L2CAP_SUPER_RCV_READY;
403
Gustavo F. Padovan2ab25cd2009-10-03 02:34:40 -0300404 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
405
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300406 l2cap_send_sframe(pi, control);
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300407}
408
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300409static inline int __l2cap_no_conn_pending(struct sock *sk)
410{
411 return !(l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND);
412}
413
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200414static void l2cap_do_start(struct sock *sk)
415{
416 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
417
418 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +0100419 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
420 return;
421
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300422 if (l2cap_check_security(sk) && __l2cap_no_conn_pending(sk)) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200423 struct l2cap_conn_req req;
424 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
425 req.psm = l2cap_pi(sk)->psm;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200426
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200427 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300428 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200429
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200430 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200431 L2CAP_CONN_REQ, sizeof(req), &req);
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200432 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200433 } else {
434 struct l2cap_info_req req;
435 req.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
436
437 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
438 conn->info_ident = l2cap_get_ident(conn);
439
440 mod_timer(&conn->info_timer, jiffies +
441 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
442
443 l2cap_send_cmd(conn, conn->info_ident,
444 L2CAP_INFO_REQ, sizeof(req), &req);
445 }
446}
447
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -0300448static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
449{
450 u32 local_feat_mask = l2cap_feat_mask;
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -0300451 if (!disable_ertm)
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -0300452 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
453
454 switch (mode) {
455 case L2CAP_MODE_ERTM:
456 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
457 case L2CAP_MODE_STREAMING:
458 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
459 default:
460 return 0x00;
461 }
462}
463
Gustavo F. Padovan6de07022011-02-04 03:35:20 -0200464void l2cap_send_disconn_req(struct l2cap_conn *conn, struct sock *sk, int err)
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300465{
466 struct l2cap_disconn_req req;
467
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300468 if (!conn)
469 return;
470
471 skb_queue_purge(TX_QUEUE(sk));
472
473 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
474 del_timer(&l2cap_pi(sk)->retrans_timer);
475 del_timer(&l2cap_pi(sk)->monitor_timer);
476 del_timer(&l2cap_pi(sk)->ack_timer);
477 }
478
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300479 req.dcid = cpu_to_le16(l2cap_pi(sk)->dcid);
480 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
481 l2cap_send_cmd(conn, l2cap_get_ident(conn),
482 L2CAP_DISCONN_REQ, sizeof(req), &req);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300483
484 sk->sk_state = BT_DISCONN;
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -0300485 sk->sk_err = err;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300486}
487
Linus Torvalds1da177e2005-04-16 15:20:36 -0700488/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200489static void l2cap_conn_start(struct l2cap_conn *conn)
490{
491 struct l2cap_chan_list *l = &conn->chan_list;
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -0300492 struct sock_del_list del, *tmp1, *tmp2;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200493 struct sock *sk;
494
495 BT_DBG("conn %p", conn);
496
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -0300497 INIT_LIST_HEAD(&del.list);
498
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200499 read_lock(&l->lock);
500
501 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
502 bh_lock_sock(sk);
503
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300504 if (sk->sk_type != SOCK_SEQPACKET &&
505 sk->sk_type != SOCK_STREAM) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200506 bh_unlock_sock(sk);
507 continue;
508 }
509
510 if (sk->sk_state == BT_CONNECT) {
Gustavo F. Padovan47731de2010-07-09 16:38:35 -0300511 struct l2cap_conn_req req;
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -0300512
Gustavo F. Padovan47731de2010-07-09 16:38:35 -0300513 if (!l2cap_check_security(sk) ||
514 !__l2cap_no_conn_pending(sk)) {
515 bh_unlock_sock(sk);
516 continue;
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200517 }
Gustavo F. Padovan47731de2010-07-09 16:38:35 -0300518
519 if (!l2cap_mode_supported(l2cap_pi(sk)->mode,
520 conn->feat_mask)
521 && l2cap_pi(sk)->conf_state &
522 L2CAP_CONF_STATE2_DEVICE) {
523 tmp1 = kzalloc(sizeof(struct sock_del_list),
524 GFP_ATOMIC);
525 tmp1->sk = sk;
526 list_add_tail(&tmp1->list, &del.list);
527 bh_unlock_sock(sk);
528 continue;
529 }
530
531 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
532 req.psm = l2cap_pi(sk)->psm;
533
534 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
535 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
536
537 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
538 L2CAP_CONN_REQ, sizeof(req), &req);
539
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200540 } else if (sk->sk_state == BT_CONNECT2) {
541 struct l2cap_conn_rsp rsp;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -0300542 char buf[128];
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200543 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
544 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
545
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100546 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100547 if (bt_sk(sk)->defer_setup) {
548 struct sock *parent = bt_sk(sk)->parent;
549 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
550 rsp.status = cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
551 parent->sk_data_ready(parent, 0);
552
553 } else {
554 sk->sk_state = BT_CONFIG;
555 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
556 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
557 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200558 } else {
559 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
560 rsp.status = cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
561 }
562
563 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
564 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -0300565
566 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT ||
567 rsp.result != L2CAP_CR_SUCCESS) {
568 bh_unlock_sock(sk);
569 continue;
570 }
571
572 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
573 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
574 l2cap_build_conf_req(sk, buf), buf);
575 l2cap_pi(sk)->num_conf_req++;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200576 }
577
578 bh_unlock_sock(sk);
579 }
580
581 read_unlock(&l->lock);
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -0300582
583 list_for_each_entry_safe(tmp1, tmp2, &del.list, list) {
584 bh_lock_sock(tmp1->sk);
585 __l2cap_sock_close(tmp1->sk, ECONNRESET);
586 bh_unlock_sock(tmp1->sk);
587 list_del(&tmp1->list);
588 kfree(tmp1);
589 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200590}
591
Ville Tervob62f3282011-02-10 22:38:50 -0300592/* Find socket with cid and source bdaddr.
593 * Returns closest match, locked.
594 */
595static struct sock *l2cap_get_sock_by_scid(int state, __le16 cid, bdaddr_t *src)
596{
597 struct sock *s, *sk = NULL, *sk1 = NULL;
598 struct hlist_node *node;
599
600 read_lock(&l2cap_sk_list.lock);
601
602 sk_for_each(sk, node, &l2cap_sk_list.head) {
603 if (state && sk->sk_state != state)
604 continue;
605
606 if (l2cap_pi(sk)->scid == cid) {
607 /* Exact match. */
608 if (!bacmp(&bt_sk(sk)->src, src))
609 break;
610
611 /* Closest match */
612 if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY))
613 sk1 = sk;
614 }
615 }
616 s = node ? sk : sk1;
617 if (s)
618 bh_lock_sock(s);
619 read_unlock(&l2cap_sk_list.lock);
620
621 return s;
622}
623
624static void l2cap_le_conn_ready(struct l2cap_conn *conn)
625{
626 struct l2cap_chan_list *list = &conn->chan_list;
627 struct sock *parent, *uninitialized_var(sk);
628
629 BT_DBG("");
630
631 /* Check if we have socket listening on cid */
632 parent = l2cap_get_sock_by_scid(BT_LISTEN, L2CAP_CID_LE_DATA,
633 conn->src);
634 if (!parent)
635 return;
636
637 /* Check for backlog size */
638 if (sk_acceptq_is_full(parent)) {
639 BT_DBG("backlog full %d", parent->sk_ack_backlog);
640 goto clean;
641 }
642
643 sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, GFP_ATOMIC);
644 if (!sk)
645 goto clean;
646
647 write_lock_bh(&list->lock);
648
649 hci_conn_hold(conn->hcon);
650
651 l2cap_sock_init(sk, parent);
652 bacpy(&bt_sk(sk)->src, conn->src);
653 bacpy(&bt_sk(sk)->dst, conn->dst);
654
655 __l2cap_chan_add(conn, sk, parent);
656
657 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
658
659 sk->sk_state = BT_CONNECTED;
660 parent->sk_data_ready(parent, 0);
661
662 write_unlock_bh(&list->lock);
663
664clean:
665 bh_unlock_sock(parent);
666}
667
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200668static void l2cap_conn_ready(struct l2cap_conn *conn)
669{
670 struct l2cap_chan_list *l = &conn->chan_list;
671 struct sock *sk;
672
673 BT_DBG("conn %p", conn);
674
Ville Tervob62f3282011-02-10 22:38:50 -0300675 if (!conn->hcon->out && conn->hcon->type == LE_LINK)
676 l2cap_le_conn_ready(conn);
677
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200678 read_lock(&l->lock);
679
680 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
681 bh_lock_sock(sk);
682
Ville Tervoacd7d372011-02-10 22:38:49 -0300683 if (conn->hcon->type == LE_LINK) {
684 l2cap_sock_clear_timer(sk);
685 sk->sk_state = BT_CONNECTED;
686 sk->sk_state_change(sk);
687 }
688
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300689 if (sk->sk_type != SOCK_SEQPACKET &&
690 sk->sk_type != SOCK_STREAM) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200691 l2cap_sock_clear_timer(sk);
692 sk->sk_state = BT_CONNECTED;
693 sk->sk_state_change(sk);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200694 } else if (sk->sk_state == BT_CONNECT)
695 l2cap_do_start(sk);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200696
697 bh_unlock_sock(sk);
698 }
699
700 read_unlock(&l->lock);
701}
702
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200703/* Notify sockets that we cannot guaranty reliability anymore */
704static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
705{
706 struct l2cap_chan_list *l = &conn->chan_list;
707 struct sock *sk;
708
709 BT_DBG("conn %p", conn);
710
711 read_lock(&l->lock);
712
713 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100714 if (l2cap_pi(sk)->force_reliable)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200715 sk->sk_err = err;
716 }
717
718 read_unlock(&l->lock);
719}
720
721static void l2cap_info_timeout(unsigned long arg)
722{
723 struct l2cap_conn *conn = (void *) arg;
724
Marcel Holtmann984947d2009-02-06 23:35:19 +0100725 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +0100726 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +0100727
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200728 l2cap_conn_start(conn);
729}
730
Linus Torvalds1da177e2005-04-16 15:20:36 -0700731static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
732{
Marcel Holtmann01394182006-07-03 10:02:46 +0200733 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700734
Marcel Holtmann01394182006-07-03 10:02:46 +0200735 if (conn || status)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700736 return conn;
737
Marcel Holtmann01394182006-07-03 10:02:46 +0200738 conn = kzalloc(sizeof(struct l2cap_conn), GFP_ATOMIC);
739 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700740 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700741
742 hcon->l2cap_data = conn;
743 conn->hcon = hcon;
744
Marcel Holtmann01394182006-07-03 10:02:46 +0200745 BT_DBG("hcon %p conn %p", hcon, conn);
746
Ville Tervoacd7d372011-02-10 22:38:49 -0300747 if (hcon->hdev->le_mtu && hcon->type == LE_LINK)
748 conn->mtu = hcon->hdev->le_mtu;
749 else
750 conn->mtu = hcon->hdev->acl_mtu;
751
Linus Torvalds1da177e2005-04-16 15:20:36 -0700752 conn->src = &hcon->hdev->bdaddr;
753 conn->dst = &hcon->dst;
754
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200755 conn->feat_mask = 0;
756
Linus Torvalds1da177e2005-04-16 15:20:36 -0700757 spin_lock_init(&conn->lock);
758 rwlock_init(&conn->chan_list.lock);
759
Ville Tervob62f3282011-02-10 22:38:50 -0300760 if (hcon->type != LE_LINK)
761 setup_timer(&conn->info_timer, l2cap_info_timeout,
Dave Young45054dc2009-10-18 20:28:30 +0000762 (unsigned long) conn);
763
Marcel Holtmann2950f212009-02-12 14:02:50 +0100764 conn->disc_reason = 0x13;
765
Linus Torvalds1da177e2005-04-16 15:20:36 -0700766 return conn;
767}
768
Marcel Holtmann01394182006-07-03 10:02:46 +0200769static void l2cap_conn_del(struct hci_conn *hcon, int err)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700770{
Marcel Holtmann01394182006-07-03 10:02:46 +0200771 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700772 struct sock *sk;
773
Marcel Holtmann01394182006-07-03 10:02:46 +0200774 if (!conn)
775 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700776
777 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
778
Wei Yongjun7585b972009-02-25 18:29:52 +0800779 kfree_skb(conn->rx_skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700780
781 /* Kill channels */
782 while ((sk = conn->chan_list.head)) {
783 bh_lock_sock(sk);
784 l2cap_chan_del(sk, err);
785 bh_unlock_sock(sk);
786 l2cap_sock_kill(sk);
787 }
788
Dave Young8e8440f2008-03-03 12:18:55 -0800789 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
790 del_timer_sync(&conn->info_timer);
Thomas Gleixner3ab22732008-02-26 17:42:56 -0800791
Linus Torvalds1da177e2005-04-16 15:20:36 -0700792 hcon->l2cap_data = NULL;
793 kfree(conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700794}
795
796static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
797{
798 struct l2cap_chan_list *l = &conn->chan_list;
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200799 write_lock_bh(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700800 __l2cap_chan_add(conn, sk, parent);
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200801 write_unlock_bh(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700802}
803
Linus Torvalds1da177e2005-04-16 15:20:36 -0700804/* ---- Socket interface ---- */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700805
806/* Find socket with psm and source bdaddr.
807 * Returns closest match.
808 */
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +0000809static struct sock *l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700810{
811 struct sock *sk = NULL, *sk1 = NULL;
812 struct hlist_node *node;
813
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +0000814 read_lock(&l2cap_sk_list.lock);
815
Linus Torvalds1da177e2005-04-16 15:20:36 -0700816 sk_for_each(sk, node, &l2cap_sk_list.head) {
817 if (state && sk->sk_state != state)
818 continue;
819
820 if (l2cap_pi(sk)->psm == psm) {
821 /* Exact match. */
822 if (!bacmp(&bt_sk(sk)->src, src))
823 break;
824
825 /* Closest match */
826 if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY))
827 sk1 = sk;
828 }
829 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700830
Linus Torvalds1da177e2005-04-16 15:20:36 -0700831 read_unlock(&l2cap_sk_list.lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +0000832
833 return node ? sk : sk1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700834}
835
Gustavo F. Padovan4e34c502011-02-04 02:56:13 -0200836int l2cap_do_connect(struct sock *sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700837{
838 bdaddr_t *src = &bt_sk(sk)->src;
839 bdaddr_t *dst = &bt_sk(sk)->dst;
840 struct l2cap_conn *conn;
841 struct hci_conn *hcon;
842 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200843 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +0200844 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700845
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100846 BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst),
847 l2cap_pi(sk)->psm);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700848
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300849 hdev = hci_get_route(dst, src);
850 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700851 return -EHOSTUNREACH;
852
853 hci_dev_lock_bh(hdev);
854
855 err = -ENOMEM;
856
Johan Hedberg8556edd32011-01-19 12:06:50 +0530857 auth_type = l2cap_get_auth_type(sk);
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200858
Ville Tervoacd7d372011-02-10 22:38:49 -0300859 if (l2cap_pi(sk)->dcid == L2CAP_CID_LE_DATA)
860 hcon = hci_connect(hdev, LE_LINK, dst,
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100861 l2cap_pi(sk)->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -0300862 else
863 hcon = hci_connect(hdev, ACL_LINK, dst,
864 l2cap_pi(sk)->sec_level, auth_type);
865
Linus Torvalds1da177e2005-04-16 15:20:36 -0700866 if (!hcon)
867 goto done;
868
869 conn = l2cap_conn_add(hcon, 0);
870 if (!conn) {
871 hci_conn_put(hcon);
872 goto done;
873 }
874
875 err = 0;
876
877 /* Update source addr of the socket */
878 bacpy(src, conn->src);
879
880 l2cap_chan_add(conn, sk, NULL);
881
882 sk->sk_state = BT_CONNECT;
883 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
884
885 if (hcon->state == BT_CONNECTED) {
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300886 if (sk->sk_type != SOCK_SEQPACKET &&
887 sk->sk_type != SOCK_STREAM) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700888 l2cap_sock_clear_timer(sk);
Johan Hedbergd00ef242011-01-19 12:06:51 +0530889 if (l2cap_check_security(sk))
890 sk->sk_state = BT_CONNECTED;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200891 } else
892 l2cap_do_start(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700893 }
894
895done:
896 hci_dev_unlock_bh(hdev);
897 hci_dev_put(hdev);
898 return err;
899}
900
Gustavo F. Padovandcba0db2011-02-04 03:08:36 -0200901int __l2cap_wait_ack(struct sock *sk)
Gustavo F. Padovan6161c032010-05-01 16:15:44 -0300902{
903 DECLARE_WAITQUEUE(wait, current);
904 int err = 0;
905 int timeo = HZ/5;
906
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +0200907 add_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -0300908 while ((l2cap_pi(sk)->unacked_frames > 0 && l2cap_pi(sk)->conn)) {
909 set_current_state(TASK_INTERRUPTIBLE);
910
911 if (!timeo)
912 timeo = HZ/5;
913
914 if (signal_pending(current)) {
915 err = sock_intr_errno(timeo);
916 break;
917 }
918
919 release_sock(sk);
920 timeo = schedule_timeout(timeo);
921 lock_sock(sk);
922
923 err = sock_error(sk);
924 if (err)
925 break;
926 }
927 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +0200928 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -0300929 return err;
930}
931
Gustavo F. Padovane90bac02009-08-20 22:26:00 -0300932static void l2cap_monitor_timeout(unsigned long arg)
933{
934 struct sock *sk = (void *) arg;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -0300935
Gustavo F. Padovan0e989582010-04-19 14:45:38 -0300936 BT_DBG("sk %p", sk);
937
Gustavo F. Padovane6862192009-08-24 00:45:19 -0300938 bh_lock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -0300939 if (l2cap_pi(sk)->retry_count >= l2cap_pi(sk)->remote_max_tx) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -0300940 l2cap_send_disconn_req(l2cap_pi(sk)->conn, sk, ECONNABORTED);
Andrei Emeltchenkob13f5862009-12-15 11:38:04 +0200941 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -0300942 return;
943 }
944
945 l2cap_pi(sk)->retry_count++;
946 __mod_monitor_timer();
947
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -0300948 l2cap_send_rr_or_rnr(l2cap_pi(sk), L2CAP_CTRL_POLL);
Gustavo F. Padovane6862192009-08-24 00:45:19 -0300949 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -0300950}
951
952static void l2cap_retrans_timeout(unsigned long arg)
953{
954 struct sock *sk = (void *) arg;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -0300955
Gustavo F. Padovan0e989582010-04-19 14:45:38 -0300956 BT_DBG("sk %p", sk);
957
Gustavo F. Padovane6862192009-08-24 00:45:19 -0300958 bh_lock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -0300959 l2cap_pi(sk)->retry_count = 1;
960 __mod_monitor_timer();
961
962 l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
963
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -0300964 l2cap_send_rr_or_rnr(l2cap_pi(sk), L2CAP_CTRL_POLL);
Gustavo F. Padovane6862192009-08-24 00:45:19 -0300965 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -0300966}
967
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300968static void l2cap_drop_acked_frames(struct sock *sk)
969{
970 struct sk_buff *skb;
971
Gustavo F. Padovan812e7372010-05-01 16:15:42 -0300972 while ((skb = skb_peek(TX_QUEUE(sk))) &&
973 l2cap_pi(sk)->unacked_frames) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300974 if (bt_cb(skb)->tx_seq == l2cap_pi(sk)->expected_ack_seq)
975 break;
976
977 skb = skb_dequeue(TX_QUEUE(sk));
978 kfree_skb(skb);
979
980 l2cap_pi(sk)->unacked_frames--;
981 }
982
Gustavo F. Padovane90bac02009-08-20 22:26:00 -0300983 if (!l2cap_pi(sk)->unacked_frames)
984 del_timer(&l2cap_pi(sk)->retrans_timer);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300985}
986
Gustavo F. Padovanfd83ccd2011-02-04 03:20:52 -0200987void l2cap_do_send(struct sock *sk, struct sk_buff *skb)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300988{
989 struct l2cap_pinfo *pi = l2cap_pi(sk);
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200990 struct hci_conn *hcon = pi->conn->hcon;
991 u16 flags;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300992
993 BT_DBG("sk %p, skb %p len %d", sk, skb, skb->len);
994
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200995 if (!pi->flushable && lmp_no_flush_capable(hcon->hdev))
996 flags = ACL_START_NO_FLUSH;
997 else
998 flags = ACL_START;
999
1000 hci_send_acl(hcon, skb, flags);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001001}
1002
Gustavo F. Padovanfd83ccd2011-02-04 03:20:52 -02001003void l2cap_streaming_send(struct sock *sk)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001004{
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001005 struct sk_buff *skb;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001006 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001007 u16 control, fcs;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001008
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001009 while ((skb = skb_dequeue(TX_QUEUE(sk)))) {
1010 control = get_unaligned_le16(skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001011 control |= pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT;
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001012 put_unaligned_le16(control, skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001013
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001014 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001015 fcs = crc16(0, (u8 *)skb->data, skb->len - 2);
1016 put_unaligned_le16(fcs, skb->data + skb->len - 2);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001017 }
1018
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001019 l2cap_do_send(sk, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001020
1021 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001022 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001023}
1024
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001025static void l2cap_retransmit_one_frame(struct sock *sk, u8 tx_seq)
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001026{
1027 struct l2cap_pinfo *pi = l2cap_pi(sk);
1028 struct sk_buff *skb, *tx_skb;
1029 u16 control, fcs;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001030
1031 skb = skb_peek(TX_QUEUE(sk));
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001032 if (!skb)
1033 return;
1034
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001035 do {
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001036 if (bt_cb(skb)->tx_seq == tx_seq)
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001037 break;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001038
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001039 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1040 return;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001041
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001042 } while ((skb = skb_queue_next(TX_QUEUE(sk), skb)));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001043
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001044 if (pi->remote_max_tx &&
1045 bt_cb(skb)->retries == pi->remote_max_tx) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03001046 l2cap_send_disconn_req(pi->conn, sk, ECONNABORTED);
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001047 return;
1048 }
1049
1050 tx_skb = skb_clone(skb, GFP_ATOMIC);
1051 bt_cb(skb)->retries++;
1052 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03001053
1054 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
1055 control |= L2CAP_CTRL_FINAL;
1056 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
1057 }
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03001058
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001059 control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
1060 | (tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03001061
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001062 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1063
1064 if (pi->fcs == L2CAP_FCS_CRC16) {
1065 fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
1066 put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
1067 }
1068
1069 l2cap_do_send(sk, tx_skb);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001070}
1071
Gustavo F. Padovanfd83ccd2011-02-04 03:20:52 -02001072int l2cap_ertm_send(struct sock *sk)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001073{
1074 struct sk_buff *skb, *tx_skb;
1075 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001076 u16 control, fcs;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001077 int nsent = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001078
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001079 if (sk->sk_state != BT_CONNECTED)
1080 return -ENOTCONN;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001081
Gustavo F. Padovan6e2b6722010-06-01 18:52:58 -03001082 while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(sk))) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001083
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001084 if (pi->remote_max_tx &&
1085 bt_cb(skb)->retries == pi->remote_max_tx) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03001086 l2cap_send_disconn_req(pi->conn, sk, ECONNABORTED);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001087 break;
1088 }
1089
Andrei Emeltchenkoe420aba2009-12-23 13:07:14 +02001090 tx_skb = skb_clone(skb, GFP_ATOMIC);
1091
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001092 bt_cb(skb)->retries++;
1093
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001094 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03001095 control &= L2CAP_CTRL_SAR;
1096
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001097 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
1098 control |= L2CAP_CTRL_FINAL;
1099 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
1100 }
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03001101 control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001102 | (pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
1103 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1104
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001105
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001106 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001107 fcs = crc16(0, (u8 *)skb->data, tx_skb->len - 2);
1108 put_unaligned_le16(fcs, skb->data + tx_skb->len - 2);
1109 }
1110
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001111 l2cap_do_send(sk, tx_skb);
1112
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001113 __mod_retrans_timer();
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001114
1115 bt_cb(skb)->tx_seq = pi->next_tx_seq;
1116 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
1117
1118 pi->unacked_frames++;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001119 pi->frames_sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001120
1121 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1122 sk->sk_send_head = NULL;
1123 else
1124 sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001125
1126 nsent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001127 }
1128
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001129 return nsent;
1130}
1131
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001132static int l2cap_retransmit_frames(struct sock *sk)
1133{
1134 struct l2cap_pinfo *pi = l2cap_pi(sk);
1135 int ret;
1136
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001137 if (!skb_queue_empty(TX_QUEUE(sk)))
1138 sk->sk_send_head = TX_QUEUE(sk)->next;
1139
1140 pi->next_tx_seq = pi->expected_ack_seq;
1141 ret = l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001142 return ret;
1143}
1144
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001145static void l2cap_send_ack(struct l2cap_pinfo *pi)
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001146{
1147 struct sock *sk = (struct sock *)pi;
1148 u16 control = 0;
1149
1150 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1151
1152 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
1153 control |= L2CAP_SUPER_RCV_NOT_READY;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03001154 pi->conn_state |= L2CAP_CONN_RNR_SENT;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001155 l2cap_send_sframe(pi, control);
1156 return;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001157 }
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001158
Gustavo F. Padovane0f66212010-06-21 18:50:49 -03001159 if (l2cap_ertm_send(sk) > 0)
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001160 return;
1161
1162 control |= L2CAP_SUPER_RCV_READY;
1163 l2cap_send_sframe(pi, control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001164}
1165
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001166static void l2cap_send_srejtail(struct sock *sk)
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03001167{
1168 struct srej_list *tail;
1169 u16 control;
1170
1171 control = L2CAP_SUPER_SELECT_REJECT;
1172 control |= L2CAP_CTRL_FINAL;
1173
1174 tail = list_entry(SREJ_LIST(sk)->prev, struct srej_list, list);
1175 control |= tail->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1176
1177 l2cap_send_sframe(l2cap_pi(sk), control);
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03001178}
1179
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001180static inline int l2cap_skbuff_fromiovec(struct sock *sk, struct msghdr *msg, int len, int count, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001181{
1182 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001183 struct sk_buff **frag;
1184 int err, sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001185
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03001186 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001187 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001188
1189 sent += count;
1190 len -= count;
1191
1192 /* Continuation fragments (no L2CAP header) */
1193 frag = &skb_shinfo(skb)->frag_list;
1194 while (len) {
1195 count = min_t(unsigned int, conn->mtu, len);
1196
1197 *frag = bt_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err);
1198 if (!*frag)
Gustavo F. Padovan0175d622010-09-24 20:30:57 -03001199 return err;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001200 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
1201 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001202
1203 sent += count;
1204 len -= count;
1205
1206 frag = &(*frag)->next;
1207 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001208
1209 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001210}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001211
Gustavo F. Padovanfd83ccd2011-02-04 03:20:52 -02001212struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, size_t len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001213{
1214 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1215 struct sk_buff *skb;
1216 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1217 struct l2cap_hdr *lh;
1218
1219 BT_DBG("sk %p len %d", sk, (int)len);
1220
1221 count = min_t(unsigned int, (conn->mtu - hlen), len);
1222 skb = bt_skb_send_alloc(sk, count + hlen,
1223 msg->msg_flags & MSG_DONTWAIT, &err);
1224 if (!skb)
Gustavo F. Padovan0175d622010-09-24 20:30:57 -03001225 return ERR_PTR(err);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001226
1227 /* Create L2CAP header */
1228 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1229 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1230 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1231 put_unaligned_le16(l2cap_pi(sk)->psm, skb_put(skb, 2));
1232
1233 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1234 if (unlikely(err < 0)) {
1235 kfree_skb(skb);
1236 return ERR_PTR(err);
1237 }
1238 return skb;
1239}
1240
Gustavo F. Padovanfd83ccd2011-02-04 03:20:52 -02001241struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *msg, size_t len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001242{
1243 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1244 struct sk_buff *skb;
1245 int err, count, hlen = L2CAP_HDR_SIZE;
1246 struct l2cap_hdr *lh;
1247
1248 BT_DBG("sk %p len %d", sk, (int)len);
1249
1250 count = min_t(unsigned int, (conn->mtu - hlen), len);
1251 skb = bt_skb_send_alloc(sk, count + hlen,
1252 msg->msg_flags & MSG_DONTWAIT, &err);
1253 if (!skb)
Gustavo F. Padovan0175d622010-09-24 20:30:57 -03001254 return ERR_PTR(err);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001255
1256 /* Create L2CAP header */
1257 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1258 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1259 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1260
1261 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1262 if (unlikely(err < 0)) {
1263 kfree_skb(skb);
1264 return ERR_PTR(err);
1265 }
1266 return skb;
1267}
1268
Gustavo F. Padovanfd83ccd2011-02-04 03:20:52 -02001269struct sk_buff *l2cap_create_iframe_pdu(struct sock *sk, struct msghdr *msg, size_t len, u16 control, u16 sdulen)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001270{
1271 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1272 struct sk_buff *skb;
1273 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1274 struct l2cap_hdr *lh;
1275
1276 BT_DBG("sk %p len %d", sk, (int)len);
1277
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03001278 if (!conn)
1279 return ERR_PTR(-ENOTCONN);
1280
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001281 if (sdulen)
1282 hlen += 2;
1283
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001284 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1285 hlen += 2;
1286
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001287 count = min_t(unsigned int, (conn->mtu - hlen), len);
1288 skb = bt_skb_send_alloc(sk, count + hlen,
1289 msg->msg_flags & MSG_DONTWAIT, &err);
1290 if (!skb)
Gustavo F. Padovan0175d622010-09-24 20:30:57 -03001291 return ERR_PTR(err);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001292
1293 /* Create L2CAP header */
1294 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1295 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1296 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1297 put_unaligned_le16(control, skb_put(skb, 2));
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001298 if (sdulen)
1299 put_unaligned_le16(sdulen, skb_put(skb, 2));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001300
1301 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1302 if (unlikely(err < 0)) {
1303 kfree_skb(skb);
1304 return ERR_PTR(err);
1305 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001306
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001307 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1308 put_unaligned_le16(0, skb_put(skb, 2));
1309
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001310 bt_cb(skb)->retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001311 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001312}
1313
Gustavo F. Padovanfd83ccd2011-02-04 03:20:52 -02001314int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001315{
1316 struct l2cap_pinfo *pi = l2cap_pi(sk);
1317 struct sk_buff *skb;
1318 struct sk_buff_head sar_queue;
1319 u16 control;
1320 size_t size = 0;
1321
Gustavo F. Padovanff12fd62010-05-05 22:09:15 -03001322 skb_queue_head_init(&sar_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001323 control = L2CAP_SDU_START;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001324 skb = l2cap_create_iframe_pdu(sk, msg, pi->remote_mps, control, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001325 if (IS_ERR(skb))
1326 return PTR_ERR(skb);
1327
1328 __skb_queue_tail(&sar_queue, skb);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001329 len -= pi->remote_mps;
1330 size += pi->remote_mps;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001331
1332 while (len > 0) {
1333 size_t buflen;
1334
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001335 if (len > pi->remote_mps) {
Gustavo F. Padovan44651b82010-05-01 16:15:43 -03001336 control = L2CAP_SDU_CONTINUE;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001337 buflen = pi->remote_mps;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001338 } else {
Gustavo F. Padovan44651b82010-05-01 16:15:43 -03001339 control = L2CAP_SDU_END;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001340 buflen = len;
1341 }
1342
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001343 skb = l2cap_create_iframe_pdu(sk, msg, buflen, control, 0);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001344 if (IS_ERR(skb)) {
1345 skb_queue_purge(&sar_queue);
1346 return PTR_ERR(skb);
1347 }
1348
1349 __skb_queue_tail(&sar_queue, skb);
1350 len -= buflen;
1351 size += buflen;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001352 }
1353 skb_queue_splice_tail(&sar_queue, TX_QUEUE(sk));
1354 if (sk->sk_send_head == NULL)
1355 sk->sk_send_head = sar_queue.next;
1356
1357 return size;
1358}
1359
Linus Torvalds1da177e2005-04-16 15:20:36 -07001360static void l2cap_chan_ready(struct sock *sk)
1361{
1362 struct sock *parent = bt_sk(sk)->parent;
1363
1364 BT_DBG("sk %p, parent %p", sk, parent);
1365
1366 l2cap_pi(sk)->conf_state = 0;
1367 l2cap_sock_clear_timer(sk);
1368
1369 if (!parent) {
1370 /* Outgoing channel.
1371 * Wake up socket sleeping on connect.
1372 */
1373 sk->sk_state = BT_CONNECTED;
1374 sk->sk_state_change(sk);
1375 } else {
1376 /* Incoming channel.
1377 * Wake up socket sleeping on accept.
1378 */
1379 parent->sk_data_ready(parent, 0);
1380 }
1381}
1382
1383/* Copy frame to all raw sockets on that connection */
1384static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
1385{
1386 struct l2cap_chan_list *l = &conn->chan_list;
1387 struct sk_buff *nskb;
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001388 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001389
1390 BT_DBG("conn %p", conn);
1391
1392 read_lock(&l->lock);
1393 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
1394 if (sk->sk_type != SOCK_RAW)
1395 continue;
1396
1397 /* Don't send frame to the socket it came from */
1398 if (skb->sk == sk)
1399 continue;
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001400 nskb = skb_clone(skb, GFP_ATOMIC);
1401 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001402 continue;
1403
1404 if (sock_queue_rcv_skb(sk, nskb))
1405 kfree_skb(nskb);
1406 }
1407 read_unlock(&l->lock);
1408}
1409
1410/* ---- L2CAP signalling commands ---- */
1411static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
1412 u8 code, u8 ident, u16 dlen, void *data)
1413{
1414 struct sk_buff *skb, **frag;
1415 struct l2cap_cmd_hdr *cmd;
1416 struct l2cap_hdr *lh;
1417 int len, count;
1418
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001419 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d",
1420 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001421
1422 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
1423 count = min_t(unsigned int, conn->mtu, len);
1424
1425 skb = bt_skb_alloc(count, GFP_ATOMIC);
1426 if (!skb)
1427 return NULL;
1428
1429 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07001430 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02001431
1432 if (conn->hcon->type == LE_LINK)
1433 lh->cid = cpu_to_le16(L2CAP_CID_LE_SIGNALING);
1434 else
1435 lh->cid = cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001436
1437 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
1438 cmd->code = code;
1439 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07001440 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001441
1442 if (dlen) {
1443 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
1444 memcpy(skb_put(skb, count), data, count);
1445 data += count;
1446 }
1447
1448 len -= skb->len;
1449
1450 /* Continuation fragments (no L2CAP header) */
1451 frag = &skb_shinfo(skb)->frag_list;
1452 while (len) {
1453 count = min_t(unsigned int, conn->mtu, len);
1454
1455 *frag = bt_skb_alloc(count, GFP_ATOMIC);
1456 if (!*frag)
1457 goto fail;
1458
1459 memcpy(skb_put(*frag, count), data, count);
1460
1461 len -= count;
1462 data += count;
1463
1464 frag = &(*frag)->next;
1465 }
1466
1467 return skb;
1468
1469fail:
1470 kfree_skb(skb);
1471 return NULL;
1472}
1473
1474static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned long *val)
1475{
1476 struct l2cap_conf_opt *opt = *ptr;
1477 int len;
1478
1479 len = L2CAP_CONF_OPT_SIZE + opt->len;
1480 *ptr += len;
1481
1482 *type = opt->type;
1483 *olen = opt->len;
1484
1485 switch (opt->len) {
1486 case 1:
1487 *val = *((u8 *) opt->val);
1488 break;
1489
1490 case 2:
steven miaobfaaeb32010-10-16 18:29:47 -04001491 *val = get_unaligned_le16(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001492 break;
1493
1494 case 4:
steven miaobfaaeb32010-10-16 18:29:47 -04001495 *val = get_unaligned_le32(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001496 break;
1497
1498 default:
1499 *val = (unsigned long) opt->val;
1500 break;
1501 }
1502
1503 BT_DBG("type 0x%2.2x len %d val 0x%lx", *type, opt->len, *val);
1504 return len;
1505}
1506
Linus Torvalds1da177e2005-04-16 15:20:36 -07001507static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
1508{
1509 struct l2cap_conf_opt *opt = *ptr;
1510
1511 BT_DBG("type 0x%2.2x len %d val 0x%lx", type, len, val);
1512
1513 opt->type = type;
1514 opt->len = len;
1515
1516 switch (len) {
1517 case 1:
1518 *((u8 *) opt->val) = val;
1519 break;
1520
1521 case 2:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02001522 put_unaligned_le16(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001523 break;
1524
1525 case 4:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02001526 put_unaligned_le32(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001527 break;
1528
1529 default:
1530 memcpy(opt->val, (void *) val, len);
1531 break;
1532 }
1533
1534 *ptr += L2CAP_CONF_OPT_SIZE + len;
1535}
1536
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03001537static void l2cap_ack_timeout(unsigned long arg)
1538{
1539 struct sock *sk = (void *) arg;
1540
1541 bh_lock_sock(sk);
1542 l2cap_send_ack(l2cap_pi(sk));
1543 bh_unlock_sock(sk);
1544}
1545
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03001546static inline void l2cap_ertm_init(struct sock *sk)
1547{
1548 l2cap_pi(sk)->expected_ack_seq = 0;
1549 l2cap_pi(sk)->unacked_frames = 0;
1550 l2cap_pi(sk)->buffer_seq = 0;
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03001551 l2cap_pi(sk)->num_acked = 0;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001552 l2cap_pi(sk)->frames_sent = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03001553
1554 setup_timer(&l2cap_pi(sk)->retrans_timer,
1555 l2cap_retrans_timeout, (unsigned long) sk);
1556 setup_timer(&l2cap_pi(sk)->monitor_timer,
1557 l2cap_monitor_timeout, (unsigned long) sk);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03001558 setup_timer(&l2cap_pi(sk)->ack_timer,
1559 l2cap_ack_timeout, (unsigned long) sk);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03001560
1561 __skb_queue_head_init(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03001562 __skb_queue_head_init(BUSY_QUEUE(sk));
1563
1564 INIT_WORK(&l2cap_pi(sk)->busy_work, l2cap_busy_work);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03001565
1566 sk->sk_backlog_rcv = l2cap_ertm_data_rcv;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03001567}
1568
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001569static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
1570{
1571 switch (mode) {
1572 case L2CAP_MODE_STREAMING:
1573 case L2CAP_MODE_ERTM:
1574 if (l2cap_mode_supported(mode, remote_feat_mask))
1575 return mode;
1576 /* fall through */
1577 default:
1578 return L2CAP_MODE_BASIC;
1579 }
1580}
1581
Gustavo F. Padovan68983252011-02-04 03:02:31 -02001582int l2cap_build_conf_req(struct sock *sk, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001583{
1584 struct l2cap_pinfo *pi = l2cap_pi(sk);
1585 struct l2cap_conf_req *req = data;
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001586 struct l2cap_conf_rfc rfc = { .mode = pi->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07001587 void *ptr = req->data;
1588
1589 BT_DBG("sk %p", sk);
1590
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001591 if (pi->num_conf_req || pi->num_conf_rsp)
1592 goto done;
1593
1594 switch (pi->mode) {
1595 case L2CAP_MODE_STREAMING:
1596 case L2CAP_MODE_ERTM:
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03001597 if (pi->conf_state & L2CAP_CONF_STATE2_DEVICE)
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03001598 break;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03001599
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03001600 /* fall through */
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001601 default:
1602 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
1603 break;
1604 }
1605
1606done:
Gustavo F. Padovan7990681c2011-01-24 16:01:43 -02001607 if (pi->imtu != L2CAP_DEFAULT_MTU)
1608 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
1609
Marcel Holtmann65c7c492009-05-02 23:07:53 -07001610 switch (pi->mode) {
1611 case L2CAP_MODE_BASIC:
Gustavo F. Padovan63406502010-08-03 23:49:29 -03001612 if (!(pi->conn->feat_mask & L2CAP_FEAT_ERTM) &&
1613 !(pi->conn->feat_mask & L2CAP_FEAT_STREAMING))
1614 break;
1615
Gustavo F. Padovan62547752010-06-08 20:05:31 -03001616 rfc.mode = L2CAP_MODE_BASIC;
1617 rfc.txwin_size = 0;
1618 rfc.max_transmit = 0;
1619 rfc.retrans_timeout = 0;
1620 rfc.monitor_timeout = 0;
1621 rfc.max_pdu_size = 0;
1622
Gustavo F. Padovan63406502010-08-03 23:49:29 -03001623 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
1624 (unsigned long) &rfc);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07001625 break;
1626
1627 case L2CAP_MODE_ERTM:
1628 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03001629 rfc.txwin_size = pi->tx_win;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03001630 rfc.max_transmit = pi->max_tx;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001631 rfc.retrans_timeout = 0;
1632 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001633 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03001634 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001635 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001636
Gustavo F. Padovan63406502010-08-03 23:49:29 -03001637 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
1638 (unsigned long) &rfc);
1639
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001640 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
1641 break;
1642
1643 if (pi->fcs == L2CAP_FCS_NONE ||
1644 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
1645 pi->fcs = L2CAP_FCS_NONE;
1646 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
1647 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001648 break;
1649
1650 case L2CAP_MODE_STREAMING:
1651 rfc.mode = L2CAP_MODE_STREAMING;
1652 rfc.txwin_size = 0;
1653 rfc.max_transmit = 0;
1654 rfc.retrans_timeout = 0;
1655 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001656 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03001657 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001658 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07001659
Gustavo F. Padovan63406502010-08-03 23:49:29 -03001660 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
1661 (unsigned long) &rfc);
1662
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001663 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
1664 break;
1665
1666 if (pi->fcs == L2CAP_FCS_NONE ||
1667 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
1668 pi->fcs = L2CAP_FCS_NONE;
1669 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
1670 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07001671 break;
1672 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001673
1674 /* FIXME: Need actual value of the flush timeout */
1675 //if (flush_to != L2CAP_DEFAULT_FLUSH_TO)
1676 // l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2, pi->flush_to);
1677
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07001678 req->dcid = cpu_to_le16(pi->dcid);
1679 req->flags = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001680
1681 return ptr - data;
1682}
1683
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001684static int l2cap_parse_conf_req(struct sock *sk, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001685{
1686 struct l2cap_pinfo *pi = l2cap_pi(sk);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001687 struct l2cap_conf_rsp *rsp = data;
1688 void *ptr = rsp->data;
1689 void *req = pi->conf_req;
1690 int len = pi->conf_len;
1691 int type, hint, olen;
1692 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02001693 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Marcel Holtmann861d6882007-10-20 13:37:06 +02001694 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001695 u16 result = L2CAP_CONF_SUCCESS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001696
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001697 BT_DBG("sk %p", sk);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01001698
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001699 while (len >= L2CAP_CONF_OPT_SIZE) {
1700 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001701
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03001702 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07001703 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001704
1705 switch (type) {
1706 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02001707 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001708 break;
1709
1710 case L2CAP_CONF_FLUSH_TO:
1711 pi->flush_to = val;
1712 break;
1713
1714 case L2CAP_CONF_QOS:
1715 break;
1716
Marcel Holtmann6464f352007-10-20 13:39:51 +02001717 case L2CAP_CONF_RFC:
1718 if (olen == sizeof(rfc))
1719 memcpy(&rfc, (void *) val, olen);
1720 break;
1721
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001722 case L2CAP_CONF_FCS:
1723 if (val == L2CAP_FCS_NONE)
1724 pi->conf_state |= L2CAP_CONF_NO_FCS_RECV;
1725
1726 break;
1727
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001728 default:
1729 if (hint)
1730 break;
1731
1732 result = L2CAP_CONF_UNKNOWN;
1733 *((u8 *) ptr++) = type;
1734 break;
1735 }
1736 }
1737
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001738 if (pi->num_conf_rsp || pi->num_conf_req > 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001739 goto done;
1740
1741 switch (pi->mode) {
1742 case L2CAP_MODE_STREAMING:
1743 case L2CAP_MODE_ERTM:
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03001744 if (!(pi->conf_state & L2CAP_CONF_STATE2_DEVICE)) {
1745 pi->mode = l2cap_select_mode(rfc.mode,
1746 pi->conn->feat_mask);
1747 break;
1748 }
1749
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03001750 if (pi->mode != rfc.mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001751 return -ECONNREFUSED;
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03001752
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001753 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001754 }
1755
1756done:
1757 if (pi->mode != rfc.mode) {
1758 result = L2CAP_CONF_UNACCEPT;
1759 rfc.mode = pi->mode;
1760
1761 if (pi->num_conf_rsp == 1)
1762 return -ECONNREFUSED;
1763
1764 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
1765 sizeof(rfc), (unsigned long) &rfc);
1766 }
1767
1768
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001769 if (result == L2CAP_CONF_SUCCESS) {
1770 /* Configure output options and let the other side know
1771 * which ones we don't like. */
1772
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001773 if (mtu < L2CAP_DEFAULT_MIN_MTU)
1774 result = L2CAP_CONF_UNACCEPT;
1775 else {
1776 pi->omtu = mtu;
1777 pi->conf_state |= L2CAP_CONF_MTU_DONE;
1778 }
1779 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001780
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001781 switch (rfc.mode) {
1782 case L2CAP_MODE_BASIC:
1783 pi->fcs = L2CAP_FCS_NONE;
1784 pi->conf_state |= L2CAP_CONF_MODE_DONE;
1785 break;
1786
1787 case L2CAP_MODE_ERTM:
1788 pi->remote_tx_win = rfc.txwin_size;
1789 pi->remote_max_tx = rfc.max_transmit;
Mat Martineau86b1b262010-08-05 15:54:22 -07001790
1791 if (le16_to_cpu(rfc.max_pdu_size) > pi->conn->mtu - 10)
1792 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001793
1794 pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001795
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03001796 rfc.retrans_timeout =
1797 le16_to_cpu(L2CAP_DEFAULT_RETRANS_TO);
1798 rfc.monitor_timeout =
1799 le16_to_cpu(L2CAP_DEFAULT_MONITOR_TO);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001800
1801 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03001802
1803 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
1804 sizeof(rfc), (unsigned long) &rfc);
1805
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001806 break;
1807
1808 case L2CAP_MODE_STREAMING:
Mat Martineau86b1b262010-08-05 15:54:22 -07001809 if (le16_to_cpu(rfc.max_pdu_size) > pi->conn->mtu - 10)
1810 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001811
1812 pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001813
1814 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03001815
1816 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
1817 sizeof(rfc), (unsigned long) &rfc);
1818
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001819 break;
1820
1821 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02001822 result = L2CAP_CONF_UNACCEPT;
1823
1824 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001825 rfc.mode = pi->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02001826 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001827
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001828 if (result == L2CAP_CONF_SUCCESS)
1829 pi->conf_state |= L2CAP_CONF_OUTPUT_DONE;
1830 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001831 rsp->scid = cpu_to_le16(pi->dcid);
1832 rsp->result = cpu_to_le16(result);
1833 rsp->flags = cpu_to_le16(0x0000);
1834
1835 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001836}
1837
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001838static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data, u16 *result)
1839{
1840 struct l2cap_pinfo *pi = l2cap_pi(sk);
1841 struct l2cap_conf_req *req = data;
1842 void *ptr = req->data;
1843 int type, olen;
1844 unsigned long val;
1845 struct l2cap_conf_rfc rfc;
1846
1847 BT_DBG("sk %p, rsp %p, len %d, req %p", sk, rsp, len, data);
1848
1849 while (len >= L2CAP_CONF_OPT_SIZE) {
1850 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
1851
1852 switch (type) {
1853 case L2CAP_CONF_MTU:
1854 if (val < L2CAP_DEFAULT_MIN_MTU) {
1855 *result = L2CAP_CONF_UNACCEPT;
Andrei Emeltchenko8183b772010-09-01 15:17:25 +03001856 pi->imtu = L2CAP_DEFAULT_MIN_MTU;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001857 } else
Andrei Emeltchenko8183b772010-09-01 15:17:25 +03001858 pi->imtu = val;
1859 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001860 break;
1861
1862 case L2CAP_CONF_FLUSH_TO:
1863 pi->flush_to = val;
1864 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
1865 2, pi->flush_to);
1866 break;
1867
1868 case L2CAP_CONF_RFC:
1869 if (olen == sizeof(rfc))
1870 memcpy(&rfc, (void *)val, olen);
1871
1872 if ((pi->conf_state & L2CAP_CONF_STATE2_DEVICE) &&
1873 rfc.mode != pi->mode)
1874 return -ECONNREFUSED;
1875
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001876 pi->fcs = 0;
1877
1878 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
1879 sizeof(rfc), (unsigned long) &rfc);
1880 break;
1881 }
1882 }
1883
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03001884 if (pi->mode == L2CAP_MODE_BASIC && pi->mode != rfc.mode)
1885 return -ECONNREFUSED;
1886
1887 pi->mode = rfc.mode;
1888
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001889 if (*result == L2CAP_CONF_SUCCESS) {
1890 switch (rfc.mode) {
1891 case L2CAP_MODE_ERTM:
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03001892 pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
1893 pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001894 pi->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001895 break;
1896 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001897 pi->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001898 }
1899 }
1900
1901 req->dcid = cpu_to_le16(pi->dcid);
1902 req->flags = cpu_to_le16(0x0000);
1903
1904 return ptr - data;
1905}
1906
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001907static int l2cap_build_conf_rsp(struct sock *sk, void *data, u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001908{
1909 struct l2cap_conf_rsp *rsp = data;
1910 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001911
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001912 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001913
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07001914 rsp->scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001915 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07001916 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001917
1918 return ptr - data;
1919}
1920
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03001921static void l2cap_conf_rfc_get(struct sock *sk, void *rsp, int len)
1922{
1923 struct l2cap_pinfo *pi = l2cap_pi(sk);
1924 int type, olen;
1925 unsigned long val;
1926 struct l2cap_conf_rfc rfc;
1927
1928 BT_DBG("sk %p, rsp %p, len %d", sk, rsp, len);
1929
1930 if ((pi->mode != L2CAP_MODE_ERTM) && (pi->mode != L2CAP_MODE_STREAMING))
1931 return;
1932
1933 while (len >= L2CAP_CONF_OPT_SIZE) {
1934 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
1935
1936 switch (type) {
1937 case L2CAP_CONF_RFC:
1938 if (olen == sizeof(rfc))
1939 memcpy(&rfc, (void *)val, olen);
1940 goto done;
1941 }
1942 }
1943
1944done:
1945 switch (rfc.mode) {
1946 case L2CAP_MODE_ERTM:
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03001947 pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
1948 pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03001949 pi->mps = le16_to_cpu(rfc.max_pdu_size);
1950 break;
1951 case L2CAP_MODE_STREAMING:
1952 pi->mps = le16_to_cpu(rfc.max_pdu_size);
1953 }
1954}
1955
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001956static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
1957{
1958 struct l2cap_cmd_rej *rej = (struct l2cap_cmd_rej *) data;
1959
1960 if (rej->reason != 0x0000)
1961 return 0;
1962
1963 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
1964 cmd->ident == conn->info_ident) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001965 del_timer(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01001966
1967 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01001968 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01001969
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001970 l2cap_conn_start(conn);
1971 }
1972
1973 return 0;
1974}
1975
Linus Torvalds1da177e2005-04-16 15:20:36 -07001976static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
1977{
1978 struct l2cap_chan_list *list = &conn->chan_list;
1979 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
1980 struct l2cap_conn_rsp rsp;
Nathan Holsteind793fe82010-10-15 11:54:02 -04001981 struct sock *parent, *sk = NULL;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02001982 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001983
1984 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02001985 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001986
1987 BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
1988
1989 /* Check if we have socket listening on psm */
1990 parent = l2cap_get_sock_by_psm(BT_LISTEN, psm, conn->src);
1991 if (!parent) {
1992 result = L2CAP_CR_BAD_PSM;
1993 goto sendresp;
1994 }
1995
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001996 bh_lock_sock(parent);
1997
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02001998 /* Check if the ACL is secure enough (if not SDP) */
1999 if (psm != cpu_to_le16(0x0001) &&
2000 !hci_conn_check_link_mode(conn->hcon)) {
Marcel Holtmann2950f212009-02-12 14:02:50 +01002001 conn->disc_reason = 0x05;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002002 result = L2CAP_CR_SEC_BLOCK;
2003 goto response;
2004 }
2005
Linus Torvalds1da177e2005-04-16 15:20:36 -07002006 result = L2CAP_CR_NO_MEM;
2007
2008 /* Check for backlog size */
2009 if (sk_acceptq_is_full(parent)) {
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09002010 BT_DBG("backlog full %d", parent->sk_ack_backlog);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002011 goto response;
2012 }
2013
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09002014 sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002015 if (!sk)
2016 goto response;
2017
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002018 write_lock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002019
2020 /* Check if we already have channel with that dcid */
2021 if (__l2cap_get_chan_by_dcid(list, scid)) {
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002022 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002023 sock_set_flag(sk, SOCK_ZAPPED);
2024 l2cap_sock_kill(sk);
2025 goto response;
2026 }
2027
2028 hci_conn_hold(conn->hcon);
2029
2030 l2cap_sock_init(sk, parent);
2031 bacpy(&bt_sk(sk)->src, conn->src);
2032 bacpy(&bt_sk(sk)->dst, conn->dst);
2033 l2cap_pi(sk)->psm = psm;
2034 l2cap_pi(sk)->dcid = scid;
2035
2036 __l2cap_chan_add(conn, sk, parent);
2037 dcid = l2cap_pi(sk)->scid;
2038
2039 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
2040
Linus Torvalds1da177e2005-04-16 15:20:36 -07002041 l2cap_pi(sk)->ident = cmd->ident;
2042
Marcel Holtmann984947d2009-02-06 23:35:19 +01002043 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002044 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002045 if (bt_sk(sk)->defer_setup) {
2046 sk->sk_state = BT_CONNECT2;
2047 result = L2CAP_CR_PEND;
2048 status = L2CAP_CS_AUTHOR_PEND;
2049 parent->sk_data_ready(parent, 0);
2050 } else {
2051 sk->sk_state = BT_CONFIG;
2052 result = L2CAP_CR_SUCCESS;
2053 status = L2CAP_CS_NO_INFO;
2054 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002055 } else {
2056 sk->sk_state = BT_CONNECT2;
2057 result = L2CAP_CR_PEND;
2058 status = L2CAP_CS_AUTHEN_PEND;
2059 }
2060 } else {
2061 sk->sk_state = BT_CONNECT2;
2062 result = L2CAP_CR_PEND;
2063 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002064 }
2065
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002066 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002067
2068response:
2069 bh_unlock_sock(parent);
2070
2071sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002072 rsp.scid = cpu_to_le16(scid);
2073 rsp.dcid = cpu_to_le16(dcid);
2074 rsp.result = cpu_to_le16(result);
2075 rsp.status = cpu_to_le16(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002076 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002077
2078 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
2079 struct l2cap_info_req info;
2080 info.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
2081
2082 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
2083 conn->info_ident = l2cap_get_ident(conn);
2084
2085 mod_timer(&conn->info_timer, jiffies +
2086 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
2087
2088 l2cap_send_cmd(conn, conn->info_ident,
2089 L2CAP_INFO_REQ, sizeof(info), &info);
2090 }
2091
Nathan Holsteind793fe82010-10-15 11:54:02 -04002092 if (sk && !(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) &&
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03002093 result == L2CAP_CR_SUCCESS) {
2094 u8 buf[128];
2095 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
2096 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
2097 l2cap_build_conf_req(sk, buf), buf);
2098 l2cap_pi(sk)->num_conf_req++;
2099 }
2100
Linus Torvalds1da177e2005-04-16 15:20:36 -07002101 return 0;
2102}
2103
2104static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2105{
2106 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
2107 u16 scid, dcid, result, status;
2108 struct sock *sk;
2109 u8 req[128];
2110
2111 scid = __le16_to_cpu(rsp->scid);
2112 dcid = __le16_to_cpu(rsp->dcid);
2113 result = __le16_to_cpu(rsp->result);
2114 status = __le16_to_cpu(rsp->status);
2115
2116 BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
2117
2118 if (scid) {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002119 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2120 if (!sk)
João Paulo Rechi Vita57d3b222010-06-22 13:56:26 -03002121 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002122 } else {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002123 sk = l2cap_get_chan_by_ident(&conn->chan_list, cmd->ident);
2124 if (!sk)
João Paulo Rechi Vita57d3b222010-06-22 13:56:26 -03002125 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002126 }
2127
2128 switch (result) {
2129 case L2CAP_CR_SUCCESS:
2130 sk->sk_state = BT_CONFIG;
2131 l2cap_pi(sk)->ident = 0;
2132 l2cap_pi(sk)->dcid = dcid;
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002133 l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_CONNECT_PEND;
2134
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03002135 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)
2136 break;
2137
2138 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
2139
Linus Torvalds1da177e2005-04-16 15:20:36 -07002140 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
2141 l2cap_build_conf_req(sk, req), req);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002142 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002143 break;
2144
2145 case L2CAP_CR_PEND:
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002146 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002147 break;
2148
2149 default:
Andrei Emeltchenkoa49184c2010-11-03 12:32:44 +02002150 /* don't delete l2cap channel if sk is owned by user */
2151 if (sock_owned_by_user(sk)) {
2152 sk->sk_state = BT_DISCONN;
2153 l2cap_sock_clear_timer(sk);
2154 l2cap_sock_set_timer(sk, HZ / 5);
2155 break;
2156 }
2157
Linus Torvalds1da177e2005-04-16 15:20:36 -07002158 l2cap_chan_del(sk, ECONNREFUSED);
2159 break;
2160 }
2161
2162 bh_unlock_sock(sk);
2163 return 0;
2164}
2165
Mat Martineau8c462b62010-08-24 15:35:42 -07002166static inline void set_default_fcs(struct l2cap_pinfo *pi)
2167{
2168 /* FCS is enabled only in ERTM or streaming mode, if one or both
2169 * sides request it.
2170 */
2171 if (pi->mode != L2CAP_MODE_ERTM && pi->mode != L2CAP_MODE_STREAMING)
2172 pi->fcs = L2CAP_FCS_NONE;
2173 else if (!(pi->conf_state & L2CAP_CONF_NO_FCS_RECV))
2174 pi->fcs = L2CAP_FCS_CRC16;
2175}
2176
Al Viro88219a02007-07-29 00:17:25 -07002177static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002178{
2179 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
2180 u16 dcid, flags;
2181 u8 rsp[64];
2182 struct sock *sk;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002183 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002184
2185 dcid = __le16_to_cpu(req->dcid);
2186 flags = __le16_to_cpu(req->flags);
2187
2188 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
2189
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002190 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
2191 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002192 return -ENOENT;
2193
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03002194 if (sk->sk_state != BT_CONFIG) {
2195 struct l2cap_cmd_rej rej;
2196
2197 rej.reason = cpu_to_le16(0x0002);
2198 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
2199 sizeof(rej), &rej);
Marcel Holtmann354f60a2006-11-18 22:15:20 +01002200 goto unlock;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03002201 }
Marcel Holtmann354f60a2006-11-18 22:15:20 +01002202
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002203 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07002204 len = cmd_len - sizeof(*req);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002205 if (l2cap_pi(sk)->conf_len + len > sizeof(l2cap_pi(sk)->conf_req)) {
2206 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
2207 l2cap_build_conf_rsp(sk, rsp,
2208 L2CAP_CONF_REJECT, flags), rsp);
2209 goto unlock;
2210 }
2211
2212 /* Store config. */
2213 memcpy(l2cap_pi(sk)->conf_req + l2cap_pi(sk)->conf_len, req->data, len);
2214 l2cap_pi(sk)->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002215
2216 if (flags & 0x0001) {
2217 /* Incomplete config. Send empty response. */
2218 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002219 l2cap_build_conf_rsp(sk, rsp,
2220 L2CAP_CONF_SUCCESS, 0x0001), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002221 goto unlock;
2222 }
2223
2224 /* Complete config. */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002225 len = l2cap_parse_conf_req(sk, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002226 if (len < 0) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03002227 l2cap_send_disconn_req(conn, sk, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002228 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002229 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002230
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002231 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002232 l2cap_pi(sk)->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002233
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002234 /* Reset config buffer. */
2235 l2cap_pi(sk)->conf_len = 0;
2236
Marcel Holtmann876d9482007-10-20 13:35:42 +02002237 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE))
2238 goto unlock;
2239
Linus Torvalds1da177e2005-04-16 15:20:36 -07002240 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) {
Mat Martineau8c462b62010-08-24 15:35:42 -07002241 set_default_fcs(l2cap_pi(sk));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002242
Linus Torvalds1da177e2005-04-16 15:20:36 -07002243 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002244
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002245 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002246 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002247 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002248 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
2249 l2cap_ertm_init(sk);
2250
Linus Torvalds1da177e2005-04-16 15:20:36 -07002251 l2cap_chan_ready(sk);
Marcel Holtmann876d9482007-10-20 13:35:42 +02002252 goto unlock;
2253 }
2254
2255 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002256 u8 buf[64];
Haijun Liuab3e5712010-09-30 16:52:40 +08002257 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002258 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002259 l2cap_build_conf_req(sk, buf), buf);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002260 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002261 }
2262
2263unlock:
2264 bh_unlock_sock(sk);
2265 return 0;
2266}
2267
2268static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2269{
2270 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
2271 u16 scid, flags, result;
2272 struct sock *sk;
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002273 int len = cmd->len - sizeof(*rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002274
2275 scid = __le16_to_cpu(rsp->scid);
2276 flags = __le16_to_cpu(rsp->flags);
2277 result = __le16_to_cpu(rsp->result);
2278
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002279 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x",
2280 scid, flags, result);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002281
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002282 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2283 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002284 return 0;
2285
2286 switch (result) {
2287 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002288 l2cap_conf_rfc_get(sk, rsp->data, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002289 break;
2290
2291 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002292 if (l2cap_pi(sk)->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002293 char req[64];
2294
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02002295 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03002296 l2cap_send_disconn_req(conn, sk, ECONNRESET);
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02002297 goto done;
2298 }
2299
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002300 /* throw out any old stored conf requests */
2301 result = L2CAP_CONF_SUCCESS;
2302 len = l2cap_parse_conf_rsp(sk, rsp->data,
2303 len, req, &result);
2304 if (len < 0) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03002305 l2cap_send_disconn_req(conn, sk, ECONNRESET);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002306 goto done;
2307 }
2308
2309 l2cap_send_cmd(conn, l2cap_get_ident(conn),
2310 L2CAP_CONF_REQ, len, req);
2311 l2cap_pi(sk)->num_conf_req++;
2312 if (result != L2CAP_CONF_SUCCESS)
2313 goto done;
2314 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002315 }
2316
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09002317 default:
Marcel Holtmannb1235d72008-07-14 20:13:54 +02002318 sk->sk_err = ECONNRESET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002319 l2cap_sock_set_timer(sk, HZ * 5);
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03002320 l2cap_send_disconn_req(conn, sk, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002321 goto done;
2322 }
2323
2324 if (flags & 0x01)
2325 goto done;
2326
Linus Torvalds1da177e2005-04-16 15:20:36 -07002327 l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE;
2328
2329 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) {
Mat Martineau8c462b62010-08-24 15:35:42 -07002330 set_default_fcs(l2cap_pi(sk));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002331
Linus Torvalds1da177e2005-04-16 15:20:36 -07002332 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002333 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002334 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002335 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002336 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
2337 l2cap_ertm_init(sk);
2338
Linus Torvalds1da177e2005-04-16 15:20:36 -07002339 l2cap_chan_ready(sk);
2340 }
2341
2342done:
2343 bh_unlock_sock(sk);
2344 return 0;
2345}
2346
2347static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2348{
2349 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
2350 struct l2cap_disconn_rsp rsp;
2351 u16 dcid, scid;
2352 struct sock *sk;
2353
2354 scid = __le16_to_cpu(req->scid);
2355 dcid = __le16_to_cpu(req->dcid);
2356
2357 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
2358
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002359 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
2360 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002361 return 0;
2362
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002363 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
2364 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002365 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
2366
2367 sk->sk_shutdown = SHUTDOWN_MASK;
2368
Andrei Emeltchenkoa49184c2010-11-03 12:32:44 +02002369 /* don't delete l2cap channel if sk is owned by user */
2370 if (sock_owned_by_user(sk)) {
2371 sk->sk_state = BT_DISCONN;
2372 l2cap_sock_clear_timer(sk);
2373 l2cap_sock_set_timer(sk, HZ / 5);
2374 bh_unlock_sock(sk);
2375 return 0;
2376 }
2377
Linus Torvalds1da177e2005-04-16 15:20:36 -07002378 l2cap_chan_del(sk, ECONNRESET);
2379 bh_unlock_sock(sk);
2380
2381 l2cap_sock_kill(sk);
2382 return 0;
2383}
2384
2385static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2386{
2387 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
2388 u16 dcid, scid;
2389 struct sock *sk;
2390
2391 scid = __le16_to_cpu(rsp->scid);
2392 dcid = __le16_to_cpu(rsp->dcid);
2393
2394 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
2395
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002396 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2397 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002398 return 0;
2399
Andrei Emeltchenkoa49184c2010-11-03 12:32:44 +02002400 /* don't delete l2cap channel if sk is owned by user */
2401 if (sock_owned_by_user(sk)) {
2402 sk->sk_state = BT_DISCONN;
2403 l2cap_sock_clear_timer(sk);
2404 l2cap_sock_set_timer(sk, HZ / 5);
2405 bh_unlock_sock(sk);
2406 return 0;
2407 }
2408
Linus Torvalds1da177e2005-04-16 15:20:36 -07002409 l2cap_chan_del(sk, 0);
2410 bh_unlock_sock(sk);
2411
2412 l2cap_sock_kill(sk);
2413 return 0;
2414}
2415
2416static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2417{
2418 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002419 u16 type;
2420
2421 type = __le16_to_cpu(req->type);
2422
2423 BT_DBG("type 0x%4.4x", type);
2424
Marcel Holtmannf0709e02007-10-20 13:38:51 +02002425 if (type == L2CAP_IT_FEAT_MASK) {
2426 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07002427 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02002428 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
2429 rsp->type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
2430 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03002431 if (!disable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002432 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
2433 | L2CAP_FEAT_FCS;
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03002434 put_unaligned_le32(feat_mask, rsp->data);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02002435 l2cap_send_cmd(conn, cmd->ident,
2436 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002437 } else if (type == L2CAP_IT_FIXED_CHAN) {
2438 u8 buf[12];
2439 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
2440 rsp->type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
2441 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
2442 memcpy(buf + 4, l2cap_fixed_chan, 8);
2443 l2cap_send_cmd(conn, cmd->ident,
2444 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02002445 } else {
2446 struct l2cap_info_rsp rsp;
2447 rsp.type = cpu_to_le16(type);
2448 rsp.result = cpu_to_le16(L2CAP_IR_NOTSUPP);
2449 l2cap_send_cmd(conn, cmd->ident,
2450 L2CAP_INFO_RSP, sizeof(rsp), &rsp);
2451 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002452
2453 return 0;
2454}
2455
2456static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2457{
2458 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
2459 u16 type, result;
2460
2461 type = __le16_to_cpu(rsp->type);
2462 result = __le16_to_cpu(rsp->result);
2463
2464 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
2465
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002466 del_timer(&conn->info_timer);
2467
Ville Tervoadb08ed2010-08-04 09:43:33 +03002468 if (result != L2CAP_IR_SUCCESS) {
2469 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
2470 conn->info_ident = 0;
2471
2472 l2cap_conn_start(conn);
2473
2474 return 0;
2475 }
2476
Marcel Holtmann984947d2009-02-06 23:35:19 +01002477 if (type == L2CAP_IT_FEAT_MASK) {
Harvey Harrison83985312008-05-02 16:25:46 -07002478 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002479
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07002480 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002481 struct l2cap_info_req req;
2482 req.type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
2483
2484 conn->info_ident = l2cap_get_ident(conn);
2485
2486 l2cap_send_cmd(conn, conn->info_ident,
2487 L2CAP_INFO_REQ, sizeof(req), &req);
2488 } else {
2489 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
2490 conn->info_ident = 0;
2491
2492 l2cap_conn_start(conn);
2493 }
2494 } else if (type == L2CAP_IT_FIXED_CHAN) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01002495 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002496 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01002497
2498 l2cap_conn_start(conn);
2499 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002500
Linus Torvalds1da177e2005-04-16 15:20:36 -07002501 return 0;
2502}
2503
Claudio Takahaside731152011-02-11 19:28:55 -02002504static int inline l2cap_check_conn_param(u16 min, u16 max, u16 latency,
2505 u16 to_multiplier)
2506{
2507 u16 max_latency;
2508
2509 if (min > max || min < 6 || max > 3200)
2510 return -EINVAL;
2511
2512 if (to_multiplier < 10 || to_multiplier > 3200)
2513 return -EINVAL;
2514
2515 if (max >= to_multiplier * 8)
2516 return -EINVAL;
2517
2518 max_latency = (to_multiplier * 8 / max) - 1;
2519 if (latency > 499 || latency > max_latency)
2520 return -EINVAL;
2521
2522 return 0;
2523}
2524
2525static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
2526 struct l2cap_cmd_hdr *cmd, u8 *data)
2527{
2528 struct hci_conn *hcon = conn->hcon;
2529 struct l2cap_conn_param_update_req *req;
2530 struct l2cap_conn_param_update_rsp rsp;
2531 u16 min, max, latency, to_multiplier, cmd_len;
2532
2533 if (!(hcon->link_mode & HCI_LM_MASTER))
2534 return -EINVAL;
2535
2536 cmd_len = __le16_to_cpu(cmd->len);
2537 if (cmd_len != sizeof(struct l2cap_conn_param_update_req))
2538 return -EPROTO;
2539
2540 req = (struct l2cap_conn_param_update_req *) data;
2541 min = __le16_to_cpu(req->min);
2542 max = __le16_to_cpu(req->max);
2543 latency = __le16_to_cpu(req->latency);
2544 to_multiplier = __le16_to_cpu(req->to_multiplier);
2545
2546 BT_DBG("min 0x%4.4x max 0x%4.4x latency: 0x%4.4x Timeout: 0x%4.4x",
2547 min, max, latency, to_multiplier);
2548
2549 memset(&rsp, 0, sizeof(rsp));
2550 if (l2cap_check_conn_param(min, max, latency, to_multiplier))
2551 rsp.result = cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
2552 else
2553 rsp.result = cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED);
2554
2555 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP,
2556 sizeof(rsp), &rsp);
2557
2558 return 0;
2559}
2560
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002561static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
2562 struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
2563{
2564 int err = 0;
2565
2566 switch (cmd->code) {
2567 case L2CAP_COMMAND_REJ:
2568 l2cap_command_rej(conn, cmd, data);
2569 break;
2570
2571 case L2CAP_CONN_REQ:
2572 err = l2cap_connect_req(conn, cmd, data);
2573 break;
2574
2575 case L2CAP_CONN_RSP:
2576 err = l2cap_connect_rsp(conn, cmd, data);
2577 break;
2578
2579 case L2CAP_CONF_REQ:
2580 err = l2cap_config_req(conn, cmd, cmd_len, data);
2581 break;
2582
2583 case L2CAP_CONF_RSP:
2584 err = l2cap_config_rsp(conn, cmd, data);
2585 break;
2586
2587 case L2CAP_DISCONN_REQ:
2588 err = l2cap_disconnect_req(conn, cmd, data);
2589 break;
2590
2591 case L2CAP_DISCONN_RSP:
2592 err = l2cap_disconnect_rsp(conn, cmd, data);
2593 break;
2594
2595 case L2CAP_ECHO_REQ:
2596 l2cap_send_cmd(conn, cmd->ident, L2CAP_ECHO_RSP, cmd_len, data);
2597 break;
2598
2599 case L2CAP_ECHO_RSP:
2600 break;
2601
2602 case L2CAP_INFO_REQ:
2603 err = l2cap_information_req(conn, cmd, data);
2604 break;
2605
2606 case L2CAP_INFO_RSP:
2607 err = l2cap_information_rsp(conn, cmd, data);
2608 break;
2609
2610 default:
2611 BT_ERR("Unknown BR/EDR signaling command 0x%2.2x", cmd->code);
2612 err = -EINVAL;
2613 break;
2614 }
2615
2616 return err;
2617}
2618
2619static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn,
2620 struct l2cap_cmd_hdr *cmd, u8 *data)
2621{
2622 switch (cmd->code) {
2623 case L2CAP_COMMAND_REJ:
2624 return 0;
2625
2626 case L2CAP_CONN_PARAM_UPDATE_REQ:
Claudio Takahaside731152011-02-11 19:28:55 -02002627 return l2cap_conn_param_update_req(conn, cmd, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002628
2629 case L2CAP_CONN_PARAM_UPDATE_RSP:
2630 return 0;
2631
2632 default:
2633 BT_ERR("Unknown LE signaling command 0x%2.2x", cmd->code);
2634 return -EINVAL;
2635 }
2636}
2637
2638static inline void l2cap_sig_channel(struct l2cap_conn *conn,
2639 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002640{
2641 u8 *data = skb->data;
2642 int len = skb->len;
2643 struct l2cap_cmd_hdr cmd;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002644 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002645
2646 l2cap_raw_recv(conn, skb);
2647
2648 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07002649 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002650 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
2651 data += L2CAP_CMD_HDR_SIZE;
2652 len -= L2CAP_CMD_HDR_SIZE;
2653
Al Viro88219a02007-07-29 00:17:25 -07002654 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002655
Al Viro88219a02007-07-29 00:17:25 -07002656 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len, cmd.ident);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002657
Al Viro88219a02007-07-29 00:17:25 -07002658 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002659 BT_DBG("corrupted command");
2660 break;
2661 }
2662
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002663 if (conn->hcon->type == LE_LINK)
2664 err = l2cap_le_sig_cmd(conn, &cmd, data);
2665 else
2666 err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002667
2668 if (err) {
2669 struct l2cap_cmd_rej rej;
2670 BT_DBG("error %d", err);
2671
2672 /* FIXME: Map err to a valid reason */
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002673 rej.reason = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002674 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
2675 }
2676
Al Viro88219a02007-07-29 00:17:25 -07002677 data += cmd_len;
2678 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002679 }
2680
2681 kfree_skb(skb);
2682}
2683
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002684static int l2cap_check_fcs(struct l2cap_pinfo *pi, struct sk_buff *skb)
2685{
2686 u16 our_fcs, rcv_fcs;
2687 int hdr_size = L2CAP_HDR_SIZE + 2;
2688
2689 if (pi->fcs == L2CAP_FCS_CRC16) {
2690 skb_trim(skb, skb->len - 2);
2691 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
2692 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
2693
2694 if (our_fcs != rcv_fcs)
João Paulo Rechi Vita7a560e52010-06-22 13:56:27 -03002695 return -EBADMSG;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002696 }
2697 return 0;
2698}
2699
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03002700static inline void l2cap_send_i_or_rr_or_rnr(struct sock *sk)
2701{
2702 struct l2cap_pinfo *pi = l2cap_pi(sk);
2703 u16 control = 0;
2704
2705 pi->frames_sent = 0;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03002706
2707 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
2708
2709 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
Gustavo F. Padovan64988862010-05-10 14:54:14 -03002710 control |= L2CAP_SUPER_RCV_NOT_READY;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03002711 l2cap_send_sframe(pi, control);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002712 pi->conn_state |= L2CAP_CONN_RNR_SENT;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03002713 }
2714
Gustavo F. Padovan4ea727e2010-06-03 16:34:20 -03002715 if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY)
2716 l2cap_retransmit_frames(sk);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03002717
2718 l2cap_ertm_send(sk);
2719
2720 if (!(pi->conn_state & L2CAP_CONN_LOCAL_BUSY) &&
2721 pi->frames_sent == 0) {
2722 control |= L2CAP_SUPER_RCV_READY;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03002723 l2cap_send_sframe(pi, control);
2724 }
2725}
2726
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03002727static int l2cap_add_to_srej_queue(struct sock *sk, struct sk_buff *skb, u8 tx_seq, u8 sar)
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03002728{
2729 struct sk_buff *next_skb;
João Paulo Rechi Vitabfbacc112010-05-31 18:35:44 -03002730 struct l2cap_pinfo *pi = l2cap_pi(sk);
2731 int tx_seq_offset, next_tx_seq_offset;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03002732
2733 bt_cb(skb)->tx_seq = tx_seq;
2734 bt_cb(skb)->sar = sar;
2735
2736 next_skb = skb_peek(SREJ_QUEUE(sk));
2737 if (!next_skb) {
2738 __skb_queue_tail(SREJ_QUEUE(sk), skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03002739 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03002740 }
2741
João Paulo Rechi Vitabfbacc112010-05-31 18:35:44 -03002742 tx_seq_offset = (tx_seq - pi->buffer_seq) % 64;
2743 if (tx_seq_offset < 0)
2744 tx_seq_offset += 64;
2745
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03002746 do {
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03002747 if (bt_cb(next_skb)->tx_seq == tx_seq)
2748 return -EINVAL;
2749
João Paulo Rechi Vitabfbacc112010-05-31 18:35:44 -03002750 next_tx_seq_offset = (bt_cb(next_skb)->tx_seq -
2751 pi->buffer_seq) % 64;
2752 if (next_tx_seq_offset < 0)
2753 next_tx_seq_offset += 64;
2754
2755 if (next_tx_seq_offset > tx_seq_offset) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03002756 __skb_queue_before(SREJ_QUEUE(sk), next_skb, skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03002757 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03002758 }
2759
2760 if (skb_queue_is_last(SREJ_QUEUE(sk), next_skb))
2761 break;
2762
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03002763 } while ((next_skb = skb_queue_next(SREJ_QUEUE(sk), next_skb)));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03002764
2765 __skb_queue_tail(SREJ_QUEUE(sk), skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03002766
2767 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03002768}
2769
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002770static int l2cap_ertm_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
2771{
2772 struct l2cap_pinfo *pi = l2cap_pi(sk);
2773 struct sk_buff *_skb;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002774 int err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002775
2776 switch (control & L2CAP_CTRL_SAR) {
2777 case L2CAP_SDU_UNSEGMENTED:
2778 if (pi->conn_state & L2CAP_CONN_SAR_SDU)
2779 goto drop;
2780
2781 err = sock_queue_rcv_skb(sk, skb);
2782 if (!err)
2783 return err;
2784
2785 break;
2786
2787 case L2CAP_SDU_START:
2788 if (pi->conn_state & L2CAP_CONN_SAR_SDU)
2789 goto drop;
2790
2791 pi->sdu_len = get_unaligned_le16(skb->data);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002792
2793 if (pi->sdu_len > pi->imtu)
2794 goto disconnect;
2795
2796 pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002797 if (!pi->sdu)
2798 return -ENOMEM;
2799
2800 /* pull sdu_len bytes only after alloc, because of Local Busy
2801 * condition we have to be sure that this will be executed
2802 * only once, i.e., when alloc does not fail */
2803 skb_pull(skb, 2);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002804
2805 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
2806
2807 pi->conn_state |= L2CAP_CONN_SAR_SDU;
2808 pi->partial_sdu_len = skb->len;
2809 break;
2810
2811 case L2CAP_SDU_CONTINUE:
2812 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
2813 goto disconnect;
2814
2815 if (!pi->sdu)
2816 goto disconnect;
2817
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002818 pi->partial_sdu_len += skb->len;
2819 if (pi->partial_sdu_len > pi->sdu_len)
2820 goto drop;
2821
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03002822 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
2823
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002824 break;
2825
2826 case L2CAP_SDU_END:
2827 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
2828 goto disconnect;
2829
2830 if (!pi->sdu)
2831 goto disconnect;
2832
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002833 if (!(pi->conn_state & L2CAP_CONN_SAR_RETRY)) {
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002834 pi->partial_sdu_len += skb->len;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002835
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002836 if (pi->partial_sdu_len > pi->imtu)
2837 goto drop;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002838
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002839 if (pi->partial_sdu_len != pi->sdu_len)
2840 goto drop;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03002841
2842 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002843 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002844
2845 _skb = skb_clone(pi->sdu, GFP_ATOMIC);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002846 if (!_skb) {
2847 pi->conn_state |= L2CAP_CONN_SAR_RETRY;
2848 return -ENOMEM;
2849 }
2850
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002851 err = sock_queue_rcv_skb(sk, _skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002852 if (err < 0) {
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002853 kfree_skb(_skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002854 pi->conn_state |= L2CAP_CONN_SAR_RETRY;
2855 return err;
2856 }
2857
2858 pi->conn_state &= ~L2CAP_CONN_SAR_RETRY;
2859 pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002860
2861 kfree_skb(pi->sdu);
2862 break;
2863 }
2864
2865 kfree_skb(skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002866 return 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002867
2868drop:
2869 kfree_skb(pi->sdu);
2870 pi->sdu = NULL;
2871
2872disconnect:
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03002873 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002874 kfree_skb(skb);
2875 return 0;
2876}
2877
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03002878static int l2cap_try_push_rx_skb(struct sock *sk)
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002879{
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03002880 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002881 struct sk_buff *skb;
2882 u16 control;
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03002883 int err;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002884
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03002885 while ((skb = skb_dequeue(BUSY_QUEUE(sk)))) {
2886 control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
2887 err = l2cap_ertm_reassembly_sdu(sk, skb, control);
2888 if (err < 0) {
2889 skb_queue_head(BUSY_QUEUE(sk), skb);
2890 return -EBUSY;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002891 }
2892
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03002893 pi->buffer_seq = (pi->buffer_seq + 1) % 64;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002894 }
2895
2896 if (!(pi->conn_state & L2CAP_CONN_RNR_SENT))
2897 goto done;
2898
2899 control = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
2900 control |= L2CAP_SUPER_RCV_READY | L2CAP_CTRL_POLL;
2901 l2cap_send_sframe(pi, control);
2902 l2cap_pi(sk)->retry_count = 1;
2903
2904 del_timer(&pi->retrans_timer);
2905 __mod_monitor_timer();
2906
2907 l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
2908
2909done:
2910 pi->conn_state &= ~L2CAP_CONN_LOCAL_BUSY;
2911 pi->conn_state &= ~L2CAP_CONN_RNR_SENT;
2912
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03002913 BT_DBG("sk %p, Exit local busy", sk);
2914
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03002915 return 0;
2916}
2917
2918static void l2cap_busy_work(struct work_struct *work)
2919{
2920 DECLARE_WAITQUEUE(wait, current);
2921 struct l2cap_pinfo *pi =
2922 container_of(work, struct l2cap_pinfo, busy_work);
2923 struct sock *sk = (struct sock *)pi;
2924 int n_tries = 0, timeo = HZ/5, err;
2925 struct sk_buff *skb;
2926
2927 lock_sock(sk);
2928
2929 add_wait_queue(sk_sleep(sk), &wait);
2930 while ((skb = skb_peek(BUSY_QUEUE(sk)))) {
2931 set_current_state(TASK_INTERRUPTIBLE);
2932
2933 if (n_tries++ > L2CAP_LOCAL_BUSY_TRIES) {
2934 err = -EBUSY;
2935 l2cap_send_disconn_req(pi->conn, sk, EBUSY);
2936 break;
2937 }
2938
2939 if (!timeo)
2940 timeo = HZ/5;
2941
2942 if (signal_pending(current)) {
2943 err = sock_intr_errno(timeo);
2944 break;
2945 }
2946
2947 release_sock(sk);
2948 timeo = schedule_timeout(timeo);
2949 lock_sock(sk);
2950
2951 err = sock_error(sk);
2952 if (err)
2953 break;
2954
2955 if (l2cap_try_push_rx_skb(sk) == 0)
2956 break;
2957 }
2958
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002959 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02002960 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002961
2962 release_sock(sk);
2963}
2964
2965static int l2cap_push_rx_skb(struct sock *sk, struct sk_buff *skb, u16 control)
2966{
2967 struct l2cap_pinfo *pi = l2cap_pi(sk);
2968 int sctrl, err;
2969
2970 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
2971 bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT;
2972 __skb_queue_tail(BUSY_QUEUE(sk), skb);
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03002973 return l2cap_try_push_rx_skb(sk);
2974
2975
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002976 }
2977
2978 err = l2cap_ertm_reassembly_sdu(sk, skb, control);
2979 if (err >= 0) {
2980 pi->buffer_seq = (pi->buffer_seq + 1) % 64;
2981 return err;
2982 }
2983
2984 /* Busy Condition */
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03002985 BT_DBG("sk %p, Enter local busy", sk);
2986
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002987 pi->conn_state |= L2CAP_CONN_LOCAL_BUSY;
2988 bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT;
2989 __skb_queue_tail(BUSY_QUEUE(sk), skb);
2990
2991 sctrl = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
2992 sctrl |= L2CAP_SUPER_RCV_NOT_READY;
2993 l2cap_send_sframe(pi, sctrl);
2994
2995 pi->conn_state |= L2CAP_CONN_RNR_SENT;
2996
Gustavo F. Padovan7fe9b292010-05-12 18:32:04 -03002997 del_timer(&pi->ack_timer);
2998
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002999 queue_work(_busy_wq, &pi->busy_work);
3000
3001 return err;
3002}
3003
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003004static int l2cap_streaming_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003005{
3006 struct l2cap_pinfo *pi = l2cap_pi(sk);
3007 struct sk_buff *_skb;
3008 int err = -EINVAL;
3009
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003010 /*
3011 * TODO: We have to notify the userland if some data is lost with the
3012 * Streaming Mode.
3013 */
3014
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003015 switch (control & L2CAP_CTRL_SAR) {
3016 case L2CAP_SDU_UNSEGMENTED:
3017 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3018 kfree_skb(pi->sdu);
3019 break;
3020 }
3021
3022 err = sock_queue_rcv_skb(sk, skb);
3023 if (!err)
3024 return 0;
3025
3026 break;
3027
3028 case L2CAP_SDU_START:
3029 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3030 kfree_skb(pi->sdu);
3031 break;
3032 }
3033
3034 pi->sdu_len = get_unaligned_le16(skb->data);
3035 skb_pull(skb, 2);
3036
Gustavo F. Padovan052897c2010-05-01 16:15:40 -03003037 if (pi->sdu_len > pi->imtu) {
3038 err = -EMSGSIZE;
3039 break;
3040 }
3041
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003042 pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
3043 if (!pi->sdu) {
3044 err = -ENOMEM;
3045 break;
3046 }
3047
3048 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3049
3050 pi->conn_state |= L2CAP_CONN_SAR_SDU;
3051 pi->partial_sdu_len = skb->len;
3052 err = 0;
3053 break;
3054
3055 case L2CAP_SDU_CONTINUE:
3056 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3057 break;
3058
3059 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3060
3061 pi->partial_sdu_len += skb->len;
3062 if (pi->partial_sdu_len > pi->sdu_len)
3063 kfree_skb(pi->sdu);
3064 else
3065 err = 0;
3066
3067 break;
3068
3069 case L2CAP_SDU_END:
3070 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3071 break;
3072
3073 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3074
3075 pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
3076 pi->partial_sdu_len += skb->len;
3077
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003078 if (pi->partial_sdu_len > pi->imtu)
3079 goto drop;
3080
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003081 if (pi->partial_sdu_len == pi->sdu_len) {
3082 _skb = skb_clone(pi->sdu, GFP_ATOMIC);
3083 err = sock_queue_rcv_skb(sk, _skb);
3084 if (err < 0)
3085 kfree_skb(_skb);
3086 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003087 err = 0;
3088
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003089drop:
3090 kfree_skb(pi->sdu);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003091 break;
3092 }
3093
3094 kfree_skb(skb);
3095 return err;
3096}
3097
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003098static void l2cap_check_srej_gap(struct sock *sk, u8 tx_seq)
3099{
3100 struct sk_buff *skb;
Gustavo F. Padovanafefdbc2010-05-01 16:15:43 -03003101 u16 control;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003102
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003103 while ((skb = skb_peek(SREJ_QUEUE(sk)))) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003104 if (bt_cb(skb)->tx_seq != tx_seq)
3105 break;
3106
3107 skb = skb_dequeue(SREJ_QUEUE(sk));
Gustavo F. Padovanafefdbc2010-05-01 16:15:43 -03003108 control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003109 l2cap_ertm_reassembly_sdu(sk, skb, control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003110 l2cap_pi(sk)->buffer_seq_srej =
3111 (l2cap_pi(sk)->buffer_seq_srej + 1) % 64;
Gustavo F. Padovan8ff50ec2010-05-10 19:34:11 -03003112 tx_seq = (tx_seq + 1) % 64;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003113 }
3114}
3115
3116static void l2cap_resend_srejframe(struct sock *sk, u8 tx_seq)
3117{
3118 struct l2cap_pinfo *pi = l2cap_pi(sk);
3119 struct srej_list *l, *tmp;
3120 u16 control;
3121
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003122 list_for_each_entry_safe(l, tmp, SREJ_LIST(sk), list) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003123 if (l->tx_seq == tx_seq) {
3124 list_del(&l->list);
3125 kfree(l);
3126 return;
3127 }
3128 control = L2CAP_SUPER_SELECT_REJECT;
3129 control |= l->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3130 l2cap_send_sframe(pi, control);
3131 list_del(&l->list);
3132 list_add_tail(&l->list, SREJ_LIST(sk));
3133 }
3134}
3135
3136static void l2cap_send_srejframe(struct sock *sk, u8 tx_seq)
3137{
3138 struct l2cap_pinfo *pi = l2cap_pi(sk);
3139 struct srej_list *new;
3140 u16 control;
3141
3142 while (tx_seq != pi->expected_tx_seq) {
3143 control = L2CAP_SUPER_SELECT_REJECT;
3144 control |= pi->expected_tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3145 l2cap_send_sframe(pi, control);
3146
3147 new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC);
Gustavo F. Padovan8ff50ec2010-05-10 19:34:11 -03003148 new->tx_seq = pi->expected_tx_seq;
3149 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003150 list_add_tail(&new->list, SREJ_LIST(sk));
3151 }
Gustavo F. Padovan8ff50ec2010-05-10 19:34:11 -03003152 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003153}
3154
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003155static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
3156{
3157 struct l2cap_pinfo *pi = l2cap_pi(sk);
3158 u8 tx_seq = __get_txseq(rx_control);
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003159 u8 req_seq = __get_reqseq(rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003160 u8 sar = rx_control >> L2CAP_CTRL_SAR_SHIFT;
Gustavo F. Padovanf6337c72010-05-10 18:32:04 -03003161 int tx_seq_offset, expected_tx_seq_offset;
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03003162 int num_to_ack = (pi->tx_win/6) + 1;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003163 int err = 0;
3164
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003165 BT_DBG("sk %p len %d tx_seq %d rx_control 0x%4.4x", sk, skb->len, tx_seq,
3166 rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003167
Gustavo F. Padovan9b16dc62010-05-05 20:05:57 -03003168 if (L2CAP_CTRL_FINAL & rx_control &&
3169 l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) {
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003170 del_timer(&pi->monitor_timer);
3171 if (pi->unacked_frames > 0)
3172 __mod_retrans_timer();
3173 pi->conn_state &= ~L2CAP_CONN_WAIT_F;
3174 }
3175
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003176 pi->expected_ack_seq = req_seq;
3177 l2cap_drop_acked_frames(sk);
3178
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003179 if (tx_seq == pi->expected_tx_seq)
3180 goto expected;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003181
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003182 tx_seq_offset = (tx_seq - pi->buffer_seq) % 64;
3183 if (tx_seq_offset < 0)
3184 tx_seq_offset += 64;
3185
3186 /* invalid tx_seq */
3187 if (tx_seq_offset >= pi->tx_win) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03003188 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003189 goto drop;
3190 }
3191
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003192 if (pi->conn_state == L2CAP_CONN_LOCAL_BUSY)
3193 goto drop;
3194
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003195 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3196 struct srej_list *first;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003197
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003198 first = list_first_entry(SREJ_LIST(sk),
3199 struct srej_list, list);
3200 if (tx_seq == first->tx_seq) {
3201 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3202 l2cap_check_srej_gap(sk, tx_seq);
3203
3204 list_del(&first->list);
3205 kfree(first);
3206
3207 if (list_empty(SREJ_LIST(sk))) {
3208 pi->buffer_seq = pi->buffer_seq_srej;
3209 pi->conn_state &= ~L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan855666c2010-05-01 16:15:40 -03003210 l2cap_send_ack(pi);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003211 BT_DBG("sk %p, Exit SREJ_SENT", sk);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003212 }
3213 } else {
3214 struct srej_list *l;
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003215
3216 /* duplicated tx_seq */
3217 if (l2cap_add_to_srej_queue(sk, skb, tx_seq, sar) < 0)
3218 goto drop;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003219
3220 list_for_each_entry(l, SREJ_LIST(sk), list) {
3221 if (l->tx_seq == tx_seq) {
3222 l2cap_resend_srejframe(sk, tx_seq);
3223 return 0;
3224 }
3225 }
3226 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003227 }
3228 } else {
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003229 expected_tx_seq_offset =
3230 (pi->expected_tx_seq - pi->buffer_seq) % 64;
3231 if (expected_tx_seq_offset < 0)
3232 expected_tx_seq_offset += 64;
3233
3234 /* duplicated tx_seq */
3235 if (tx_seq_offset < expected_tx_seq_offset)
3236 goto drop;
3237
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003238 pi->conn_state |= L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003239
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003240 BT_DBG("sk %p, Enter SREJ", sk);
3241
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003242 INIT_LIST_HEAD(SREJ_LIST(sk));
3243 pi->buffer_seq_srej = pi->buffer_seq;
3244
3245 __skb_queue_head_init(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003246 __skb_queue_head_init(BUSY_QUEUE(sk));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003247 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3248
Gustavo F. Padovanef54fd92009-08-20 22:26:04 -03003249 pi->conn_state |= L2CAP_CONN_SEND_PBIT;
3250
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003251 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan7fe9b292010-05-12 18:32:04 -03003252
3253 del_timer(&pi->ack_timer);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003254 }
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003255 return 0;
3256
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003257expected:
3258 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
3259
3260 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
Gustavo F. Padovan3b1a9f32010-05-01 16:15:42 -03003261 bt_cb(skb)->tx_seq = tx_seq;
3262 bt_cb(skb)->sar = sar;
3263 __skb_queue_tail(SREJ_QUEUE(sk), skb);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003264 return 0;
3265 }
3266
Gustavo F. Padovan2ece3682010-06-16 17:21:44 -03003267 err = l2cap_push_rx_skb(sk, skb, rx_control);
3268 if (err < 0)
3269 return 0;
3270
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03003271 if (rx_control & L2CAP_CTRL_FINAL) {
3272 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3273 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003274 else
3275 l2cap_retransmit_frames(sk);
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03003276 }
3277
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003278 __mod_ack_timer();
3279
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03003280 pi->num_acked = (pi->num_acked + 1) % num_to_ack;
3281 if (pi->num_acked == num_to_ack - 1)
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03003282 l2cap_send_ack(pi);
3283
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003284 return 0;
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003285
3286drop:
3287 kfree_skb(skb);
3288 return 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003289}
3290
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003291static inline void l2cap_data_channel_rrframe(struct sock *sk, u16 rx_control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003292{
3293 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan6e3a5982010-05-01 16:15:38 -03003294
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003295 BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, __get_reqseq(rx_control),
3296 rx_control);
3297
Gustavo F. Padovan6e3a5982010-05-01 16:15:38 -03003298 pi->expected_ack_seq = __get_reqseq(rx_control);
3299 l2cap_drop_acked_frames(sk);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003300
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003301 if (rx_control & L2CAP_CTRL_POLL) {
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03003302 pi->conn_state |= L2CAP_CONN_SEND_FBIT;
Gustavo F. Padovan05fbd892010-05-01 16:15:39 -03003303 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3304 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
3305 (pi->unacked_frames > 0))
3306 __mod_retrans_timer();
3307
3308 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3309 l2cap_send_srejtail(sk);
3310 } else {
3311 l2cap_send_i_or_rr_or_rnr(sk);
Gustavo F. Padovan05fbd892010-05-01 16:15:39 -03003312 }
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003313
3314 } else if (rx_control & L2CAP_CTRL_FINAL) {
3315 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003316
3317 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3318 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003319 else
3320 l2cap_retransmit_frames(sk);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003321
3322 } else {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003323 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
3324 (pi->unacked_frames > 0))
3325 __mod_retrans_timer();
3326
3327 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
Andrei Emeltchenko894718a2010-12-01 16:58:24 +02003328 if (pi->conn_state & L2CAP_CONN_SREJ_SENT)
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003329 l2cap_send_ack(pi);
Andrei Emeltchenko894718a2010-12-01 16:58:24 +02003330 else
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003331 l2cap_ertm_send(sk);
3332 }
3333}
3334
3335static inline void l2cap_data_channel_rejframe(struct sock *sk, u16 rx_control)
3336{
3337 struct l2cap_pinfo *pi = l2cap_pi(sk);
3338 u8 tx_seq = __get_reqseq(rx_control);
3339
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003340 BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, tx_seq, rx_control);
3341
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003342 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3343
Gustavo F. Padovan8abb52e2010-05-01 16:15:38 -03003344 pi->expected_ack_seq = tx_seq;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003345 l2cap_drop_acked_frames(sk);
3346
3347 if (rx_control & L2CAP_CTRL_FINAL) {
3348 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3349 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003350 else
3351 l2cap_retransmit_frames(sk);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003352 } else {
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003353 l2cap_retransmit_frames(sk);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003354
Gustavo F. Padovan0301ef02010-05-05 20:56:43 -03003355 if (pi->conn_state & L2CAP_CONN_WAIT_F)
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003356 pi->conn_state |= L2CAP_CONN_REJ_ACT;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003357 }
3358}
3359static inline void l2cap_data_channel_srejframe(struct sock *sk, u16 rx_control)
3360{
3361 struct l2cap_pinfo *pi = l2cap_pi(sk);
3362 u8 tx_seq = __get_reqseq(rx_control);
3363
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003364 BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, tx_seq, rx_control);
3365
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003366 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3367
3368 if (rx_control & L2CAP_CTRL_POLL) {
3369 pi->expected_ack_seq = tx_seq;
3370 l2cap_drop_acked_frames(sk);
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03003371
3372 pi->conn_state |= L2CAP_CONN_SEND_FBIT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003373 l2cap_retransmit_one_frame(sk, tx_seq);
3374
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003375 l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003376
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003377 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
3378 pi->srej_save_reqseq = tx_seq;
3379 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
3380 }
3381 } else if (rx_control & L2CAP_CTRL_FINAL) {
3382 if ((pi->conn_state & L2CAP_CONN_SREJ_ACT) &&
3383 pi->srej_save_reqseq == tx_seq)
3384 pi->conn_state &= ~L2CAP_CONN_SREJ_ACT;
3385 else
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003386 l2cap_retransmit_one_frame(sk, tx_seq);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003387 } else {
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003388 l2cap_retransmit_one_frame(sk, tx_seq);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003389 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
3390 pi->srej_save_reqseq = tx_seq;
3391 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
3392 }
3393 }
3394}
3395
3396static inline void l2cap_data_channel_rnrframe(struct sock *sk, u16 rx_control)
3397{
3398 struct l2cap_pinfo *pi = l2cap_pi(sk);
3399 u8 tx_seq = __get_reqseq(rx_control);
3400
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003401 BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, tx_seq, rx_control);
3402
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003403 pi->conn_state |= L2CAP_CONN_REMOTE_BUSY;
3404 pi->expected_ack_seq = tx_seq;
3405 l2cap_drop_acked_frames(sk);
3406
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03003407 if (rx_control & L2CAP_CTRL_POLL)
3408 pi->conn_state |= L2CAP_CONN_SEND_FBIT;
3409
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03003410 if (!(pi->conn_state & L2CAP_CONN_SREJ_SENT)) {
3411 del_timer(&pi->retrans_timer);
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -03003412 if (rx_control & L2CAP_CTRL_POLL)
3413 l2cap_send_rr_or_rnr(pi, L2CAP_CTRL_FINAL);
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03003414 return;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003415 }
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03003416
3417 if (rx_control & L2CAP_CTRL_POLL)
3418 l2cap_send_srejtail(sk);
3419 else
3420 l2cap_send_sframe(pi, L2CAP_SUPER_RCV_READY);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003421}
3422
3423static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
3424{
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003425 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
3426
Gustavo F. Padovan9b16dc62010-05-05 20:05:57 -03003427 if (L2CAP_CTRL_FINAL & rx_control &&
3428 l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003429 del_timer(&l2cap_pi(sk)->monitor_timer);
3430 if (l2cap_pi(sk)->unacked_frames > 0)
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003431 __mod_retrans_timer();
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003432 l2cap_pi(sk)->conn_state &= ~L2CAP_CONN_WAIT_F;
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003433 }
3434
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003435 switch (rx_control & L2CAP_CTRL_SUPERVISE) {
3436 case L2CAP_SUPER_RCV_READY:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003437 l2cap_data_channel_rrframe(sk, rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003438 break;
3439
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003440 case L2CAP_SUPER_REJECT:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003441 l2cap_data_channel_rejframe(sk, rx_control);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003442 break;
3443
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003444 case L2CAP_SUPER_SELECT_REJECT:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003445 l2cap_data_channel_srejframe(sk, rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003446 break;
3447
3448 case L2CAP_SUPER_RCV_NOT_READY:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003449 l2cap_data_channel_rnrframe(sk, rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003450 break;
3451 }
3452
Gustavo F. Padovanfaaebd12010-05-01 16:15:35 -03003453 kfree_skb(skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003454 return 0;
3455}
3456
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03003457static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb)
3458{
3459 struct l2cap_pinfo *pi = l2cap_pi(sk);
3460 u16 control;
3461 u8 req_seq;
3462 int len, next_tx_seq_offset, req_seq_offset;
3463
3464 control = get_unaligned_le16(skb->data);
3465 skb_pull(skb, 2);
3466 len = skb->len;
3467
3468 /*
3469 * We can just drop the corrupted I-frame here.
3470 * Receiver will miss it and start proper recovery
3471 * procedures and ask retransmission.
3472 */
3473 if (l2cap_check_fcs(pi, skb))
3474 goto drop;
3475
3476 if (__is_sar_start(control) && __is_iframe(control))
3477 len -= 2;
3478
3479 if (pi->fcs == L2CAP_FCS_CRC16)
3480 len -= 2;
3481
3482 if (len > pi->mps) {
3483 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
3484 goto drop;
3485 }
3486
3487 req_seq = __get_reqseq(control);
3488 req_seq_offset = (req_seq - pi->expected_ack_seq) % 64;
3489 if (req_seq_offset < 0)
3490 req_seq_offset += 64;
3491
3492 next_tx_seq_offset =
3493 (pi->next_tx_seq - pi->expected_ack_seq) % 64;
3494 if (next_tx_seq_offset < 0)
3495 next_tx_seq_offset += 64;
3496
3497 /* check for invalid req-seq */
3498 if (req_seq_offset > next_tx_seq_offset) {
3499 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
3500 goto drop;
3501 }
3502
3503 if (__is_iframe(control)) {
3504 if (len < 0) {
3505 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
3506 goto drop;
3507 }
3508
3509 l2cap_data_channel_iframe(sk, control, skb);
3510 } else {
3511 if (len != 0) {
3512 BT_ERR("%d", len);
3513 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
3514 goto drop;
3515 }
3516
3517 l2cap_data_channel_sframe(sk, control, skb);
3518 }
3519
3520 return 0;
3521
3522drop:
3523 kfree_skb(skb);
3524 return 0;
3525}
3526
Linus Torvalds1da177e2005-04-16 15:20:36 -07003527static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk_buff *skb)
3528{
3529 struct sock *sk;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003530 struct l2cap_pinfo *pi;
Nathan Holstein51893f82010-06-09 15:46:25 -04003531 u16 control;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03003532 u8 tx_seq;
3533 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003534
3535 sk = l2cap_get_chan_by_scid(&conn->chan_list, cid);
3536 if (!sk) {
3537 BT_DBG("unknown cid 0x%4.4x", cid);
3538 goto drop;
3539 }
3540
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003541 pi = l2cap_pi(sk);
3542
Linus Torvalds1da177e2005-04-16 15:20:36 -07003543 BT_DBG("sk %p, len %d", sk, skb->len);
3544
3545 if (sk->sk_state != BT_CONNECTED)
3546 goto drop;
3547
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003548 switch (pi->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003549 case L2CAP_MODE_BASIC:
3550 /* If socket recv buffers overflows we drop data here
3551 * which is *bad* because L2CAP has to be reliable.
3552 * But we don't have any other choice. L2CAP doesn't
3553 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003554
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003555 if (pi->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003556 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003557
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003558 if (!sock_queue_rcv_skb(sk, skb))
3559 goto done;
3560 break;
3561
3562 case L2CAP_MODE_ERTM:
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03003563 if (!sock_owned_by_user(sk)) {
3564 l2cap_ertm_data_rcv(sk, skb);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03003565 } else {
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03003566 if (sk_add_backlog(sk, skb))
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03003567 goto drop;
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03003568 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003569
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02003570 goto done;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003571
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003572 case L2CAP_MODE_STREAMING:
3573 control = get_unaligned_le16(skb->data);
3574 skb_pull(skb, 2);
3575 len = skb->len;
3576
Gustavo F. Padovan26000082010-05-11 22:02:00 -03003577 if (l2cap_check_fcs(pi, skb))
3578 goto drop;
3579
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003580 if (__is_sar_start(control))
3581 len -= 2;
3582
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003583 if (pi->fcs == L2CAP_FCS_CRC16)
3584 len -= 2;
3585
Nathan Holstein51893f82010-06-09 15:46:25 -04003586 if (len > pi->mps || len < 0 || __is_sframe(control))
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003587 goto drop;
3588
3589 tx_seq = __get_txseq(control);
3590
3591 if (pi->expected_tx_seq == tx_seq)
3592 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
3593 else
Gustavo F. Padovan7dffe422010-05-01 16:15:36 -03003594 pi->expected_tx_seq = (tx_seq + 1) % 64;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003595
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003596 l2cap_streaming_reassembly_sdu(sk, skb, control);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003597
3598 goto done;
3599
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003600 default:
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03003601 BT_DBG("sk %p: bad mode 0x%2.2x", sk, pi->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003602 break;
3603 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003604
3605drop:
3606 kfree_skb(skb);
3607
3608done:
Marcel Holtmann01394182006-07-03 10:02:46 +02003609 if (sk)
3610 bh_unlock_sock(sk);
3611
Linus Torvalds1da177e2005-04-16 15:20:36 -07003612 return 0;
3613}
3614
Al Viro8e036fc2007-07-29 00:16:36 -07003615static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003616{
3617 struct sock *sk;
3618
3619 sk = l2cap_get_sock_by_psm(0, psm, conn->src);
3620 if (!sk)
3621 goto drop;
3622
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00003623 bh_lock_sock(sk);
3624
Linus Torvalds1da177e2005-04-16 15:20:36 -07003625 BT_DBG("sk %p, len %d", sk, skb->len);
3626
3627 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_CONNECTED)
3628 goto drop;
3629
3630 if (l2cap_pi(sk)->imtu < skb->len)
3631 goto drop;
3632
3633 if (!sock_queue_rcv_skb(sk, skb))
3634 goto done;
3635
3636drop:
3637 kfree_skb(skb);
3638
3639done:
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003640 if (sk)
3641 bh_unlock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003642 return 0;
3643}
3644
3645static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
3646{
3647 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07003648 u16 cid, len;
3649 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003650
3651 skb_pull(skb, L2CAP_HDR_SIZE);
3652 cid = __le16_to_cpu(lh->cid);
3653 len = __le16_to_cpu(lh->len);
3654
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003655 if (len != skb->len) {
3656 kfree_skb(skb);
3657 return;
3658 }
3659
Linus Torvalds1da177e2005-04-16 15:20:36 -07003660 BT_DBG("len %d, cid 0x%4.4x", len, cid);
3661
3662 switch (cid) {
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02003663 case L2CAP_CID_LE_SIGNALING:
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03003664 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07003665 l2cap_sig_channel(conn, skb);
3666 break;
3667
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03003668 case L2CAP_CID_CONN_LESS:
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03003669 psm = get_unaligned_le16(skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003670 skb_pull(skb, 2);
3671 l2cap_conless_channel(conn, psm, skb);
3672 break;
3673
3674 default:
3675 l2cap_data_channel(conn, cid, skb);
3676 break;
3677 }
3678}
3679
3680/* ---- L2CAP interface with lower layer (HCI) ---- */
3681
3682static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
3683{
3684 int exact = 0, lm1 = 0, lm2 = 0;
3685 register struct sock *sk;
3686 struct hlist_node *node;
3687
3688 if (type != ACL_LINK)
João Paulo Rechi Vita963cf682010-06-22 13:56:28 -03003689 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003690
3691 BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
3692
3693 /* Find listening sockets and check their link_mode */
3694 read_lock(&l2cap_sk_list.lock);
3695 sk_for_each(sk, node, &l2cap_sk_list.head) {
3696 if (sk->sk_state != BT_LISTEN)
3697 continue;
3698
3699 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01003700 lm1 |= HCI_LM_ACCEPT;
3701 if (l2cap_pi(sk)->role_switch)
3702 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003703 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01003704 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
3705 lm2 |= HCI_LM_ACCEPT;
3706 if (l2cap_pi(sk)->role_switch)
3707 lm2 |= HCI_LM_MASTER;
3708 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003709 }
3710 read_unlock(&l2cap_sk_list.lock);
3711
3712 return exact ? lm1 : lm2;
3713}
3714
3715static int l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
3716{
Marcel Holtmann01394182006-07-03 10:02:46 +02003717 struct l2cap_conn *conn;
3718
Linus Torvalds1da177e2005-04-16 15:20:36 -07003719 BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
3720
Ville Tervoacd7d372011-02-10 22:38:49 -03003721 if (!(hcon->type == ACL_LINK || hcon->type == LE_LINK))
João Paulo Rechi Vita963cf682010-06-22 13:56:28 -03003722 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003723
3724 if (!status) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003725 conn = l2cap_conn_add(hcon, status);
3726 if (conn)
3727 l2cap_conn_ready(conn);
Marcel Holtmann01394182006-07-03 10:02:46 +02003728 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -07003729 l2cap_conn_del(hcon, bt_err(status));
3730
3731 return 0;
3732}
3733
Marcel Holtmann2950f212009-02-12 14:02:50 +01003734static int l2cap_disconn_ind(struct hci_conn *hcon)
3735{
3736 struct l2cap_conn *conn = hcon->l2cap_data;
3737
3738 BT_DBG("hcon %p", hcon);
3739
3740 if (hcon->type != ACL_LINK || !conn)
3741 return 0x13;
3742
3743 return conn->disc_reason;
3744}
3745
3746static int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003747{
3748 BT_DBG("hcon %p reason %d", hcon, reason);
3749
Ville Tervoacd7d372011-02-10 22:38:49 -03003750 if (!(hcon->type == ACL_LINK || hcon->type == LE_LINK))
João Paulo Rechi Vita963cf682010-06-22 13:56:28 -03003751 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003752
3753 l2cap_conn_del(hcon, bt_err(reason));
Marcel Holtmann01394182006-07-03 10:02:46 +02003754
Linus Torvalds1da177e2005-04-16 15:20:36 -07003755 return 0;
3756}
3757
Marcel Holtmannf62e4322009-01-15 21:58:44 +01003758static inline void l2cap_check_encryption(struct sock *sk, u8 encrypt)
3759{
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03003760 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM)
Marcel Holtmann255c7602009-02-04 21:07:19 +01003761 return;
3762
Marcel Holtmannf62e4322009-01-15 21:58:44 +01003763 if (encrypt == 0x00) {
3764 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM) {
3765 l2cap_sock_clear_timer(sk);
3766 l2cap_sock_set_timer(sk, HZ * 5);
3767 } else if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
3768 __l2cap_sock_close(sk, ECONNREFUSED);
3769 } else {
3770 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM)
3771 l2cap_sock_clear_timer(sk);
3772 }
3773}
3774
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01003775static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003776{
3777 struct l2cap_chan_list *l;
Marcel Holtmann40be4922008-07-14 20:13:50 +02003778 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003779 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003780
Marcel Holtmann01394182006-07-03 10:02:46 +02003781 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003782 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02003783
Linus Torvalds1da177e2005-04-16 15:20:36 -07003784 l = &conn->chan_list;
3785
3786 BT_DBG("conn %p", conn);
3787
3788 read_lock(&l->lock);
3789
3790 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
3791 bh_lock_sock(sk);
3792
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003793 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND) {
3794 bh_unlock_sock(sk);
3795 continue;
3796 }
3797
Marcel Holtmannf62e4322009-01-15 21:58:44 +01003798 if (!status && (sk->sk_state == BT_CONNECTED ||
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01003799 sk->sk_state == BT_CONFIG)) {
Marcel Holtmannf62e4322009-01-15 21:58:44 +01003800 l2cap_check_encryption(sk, encrypt);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02003801 bh_unlock_sock(sk);
3802 continue;
3803 }
3804
Marcel Holtmannb1235d72008-07-14 20:13:54 +02003805 if (sk->sk_state == BT_CONNECT) {
3806 if (!status) {
3807 struct l2cap_conn_req req;
3808 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
3809 req.psm = l2cap_pi(sk)->psm;
3810
3811 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03003812 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02003813
3814 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
3815 L2CAP_CONN_REQ, sizeof(req), &req);
3816 } else {
3817 l2cap_sock_clear_timer(sk);
3818 l2cap_sock_set_timer(sk, HZ / 10);
3819 }
3820 } else if (sk->sk_state == BT_CONNECT2) {
3821 struct l2cap_conn_rsp rsp;
3822 __u16 result;
3823
3824 if (!status) {
3825 sk->sk_state = BT_CONFIG;
3826 result = L2CAP_CR_SUCCESS;
3827 } else {
3828 sk->sk_state = BT_DISCONN;
3829 l2cap_sock_set_timer(sk, HZ / 10);
3830 result = L2CAP_CR_SEC_BLOCK;
3831 }
3832
3833 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
3834 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
3835 rsp.result = cpu_to_le16(result);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003836 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02003837 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
3838 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003839 }
3840
Linus Torvalds1da177e2005-04-16 15:20:36 -07003841 bh_unlock_sock(sk);
3842 }
3843
3844 read_unlock(&l->lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02003845
Linus Torvalds1da177e2005-04-16 15:20:36 -07003846 return 0;
3847}
3848
3849static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
3850{
3851 struct l2cap_conn *conn = hcon->l2cap_data;
3852
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02003853 if (!conn)
3854 conn = l2cap_conn_add(hcon, 0);
3855
3856 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003857 goto drop;
3858
3859 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
3860
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +02003861 if (!(flags & ACL_CONT)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003862 struct l2cap_hdr *hdr;
Andrei Emeltchenko89794812010-09-15 14:28:44 +03003863 struct sock *sk;
3864 u16 cid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003865 int len;
3866
3867 if (conn->rx_len) {
3868 BT_ERR("Unexpected start frame (len %d)", skb->len);
3869 kfree_skb(conn->rx_skb);
3870 conn->rx_skb = NULL;
3871 conn->rx_len = 0;
3872 l2cap_conn_unreliable(conn, ECOMM);
3873 }
3874
Andrei Emeltchenkoaae7fe22010-09-15 14:28:43 +03003875 /* Start fragment always begin with Basic L2CAP header */
3876 if (skb->len < L2CAP_HDR_SIZE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003877 BT_ERR("Frame is too short (len %d)", skb->len);
3878 l2cap_conn_unreliable(conn, ECOMM);
3879 goto drop;
3880 }
3881
3882 hdr = (struct l2cap_hdr *) skb->data;
3883 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
Andrei Emeltchenko89794812010-09-15 14:28:44 +03003884 cid = __le16_to_cpu(hdr->cid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003885
3886 if (len == skb->len) {
3887 /* Complete frame received */
3888 l2cap_recv_frame(conn, skb);
3889 return 0;
3890 }
3891
3892 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
3893
3894 if (skb->len > len) {
3895 BT_ERR("Frame is too long (len %d, expected len %d)",
3896 skb->len, len);
3897 l2cap_conn_unreliable(conn, ECOMM);
3898 goto drop;
3899 }
3900
Andrei Emeltchenko89794812010-09-15 14:28:44 +03003901 sk = l2cap_get_chan_by_scid(&conn->chan_list, cid);
3902
3903 if (sk && l2cap_pi(sk)->imtu < len - L2CAP_HDR_SIZE) {
3904 BT_ERR("Frame exceeding recv MTU (len %d, MTU %d)",
3905 len, l2cap_pi(sk)->imtu);
3906 bh_unlock_sock(sk);
3907 l2cap_conn_unreliable(conn, ECOMM);
3908 goto drop;
3909 }
3910
3911 if (sk)
3912 bh_unlock_sock(sk);
3913
Linus Torvalds1da177e2005-04-16 15:20:36 -07003914 /* Allocate skb for the complete frame (with header) */
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003915 conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC);
3916 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003917 goto drop;
3918
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03003919 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003920 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003921 conn->rx_len = len - skb->len;
3922 } else {
3923 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
3924
3925 if (!conn->rx_len) {
3926 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
3927 l2cap_conn_unreliable(conn, ECOMM);
3928 goto drop;
3929 }
3930
3931 if (skb->len > conn->rx_len) {
3932 BT_ERR("Fragment is too long (len %d, expected %d)",
3933 skb->len, conn->rx_len);
3934 kfree_skb(conn->rx_skb);
3935 conn->rx_skb = NULL;
3936 conn->rx_len = 0;
3937 l2cap_conn_unreliable(conn, ECOMM);
3938 goto drop;
3939 }
3940
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03003941 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003942 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003943 conn->rx_len -= skb->len;
3944
3945 if (!conn->rx_len) {
3946 /* Complete frame received */
3947 l2cap_recv_frame(conn, conn->rx_skb);
3948 conn->rx_skb = NULL;
3949 }
3950 }
3951
3952drop:
3953 kfree_skb(skb);
3954 return 0;
3955}
3956
Marcel Holtmannaef7d972010-03-21 05:27:45 +01003957static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003958{
3959 struct sock *sk;
3960 struct hlist_node *node;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003961
3962 read_lock_bh(&l2cap_sk_list.lock);
3963
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08003964 sk_for_each(sk, node, &l2cap_sk_list.head) {
3965 struct l2cap_pinfo *pi = l2cap_pi(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003966
Gustavo F. Padovan903d3432011-02-10 14:16:06 -02003967 seq_printf(f, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d %d\n",
Marcel Holtmannaef7d972010-03-21 05:27:45 +01003968 batostr(&bt_sk(sk)->src),
3969 batostr(&bt_sk(sk)->dst),
3970 sk->sk_state, __le16_to_cpu(pi->psm),
3971 pi->scid, pi->dcid,
Gustavo F. Padovan903d3432011-02-10 14:16:06 -02003972 pi->imtu, pi->omtu, pi->sec_level,
3973 pi->mode);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08003974 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003975
Linus Torvalds1da177e2005-04-16 15:20:36 -07003976 read_unlock_bh(&l2cap_sk_list.lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08003977
Marcel Holtmannaef7d972010-03-21 05:27:45 +01003978 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003979}
3980
Marcel Holtmannaef7d972010-03-21 05:27:45 +01003981static int l2cap_debugfs_open(struct inode *inode, struct file *file)
3982{
3983 return single_open(file, l2cap_debugfs_show, inode->i_private);
3984}
3985
3986static const struct file_operations l2cap_debugfs_fops = {
3987 .open = l2cap_debugfs_open,
3988 .read = seq_read,
3989 .llseek = seq_lseek,
3990 .release = single_release,
3991};
3992
3993static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003994
Linus Torvalds1da177e2005-04-16 15:20:36 -07003995static struct hci_proto l2cap_hci_proto = {
3996 .name = "L2CAP",
3997 .id = HCI_PROTO_L2CAP,
3998 .connect_ind = l2cap_connect_ind,
3999 .connect_cfm = l2cap_connect_cfm,
4000 .disconn_ind = l2cap_disconn_ind,
Marcel Holtmann2950f212009-02-12 14:02:50 +01004001 .disconn_cfm = l2cap_disconn_cfm,
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004002 .security_cfm = l2cap_security_cfm,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004003 .recv_acldata = l2cap_recv_acldata
4004};
4005
Gustavo F. Padovan64274512011-02-07 20:08:52 -02004006int __init l2cap_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004007{
4008 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004009
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02004010 err = l2cap_init_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07004011 if (err < 0)
4012 return err;
4013
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004014 _busy_wq = create_singlethread_workqueue("l2cap");
Anderson Lizardob78d7b4f2010-11-29 12:15:50 -04004015 if (!_busy_wq) {
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02004016 err = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004017 goto error;
4018 }
4019
4020 err = hci_register_proto(&l2cap_hci_proto);
4021 if (err < 0) {
4022 BT_ERR("L2CAP protocol registration failed");
4023 bt_sock_unregister(BTPROTO_L2CAP);
4024 goto error;
4025 }
4026
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004027 if (bt_debugfs) {
4028 l2cap_debugfs = debugfs_create_file("l2cap", 0444,
4029 bt_debugfs, NULL, &l2cap_debugfs_fops);
4030 if (!l2cap_debugfs)
4031 BT_ERR("Failed to create L2CAP debug file");
4032 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004033
Linus Torvalds1da177e2005-04-16 15:20:36 -07004034 BT_INFO("L2CAP socket layer initialized");
4035
4036 return 0;
4037
4038error:
Anderson Lizardob78d7b4f2010-11-29 12:15:50 -04004039 destroy_workqueue(_busy_wq);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02004040 l2cap_cleanup_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07004041 return err;
4042}
4043
Gustavo F. Padovan64274512011-02-07 20:08:52 -02004044void l2cap_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004045{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004046 debugfs_remove(l2cap_debugfs);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004047
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004048 flush_workqueue(_busy_wq);
4049 destroy_workqueue(_busy_wq);
4050
Linus Torvalds1da177e2005-04-16 15:20:36 -07004051 if (hci_unregister_proto(&l2cap_hci_proto) < 0)
4052 BT_ERR("L2CAP protocol unregistration failed");
4053
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02004054 l2cap_cleanup_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07004055}
4056
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03004057module_param(disable_ertm, bool, 0644);
4058MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode");