blob: b5a1ce06e1c0da4309ba0027c468e65b3aeb9c44 [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
Johan Hedberg8556edd32011-01-19 12:06:50 +0530855 auth_type = l2cap_get_auth_type(sk);
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200856
Ville Tervoacd7d372011-02-10 22:38:49 -0300857 if (l2cap_pi(sk)->dcid == L2CAP_CID_LE_DATA)
858 hcon = hci_connect(hdev, LE_LINK, dst,
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100859 l2cap_pi(sk)->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -0300860 else
861 hcon = hci_connect(hdev, ACL_LINK, dst,
862 l2cap_pi(sk)->sec_level, auth_type);
863
Ville Tervo30e76272011-02-22 16:10:53 -0300864 if (IS_ERR(hcon)) {
865 err = PTR_ERR(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700866 goto done;
Ville Tervo30e76272011-02-22 16:10:53 -0300867 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700868
869 conn = l2cap_conn_add(hcon, 0);
870 if (!conn) {
871 hci_conn_put(hcon);
Ville Tervo30e76272011-02-22 16:10:53 -0300872 err = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700873 goto done;
874 }
875
Linus Torvalds1da177e2005-04-16 15:20:36 -0700876 /* Update source addr of the socket */
877 bacpy(src, conn->src);
878
879 l2cap_chan_add(conn, sk, NULL);
880
881 sk->sk_state = BT_CONNECT;
882 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
883
884 if (hcon->state == BT_CONNECTED) {
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300885 if (sk->sk_type != SOCK_SEQPACKET &&
886 sk->sk_type != SOCK_STREAM) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700887 l2cap_sock_clear_timer(sk);
Johan Hedbergd00ef242011-01-19 12:06:51 +0530888 if (l2cap_check_security(sk))
889 sk->sk_state = BT_CONNECTED;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200890 } else
891 l2cap_do_start(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700892 }
893
Ville Tervo30e76272011-02-22 16:10:53 -0300894 err = 0;
895
Linus Torvalds1da177e2005-04-16 15:20:36 -0700896done:
897 hci_dev_unlock_bh(hdev);
898 hci_dev_put(hdev);
899 return err;
900}
901
Gustavo F. Padovandcba0db2011-02-04 03:08:36 -0200902int __l2cap_wait_ack(struct sock *sk)
Gustavo F. Padovan6161c032010-05-01 16:15:44 -0300903{
904 DECLARE_WAITQUEUE(wait, current);
905 int err = 0;
906 int timeo = HZ/5;
907
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +0200908 add_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -0300909 while ((l2cap_pi(sk)->unacked_frames > 0 && l2cap_pi(sk)->conn)) {
910 set_current_state(TASK_INTERRUPTIBLE);
911
912 if (!timeo)
913 timeo = HZ/5;
914
915 if (signal_pending(current)) {
916 err = sock_intr_errno(timeo);
917 break;
918 }
919
920 release_sock(sk);
921 timeo = schedule_timeout(timeo);
922 lock_sock(sk);
923
924 err = sock_error(sk);
925 if (err)
926 break;
927 }
928 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +0200929 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -0300930 return err;
931}
932
Gustavo F. Padovane90bac02009-08-20 22:26:00 -0300933static void l2cap_monitor_timeout(unsigned long arg)
934{
935 struct sock *sk = (void *) arg;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -0300936
Gustavo F. Padovan0e989582010-04-19 14:45:38 -0300937 BT_DBG("sk %p", sk);
938
Gustavo F. Padovane6862192009-08-24 00:45:19 -0300939 bh_lock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -0300940 if (l2cap_pi(sk)->retry_count >= l2cap_pi(sk)->remote_max_tx) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -0300941 l2cap_send_disconn_req(l2cap_pi(sk)->conn, sk, ECONNABORTED);
Andrei Emeltchenkob13f5862009-12-15 11:38:04 +0200942 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -0300943 return;
944 }
945
946 l2cap_pi(sk)->retry_count++;
947 __mod_monitor_timer();
948
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -0300949 l2cap_send_rr_or_rnr(l2cap_pi(sk), L2CAP_CTRL_POLL);
Gustavo F. Padovane6862192009-08-24 00:45:19 -0300950 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -0300951}
952
953static void l2cap_retrans_timeout(unsigned long arg)
954{
955 struct sock *sk = (void *) arg;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -0300956
Gustavo F. Padovan0e989582010-04-19 14:45:38 -0300957 BT_DBG("sk %p", sk);
958
Gustavo F. Padovane6862192009-08-24 00:45:19 -0300959 bh_lock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -0300960 l2cap_pi(sk)->retry_count = 1;
961 __mod_monitor_timer();
962
963 l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
964
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -0300965 l2cap_send_rr_or_rnr(l2cap_pi(sk), L2CAP_CTRL_POLL);
Gustavo F. Padovane6862192009-08-24 00:45:19 -0300966 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -0300967}
968
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300969static void l2cap_drop_acked_frames(struct sock *sk)
970{
971 struct sk_buff *skb;
972
Gustavo F. Padovan812e7372010-05-01 16:15:42 -0300973 while ((skb = skb_peek(TX_QUEUE(sk))) &&
974 l2cap_pi(sk)->unacked_frames) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300975 if (bt_cb(skb)->tx_seq == l2cap_pi(sk)->expected_ack_seq)
976 break;
977
978 skb = skb_dequeue(TX_QUEUE(sk));
979 kfree_skb(skb);
980
981 l2cap_pi(sk)->unacked_frames--;
982 }
983
Gustavo F. Padovane90bac02009-08-20 22:26:00 -0300984 if (!l2cap_pi(sk)->unacked_frames)
985 del_timer(&l2cap_pi(sk)->retrans_timer);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300986}
987
Gustavo F. Padovanfd83ccd2011-02-04 03:20:52 -0200988void l2cap_do_send(struct sock *sk, struct sk_buff *skb)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300989{
990 struct l2cap_pinfo *pi = l2cap_pi(sk);
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200991 struct hci_conn *hcon = pi->conn->hcon;
992 u16 flags;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300993
994 BT_DBG("sk %p, skb %p len %d", sk, skb, skb->len);
995
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200996 if (!pi->flushable && lmp_no_flush_capable(hcon->hdev))
997 flags = ACL_START_NO_FLUSH;
998 else
999 flags = ACL_START;
1000
1001 hci_send_acl(hcon, skb, flags);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001002}
1003
Gustavo F. Padovanfd83ccd2011-02-04 03:20:52 -02001004void l2cap_streaming_send(struct sock *sk)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001005{
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001006 struct sk_buff *skb;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001007 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001008 u16 control, fcs;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001009
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001010 while ((skb = skb_dequeue(TX_QUEUE(sk)))) {
1011 control = get_unaligned_le16(skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001012 control |= pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT;
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001013 put_unaligned_le16(control, skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001014
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001015 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001016 fcs = crc16(0, (u8 *)skb->data, skb->len - 2);
1017 put_unaligned_le16(fcs, skb->data + skb->len - 2);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001018 }
1019
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001020 l2cap_do_send(sk, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001021
1022 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001023 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001024}
1025
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001026static void l2cap_retransmit_one_frame(struct sock *sk, u8 tx_seq)
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001027{
1028 struct l2cap_pinfo *pi = l2cap_pi(sk);
1029 struct sk_buff *skb, *tx_skb;
1030 u16 control, fcs;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001031
1032 skb = skb_peek(TX_QUEUE(sk));
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001033 if (!skb)
1034 return;
1035
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001036 do {
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001037 if (bt_cb(skb)->tx_seq == tx_seq)
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001038 break;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001039
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001040 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1041 return;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001042
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001043 } while ((skb = skb_queue_next(TX_QUEUE(sk), skb)));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001044
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001045 if (pi->remote_max_tx &&
1046 bt_cb(skb)->retries == pi->remote_max_tx) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03001047 l2cap_send_disconn_req(pi->conn, sk, ECONNABORTED);
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001048 return;
1049 }
1050
1051 tx_skb = skb_clone(skb, GFP_ATOMIC);
1052 bt_cb(skb)->retries++;
1053 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03001054
1055 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
1056 control |= L2CAP_CTRL_FINAL;
1057 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
1058 }
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03001059
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001060 control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
1061 | (tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03001062
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001063 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1064
1065 if (pi->fcs == L2CAP_FCS_CRC16) {
1066 fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
1067 put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
1068 }
1069
1070 l2cap_do_send(sk, tx_skb);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001071}
1072
Gustavo F. Padovanfd83ccd2011-02-04 03:20:52 -02001073int l2cap_ertm_send(struct sock *sk)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001074{
1075 struct sk_buff *skb, *tx_skb;
1076 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001077 u16 control, fcs;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001078 int nsent = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001079
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001080 if (sk->sk_state != BT_CONNECTED)
1081 return -ENOTCONN;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001082
Gustavo F. Padovan6e2b6722010-06-01 18:52:58 -03001083 while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(sk))) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001084
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001085 if (pi->remote_max_tx &&
1086 bt_cb(skb)->retries == pi->remote_max_tx) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03001087 l2cap_send_disconn_req(pi->conn, sk, ECONNABORTED);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001088 break;
1089 }
1090
Andrei Emeltchenkoe420aba2009-12-23 13:07:14 +02001091 tx_skb = skb_clone(skb, GFP_ATOMIC);
1092
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001093 bt_cb(skb)->retries++;
1094
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001095 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03001096 control &= L2CAP_CTRL_SAR;
1097
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001098 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
1099 control |= L2CAP_CTRL_FINAL;
1100 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
1101 }
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03001102 control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001103 | (pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
1104 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1105
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001106
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001107 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001108 fcs = crc16(0, (u8 *)skb->data, tx_skb->len - 2);
1109 put_unaligned_le16(fcs, skb->data + tx_skb->len - 2);
1110 }
1111
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001112 l2cap_do_send(sk, tx_skb);
1113
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001114 __mod_retrans_timer();
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001115
1116 bt_cb(skb)->tx_seq = pi->next_tx_seq;
1117 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
1118
1119 pi->unacked_frames++;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001120 pi->frames_sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001121
1122 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1123 sk->sk_send_head = NULL;
1124 else
1125 sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001126
1127 nsent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001128 }
1129
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001130 return nsent;
1131}
1132
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001133static int l2cap_retransmit_frames(struct sock *sk)
1134{
1135 struct l2cap_pinfo *pi = l2cap_pi(sk);
1136 int ret;
1137
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001138 if (!skb_queue_empty(TX_QUEUE(sk)))
1139 sk->sk_send_head = TX_QUEUE(sk)->next;
1140
1141 pi->next_tx_seq = pi->expected_ack_seq;
1142 ret = l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001143 return ret;
1144}
1145
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001146static void l2cap_send_ack(struct l2cap_pinfo *pi)
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001147{
1148 struct sock *sk = (struct sock *)pi;
1149 u16 control = 0;
1150
1151 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1152
1153 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
1154 control |= L2CAP_SUPER_RCV_NOT_READY;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03001155 pi->conn_state |= L2CAP_CONN_RNR_SENT;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001156 l2cap_send_sframe(pi, control);
1157 return;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001158 }
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001159
Gustavo F. Padovane0f66212010-06-21 18:50:49 -03001160 if (l2cap_ertm_send(sk) > 0)
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001161 return;
1162
1163 control |= L2CAP_SUPER_RCV_READY;
1164 l2cap_send_sframe(pi, control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001165}
1166
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001167static void l2cap_send_srejtail(struct sock *sk)
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03001168{
1169 struct srej_list *tail;
1170 u16 control;
1171
1172 control = L2CAP_SUPER_SELECT_REJECT;
1173 control |= L2CAP_CTRL_FINAL;
1174
1175 tail = list_entry(SREJ_LIST(sk)->prev, struct srej_list, list);
1176 control |= tail->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1177
1178 l2cap_send_sframe(l2cap_pi(sk), control);
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03001179}
1180
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001181static 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 -07001182{
1183 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001184 struct sk_buff **frag;
1185 int err, sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001186
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03001187 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001188 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001189
1190 sent += count;
1191 len -= count;
1192
1193 /* Continuation fragments (no L2CAP header) */
1194 frag = &skb_shinfo(skb)->frag_list;
1195 while (len) {
1196 count = min_t(unsigned int, conn->mtu, len);
1197
1198 *frag = bt_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err);
1199 if (!*frag)
Gustavo F. Padovan0175d622010-09-24 20:30:57 -03001200 return err;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001201 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
1202 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001203
1204 sent += count;
1205 len -= count;
1206
1207 frag = &(*frag)->next;
1208 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001209
1210 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001211}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001212
Gustavo F. Padovanfd83ccd2011-02-04 03:20:52 -02001213struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, size_t len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001214{
1215 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1216 struct sk_buff *skb;
1217 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1218 struct l2cap_hdr *lh;
1219
1220 BT_DBG("sk %p len %d", sk, (int)len);
1221
1222 count = min_t(unsigned int, (conn->mtu - hlen), len);
1223 skb = bt_skb_send_alloc(sk, count + hlen,
1224 msg->msg_flags & MSG_DONTWAIT, &err);
1225 if (!skb)
Gustavo F. Padovan0175d622010-09-24 20:30:57 -03001226 return ERR_PTR(err);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001227
1228 /* Create L2CAP header */
1229 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1230 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1231 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1232 put_unaligned_le16(l2cap_pi(sk)->psm, skb_put(skb, 2));
1233
1234 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1235 if (unlikely(err < 0)) {
1236 kfree_skb(skb);
1237 return ERR_PTR(err);
1238 }
1239 return skb;
1240}
1241
Gustavo F. Padovanfd83ccd2011-02-04 03:20:52 -02001242struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *msg, size_t len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001243{
1244 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1245 struct sk_buff *skb;
1246 int err, count, hlen = L2CAP_HDR_SIZE;
1247 struct l2cap_hdr *lh;
1248
1249 BT_DBG("sk %p len %d", sk, (int)len);
1250
1251 count = min_t(unsigned int, (conn->mtu - hlen), len);
1252 skb = bt_skb_send_alloc(sk, count + hlen,
1253 msg->msg_flags & MSG_DONTWAIT, &err);
1254 if (!skb)
Gustavo F. Padovan0175d622010-09-24 20:30:57 -03001255 return ERR_PTR(err);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001256
1257 /* Create L2CAP header */
1258 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1259 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1260 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1261
1262 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1263 if (unlikely(err < 0)) {
1264 kfree_skb(skb);
1265 return ERR_PTR(err);
1266 }
1267 return skb;
1268}
1269
Gustavo F. Padovanfd83ccd2011-02-04 03:20:52 -02001270struct 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 -03001271{
1272 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1273 struct sk_buff *skb;
1274 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1275 struct l2cap_hdr *lh;
1276
1277 BT_DBG("sk %p len %d", sk, (int)len);
1278
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03001279 if (!conn)
1280 return ERR_PTR(-ENOTCONN);
1281
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001282 if (sdulen)
1283 hlen += 2;
1284
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001285 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1286 hlen += 2;
1287
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001288 count = min_t(unsigned int, (conn->mtu - hlen), len);
1289 skb = bt_skb_send_alloc(sk, count + hlen,
1290 msg->msg_flags & MSG_DONTWAIT, &err);
1291 if (!skb)
Gustavo F. Padovan0175d622010-09-24 20:30:57 -03001292 return ERR_PTR(err);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001293
1294 /* Create L2CAP header */
1295 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1296 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1297 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1298 put_unaligned_le16(control, skb_put(skb, 2));
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001299 if (sdulen)
1300 put_unaligned_le16(sdulen, skb_put(skb, 2));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001301
1302 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1303 if (unlikely(err < 0)) {
1304 kfree_skb(skb);
1305 return ERR_PTR(err);
1306 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001307
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001308 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1309 put_unaligned_le16(0, skb_put(skb, 2));
1310
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001311 bt_cb(skb)->retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001312 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001313}
1314
Gustavo F. Padovanfd83ccd2011-02-04 03:20:52 -02001315int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001316{
1317 struct l2cap_pinfo *pi = l2cap_pi(sk);
1318 struct sk_buff *skb;
1319 struct sk_buff_head sar_queue;
1320 u16 control;
1321 size_t size = 0;
1322
Gustavo F. Padovanff12fd62010-05-05 22:09:15 -03001323 skb_queue_head_init(&sar_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001324 control = L2CAP_SDU_START;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001325 skb = l2cap_create_iframe_pdu(sk, msg, pi->remote_mps, control, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001326 if (IS_ERR(skb))
1327 return PTR_ERR(skb);
1328
1329 __skb_queue_tail(&sar_queue, skb);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001330 len -= pi->remote_mps;
1331 size += pi->remote_mps;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001332
1333 while (len > 0) {
1334 size_t buflen;
1335
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001336 if (len > pi->remote_mps) {
Gustavo F. Padovan44651b82010-05-01 16:15:43 -03001337 control = L2CAP_SDU_CONTINUE;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001338 buflen = pi->remote_mps;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001339 } else {
Gustavo F. Padovan44651b82010-05-01 16:15:43 -03001340 control = L2CAP_SDU_END;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001341 buflen = len;
1342 }
1343
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001344 skb = l2cap_create_iframe_pdu(sk, msg, buflen, control, 0);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001345 if (IS_ERR(skb)) {
1346 skb_queue_purge(&sar_queue);
1347 return PTR_ERR(skb);
1348 }
1349
1350 __skb_queue_tail(&sar_queue, skb);
1351 len -= buflen;
1352 size += buflen;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001353 }
1354 skb_queue_splice_tail(&sar_queue, TX_QUEUE(sk));
1355 if (sk->sk_send_head == NULL)
1356 sk->sk_send_head = sar_queue.next;
1357
1358 return size;
1359}
1360
Linus Torvalds1da177e2005-04-16 15:20:36 -07001361static void l2cap_chan_ready(struct sock *sk)
1362{
1363 struct sock *parent = bt_sk(sk)->parent;
1364
1365 BT_DBG("sk %p, parent %p", sk, parent);
1366
1367 l2cap_pi(sk)->conf_state = 0;
1368 l2cap_sock_clear_timer(sk);
1369
1370 if (!parent) {
1371 /* Outgoing channel.
1372 * Wake up socket sleeping on connect.
1373 */
1374 sk->sk_state = BT_CONNECTED;
1375 sk->sk_state_change(sk);
1376 } else {
1377 /* Incoming channel.
1378 * Wake up socket sleeping on accept.
1379 */
1380 parent->sk_data_ready(parent, 0);
1381 }
1382}
1383
1384/* Copy frame to all raw sockets on that connection */
1385static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
1386{
1387 struct l2cap_chan_list *l = &conn->chan_list;
1388 struct sk_buff *nskb;
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001389 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001390
1391 BT_DBG("conn %p", conn);
1392
1393 read_lock(&l->lock);
1394 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
1395 if (sk->sk_type != SOCK_RAW)
1396 continue;
1397
1398 /* Don't send frame to the socket it came from */
1399 if (skb->sk == sk)
1400 continue;
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001401 nskb = skb_clone(skb, GFP_ATOMIC);
1402 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001403 continue;
1404
1405 if (sock_queue_rcv_skb(sk, nskb))
1406 kfree_skb(nskb);
1407 }
1408 read_unlock(&l->lock);
1409}
1410
1411/* ---- L2CAP signalling commands ---- */
1412static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
1413 u8 code, u8 ident, u16 dlen, void *data)
1414{
1415 struct sk_buff *skb, **frag;
1416 struct l2cap_cmd_hdr *cmd;
1417 struct l2cap_hdr *lh;
1418 int len, count;
1419
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001420 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d",
1421 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001422
1423 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
1424 count = min_t(unsigned int, conn->mtu, len);
1425
1426 skb = bt_skb_alloc(count, GFP_ATOMIC);
1427 if (!skb)
1428 return NULL;
1429
1430 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07001431 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02001432
1433 if (conn->hcon->type == LE_LINK)
1434 lh->cid = cpu_to_le16(L2CAP_CID_LE_SIGNALING);
1435 else
1436 lh->cid = cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001437
1438 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
1439 cmd->code = code;
1440 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07001441 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001442
1443 if (dlen) {
1444 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
1445 memcpy(skb_put(skb, count), data, count);
1446 data += count;
1447 }
1448
1449 len -= skb->len;
1450
1451 /* Continuation fragments (no L2CAP header) */
1452 frag = &skb_shinfo(skb)->frag_list;
1453 while (len) {
1454 count = min_t(unsigned int, conn->mtu, len);
1455
1456 *frag = bt_skb_alloc(count, GFP_ATOMIC);
1457 if (!*frag)
1458 goto fail;
1459
1460 memcpy(skb_put(*frag, count), data, count);
1461
1462 len -= count;
1463 data += count;
1464
1465 frag = &(*frag)->next;
1466 }
1467
1468 return skb;
1469
1470fail:
1471 kfree_skb(skb);
1472 return NULL;
1473}
1474
1475static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned long *val)
1476{
1477 struct l2cap_conf_opt *opt = *ptr;
1478 int len;
1479
1480 len = L2CAP_CONF_OPT_SIZE + opt->len;
1481 *ptr += len;
1482
1483 *type = opt->type;
1484 *olen = opt->len;
1485
1486 switch (opt->len) {
1487 case 1:
1488 *val = *((u8 *) opt->val);
1489 break;
1490
1491 case 2:
steven miaobfaaeb32010-10-16 18:29:47 -04001492 *val = get_unaligned_le16(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001493 break;
1494
1495 case 4:
steven miaobfaaeb32010-10-16 18:29:47 -04001496 *val = get_unaligned_le32(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001497 break;
1498
1499 default:
1500 *val = (unsigned long) opt->val;
1501 break;
1502 }
1503
1504 BT_DBG("type 0x%2.2x len %d val 0x%lx", *type, opt->len, *val);
1505 return len;
1506}
1507
Linus Torvalds1da177e2005-04-16 15:20:36 -07001508static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
1509{
1510 struct l2cap_conf_opt *opt = *ptr;
1511
1512 BT_DBG("type 0x%2.2x len %d val 0x%lx", type, len, val);
1513
1514 opt->type = type;
1515 opt->len = len;
1516
1517 switch (len) {
1518 case 1:
1519 *((u8 *) opt->val) = val;
1520 break;
1521
1522 case 2:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02001523 put_unaligned_le16(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001524 break;
1525
1526 case 4:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02001527 put_unaligned_le32(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001528 break;
1529
1530 default:
1531 memcpy(opt->val, (void *) val, len);
1532 break;
1533 }
1534
1535 *ptr += L2CAP_CONF_OPT_SIZE + len;
1536}
1537
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03001538static void l2cap_ack_timeout(unsigned long arg)
1539{
1540 struct sock *sk = (void *) arg;
1541
1542 bh_lock_sock(sk);
1543 l2cap_send_ack(l2cap_pi(sk));
1544 bh_unlock_sock(sk);
1545}
1546
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03001547static inline void l2cap_ertm_init(struct sock *sk)
1548{
1549 l2cap_pi(sk)->expected_ack_seq = 0;
1550 l2cap_pi(sk)->unacked_frames = 0;
1551 l2cap_pi(sk)->buffer_seq = 0;
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03001552 l2cap_pi(sk)->num_acked = 0;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001553 l2cap_pi(sk)->frames_sent = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03001554
1555 setup_timer(&l2cap_pi(sk)->retrans_timer,
1556 l2cap_retrans_timeout, (unsigned long) sk);
1557 setup_timer(&l2cap_pi(sk)->monitor_timer,
1558 l2cap_monitor_timeout, (unsigned long) sk);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03001559 setup_timer(&l2cap_pi(sk)->ack_timer,
1560 l2cap_ack_timeout, (unsigned long) sk);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03001561
1562 __skb_queue_head_init(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03001563 __skb_queue_head_init(BUSY_QUEUE(sk));
1564
1565 INIT_WORK(&l2cap_pi(sk)->busy_work, l2cap_busy_work);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03001566
1567 sk->sk_backlog_rcv = l2cap_ertm_data_rcv;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03001568}
1569
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001570static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
1571{
1572 switch (mode) {
1573 case L2CAP_MODE_STREAMING:
1574 case L2CAP_MODE_ERTM:
1575 if (l2cap_mode_supported(mode, remote_feat_mask))
1576 return mode;
1577 /* fall through */
1578 default:
1579 return L2CAP_MODE_BASIC;
1580 }
1581}
1582
Gustavo F. Padovan68983252011-02-04 03:02:31 -02001583int l2cap_build_conf_req(struct sock *sk, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001584{
1585 struct l2cap_pinfo *pi = l2cap_pi(sk);
1586 struct l2cap_conf_req *req = data;
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001587 struct l2cap_conf_rfc rfc = { .mode = pi->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07001588 void *ptr = req->data;
1589
1590 BT_DBG("sk %p", sk);
1591
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001592 if (pi->num_conf_req || pi->num_conf_rsp)
1593 goto done;
1594
1595 switch (pi->mode) {
1596 case L2CAP_MODE_STREAMING:
1597 case L2CAP_MODE_ERTM:
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03001598 if (pi->conf_state & L2CAP_CONF_STATE2_DEVICE)
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03001599 break;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03001600
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03001601 /* fall through */
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001602 default:
1603 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
1604 break;
1605 }
1606
1607done:
Gustavo F. Padovan7990681c2011-01-24 16:01:43 -02001608 if (pi->imtu != L2CAP_DEFAULT_MTU)
1609 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
1610
Marcel Holtmann65c7c492009-05-02 23:07:53 -07001611 switch (pi->mode) {
1612 case L2CAP_MODE_BASIC:
Gustavo F. Padovan63406502010-08-03 23:49:29 -03001613 if (!(pi->conn->feat_mask & L2CAP_FEAT_ERTM) &&
1614 !(pi->conn->feat_mask & L2CAP_FEAT_STREAMING))
1615 break;
1616
Gustavo F. Padovan62547752010-06-08 20:05:31 -03001617 rfc.mode = L2CAP_MODE_BASIC;
1618 rfc.txwin_size = 0;
1619 rfc.max_transmit = 0;
1620 rfc.retrans_timeout = 0;
1621 rfc.monitor_timeout = 0;
1622 rfc.max_pdu_size = 0;
1623
Gustavo F. Padovan63406502010-08-03 23:49:29 -03001624 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
1625 (unsigned long) &rfc);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07001626 break;
1627
1628 case L2CAP_MODE_ERTM:
1629 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03001630 rfc.txwin_size = pi->tx_win;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03001631 rfc.max_transmit = pi->max_tx;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001632 rfc.retrans_timeout = 0;
1633 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001634 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03001635 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001636 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001637
Gustavo F. Padovan63406502010-08-03 23:49:29 -03001638 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
1639 (unsigned long) &rfc);
1640
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001641 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
1642 break;
1643
1644 if (pi->fcs == L2CAP_FCS_NONE ||
1645 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
1646 pi->fcs = L2CAP_FCS_NONE;
1647 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
1648 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001649 break;
1650
1651 case L2CAP_MODE_STREAMING:
1652 rfc.mode = L2CAP_MODE_STREAMING;
1653 rfc.txwin_size = 0;
1654 rfc.max_transmit = 0;
1655 rfc.retrans_timeout = 0;
1656 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001657 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03001658 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001659 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07001660
Gustavo F. Padovan63406502010-08-03 23:49:29 -03001661 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
1662 (unsigned long) &rfc);
1663
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001664 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
1665 break;
1666
1667 if (pi->fcs == L2CAP_FCS_NONE ||
1668 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
1669 pi->fcs = L2CAP_FCS_NONE;
1670 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
1671 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07001672 break;
1673 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001674
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07001675 req->dcid = cpu_to_le16(pi->dcid);
1676 req->flags = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001677
1678 return ptr - data;
1679}
1680
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001681static int l2cap_parse_conf_req(struct sock *sk, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001682{
1683 struct l2cap_pinfo *pi = l2cap_pi(sk);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001684 struct l2cap_conf_rsp *rsp = data;
1685 void *ptr = rsp->data;
1686 void *req = pi->conf_req;
1687 int len = pi->conf_len;
1688 int type, hint, olen;
1689 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02001690 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Marcel Holtmann861d6882007-10-20 13:37:06 +02001691 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001692 u16 result = L2CAP_CONF_SUCCESS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001693
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001694 BT_DBG("sk %p", sk);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01001695
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001696 while (len >= L2CAP_CONF_OPT_SIZE) {
1697 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001698
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03001699 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07001700 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001701
1702 switch (type) {
1703 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02001704 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001705 break;
1706
1707 case L2CAP_CONF_FLUSH_TO:
1708 pi->flush_to = val;
1709 break;
1710
1711 case L2CAP_CONF_QOS:
1712 break;
1713
Marcel Holtmann6464f352007-10-20 13:39:51 +02001714 case L2CAP_CONF_RFC:
1715 if (olen == sizeof(rfc))
1716 memcpy(&rfc, (void *) val, olen);
1717 break;
1718
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001719 case L2CAP_CONF_FCS:
1720 if (val == L2CAP_FCS_NONE)
1721 pi->conf_state |= L2CAP_CONF_NO_FCS_RECV;
1722
1723 break;
1724
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001725 default:
1726 if (hint)
1727 break;
1728
1729 result = L2CAP_CONF_UNKNOWN;
1730 *((u8 *) ptr++) = type;
1731 break;
1732 }
1733 }
1734
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001735 if (pi->num_conf_rsp || pi->num_conf_req > 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001736 goto done;
1737
1738 switch (pi->mode) {
1739 case L2CAP_MODE_STREAMING:
1740 case L2CAP_MODE_ERTM:
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03001741 if (!(pi->conf_state & L2CAP_CONF_STATE2_DEVICE)) {
1742 pi->mode = l2cap_select_mode(rfc.mode,
1743 pi->conn->feat_mask);
1744 break;
1745 }
1746
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03001747 if (pi->mode != rfc.mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001748 return -ECONNREFUSED;
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03001749
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001750 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001751 }
1752
1753done:
1754 if (pi->mode != rfc.mode) {
1755 result = L2CAP_CONF_UNACCEPT;
1756 rfc.mode = pi->mode;
1757
1758 if (pi->num_conf_rsp == 1)
1759 return -ECONNREFUSED;
1760
1761 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
1762 sizeof(rfc), (unsigned long) &rfc);
1763 }
1764
1765
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001766 if (result == L2CAP_CONF_SUCCESS) {
1767 /* Configure output options and let the other side know
1768 * which ones we don't like. */
1769
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001770 if (mtu < L2CAP_DEFAULT_MIN_MTU)
1771 result = L2CAP_CONF_UNACCEPT;
1772 else {
1773 pi->omtu = mtu;
1774 pi->conf_state |= L2CAP_CONF_MTU_DONE;
1775 }
1776 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001777
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001778 switch (rfc.mode) {
1779 case L2CAP_MODE_BASIC:
1780 pi->fcs = L2CAP_FCS_NONE;
1781 pi->conf_state |= L2CAP_CONF_MODE_DONE;
1782 break;
1783
1784 case L2CAP_MODE_ERTM:
1785 pi->remote_tx_win = rfc.txwin_size;
1786 pi->remote_max_tx = rfc.max_transmit;
Mat Martineau86b1b262010-08-05 15:54:22 -07001787
1788 if (le16_to_cpu(rfc.max_pdu_size) > pi->conn->mtu - 10)
1789 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001790
1791 pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001792
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03001793 rfc.retrans_timeout =
1794 le16_to_cpu(L2CAP_DEFAULT_RETRANS_TO);
1795 rfc.monitor_timeout =
1796 le16_to_cpu(L2CAP_DEFAULT_MONITOR_TO);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001797
1798 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03001799
1800 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
1801 sizeof(rfc), (unsigned long) &rfc);
1802
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001803 break;
1804
1805 case L2CAP_MODE_STREAMING:
Mat Martineau86b1b262010-08-05 15:54:22 -07001806 if (le16_to_cpu(rfc.max_pdu_size) > pi->conn->mtu - 10)
1807 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001808
1809 pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001810
1811 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03001812
1813 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
1814 sizeof(rfc), (unsigned long) &rfc);
1815
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001816 break;
1817
1818 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02001819 result = L2CAP_CONF_UNACCEPT;
1820
1821 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001822 rfc.mode = pi->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02001823 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001824
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001825 if (result == L2CAP_CONF_SUCCESS)
1826 pi->conf_state |= L2CAP_CONF_OUTPUT_DONE;
1827 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001828 rsp->scid = cpu_to_le16(pi->dcid);
1829 rsp->result = cpu_to_le16(result);
1830 rsp->flags = cpu_to_le16(0x0000);
1831
1832 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001833}
1834
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001835static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data, u16 *result)
1836{
1837 struct l2cap_pinfo *pi = l2cap_pi(sk);
1838 struct l2cap_conf_req *req = data;
1839 void *ptr = req->data;
1840 int type, olen;
1841 unsigned long val;
1842 struct l2cap_conf_rfc rfc;
1843
1844 BT_DBG("sk %p, rsp %p, len %d, req %p", sk, rsp, len, data);
1845
1846 while (len >= L2CAP_CONF_OPT_SIZE) {
1847 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
1848
1849 switch (type) {
1850 case L2CAP_CONF_MTU:
1851 if (val < L2CAP_DEFAULT_MIN_MTU) {
1852 *result = L2CAP_CONF_UNACCEPT;
Andrei Emeltchenko8183b772010-09-01 15:17:25 +03001853 pi->imtu = L2CAP_DEFAULT_MIN_MTU;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001854 } else
Andrei Emeltchenko8183b772010-09-01 15:17:25 +03001855 pi->imtu = val;
1856 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001857 break;
1858
1859 case L2CAP_CONF_FLUSH_TO:
1860 pi->flush_to = val;
1861 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
1862 2, pi->flush_to);
1863 break;
1864
1865 case L2CAP_CONF_RFC:
1866 if (olen == sizeof(rfc))
1867 memcpy(&rfc, (void *)val, olen);
1868
1869 if ((pi->conf_state & L2CAP_CONF_STATE2_DEVICE) &&
1870 rfc.mode != pi->mode)
1871 return -ECONNREFUSED;
1872
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001873 pi->fcs = 0;
1874
1875 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
1876 sizeof(rfc), (unsigned long) &rfc);
1877 break;
1878 }
1879 }
1880
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03001881 if (pi->mode == L2CAP_MODE_BASIC && pi->mode != rfc.mode)
1882 return -ECONNREFUSED;
1883
1884 pi->mode = rfc.mode;
1885
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001886 if (*result == L2CAP_CONF_SUCCESS) {
1887 switch (rfc.mode) {
1888 case L2CAP_MODE_ERTM:
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03001889 pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
1890 pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001891 pi->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001892 break;
1893 case L2CAP_MODE_STREAMING:
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 }
1896 }
1897
1898 req->dcid = cpu_to_le16(pi->dcid);
1899 req->flags = cpu_to_le16(0x0000);
1900
1901 return ptr - data;
1902}
1903
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001904static int l2cap_build_conf_rsp(struct sock *sk, void *data, u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001905{
1906 struct l2cap_conf_rsp *rsp = data;
1907 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001908
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001909 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001910
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07001911 rsp->scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001912 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07001913 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001914
1915 return ptr - data;
1916}
1917
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03001918static void l2cap_conf_rfc_get(struct sock *sk, void *rsp, int len)
1919{
1920 struct l2cap_pinfo *pi = l2cap_pi(sk);
1921 int type, olen;
1922 unsigned long val;
1923 struct l2cap_conf_rfc rfc;
1924
1925 BT_DBG("sk %p, rsp %p, len %d", sk, rsp, len);
1926
1927 if ((pi->mode != L2CAP_MODE_ERTM) && (pi->mode != L2CAP_MODE_STREAMING))
1928 return;
1929
1930 while (len >= L2CAP_CONF_OPT_SIZE) {
1931 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
1932
1933 switch (type) {
1934 case L2CAP_CONF_RFC:
1935 if (olen == sizeof(rfc))
1936 memcpy(&rfc, (void *)val, olen);
1937 goto done;
1938 }
1939 }
1940
1941done:
1942 switch (rfc.mode) {
1943 case L2CAP_MODE_ERTM:
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03001944 pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
1945 pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03001946 pi->mps = le16_to_cpu(rfc.max_pdu_size);
1947 break;
1948 case L2CAP_MODE_STREAMING:
1949 pi->mps = le16_to_cpu(rfc.max_pdu_size);
1950 }
1951}
1952
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001953static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
1954{
1955 struct l2cap_cmd_rej *rej = (struct l2cap_cmd_rej *) data;
1956
1957 if (rej->reason != 0x0000)
1958 return 0;
1959
1960 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
1961 cmd->ident == conn->info_ident) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001962 del_timer(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01001963
1964 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01001965 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01001966
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001967 l2cap_conn_start(conn);
1968 }
1969
1970 return 0;
1971}
1972
Linus Torvalds1da177e2005-04-16 15:20:36 -07001973static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
1974{
1975 struct l2cap_chan_list *list = &conn->chan_list;
1976 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
1977 struct l2cap_conn_rsp rsp;
Nathan Holsteind793fe82010-10-15 11:54:02 -04001978 struct sock *parent, *sk = NULL;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02001979 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001980
1981 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02001982 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001983
1984 BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
1985
1986 /* Check if we have socket listening on psm */
1987 parent = l2cap_get_sock_by_psm(BT_LISTEN, psm, conn->src);
1988 if (!parent) {
1989 result = L2CAP_CR_BAD_PSM;
1990 goto sendresp;
1991 }
1992
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001993 bh_lock_sock(parent);
1994
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02001995 /* Check if the ACL is secure enough (if not SDP) */
1996 if (psm != cpu_to_le16(0x0001) &&
1997 !hci_conn_check_link_mode(conn->hcon)) {
Marcel Holtmann2950f212009-02-12 14:02:50 +01001998 conn->disc_reason = 0x05;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02001999 result = L2CAP_CR_SEC_BLOCK;
2000 goto response;
2001 }
2002
Linus Torvalds1da177e2005-04-16 15:20:36 -07002003 result = L2CAP_CR_NO_MEM;
2004
2005 /* Check for backlog size */
2006 if (sk_acceptq_is_full(parent)) {
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09002007 BT_DBG("backlog full %d", parent->sk_ack_backlog);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002008 goto response;
2009 }
2010
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09002011 sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002012 if (!sk)
2013 goto response;
2014
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002015 write_lock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002016
2017 /* Check if we already have channel with that dcid */
2018 if (__l2cap_get_chan_by_dcid(list, scid)) {
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002019 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002020 sock_set_flag(sk, SOCK_ZAPPED);
2021 l2cap_sock_kill(sk);
2022 goto response;
2023 }
2024
2025 hci_conn_hold(conn->hcon);
2026
2027 l2cap_sock_init(sk, parent);
2028 bacpy(&bt_sk(sk)->src, conn->src);
2029 bacpy(&bt_sk(sk)->dst, conn->dst);
2030 l2cap_pi(sk)->psm = psm;
2031 l2cap_pi(sk)->dcid = scid;
2032
2033 __l2cap_chan_add(conn, sk, parent);
2034 dcid = l2cap_pi(sk)->scid;
2035
2036 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
2037
Linus Torvalds1da177e2005-04-16 15:20:36 -07002038 l2cap_pi(sk)->ident = cmd->ident;
2039
Marcel Holtmann984947d2009-02-06 23:35:19 +01002040 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002041 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002042 if (bt_sk(sk)->defer_setup) {
2043 sk->sk_state = BT_CONNECT2;
2044 result = L2CAP_CR_PEND;
2045 status = L2CAP_CS_AUTHOR_PEND;
2046 parent->sk_data_ready(parent, 0);
2047 } else {
2048 sk->sk_state = BT_CONFIG;
2049 result = L2CAP_CR_SUCCESS;
2050 status = L2CAP_CS_NO_INFO;
2051 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002052 } else {
2053 sk->sk_state = BT_CONNECT2;
2054 result = L2CAP_CR_PEND;
2055 status = L2CAP_CS_AUTHEN_PEND;
2056 }
2057 } else {
2058 sk->sk_state = BT_CONNECT2;
2059 result = L2CAP_CR_PEND;
2060 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002061 }
2062
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002063 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002064
2065response:
2066 bh_unlock_sock(parent);
2067
2068sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002069 rsp.scid = cpu_to_le16(scid);
2070 rsp.dcid = cpu_to_le16(dcid);
2071 rsp.result = cpu_to_le16(result);
2072 rsp.status = cpu_to_le16(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002073 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002074
2075 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
2076 struct l2cap_info_req info;
2077 info.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
2078
2079 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
2080 conn->info_ident = l2cap_get_ident(conn);
2081
2082 mod_timer(&conn->info_timer, jiffies +
2083 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
2084
2085 l2cap_send_cmd(conn, conn->info_ident,
2086 L2CAP_INFO_REQ, sizeof(info), &info);
2087 }
2088
Nathan Holsteind793fe82010-10-15 11:54:02 -04002089 if (sk && !(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) &&
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03002090 result == L2CAP_CR_SUCCESS) {
2091 u8 buf[128];
2092 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
2093 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
2094 l2cap_build_conf_req(sk, buf), buf);
2095 l2cap_pi(sk)->num_conf_req++;
2096 }
2097
Linus Torvalds1da177e2005-04-16 15:20:36 -07002098 return 0;
2099}
2100
2101static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2102{
2103 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
2104 u16 scid, dcid, result, status;
2105 struct sock *sk;
2106 u8 req[128];
2107
2108 scid = __le16_to_cpu(rsp->scid);
2109 dcid = __le16_to_cpu(rsp->dcid);
2110 result = __le16_to_cpu(rsp->result);
2111 status = __le16_to_cpu(rsp->status);
2112
2113 BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
2114
2115 if (scid) {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002116 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2117 if (!sk)
João Paulo Rechi Vita57d3b222010-06-22 13:56:26 -03002118 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002119 } else {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002120 sk = l2cap_get_chan_by_ident(&conn->chan_list, cmd->ident);
2121 if (!sk)
João Paulo Rechi Vita57d3b222010-06-22 13:56:26 -03002122 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002123 }
2124
2125 switch (result) {
2126 case L2CAP_CR_SUCCESS:
2127 sk->sk_state = BT_CONFIG;
2128 l2cap_pi(sk)->ident = 0;
2129 l2cap_pi(sk)->dcid = dcid;
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002130 l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_CONNECT_PEND;
2131
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03002132 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)
2133 break;
2134
2135 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
2136
Linus Torvalds1da177e2005-04-16 15:20:36 -07002137 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
2138 l2cap_build_conf_req(sk, req), req);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002139 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002140 break;
2141
2142 case L2CAP_CR_PEND:
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002143 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002144 break;
2145
2146 default:
Andrei Emeltchenkoa49184c2010-11-03 12:32:44 +02002147 /* don't delete l2cap channel if sk is owned by user */
2148 if (sock_owned_by_user(sk)) {
2149 sk->sk_state = BT_DISCONN;
2150 l2cap_sock_clear_timer(sk);
2151 l2cap_sock_set_timer(sk, HZ / 5);
2152 break;
2153 }
2154
Linus Torvalds1da177e2005-04-16 15:20:36 -07002155 l2cap_chan_del(sk, ECONNREFUSED);
2156 break;
2157 }
2158
2159 bh_unlock_sock(sk);
2160 return 0;
2161}
2162
Mat Martineau8c462b62010-08-24 15:35:42 -07002163static inline void set_default_fcs(struct l2cap_pinfo *pi)
2164{
2165 /* FCS is enabled only in ERTM or streaming mode, if one or both
2166 * sides request it.
2167 */
2168 if (pi->mode != L2CAP_MODE_ERTM && pi->mode != L2CAP_MODE_STREAMING)
2169 pi->fcs = L2CAP_FCS_NONE;
2170 else if (!(pi->conf_state & L2CAP_CONF_NO_FCS_RECV))
2171 pi->fcs = L2CAP_FCS_CRC16;
2172}
2173
Al Viro88219a02007-07-29 00:17:25 -07002174static 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 -07002175{
2176 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
2177 u16 dcid, flags;
2178 u8 rsp[64];
2179 struct sock *sk;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002180 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002181
2182 dcid = __le16_to_cpu(req->dcid);
2183 flags = __le16_to_cpu(req->flags);
2184
2185 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
2186
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002187 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
2188 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002189 return -ENOENT;
2190
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03002191 if (sk->sk_state != BT_CONFIG) {
2192 struct l2cap_cmd_rej rej;
2193
2194 rej.reason = cpu_to_le16(0x0002);
2195 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
2196 sizeof(rej), &rej);
Marcel Holtmann354f60a2006-11-18 22:15:20 +01002197 goto unlock;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03002198 }
Marcel Holtmann354f60a2006-11-18 22:15:20 +01002199
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002200 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07002201 len = cmd_len - sizeof(*req);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002202 if (l2cap_pi(sk)->conf_len + len > sizeof(l2cap_pi(sk)->conf_req)) {
2203 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
2204 l2cap_build_conf_rsp(sk, rsp,
2205 L2CAP_CONF_REJECT, flags), rsp);
2206 goto unlock;
2207 }
2208
2209 /* Store config. */
2210 memcpy(l2cap_pi(sk)->conf_req + l2cap_pi(sk)->conf_len, req->data, len);
2211 l2cap_pi(sk)->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002212
2213 if (flags & 0x0001) {
2214 /* Incomplete config. Send empty response. */
2215 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002216 l2cap_build_conf_rsp(sk, rsp,
2217 L2CAP_CONF_SUCCESS, 0x0001), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002218 goto unlock;
2219 }
2220
2221 /* Complete config. */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002222 len = l2cap_parse_conf_req(sk, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002223 if (len < 0) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03002224 l2cap_send_disconn_req(conn, sk, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002225 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002226 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002227
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002228 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002229 l2cap_pi(sk)->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002230
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002231 /* Reset config buffer. */
2232 l2cap_pi(sk)->conf_len = 0;
2233
Marcel Holtmann876d9482007-10-20 13:35:42 +02002234 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE))
2235 goto unlock;
2236
Linus Torvalds1da177e2005-04-16 15:20:36 -07002237 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) {
Mat Martineau8c462b62010-08-24 15:35:42 -07002238 set_default_fcs(l2cap_pi(sk));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002239
Linus Torvalds1da177e2005-04-16 15:20:36 -07002240 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002241
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002242 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002243 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002244 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002245 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
2246 l2cap_ertm_init(sk);
2247
Linus Torvalds1da177e2005-04-16 15:20:36 -07002248 l2cap_chan_ready(sk);
Marcel Holtmann876d9482007-10-20 13:35:42 +02002249 goto unlock;
2250 }
2251
2252 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002253 u8 buf[64];
Haijun Liuab3e5712010-09-30 16:52:40 +08002254 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002255 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002256 l2cap_build_conf_req(sk, buf), buf);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002257 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002258 }
2259
2260unlock:
2261 bh_unlock_sock(sk);
2262 return 0;
2263}
2264
2265static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2266{
2267 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
2268 u16 scid, flags, result;
2269 struct sock *sk;
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002270 int len = cmd->len - sizeof(*rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002271
2272 scid = __le16_to_cpu(rsp->scid);
2273 flags = __le16_to_cpu(rsp->flags);
2274 result = __le16_to_cpu(rsp->result);
2275
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002276 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x",
2277 scid, flags, result);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002278
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002279 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2280 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002281 return 0;
2282
2283 switch (result) {
2284 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002285 l2cap_conf_rfc_get(sk, rsp->data, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002286 break;
2287
2288 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002289 if (l2cap_pi(sk)->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002290 char req[64];
2291
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02002292 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03002293 l2cap_send_disconn_req(conn, sk, ECONNRESET);
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02002294 goto done;
2295 }
2296
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002297 /* throw out any old stored conf requests */
2298 result = L2CAP_CONF_SUCCESS;
2299 len = l2cap_parse_conf_rsp(sk, rsp->data,
2300 len, req, &result);
2301 if (len < 0) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03002302 l2cap_send_disconn_req(conn, sk, ECONNRESET);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002303 goto done;
2304 }
2305
2306 l2cap_send_cmd(conn, l2cap_get_ident(conn),
2307 L2CAP_CONF_REQ, len, req);
2308 l2cap_pi(sk)->num_conf_req++;
2309 if (result != L2CAP_CONF_SUCCESS)
2310 goto done;
2311 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002312 }
2313
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09002314 default:
Marcel Holtmannb1235d72008-07-14 20:13:54 +02002315 sk->sk_err = ECONNRESET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002316 l2cap_sock_set_timer(sk, HZ * 5);
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03002317 l2cap_send_disconn_req(conn, sk, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002318 goto done;
2319 }
2320
2321 if (flags & 0x01)
2322 goto done;
2323
Linus Torvalds1da177e2005-04-16 15:20:36 -07002324 l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE;
2325
2326 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) {
Mat Martineau8c462b62010-08-24 15:35:42 -07002327 set_default_fcs(l2cap_pi(sk));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002328
Linus Torvalds1da177e2005-04-16 15:20:36 -07002329 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002330 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002331 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002332 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002333 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
2334 l2cap_ertm_init(sk);
2335
Linus Torvalds1da177e2005-04-16 15:20:36 -07002336 l2cap_chan_ready(sk);
2337 }
2338
2339done:
2340 bh_unlock_sock(sk);
2341 return 0;
2342}
2343
2344static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2345{
2346 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
2347 struct l2cap_disconn_rsp rsp;
2348 u16 dcid, scid;
2349 struct sock *sk;
2350
2351 scid = __le16_to_cpu(req->scid);
2352 dcid = __le16_to_cpu(req->dcid);
2353
2354 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
2355
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002356 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
2357 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002358 return 0;
2359
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002360 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
2361 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002362 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
2363
2364 sk->sk_shutdown = SHUTDOWN_MASK;
2365
Andrei Emeltchenkoa49184c2010-11-03 12:32:44 +02002366 /* don't delete l2cap channel if sk is owned by user */
2367 if (sock_owned_by_user(sk)) {
2368 sk->sk_state = BT_DISCONN;
2369 l2cap_sock_clear_timer(sk);
2370 l2cap_sock_set_timer(sk, HZ / 5);
2371 bh_unlock_sock(sk);
2372 return 0;
2373 }
2374
Linus Torvalds1da177e2005-04-16 15:20:36 -07002375 l2cap_chan_del(sk, ECONNRESET);
2376 bh_unlock_sock(sk);
2377
2378 l2cap_sock_kill(sk);
2379 return 0;
2380}
2381
2382static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2383{
2384 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
2385 u16 dcid, scid;
2386 struct sock *sk;
2387
2388 scid = __le16_to_cpu(rsp->scid);
2389 dcid = __le16_to_cpu(rsp->dcid);
2390
2391 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
2392
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002393 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2394 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002395 return 0;
2396
Andrei Emeltchenkoa49184c2010-11-03 12:32:44 +02002397 /* don't delete l2cap channel if sk is owned by user */
2398 if (sock_owned_by_user(sk)) {
2399 sk->sk_state = BT_DISCONN;
2400 l2cap_sock_clear_timer(sk);
2401 l2cap_sock_set_timer(sk, HZ / 5);
2402 bh_unlock_sock(sk);
2403 return 0;
2404 }
2405
Linus Torvalds1da177e2005-04-16 15:20:36 -07002406 l2cap_chan_del(sk, 0);
2407 bh_unlock_sock(sk);
2408
2409 l2cap_sock_kill(sk);
2410 return 0;
2411}
2412
2413static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2414{
2415 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002416 u16 type;
2417
2418 type = __le16_to_cpu(req->type);
2419
2420 BT_DBG("type 0x%4.4x", type);
2421
Marcel Holtmannf0709e02007-10-20 13:38:51 +02002422 if (type == L2CAP_IT_FEAT_MASK) {
2423 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07002424 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02002425 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
2426 rsp->type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
2427 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03002428 if (!disable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002429 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
2430 | L2CAP_FEAT_FCS;
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03002431 put_unaligned_le32(feat_mask, rsp->data);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02002432 l2cap_send_cmd(conn, cmd->ident,
2433 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002434 } else if (type == L2CAP_IT_FIXED_CHAN) {
2435 u8 buf[12];
2436 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
2437 rsp->type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
2438 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
2439 memcpy(buf + 4, l2cap_fixed_chan, 8);
2440 l2cap_send_cmd(conn, cmd->ident,
2441 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02002442 } else {
2443 struct l2cap_info_rsp rsp;
2444 rsp.type = cpu_to_le16(type);
2445 rsp.result = cpu_to_le16(L2CAP_IR_NOTSUPP);
2446 l2cap_send_cmd(conn, cmd->ident,
2447 L2CAP_INFO_RSP, sizeof(rsp), &rsp);
2448 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002449
2450 return 0;
2451}
2452
2453static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2454{
2455 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
2456 u16 type, result;
2457
2458 type = __le16_to_cpu(rsp->type);
2459 result = __le16_to_cpu(rsp->result);
2460
2461 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
2462
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002463 del_timer(&conn->info_timer);
2464
Ville Tervoadb08ed2010-08-04 09:43:33 +03002465 if (result != L2CAP_IR_SUCCESS) {
2466 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
2467 conn->info_ident = 0;
2468
2469 l2cap_conn_start(conn);
2470
2471 return 0;
2472 }
2473
Marcel Holtmann984947d2009-02-06 23:35:19 +01002474 if (type == L2CAP_IT_FEAT_MASK) {
Harvey Harrison83985312008-05-02 16:25:46 -07002475 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002476
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07002477 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002478 struct l2cap_info_req req;
2479 req.type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
2480
2481 conn->info_ident = l2cap_get_ident(conn);
2482
2483 l2cap_send_cmd(conn, conn->info_ident,
2484 L2CAP_INFO_REQ, sizeof(req), &req);
2485 } else {
2486 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
2487 conn->info_ident = 0;
2488
2489 l2cap_conn_start(conn);
2490 }
2491 } else if (type == L2CAP_IT_FIXED_CHAN) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01002492 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002493 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01002494
2495 l2cap_conn_start(conn);
2496 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002497
Linus Torvalds1da177e2005-04-16 15:20:36 -07002498 return 0;
2499}
2500
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03002501static inline int l2cap_check_conn_param(u16 min, u16 max, u16 latency,
Claudio Takahaside731152011-02-11 19:28:55 -02002502 u16 to_multiplier)
2503{
2504 u16 max_latency;
2505
2506 if (min > max || min < 6 || max > 3200)
2507 return -EINVAL;
2508
2509 if (to_multiplier < 10 || to_multiplier > 3200)
2510 return -EINVAL;
2511
2512 if (max >= to_multiplier * 8)
2513 return -EINVAL;
2514
2515 max_latency = (to_multiplier * 8 / max) - 1;
2516 if (latency > 499 || latency > max_latency)
2517 return -EINVAL;
2518
2519 return 0;
2520}
2521
2522static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
2523 struct l2cap_cmd_hdr *cmd, u8 *data)
2524{
2525 struct hci_conn *hcon = conn->hcon;
2526 struct l2cap_conn_param_update_req *req;
2527 struct l2cap_conn_param_update_rsp rsp;
2528 u16 min, max, latency, to_multiplier, cmd_len;
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02002529 int err;
Claudio Takahaside731152011-02-11 19:28:55 -02002530
2531 if (!(hcon->link_mode & HCI_LM_MASTER))
2532 return -EINVAL;
2533
2534 cmd_len = __le16_to_cpu(cmd->len);
2535 if (cmd_len != sizeof(struct l2cap_conn_param_update_req))
2536 return -EPROTO;
2537
2538 req = (struct l2cap_conn_param_update_req *) data;
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03002539 min = __le16_to_cpu(req->min);
2540 max = __le16_to_cpu(req->max);
Claudio Takahaside731152011-02-11 19:28:55 -02002541 latency = __le16_to_cpu(req->latency);
2542 to_multiplier = __le16_to_cpu(req->to_multiplier);
2543
2544 BT_DBG("min 0x%4.4x max 0x%4.4x latency: 0x%4.4x Timeout: 0x%4.4x",
2545 min, max, latency, to_multiplier);
2546
2547 memset(&rsp, 0, sizeof(rsp));
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02002548
2549 err = l2cap_check_conn_param(min, max, latency, to_multiplier);
2550 if (err)
Claudio Takahaside731152011-02-11 19:28:55 -02002551 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
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02002558 if (!err)
2559 hci_le_conn_update(hcon, min, max, latency, to_multiplier);
2560
Claudio Takahaside731152011-02-11 19:28:55 -02002561 return 0;
2562}
2563
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002564static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
2565 struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
2566{
2567 int err = 0;
2568
2569 switch (cmd->code) {
2570 case L2CAP_COMMAND_REJ:
2571 l2cap_command_rej(conn, cmd, data);
2572 break;
2573
2574 case L2CAP_CONN_REQ:
2575 err = l2cap_connect_req(conn, cmd, data);
2576 break;
2577
2578 case L2CAP_CONN_RSP:
2579 err = l2cap_connect_rsp(conn, cmd, data);
2580 break;
2581
2582 case L2CAP_CONF_REQ:
2583 err = l2cap_config_req(conn, cmd, cmd_len, data);
2584 break;
2585
2586 case L2CAP_CONF_RSP:
2587 err = l2cap_config_rsp(conn, cmd, data);
2588 break;
2589
2590 case L2CAP_DISCONN_REQ:
2591 err = l2cap_disconnect_req(conn, cmd, data);
2592 break;
2593
2594 case L2CAP_DISCONN_RSP:
2595 err = l2cap_disconnect_rsp(conn, cmd, data);
2596 break;
2597
2598 case L2CAP_ECHO_REQ:
2599 l2cap_send_cmd(conn, cmd->ident, L2CAP_ECHO_RSP, cmd_len, data);
2600 break;
2601
2602 case L2CAP_ECHO_RSP:
2603 break;
2604
2605 case L2CAP_INFO_REQ:
2606 err = l2cap_information_req(conn, cmd, data);
2607 break;
2608
2609 case L2CAP_INFO_RSP:
2610 err = l2cap_information_rsp(conn, cmd, data);
2611 break;
2612
2613 default:
2614 BT_ERR("Unknown BR/EDR signaling command 0x%2.2x", cmd->code);
2615 err = -EINVAL;
2616 break;
2617 }
2618
2619 return err;
2620}
2621
2622static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn,
2623 struct l2cap_cmd_hdr *cmd, u8 *data)
2624{
2625 switch (cmd->code) {
2626 case L2CAP_COMMAND_REJ:
2627 return 0;
2628
2629 case L2CAP_CONN_PARAM_UPDATE_REQ:
Claudio Takahaside731152011-02-11 19:28:55 -02002630 return l2cap_conn_param_update_req(conn, cmd, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002631
2632 case L2CAP_CONN_PARAM_UPDATE_RSP:
2633 return 0;
2634
2635 default:
2636 BT_ERR("Unknown LE signaling command 0x%2.2x", cmd->code);
2637 return -EINVAL;
2638 }
2639}
2640
2641static inline void l2cap_sig_channel(struct l2cap_conn *conn,
2642 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002643{
2644 u8 *data = skb->data;
2645 int len = skb->len;
2646 struct l2cap_cmd_hdr cmd;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002647 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002648
2649 l2cap_raw_recv(conn, skb);
2650
2651 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07002652 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002653 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
2654 data += L2CAP_CMD_HDR_SIZE;
2655 len -= L2CAP_CMD_HDR_SIZE;
2656
Al Viro88219a02007-07-29 00:17:25 -07002657 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002658
Al Viro88219a02007-07-29 00:17:25 -07002659 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 -07002660
Al Viro88219a02007-07-29 00:17:25 -07002661 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002662 BT_DBG("corrupted command");
2663 break;
2664 }
2665
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002666 if (conn->hcon->type == LE_LINK)
2667 err = l2cap_le_sig_cmd(conn, &cmd, data);
2668 else
2669 err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002670
2671 if (err) {
2672 struct l2cap_cmd_rej rej;
Gustavo F. Padovan2c6d1a22011-03-23 14:38:32 -03002673
2674 BT_ERR("Wrong link type (%d)", err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002675
2676 /* FIXME: Map err to a valid reason */
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002677 rej.reason = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002678 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
2679 }
2680
Al Viro88219a02007-07-29 00:17:25 -07002681 data += cmd_len;
2682 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002683 }
2684
2685 kfree_skb(skb);
2686}
2687
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002688static int l2cap_check_fcs(struct l2cap_pinfo *pi, struct sk_buff *skb)
2689{
2690 u16 our_fcs, rcv_fcs;
2691 int hdr_size = L2CAP_HDR_SIZE + 2;
2692
2693 if (pi->fcs == L2CAP_FCS_CRC16) {
2694 skb_trim(skb, skb->len - 2);
2695 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
2696 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
2697
2698 if (our_fcs != rcv_fcs)
João Paulo Rechi Vita7a560e52010-06-22 13:56:27 -03002699 return -EBADMSG;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002700 }
2701 return 0;
2702}
2703
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03002704static inline void l2cap_send_i_or_rr_or_rnr(struct sock *sk)
2705{
2706 struct l2cap_pinfo *pi = l2cap_pi(sk);
2707 u16 control = 0;
2708
2709 pi->frames_sent = 0;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03002710
2711 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
2712
2713 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
Gustavo F. Padovan64988862010-05-10 14:54:14 -03002714 control |= L2CAP_SUPER_RCV_NOT_READY;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03002715 l2cap_send_sframe(pi, control);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002716 pi->conn_state |= L2CAP_CONN_RNR_SENT;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03002717 }
2718
Gustavo F. Padovan4ea727e2010-06-03 16:34:20 -03002719 if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY)
2720 l2cap_retransmit_frames(sk);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03002721
2722 l2cap_ertm_send(sk);
2723
2724 if (!(pi->conn_state & L2CAP_CONN_LOCAL_BUSY) &&
2725 pi->frames_sent == 0) {
2726 control |= L2CAP_SUPER_RCV_READY;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03002727 l2cap_send_sframe(pi, control);
2728 }
2729}
2730
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03002731static 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 -03002732{
2733 struct sk_buff *next_skb;
João Paulo Rechi Vitabfbacc12010-05-31 18:35:44 -03002734 struct l2cap_pinfo *pi = l2cap_pi(sk);
2735 int tx_seq_offset, next_tx_seq_offset;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03002736
2737 bt_cb(skb)->tx_seq = tx_seq;
2738 bt_cb(skb)->sar = sar;
2739
2740 next_skb = skb_peek(SREJ_QUEUE(sk));
2741 if (!next_skb) {
2742 __skb_queue_tail(SREJ_QUEUE(sk), skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03002743 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03002744 }
2745
João Paulo Rechi Vitabfbacc12010-05-31 18:35:44 -03002746 tx_seq_offset = (tx_seq - pi->buffer_seq) % 64;
2747 if (tx_seq_offset < 0)
2748 tx_seq_offset += 64;
2749
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03002750 do {
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03002751 if (bt_cb(next_skb)->tx_seq == tx_seq)
2752 return -EINVAL;
2753
João Paulo Rechi Vitabfbacc12010-05-31 18:35:44 -03002754 next_tx_seq_offset = (bt_cb(next_skb)->tx_seq -
2755 pi->buffer_seq) % 64;
2756 if (next_tx_seq_offset < 0)
2757 next_tx_seq_offset += 64;
2758
2759 if (next_tx_seq_offset > tx_seq_offset) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03002760 __skb_queue_before(SREJ_QUEUE(sk), next_skb, skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03002761 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03002762 }
2763
2764 if (skb_queue_is_last(SREJ_QUEUE(sk), next_skb))
2765 break;
2766
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03002767 } while ((next_skb = skb_queue_next(SREJ_QUEUE(sk), next_skb)));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03002768
2769 __skb_queue_tail(SREJ_QUEUE(sk), skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03002770
2771 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03002772}
2773
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002774static int l2cap_ertm_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
2775{
2776 struct l2cap_pinfo *pi = l2cap_pi(sk);
2777 struct sk_buff *_skb;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002778 int err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002779
2780 switch (control & L2CAP_CTRL_SAR) {
2781 case L2CAP_SDU_UNSEGMENTED:
2782 if (pi->conn_state & L2CAP_CONN_SAR_SDU)
2783 goto drop;
2784
2785 err = sock_queue_rcv_skb(sk, skb);
2786 if (!err)
2787 return err;
2788
2789 break;
2790
2791 case L2CAP_SDU_START:
2792 if (pi->conn_state & L2CAP_CONN_SAR_SDU)
2793 goto drop;
2794
2795 pi->sdu_len = get_unaligned_le16(skb->data);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002796
2797 if (pi->sdu_len > pi->imtu)
2798 goto disconnect;
2799
2800 pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002801 if (!pi->sdu)
2802 return -ENOMEM;
2803
2804 /* pull sdu_len bytes only after alloc, because of Local Busy
2805 * condition we have to be sure that this will be executed
2806 * only once, i.e., when alloc does not fail */
2807 skb_pull(skb, 2);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002808
2809 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
2810
2811 pi->conn_state |= L2CAP_CONN_SAR_SDU;
2812 pi->partial_sdu_len = skb->len;
2813 break;
2814
2815 case L2CAP_SDU_CONTINUE:
2816 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
2817 goto disconnect;
2818
2819 if (!pi->sdu)
2820 goto disconnect;
2821
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002822 pi->partial_sdu_len += skb->len;
2823 if (pi->partial_sdu_len > pi->sdu_len)
2824 goto drop;
2825
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03002826 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
2827
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002828 break;
2829
2830 case L2CAP_SDU_END:
2831 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
2832 goto disconnect;
2833
2834 if (!pi->sdu)
2835 goto disconnect;
2836
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002837 if (!(pi->conn_state & L2CAP_CONN_SAR_RETRY)) {
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002838 pi->partial_sdu_len += skb->len;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002839
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002840 if (pi->partial_sdu_len > pi->imtu)
2841 goto drop;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002842
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002843 if (pi->partial_sdu_len != pi->sdu_len)
2844 goto drop;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03002845
2846 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002847 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002848
2849 _skb = skb_clone(pi->sdu, GFP_ATOMIC);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002850 if (!_skb) {
2851 pi->conn_state |= L2CAP_CONN_SAR_RETRY;
2852 return -ENOMEM;
2853 }
2854
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002855 err = sock_queue_rcv_skb(sk, _skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002856 if (err < 0) {
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002857 kfree_skb(_skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002858 pi->conn_state |= L2CAP_CONN_SAR_RETRY;
2859 return err;
2860 }
2861
2862 pi->conn_state &= ~L2CAP_CONN_SAR_RETRY;
2863 pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002864
2865 kfree_skb(pi->sdu);
2866 break;
2867 }
2868
2869 kfree_skb(skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002870 return 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002871
2872drop:
2873 kfree_skb(pi->sdu);
2874 pi->sdu = NULL;
2875
2876disconnect:
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03002877 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002878 kfree_skb(skb);
2879 return 0;
2880}
2881
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03002882static int l2cap_try_push_rx_skb(struct sock *sk)
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002883{
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03002884 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002885 struct sk_buff *skb;
2886 u16 control;
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03002887 int err;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002888
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03002889 while ((skb = skb_dequeue(BUSY_QUEUE(sk)))) {
2890 control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
2891 err = l2cap_ertm_reassembly_sdu(sk, skb, control);
2892 if (err < 0) {
2893 skb_queue_head(BUSY_QUEUE(sk), skb);
2894 return -EBUSY;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002895 }
2896
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03002897 pi->buffer_seq = (pi->buffer_seq + 1) % 64;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002898 }
2899
2900 if (!(pi->conn_state & L2CAP_CONN_RNR_SENT))
2901 goto done;
2902
2903 control = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
2904 control |= L2CAP_SUPER_RCV_READY | L2CAP_CTRL_POLL;
2905 l2cap_send_sframe(pi, control);
2906 l2cap_pi(sk)->retry_count = 1;
2907
2908 del_timer(&pi->retrans_timer);
2909 __mod_monitor_timer();
2910
2911 l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
2912
2913done:
2914 pi->conn_state &= ~L2CAP_CONN_LOCAL_BUSY;
2915 pi->conn_state &= ~L2CAP_CONN_RNR_SENT;
2916
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03002917 BT_DBG("sk %p, Exit local busy", sk);
2918
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03002919 return 0;
2920}
2921
2922static void l2cap_busy_work(struct work_struct *work)
2923{
2924 DECLARE_WAITQUEUE(wait, current);
2925 struct l2cap_pinfo *pi =
2926 container_of(work, struct l2cap_pinfo, busy_work);
2927 struct sock *sk = (struct sock *)pi;
2928 int n_tries = 0, timeo = HZ/5, err;
2929 struct sk_buff *skb;
2930
2931 lock_sock(sk);
2932
2933 add_wait_queue(sk_sleep(sk), &wait);
2934 while ((skb = skb_peek(BUSY_QUEUE(sk)))) {
2935 set_current_state(TASK_INTERRUPTIBLE);
2936
2937 if (n_tries++ > L2CAP_LOCAL_BUSY_TRIES) {
2938 err = -EBUSY;
2939 l2cap_send_disconn_req(pi->conn, sk, EBUSY);
2940 break;
2941 }
2942
2943 if (!timeo)
2944 timeo = HZ/5;
2945
2946 if (signal_pending(current)) {
2947 err = sock_intr_errno(timeo);
2948 break;
2949 }
2950
2951 release_sock(sk);
2952 timeo = schedule_timeout(timeo);
2953 lock_sock(sk);
2954
2955 err = sock_error(sk);
2956 if (err)
2957 break;
2958
2959 if (l2cap_try_push_rx_skb(sk) == 0)
2960 break;
2961 }
2962
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002963 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02002964 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002965
2966 release_sock(sk);
2967}
2968
2969static int l2cap_push_rx_skb(struct sock *sk, struct sk_buff *skb, u16 control)
2970{
2971 struct l2cap_pinfo *pi = l2cap_pi(sk);
2972 int sctrl, err;
2973
2974 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
2975 bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT;
2976 __skb_queue_tail(BUSY_QUEUE(sk), skb);
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03002977 return l2cap_try_push_rx_skb(sk);
2978
2979
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002980 }
2981
2982 err = l2cap_ertm_reassembly_sdu(sk, skb, control);
2983 if (err >= 0) {
2984 pi->buffer_seq = (pi->buffer_seq + 1) % 64;
2985 return err;
2986 }
2987
2988 /* Busy Condition */
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03002989 BT_DBG("sk %p, Enter local busy", sk);
2990
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002991 pi->conn_state |= L2CAP_CONN_LOCAL_BUSY;
2992 bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT;
2993 __skb_queue_tail(BUSY_QUEUE(sk), skb);
2994
2995 sctrl = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
2996 sctrl |= L2CAP_SUPER_RCV_NOT_READY;
2997 l2cap_send_sframe(pi, sctrl);
2998
2999 pi->conn_state |= L2CAP_CONN_RNR_SENT;
3000
Gustavo F. Padovan7fe9b292010-05-12 18:32:04 -03003001 del_timer(&pi->ack_timer);
3002
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003003 queue_work(_busy_wq, &pi->busy_work);
3004
3005 return err;
3006}
3007
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003008static int l2cap_streaming_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003009{
3010 struct l2cap_pinfo *pi = l2cap_pi(sk);
3011 struct sk_buff *_skb;
3012 int err = -EINVAL;
3013
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003014 /*
3015 * TODO: We have to notify the userland if some data is lost with the
3016 * Streaming Mode.
3017 */
3018
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003019 switch (control & L2CAP_CTRL_SAR) {
3020 case L2CAP_SDU_UNSEGMENTED:
3021 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3022 kfree_skb(pi->sdu);
3023 break;
3024 }
3025
3026 err = sock_queue_rcv_skb(sk, skb);
3027 if (!err)
3028 return 0;
3029
3030 break;
3031
3032 case L2CAP_SDU_START:
3033 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3034 kfree_skb(pi->sdu);
3035 break;
3036 }
3037
3038 pi->sdu_len = get_unaligned_le16(skb->data);
3039 skb_pull(skb, 2);
3040
Gustavo F. Padovan052897c2010-05-01 16:15:40 -03003041 if (pi->sdu_len > pi->imtu) {
3042 err = -EMSGSIZE;
3043 break;
3044 }
3045
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003046 pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
3047 if (!pi->sdu) {
3048 err = -ENOMEM;
3049 break;
3050 }
3051
3052 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3053
3054 pi->conn_state |= L2CAP_CONN_SAR_SDU;
3055 pi->partial_sdu_len = skb->len;
3056 err = 0;
3057 break;
3058
3059 case L2CAP_SDU_CONTINUE:
3060 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3061 break;
3062
3063 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3064
3065 pi->partial_sdu_len += skb->len;
3066 if (pi->partial_sdu_len > pi->sdu_len)
3067 kfree_skb(pi->sdu);
3068 else
3069 err = 0;
3070
3071 break;
3072
3073 case L2CAP_SDU_END:
3074 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3075 break;
3076
3077 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3078
3079 pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
3080 pi->partial_sdu_len += skb->len;
3081
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003082 if (pi->partial_sdu_len > pi->imtu)
3083 goto drop;
3084
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003085 if (pi->partial_sdu_len == pi->sdu_len) {
3086 _skb = skb_clone(pi->sdu, GFP_ATOMIC);
3087 err = sock_queue_rcv_skb(sk, _skb);
3088 if (err < 0)
3089 kfree_skb(_skb);
3090 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003091 err = 0;
3092
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003093drop:
3094 kfree_skb(pi->sdu);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003095 break;
3096 }
3097
3098 kfree_skb(skb);
3099 return err;
3100}
3101
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003102static void l2cap_check_srej_gap(struct sock *sk, u8 tx_seq)
3103{
3104 struct sk_buff *skb;
Gustavo F. Padovanafefdbc2010-05-01 16:15:43 -03003105 u16 control;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003106
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003107 while ((skb = skb_peek(SREJ_QUEUE(sk)))) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003108 if (bt_cb(skb)->tx_seq != tx_seq)
3109 break;
3110
3111 skb = skb_dequeue(SREJ_QUEUE(sk));
Gustavo F. Padovanafefdbc2010-05-01 16:15:43 -03003112 control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003113 l2cap_ertm_reassembly_sdu(sk, skb, control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003114 l2cap_pi(sk)->buffer_seq_srej =
3115 (l2cap_pi(sk)->buffer_seq_srej + 1) % 64;
Gustavo F. Padovan8ff50ec2010-05-10 19:34:11 -03003116 tx_seq = (tx_seq + 1) % 64;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003117 }
3118}
3119
3120static void l2cap_resend_srejframe(struct sock *sk, u8 tx_seq)
3121{
3122 struct l2cap_pinfo *pi = l2cap_pi(sk);
3123 struct srej_list *l, *tmp;
3124 u16 control;
3125
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003126 list_for_each_entry_safe(l, tmp, SREJ_LIST(sk), list) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003127 if (l->tx_seq == tx_seq) {
3128 list_del(&l->list);
3129 kfree(l);
3130 return;
3131 }
3132 control = L2CAP_SUPER_SELECT_REJECT;
3133 control |= l->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3134 l2cap_send_sframe(pi, control);
3135 list_del(&l->list);
3136 list_add_tail(&l->list, SREJ_LIST(sk));
3137 }
3138}
3139
3140static void l2cap_send_srejframe(struct sock *sk, u8 tx_seq)
3141{
3142 struct l2cap_pinfo *pi = l2cap_pi(sk);
3143 struct srej_list *new;
3144 u16 control;
3145
3146 while (tx_seq != pi->expected_tx_seq) {
3147 control = L2CAP_SUPER_SELECT_REJECT;
3148 control |= pi->expected_tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3149 l2cap_send_sframe(pi, control);
3150
3151 new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC);
Gustavo F. Padovan8ff50ec2010-05-10 19:34:11 -03003152 new->tx_seq = pi->expected_tx_seq;
3153 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003154 list_add_tail(&new->list, SREJ_LIST(sk));
3155 }
Gustavo F. Padovan8ff50ec2010-05-10 19:34:11 -03003156 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003157}
3158
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003159static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
3160{
3161 struct l2cap_pinfo *pi = l2cap_pi(sk);
3162 u8 tx_seq = __get_txseq(rx_control);
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003163 u8 req_seq = __get_reqseq(rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003164 u8 sar = rx_control >> L2CAP_CTRL_SAR_SHIFT;
Gustavo F. Padovanf6337c72010-05-10 18:32:04 -03003165 int tx_seq_offset, expected_tx_seq_offset;
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03003166 int num_to_ack = (pi->tx_win/6) + 1;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003167 int err = 0;
3168
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003169 BT_DBG("sk %p len %d tx_seq %d rx_control 0x%4.4x", sk, skb->len, tx_seq,
3170 rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003171
Gustavo F. Padovan9b16dc62010-05-05 20:05:57 -03003172 if (L2CAP_CTRL_FINAL & rx_control &&
3173 l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) {
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003174 del_timer(&pi->monitor_timer);
3175 if (pi->unacked_frames > 0)
3176 __mod_retrans_timer();
3177 pi->conn_state &= ~L2CAP_CONN_WAIT_F;
3178 }
3179
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003180 pi->expected_ack_seq = req_seq;
3181 l2cap_drop_acked_frames(sk);
3182
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003183 if (tx_seq == pi->expected_tx_seq)
3184 goto expected;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003185
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003186 tx_seq_offset = (tx_seq - pi->buffer_seq) % 64;
3187 if (tx_seq_offset < 0)
3188 tx_seq_offset += 64;
3189
3190 /* invalid tx_seq */
3191 if (tx_seq_offset >= pi->tx_win) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03003192 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003193 goto drop;
3194 }
3195
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003196 if (pi->conn_state == L2CAP_CONN_LOCAL_BUSY)
3197 goto drop;
3198
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003199 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3200 struct srej_list *first;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003201
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003202 first = list_first_entry(SREJ_LIST(sk),
3203 struct srej_list, list);
3204 if (tx_seq == first->tx_seq) {
3205 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3206 l2cap_check_srej_gap(sk, tx_seq);
3207
3208 list_del(&first->list);
3209 kfree(first);
3210
3211 if (list_empty(SREJ_LIST(sk))) {
3212 pi->buffer_seq = pi->buffer_seq_srej;
3213 pi->conn_state &= ~L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan855666cc2010-05-01 16:15:40 -03003214 l2cap_send_ack(pi);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003215 BT_DBG("sk %p, Exit SREJ_SENT", sk);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003216 }
3217 } else {
3218 struct srej_list *l;
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003219
3220 /* duplicated tx_seq */
3221 if (l2cap_add_to_srej_queue(sk, skb, tx_seq, sar) < 0)
3222 goto drop;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003223
3224 list_for_each_entry(l, SREJ_LIST(sk), list) {
3225 if (l->tx_seq == tx_seq) {
3226 l2cap_resend_srejframe(sk, tx_seq);
3227 return 0;
3228 }
3229 }
3230 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003231 }
3232 } else {
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003233 expected_tx_seq_offset =
3234 (pi->expected_tx_seq - pi->buffer_seq) % 64;
3235 if (expected_tx_seq_offset < 0)
3236 expected_tx_seq_offset += 64;
3237
3238 /* duplicated tx_seq */
3239 if (tx_seq_offset < expected_tx_seq_offset)
3240 goto drop;
3241
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003242 pi->conn_state |= L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003243
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003244 BT_DBG("sk %p, Enter SREJ", sk);
3245
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003246 INIT_LIST_HEAD(SREJ_LIST(sk));
3247 pi->buffer_seq_srej = pi->buffer_seq;
3248
3249 __skb_queue_head_init(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003250 __skb_queue_head_init(BUSY_QUEUE(sk));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003251 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3252
Gustavo F. Padovanef54fd92009-08-20 22:26:04 -03003253 pi->conn_state |= L2CAP_CONN_SEND_PBIT;
3254
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003255 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan7fe9b292010-05-12 18:32:04 -03003256
3257 del_timer(&pi->ack_timer);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003258 }
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003259 return 0;
3260
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003261expected:
3262 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
3263
3264 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
Gustavo F. Padovan3b1a9f32010-05-01 16:15:42 -03003265 bt_cb(skb)->tx_seq = tx_seq;
3266 bt_cb(skb)->sar = sar;
3267 __skb_queue_tail(SREJ_QUEUE(sk), skb);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003268 return 0;
3269 }
3270
Gustavo F. Padovan2ece3682010-06-16 17:21:44 -03003271 err = l2cap_push_rx_skb(sk, skb, rx_control);
3272 if (err < 0)
3273 return 0;
3274
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03003275 if (rx_control & L2CAP_CTRL_FINAL) {
3276 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3277 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003278 else
3279 l2cap_retransmit_frames(sk);
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03003280 }
3281
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003282 __mod_ack_timer();
3283
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03003284 pi->num_acked = (pi->num_acked + 1) % num_to_ack;
3285 if (pi->num_acked == num_to_ack - 1)
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03003286 l2cap_send_ack(pi);
3287
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003288 return 0;
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003289
3290drop:
3291 kfree_skb(skb);
3292 return 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003293}
3294
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003295static inline void l2cap_data_channel_rrframe(struct sock *sk, u16 rx_control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003296{
3297 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan6e3a5982010-05-01 16:15:38 -03003298
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003299 BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, __get_reqseq(rx_control),
3300 rx_control);
3301
Gustavo F. Padovan6e3a5982010-05-01 16:15:38 -03003302 pi->expected_ack_seq = __get_reqseq(rx_control);
3303 l2cap_drop_acked_frames(sk);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003304
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003305 if (rx_control & L2CAP_CTRL_POLL) {
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03003306 pi->conn_state |= L2CAP_CONN_SEND_FBIT;
Gustavo F. Padovan05fbd892010-05-01 16:15:39 -03003307 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3308 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
3309 (pi->unacked_frames > 0))
3310 __mod_retrans_timer();
3311
3312 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3313 l2cap_send_srejtail(sk);
3314 } else {
3315 l2cap_send_i_or_rr_or_rnr(sk);
Gustavo F. Padovan05fbd892010-05-01 16:15:39 -03003316 }
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003317
3318 } else if (rx_control & L2CAP_CTRL_FINAL) {
3319 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003320
3321 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3322 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003323 else
3324 l2cap_retransmit_frames(sk);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003325
3326 } else {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003327 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
3328 (pi->unacked_frames > 0))
3329 __mod_retrans_timer();
3330
3331 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
Andrei Emeltchenko894718a2010-12-01 16:58:24 +02003332 if (pi->conn_state & L2CAP_CONN_SREJ_SENT)
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003333 l2cap_send_ack(pi);
Andrei Emeltchenko894718a2010-12-01 16:58:24 +02003334 else
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003335 l2cap_ertm_send(sk);
3336 }
3337}
3338
3339static inline void l2cap_data_channel_rejframe(struct sock *sk, u16 rx_control)
3340{
3341 struct l2cap_pinfo *pi = l2cap_pi(sk);
3342 u8 tx_seq = __get_reqseq(rx_control);
3343
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003344 BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, tx_seq, rx_control);
3345
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003346 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3347
Gustavo F. Padovan8abb52e2010-05-01 16:15:38 -03003348 pi->expected_ack_seq = tx_seq;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003349 l2cap_drop_acked_frames(sk);
3350
3351 if (rx_control & L2CAP_CTRL_FINAL) {
3352 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3353 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003354 else
3355 l2cap_retransmit_frames(sk);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003356 } else {
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003357 l2cap_retransmit_frames(sk);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003358
Gustavo F. Padovan0301ef02010-05-05 20:56:43 -03003359 if (pi->conn_state & L2CAP_CONN_WAIT_F)
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003360 pi->conn_state |= L2CAP_CONN_REJ_ACT;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003361 }
3362}
3363static inline void l2cap_data_channel_srejframe(struct sock *sk, u16 rx_control)
3364{
3365 struct l2cap_pinfo *pi = l2cap_pi(sk);
3366 u8 tx_seq = __get_reqseq(rx_control);
3367
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003368 BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, tx_seq, rx_control);
3369
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003370 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3371
3372 if (rx_control & L2CAP_CTRL_POLL) {
3373 pi->expected_ack_seq = tx_seq;
3374 l2cap_drop_acked_frames(sk);
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03003375
3376 pi->conn_state |= L2CAP_CONN_SEND_FBIT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003377 l2cap_retransmit_one_frame(sk, tx_seq);
3378
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003379 l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003380
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003381 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
3382 pi->srej_save_reqseq = tx_seq;
3383 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
3384 }
3385 } else if (rx_control & L2CAP_CTRL_FINAL) {
3386 if ((pi->conn_state & L2CAP_CONN_SREJ_ACT) &&
3387 pi->srej_save_reqseq == tx_seq)
3388 pi->conn_state &= ~L2CAP_CONN_SREJ_ACT;
3389 else
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003390 l2cap_retransmit_one_frame(sk, tx_seq);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003391 } else {
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003392 l2cap_retransmit_one_frame(sk, tx_seq);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003393 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
3394 pi->srej_save_reqseq = tx_seq;
3395 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
3396 }
3397 }
3398}
3399
3400static inline void l2cap_data_channel_rnrframe(struct sock *sk, u16 rx_control)
3401{
3402 struct l2cap_pinfo *pi = l2cap_pi(sk);
3403 u8 tx_seq = __get_reqseq(rx_control);
3404
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003405 BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, tx_seq, rx_control);
3406
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003407 pi->conn_state |= L2CAP_CONN_REMOTE_BUSY;
3408 pi->expected_ack_seq = tx_seq;
3409 l2cap_drop_acked_frames(sk);
3410
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03003411 if (rx_control & L2CAP_CTRL_POLL)
3412 pi->conn_state |= L2CAP_CONN_SEND_FBIT;
3413
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03003414 if (!(pi->conn_state & L2CAP_CONN_SREJ_SENT)) {
3415 del_timer(&pi->retrans_timer);
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -03003416 if (rx_control & L2CAP_CTRL_POLL)
3417 l2cap_send_rr_or_rnr(pi, L2CAP_CTRL_FINAL);
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03003418 return;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003419 }
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03003420
3421 if (rx_control & L2CAP_CTRL_POLL)
3422 l2cap_send_srejtail(sk);
3423 else
3424 l2cap_send_sframe(pi, L2CAP_SUPER_RCV_READY);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003425}
3426
3427static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
3428{
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003429 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
3430
Gustavo F. Padovan9b16dc62010-05-05 20:05:57 -03003431 if (L2CAP_CTRL_FINAL & rx_control &&
3432 l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003433 del_timer(&l2cap_pi(sk)->monitor_timer);
3434 if (l2cap_pi(sk)->unacked_frames > 0)
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003435 __mod_retrans_timer();
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003436 l2cap_pi(sk)->conn_state &= ~L2CAP_CONN_WAIT_F;
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003437 }
3438
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003439 switch (rx_control & L2CAP_CTRL_SUPERVISE) {
3440 case L2CAP_SUPER_RCV_READY:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003441 l2cap_data_channel_rrframe(sk, rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003442 break;
3443
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003444 case L2CAP_SUPER_REJECT:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003445 l2cap_data_channel_rejframe(sk, rx_control);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003446 break;
3447
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003448 case L2CAP_SUPER_SELECT_REJECT:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003449 l2cap_data_channel_srejframe(sk, rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003450 break;
3451
3452 case L2CAP_SUPER_RCV_NOT_READY:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003453 l2cap_data_channel_rnrframe(sk, rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003454 break;
3455 }
3456
Gustavo F. Padovanfaaebd12010-05-01 16:15:35 -03003457 kfree_skb(skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003458 return 0;
3459}
3460
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03003461static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb)
3462{
3463 struct l2cap_pinfo *pi = l2cap_pi(sk);
3464 u16 control;
3465 u8 req_seq;
3466 int len, next_tx_seq_offset, req_seq_offset;
3467
3468 control = get_unaligned_le16(skb->data);
3469 skb_pull(skb, 2);
3470 len = skb->len;
3471
3472 /*
3473 * We can just drop the corrupted I-frame here.
3474 * Receiver will miss it and start proper recovery
3475 * procedures and ask retransmission.
3476 */
3477 if (l2cap_check_fcs(pi, skb))
3478 goto drop;
3479
3480 if (__is_sar_start(control) && __is_iframe(control))
3481 len -= 2;
3482
3483 if (pi->fcs == L2CAP_FCS_CRC16)
3484 len -= 2;
3485
3486 if (len > pi->mps) {
3487 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
3488 goto drop;
3489 }
3490
3491 req_seq = __get_reqseq(control);
3492 req_seq_offset = (req_seq - pi->expected_ack_seq) % 64;
3493 if (req_seq_offset < 0)
3494 req_seq_offset += 64;
3495
3496 next_tx_seq_offset =
3497 (pi->next_tx_seq - pi->expected_ack_seq) % 64;
3498 if (next_tx_seq_offset < 0)
3499 next_tx_seq_offset += 64;
3500
3501 /* check for invalid req-seq */
3502 if (req_seq_offset > next_tx_seq_offset) {
3503 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
3504 goto drop;
3505 }
3506
3507 if (__is_iframe(control)) {
3508 if (len < 0) {
3509 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
3510 goto drop;
3511 }
3512
3513 l2cap_data_channel_iframe(sk, control, skb);
3514 } else {
3515 if (len != 0) {
3516 BT_ERR("%d", len);
3517 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
3518 goto drop;
3519 }
3520
3521 l2cap_data_channel_sframe(sk, control, skb);
3522 }
3523
3524 return 0;
3525
3526drop:
3527 kfree_skb(skb);
3528 return 0;
3529}
3530
Linus Torvalds1da177e2005-04-16 15:20:36 -07003531static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk_buff *skb)
3532{
3533 struct sock *sk;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003534 struct l2cap_pinfo *pi;
Nathan Holstein51893f82010-06-09 15:46:25 -04003535 u16 control;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03003536 u8 tx_seq;
3537 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003538
3539 sk = l2cap_get_chan_by_scid(&conn->chan_list, cid);
3540 if (!sk) {
3541 BT_DBG("unknown cid 0x%4.4x", cid);
3542 goto drop;
3543 }
3544
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003545 pi = l2cap_pi(sk);
3546
Linus Torvalds1da177e2005-04-16 15:20:36 -07003547 BT_DBG("sk %p, len %d", sk, skb->len);
3548
3549 if (sk->sk_state != BT_CONNECTED)
3550 goto drop;
3551
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003552 switch (pi->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003553 case L2CAP_MODE_BASIC:
3554 /* If socket recv buffers overflows we drop data here
3555 * which is *bad* because L2CAP has to be reliable.
3556 * But we don't have any other choice. L2CAP doesn't
3557 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003558
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003559 if (pi->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003560 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003561
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003562 if (!sock_queue_rcv_skb(sk, skb))
3563 goto done;
3564 break;
3565
3566 case L2CAP_MODE_ERTM:
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03003567 if (!sock_owned_by_user(sk)) {
3568 l2cap_ertm_data_rcv(sk, skb);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03003569 } else {
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03003570 if (sk_add_backlog(sk, skb))
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03003571 goto drop;
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03003572 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003573
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02003574 goto done;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003575
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003576 case L2CAP_MODE_STREAMING:
3577 control = get_unaligned_le16(skb->data);
3578 skb_pull(skb, 2);
3579 len = skb->len;
3580
Gustavo F. Padovan26000082010-05-11 22:02:00 -03003581 if (l2cap_check_fcs(pi, skb))
3582 goto drop;
3583
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003584 if (__is_sar_start(control))
3585 len -= 2;
3586
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003587 if (pi->fcs == L2CAP_FCS_CRC16)
3588 len -= 2;
3589
Nathan Holstein51893f82010-06-09 15:46:25 -04003590 if (len > pi->mps || len < 0 || __is_sframe(control))
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003591 goto drop;
3592
3593 tx_seq = __get_txseq(control);
3594
3595 if (pi->expected_tx_seq == tx_seq)
3596 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
3597 else
Gustavo F. Padovan7dffe422010-05-01 16:15:36 -03003598 pi->expected_tx_seq = (tx_seq + 1) % 64;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003599
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003600 l2cap_streaming_reassembly_sdu(sk, skb, control);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003601
3602 goto done;
3603
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003604 default:
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03003605 BT_DBG("sk %p: bad mode 0x%2.2x", sk, pi->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003606 break;
3607 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003608
3609drop:
3610 kfree_skb(skb);
3611
3612done:
Marcel Holtmann01394182006-07-03 10:02:46 +02003613 if (sk)
3614 bh_unlock_sock(sk);
3615
Linus Torvalds1da177e2005-04-16 15:20:36 -07003616 return 0;
3617}
3618
Al Viro8e036fc2007-07-29 00:16:36 -07003619static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003620{
3621 struct sock *sk;
3622
3623 sk = l2cap_get_sock_by_psm(0, psm, conn->src);
3624 if (!sk)
3625 goto drop;
3626
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00003627 bh_lock_sock(sk);
3628
Linus Torvalds1da177e2005-04-16 15:20:36 -07003629 BT_DBG("sk %p, len %d", sk, skb->len);
3630
3631 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_CONNECTED)
3632 goto drop;
3633
3634 if (l2cap_pi(sk)->imtu < skb->len)
3635 goto drop;
3636
3637 if (!sock_queue_rcv_skb(sk, skb))
3638 goto done;
3639
3640drop:
3641 kfree_skb(skb);
3642
3643done:
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003644 if (sk)
3645 bh_unlock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003646 return 0;
3647}
3648
3649static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
3650{
3651 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07003652 u16 cid, len;
3653 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003654
3655 skb_pull(skb, L2CAP_HDR_SIZE);
3656 cid = __le16_to_cpu(lh->cid);
3657 len = __le16_to_cpu(lh->len);
3658
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003659 if (len != skb->len) {
3660 kfree_skb(skb);
3661 return;
3662 }
3663
Linus Torvalds1da177e2005-04-16 15:20:36 -07003664 BT_DBG("len %d, cid 0x%4.4x", len, cid);
3665
3666 switch (cid) {
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02003667 case L2CAP_CID_LE_SIGNALING:
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03003668 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07003669 l2cap_sig_channel(conn, skb);
3670 break;
3671
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03003672 case L2CAP_CID_CONN_LESS:
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03003673 psm = get_unaligned_le16(skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003674 skb_pull(skb, 2);
3675 l2cap_conless_channel(conn, psm, skb);
3676 break;
3677
3678 default:
3679 l2cap_data_channel(conn, cid, skb);
3680 break;
3681 }
3682}
3683
3684/* ---- L2CAP interface with lower layer (HCI) ---- */
3685
3686static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
3687{
3688 int exact = 0, lm1 = 0, lm2 = 0;
3689 register struct sock *sk;
3690 struct hlist_node *node;
3691
3692 if (type != ACL_LINK)
João Paulo Rechi Vita963cf682010-06-22 13:56:28 -03003693 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003694
3695 BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
3696
3697 /* Find listening sockets and check their link_mode */
3698 read_lock(&l2cap_sk_list.lock);
3699 sk_for_each(sk, node, &l2cap_sk_list.head) {
3700 if (sk->sk_state != BT_LISTEN)
3701 continue;
3702
3703 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01003704 lm1 |= HCI_LM_ACCEPT;
3705 if (l2cap_pi(sk)->role_switch)
3706 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003707 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01003708 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
3709 lm2 |= HCI_LM_ACCEPT;
3710 if (l2cap_pi(sk)->role_switch)
3711 lm2 |= HCI_LM_MASTER;
3712 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003713 }
3714 read_unlock(&l2cap_sk_list.lock);
3715
3716 return exact ? lm1 : lm2;
3717}
3718
3719static int l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
3720{
Marcel Holtmann01394182006-07-03 10:02:46 +02003721 struct l2cap_conn *conn;
3722
Linus Torvalds1da177e2005-04-16 15:20:36 -07003723 BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
3724
Ville Tervoacd7d372011-02-10 22:38:49 -03003725 if (!(hcon->type == ACL_LINK || hcon->type == LE_LINK))
João Paulo Rechi Vita963cf682010-06-22 13:56:28 -03003726 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003727
3728 if (!status) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003729 conn = l2cap_conn_add(hcon, status);
3730 if (conn)
3731 l2cap_conn_ready(conn);
Marcel Holtmann01394182006-07-03 10:02:46 +02003732 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -07003733 l2cap_conn_del(hcon, bt_err(status));
3734
3735 return 0;
3736}
3737
Marcel Holtmann2950f212009-02-12 14:02:50 +01003738static int l2cap_disconn_ind(struct hci_conn *hcon)
3739{
3740 struct l2cap_conn *conn = hcon->l2cap_data;
3741
3742 BT_DBG("hcon %p", hcon);
3743
3744 if (hcon->type != ACL_LINK || !conn)
3745 return 0x13;
3746
3747 return conn->disc_reason;
3748}
3749
3750static int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003751{
3752 BT_DBG("hcon %p reason %d", hcon, reason);
3753
Ville Tervoacd7d372011-02-10 22:38:49 -03003754 if (!(hcon->type == ACL_LINK || hcon->type == LE_LINK))
João Paulo Rechi Vita963cf682010-06-22 13:56:28 -03003755 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003756
3757 l2cap_conn_del(hcon, bt_err(reason));
Marcel Holtmann01394182006-07-03 10:02:46 +02003758
Linus Torvalds1da177e2005-04-16 15:20:36 -07003759 return 0;
3760}
3761
Marcel Holtmannf62e4322009-01-15 21:58:44 +01003762static inline void l2cap_check_encryption(struct sock *sk, u8 encrypt)
3763{
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03003764 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM)
Marcel Holtmann255c7602009-02-04 21:07:19 +01003765 return;
3766
Marcel Holtmannf62e4322009-01-15 21:58:44 +01003767 if (encrypt == 0x00) {
3768 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM) {
3769 l2cap_sock_clear_timer(sk);
3770 l2cap_sock_set_timer(sk, HZ * 5);
3771 } else if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
3772 __l2cap_sock_close(sk, ECONNREFUSED);
3773 } else {
3774 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM)
3775 l2cap_sock_clear_timer(sk);
3776 }
3777}
3778
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01003779static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003780{
3781 struct l2cap_chan_list *l;
Marcel Holtmann40be4922008-07-14 20:13:50 +02003782 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003783 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003784
Marcel Holtmann01394182006-07-03 10:02:46 +02003785 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003786 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02003787
Linus Torvalds1da177e2005-04-16 15:20:36 -07003788 l = &conn->chan_list;
3789
3790 BT_DBG("conn %p", conn);
3791
3792 read_lock(&l->lock);
3793
3794 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
3795 bh_lock_sock(sk);
3796
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003797 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND) {
3798 bh_unlock_sock(sk);
3799 continue;
3800 }
3801
Marcel Holtmannf62e4322009-01-15 21:58:44 +01003802 if (!status && (sk->sk_state == BT_CONNECTED ||
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01003803 sk->sk_state == BT_CONFIG)) {
Marcel Holtmannf62e4322009-01-15 21:58:44 +01003804 l2cap_check_encryption(sk, encrypt);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02003805 bh_unlock_sock(sk);
3806 continue;
3807 }
3808
Marcel Holtmannb1235d72008-07-14 20:13:54 +02003809 if (sk->sk_state == BT_CONNECT) {
3810 if (!status) {
3811 struct l2cap_conn_req req;
3812 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
3813 req.psm = l2cap_pi(sk)->psm;
3814
3815 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03003816 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02003817
3818 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
3819 L2CAP_CONN_REQ, sizeof(req), &req);
3820 } else {
3821 l2cap_sock_clear_timer(sk);
3822 l2cap_sock_set_timer(sk, HZ / 10);
3823 }
3824 } else if (sk->sk_state == BT_CONNECT2) {
3825 struct l2cap_conn_rsp rsp;
3826 __u16 result;
3827
3828 if (!status) {
3829 sk->sk_state = BT_CONFIG;
3830 result = L2CAP_CR_SUCCESS;
3831 } else {
3832 sk->sk_state = BT_DISCONN;
3833 l2cap_sock_set_timer(sk, HZ / 10);
3834 result = L2CAP_CR_SEC_BLOCK;
3835 }
3836
3837 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
3838 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
3839 rsp.result = cpu_to_le16(result);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003840 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02003841 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
3842 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003843 }
3844
Linus Torvalds1da177e2005-04-16 15:20:36 -07003845 bh_unlock_sock(sk);
3846 }
3847
3848 read_unlock(&l->lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02003849
Linus Torvalds1da177e2005-04-16 15:20:36 -07003850 return 0;
3851}
3852
3853static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
3854{
3855 struct l2cap_conn *conn = hcon->l2cap_data;
3856
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02003857 if (!conn)
3858 conn = l2cap_conn_add(hcon, 0);
3859
3860 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003861 goto drop;
3862
3863 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
3864
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +02003865 if (!(flags & ACL_CONT)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003866 struct l2cap_hdr *hdr;
Andrei Emeltchenko89794812010-09-15 14:28:44 +03003867 struct sock *sk;
3868 u16 cid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003869 int len;
3870
3871 if (conn->rx_len) {
3872 BT_ERR("Unexpected start frame (len %d)", skb->len);
3873 kfree_skb(conn->rx_skb);
3874 conn->rx_skb = NULL;
3875 conn->rx_len = 0;
3876 l2cap_conn_unreliable(conn, ECOMM);
3877 }
3878
Andrei Emeltchenkoaae7fe22010-09-15 14:28:43 +03003879 /* Start fragment always begin with Basic L2CAP header */
3880 if (skb->len < L2CAP_HDR_SIZE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003881 BT_ERR("Frame is too short (len %d)", skb->len);
3882 l2cap_conn_unreliable(conn, ECOMM);
3883 goto drop;
3884 }
3885
3886 hdr = (struct l2cap_hdr *) skb->data;
3887 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
Andrei Emeltchenko89794812010-09-15 14:28:44 +03003888 cid = __le16_to_cpu(hdr->cid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003889
3890 if (len == skb->len) {
3891 /* Complete frame received */
3892 l2cap_recv_frame(conn, skb);
3893 return 0;
3894 }
3895
3896 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
3897
3898 if (skb->len > len) {
3899 BT_ERR("Frame is too long (len %d, expected len %d)",
3900 skb->len, len);
3901 l2cap_conn_unreliable(conn, ECOMM);
3902 goto drop;
3903 }
3904
Andrei Emeltchenko89794812010-09-15 14:28:44 +03003905 sk = l2cap_get_chan_by_scid(&conn->chan_list, cid);
3906
3907 if (sk && l2cap_pi(sk)->imtu < len - L2CAP_HDR_SIZE) {
3908 BT_ERR("Frame exceeding recv MTU (len %d, MTU %d)",
3909 len, l2cap_pi(sk)->imtu);
3910 bh_unlock_sock(sk);
3911 l2cap_conn_unreliable(conn, ECOMM);
3912 goto drop;
3913 }
3914
3915 if (sk)
3916 bh_unlock_sock(sk);
3917
Linus Torvalds1da177e2005-04-16 15:20:36 -07003918 /* Allocate skb for the complete frame (with header) */
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003919 conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC);
3920 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003921 goto drop;
3922
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03003923 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003924 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003925 conn->rx_len = len - skb->len;
3926 } else {
3927 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
3928
3929 if (!conn->rx_len) {
3930 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
3931 l2cap_conn_unreliable(conn, ECOMM);
3932 goto drop;
3933 }
3934
3935 if (skb->len > conn->rx_len) {
3936 BT_ERR("Fragment is too long (len %d, expected %d)",
3937 skb->len, conn->rx_len);
3938 kfree_skb(conn->rx_skb);
3939 conn->rx_skb = NULL;
3940 conn->rx_len = 0;
3941 l2cap_conn_unreliable(conn, ECOMM);
3942 goto drop;
3943 }
3944
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03003945 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003946 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003947 conn->rx_len -= skb->len;
3948
3949 if (!conn->rx_len) {
3950 /* Complete frame received */
3951 l2cap_recv_frame(conn, conn->rx_skb);
3952 conn->rx_skb = NULL;
3953 }
3954 }
3955
3956drop:
3957 kfree_skb(skb);
3958 return 0;
3959}
3960
Marcel Holtmannaef7d972010-03-21 05:27:45 +01003961static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003962{
3963 struct sock *sk;
3964 struct hlist_node *node;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003965
3966 read_lock_bh(&l2cap_sk_list.lock);
3967
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08003968 sk_for_each(sk, node, &l2cap_sk_list.head) {
3969 struct l2cap_pinfo *pi = l2cap_pi(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003970
Gustavo F. Padovan903d3432011-02-10 14:16:06 -02003971 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 +01003972 batostr(&bt_sk(sk)->src),
3973 batostr(&bt_sk(sk)->dst),
3974 sk->sk_state, __le16_to_cpu(pi->psm),
3975 pi->scid, pi->dcid,
Gustavo F. Padovan903d3432011-02-10 14:16:06 -02003976 pi->imtu, pi->omtu, pi->sec_level,
3977 pi->mode);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08003978 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003979
Linus Torvalds1da177e2005-04-16 15:20:36 -07003980 read_unlock_bh(&l2cap_sk_list.lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08003981
Marcel Holtmannaef7d972010-03-21 05:27:45 +01003982 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003983}
3984
Marcel Holtmannaef7d972010-03-21 05:27:45 +01003985static int l2cap_debugfs_open(struct inode *inode, struct file *file)
3986{
3987 return single_open(file, l2cap_debugfs_show, inode->i_private);
3988}
3989
3990static const struct file_operations l2cap_debugfs_fops = {
3991 .open = l2cap_debugfs_open,
3992 .read = seq_read,
3993 .llseek = seq_lseek,
3994 .release = single_release,
3995};
3996
3997static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003998
Linus Torvalds1da177e2005-04-16 15:20:36 -07003999static struct hci_proto l2cap_hci_proto = {
4000 .name = "L2CAP",
4001 .id = HCI_PROTO_L2CAP,
4002 .connect_ind = l2cap_connect_ind,
4003 .connect_cfm = l2cap_connect_cfm,
4004 .disconn_ind = l2cap_disconn_ind,
Marcel Holtmann2950f212009-02-12 14:02:50 +01004005 .disconn_cfm = l2cap_disconn_cfm,
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004006 .security_cfm = l2cap_security_cfm,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004007 .recv_acldata = l2cap_recv_acldata
4008};
4009
Gustavo F. Padovan64274512011-02-07 20:08:52 -02004010int __init l2cap_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004011{
4012 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004013
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02004014 err = l2cap_init_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07004015 if (err < 0)
4016 return err;
4017
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004018 _busy_wq = create_singlethread_workqueue("l2cap");
Anderson Lizardob78d7b4f2010-11-29 12:15:50 -04004019 if (!_busy_wq) {
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02004020 err = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004021 goto error;
4022 }
4023
4024 err = hci_register_proto(&l2cap_hci_proto);
4025 if (err < 0) {
4026 BT_ERR("L2CAP protocol registration failed");
4027 bt_sock_unregister(BTPROTO_L2CAP);
4028 goto error;
4029 }
4030
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004031 if (bt_debugfs) {
4032 l2cap_debugfs = debugfs_create_file("l2cap", 0444,
4033 bt_debugfs, NULL, &l2cap_debugfs_fops);
4034 if (!l2cap_debugfs)
4035 BT_ERR("Failed to create L2CAP debug file");
4036 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004037
Linus Torvalds1da177e2005-04-16 15:20:36 -07004038 return 0;
4039
4040error:
Anderson Lizardob78d7b4f2010-11-29 12:15:50 -04004041 destroy_workqueue(_busy_wq);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02004042 l2cap_cleanup_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07004043 return err;
4044}
4045
Gustavo F. Padovan64274512011-02-07 20:08:52 -02004046void l2cap_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004047{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004048 debugfs_remove(l2cap_debugfs);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004049
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004050 flush_workqueue(_busy_wq);
4051 destroy_workqueue(_busy_wq);
4052
Linus Torvalds1da177e2005-04-16 15:20:36 -07004053 if (hci_unregister_proto(&l2cap_hci_proto) < 0)
4054 BT_ERR("L2CAP protocol unregistration failed");
4055
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02004056 l2cap_cleanup_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07004057}
4058
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03004059module_param(disable_ertm, bool, 0644);
4060MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode");