blob: efcef0dc12599127344417d3db993078616dbc57 [file] [log] [blame]
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 BlueZ - Bluetooth protocol stack for Linux
3 Copyright (C) 2000-2001 Qualcomm Incorporated
Gustavo F. Padovance5706b2010-07-13 11:57:11 -03004 Copyright (C) 2009-2010 Gustavo F. Padovan <gustavo@padovan.org>
Gustavo F. Padovan5d8868f2010-07-16 16:18:39 -03005 Copyright (C) 2010 Google Inc.
Linus Torvalds1da177e2005-04-16 15:20:36 -07006
7 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License version 2 as
11 published by the Free Software Foundation;
12
13 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
14 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
16 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090017 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
18 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Linus Torvalds1da177e2005-04-16 15:20:36 -070020 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090022 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
23 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
Linus Torvalds1da177e2005-04-16 15:20:36 -070024 SOFTWARE IS DISCLAIMED.
25*/
26
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -020027/* Bluetooth L2CAP core. */
Linus Torvalds1da177e2005-04-16 15:20:36 -070028
Linus Torvalds1da177e2005-04-16 15:20:36 -070029#include <linux/module.h>
30
31#include <linux/types.h>
Randy Dunlap4fc268d2006-01-11 12:17:47 -080032#include <linux/capability.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070033#include <linux/errno.h>
34#include <linux/kernel.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070035#include <linux/sched.h>
36#include <linux/slab.h>
37#include <linux/poll.h>
38#include <linux/fcntl.h>
39#include <linux/init.h>
40#include <linux/interrupt.h>
41#include <linux/socket.h>
42#include <linux/skbuff.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070043#include <linux/list.h>
Marcel Holtmannbe9d1222005-11-08 09:57:38 -080044#include <linux/device.h>
Marcel Holtmannaef7d972010-03-21 05:27:45 +010045#include <linux/debugfs.h>
46#include <linux/seq_file.h>
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -030047#include <linux/uaccess.h>
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -030048#include <linux/crc16.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070049#include <net/sock.h>
50
51#include <asm/system.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070052#include <asm/unaligned.h>
53
54#include <net/bluetooth/bluetooth.h>
55#include <net/bluetooth/hci_core.h>
56#include <net/bluetooth/l2cap.h>
57
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -020058int disable_ertm;
Marcel Holtmannf0709e02007-10-20 13:38:51 +020059
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -070060static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN;
Marcel Holtmanne1027a72009-02-09 09:18:02 +010061static u8 l2cap_fixed_chan[8] = { 0x02, };
Linus Torvalds1da177e2005-04-16 15:20:36 -070062
Gustavo F. Padovan1890d362010-05-01 16:15:44 -030063static struct workqueue_struct *_busy_wq;
64
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -020065struct bt_sock_list l2cap_sk_list = {
Robert P. J. Dayd5fb2962008-03-28 16:17:38 -070066 .lock = __RW_LOCK_UNLOCKED(l2cap_sk_list.lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -070067};
68
Gustavo F. Padovan1890d362010-05-01 16:15:44 -030069static void l2cap_busy_work(struct work_struct *work);
70
Linus Torvalds1da177e2005-04-16 15:20:36 -070071static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
72 u8 code, u8 ident, u16 dlen, void *data);
73
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -030074static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb);
75
Marcel Holtmann01394182006-07-03 10:02:46 +020076/* ---- L2CAP channels ---- */
77static struct sock *__l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, u16 cid)
78{
79 struct sock *s;
80 for (s = l->head; s; s = l2cap_pi(s)->next_c) {
81 if (l2cap_pi(s)->dcid == cid)
82 break;
83 }
84 return s;
85}
86
87static struct sock *__l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid)
88{
89 struct sock *s;
90 for (s = l->head; s; s = l2cap_pi(s)->next_c) {
91 if (l2cap_pi(s)->scid == cid)
92 break;
93 }
94 return s;
95}
96
97/* Find channel with given SCID.
98 * Returns locked socket */
99static inline struct sock *l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid)
100{
101 struct sock *s;
102 read_lock(&l->lock);
103 s = __l2cap_get_chan_by_scid(l, cid);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300104 if (s)
105 bh_lock_sock(s);
Marcel Holtmann01394182006-07-03 10:02:46 +0200106 read_unlock(&l->lock);
107 return s;
108}
109
110static struct sock *__l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 ident)
111{
112 struct sock *s;
113 for (s = l->head; s; s = l2cap_pi(s)->next_c) {
114 if (l2cap_pi(s)->ident == ident)
115 break;
116 }
117 return s;
118}
119
120static inline struct sock *l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 ident)
121{
122 struct sock *s;
123 read_lock(&l->lock);
124 s = __l2cap_get_chan_by_ident(l, ident);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300125 if (s)
126 bh_lock_sock(s);
Marcel Holtmann01394182006-07-03 10:02:46 +0200127 read_unlock(&l->lock);
128 return s;
129}
130
131static u16 l2cap_alloc_cid(struct l2cap_chan_list *l)
132{
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300133 u16 cid = L2CAP_CID_DYN_START;
Marcel Holtmann01394182006-07-03 10:02:46 +0200134
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300135 for (; cid < L2CAP_CID_DYN_END; cid++) {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300136 if (!__l2cap_get_chan_by_scid(l, cid))
Marcel Holtmann01394182006-07-03 10:02:46 +0200137 return cid;
138 }
139
140 return 0;
141}
142
143static inline void __l2cap_chan_link(struct l2cap_chan_list *l, struct sock *sk)
144{
145 sock_hold(sk);
146
147 if (l->head)
148 l2cap_pi(l->head)->prev_c = sk;
149
150 l2cap_pi(sk)->next_c = l->head;
151 l2cap_pi(sk)->prev_c = NULL;
152 l->head = sk;
153}
154
155static inline void l2cap_chan_unlink(struct l2cap_chan_list *l, struct sock *sk)
156{
157 struct sock *next = l2cap_pi(sk)->next_c, *prev = l2cap_pi(sk)->prev_c;
158
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200159 write_lock_bh(&l->lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200160 if (sk == l->head)
161 l->head = next;
162
163 if (next)
164 l2cap_pi(next)->prev_c = prev;
165 if (prev)
166 l2cap_pi(prev)->next_c = next;
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200167 write_unlock_bh(&l->lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200168
169 __sock_put(sk);
170}
171
172static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
173{
174 struct l2cap_chan_list *l = &conn->chan_list;
175
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300176 BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
177 l2cap_pi(sk)->psm, l2cap_pi(sk)->dcid);
Marcel Holtmann01394182006-07-03 10:02:46 +0200178
Marcel Holtmann2950f212009-02-12 14:02:50 +0100179 conn->disc_reason = 0x13;
180
Marcel Holtmann01394182006-07-03 10:02:46 +0200181 l2cap_pi(sk)->conn = conn;
182
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300183 if (sk->sk_type == SOCK_SEQPACKET || sk->sk_type == SOCK_STREAM) {
Ville Tervob62f3282011-02-10 22:38:50 -0300184 if (conn->hcon->type == LE_LINK) {
185 /* LE connection */
186 l2cap_pi(sk)->omtu = L2CAP_LE_DEFAULT_MTU;
187 l2cap_pi(sk)->scid = L2CAP_CID_LE_DATA;
188 l2cap_pi(sk)->dcid = L2CAP_CID_LE_DATA;
189 } else {
190 /* Alloc CID for connection-oriented socket */
191 l2cap_pi(sk)->scid = l2cap_alloc_cid(l);
192 l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
193 }
Marcel Holtmann01394182006-07-03 10:02:46 +0200194 } else if (sk->sk_type == SOCK_DGRAM) {
195 /* Connectionless socket */
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300196 l2cap_pi(sk)->scid = L2CAP_CID_CONN_LESS;
197 l2cap_pi(sk)->dcid = L2CAP_CID_CONN_LESS;
Marcel Holtmann01394182006-07-03 10:02:46 +0200198 l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
199 } else {
200 /* Raw socket can send/recv signalling messages only */
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300201 l2cap_pi(sk)->scid = L2CAP_CID_SIGNALING;
202 l2cap_pi(sk)->dcid = L2CAP_CID_SIGNALING;
Marcel Holtmann01394182006-07-03 10:02:46 +0200203 l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
204 }
205
206 __l2cap_chan_link(l, sk);
207
208 if (parent)
209 bt_accept_enqueue(parent, sk);
210}
211
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900212/* Delete channel.
Marcel Holtmann01394182006-07-03 10:02:46 +0200213 * Must be called on the locked socket. */
Gustavo F. Padovan6de07022011-02-04 03:35:20 -0200214void l2cap_chan_del(struct sock *sk, int err)
Marcel Holtmann01394182006-07-03 10:02:46 +0200215{
216 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
217 struct sock *parent = bt_sk(sk)->parent;
218
219 l2cap_sock_clear_timer(sk);
220
221 BT_DBG("sk %p, conn %p, err %d", sk, conn, err);
222
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900223 if (conn) {
Marcel Holtmann01394182006-07-03 10:02:46 +0200224 /* Unlink from channel list */
225 l2cap_chan_unlink(&conn->chan_list, sk);
226 l2cap_pi(sk)->conn = NULL;
227 hci_conn_put(conn->hcon);
228 }
229
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200230 sk->sk_state = BT_CLOSED;
Marcel Holtmann01394182006-07-03 10:02:46 +0200231 sock_set_flag(sk, SOCK_ZAPPED);
232
233 if (err)
234 sk->sk_err = err;
235
236 if (parent) {
237 bt_accept_unlink(sk);
238 parent->sk_data_ready(parent, 0);
239 } else
240 sk->sk_state_change(sk);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300241
242 skb_queue_purge(TX_QUEUE(sk));
243
244 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
245 struct srej_list *l, *tmp;
246
247 del_timer(&l2cap_pi(sk)->retrans_timer);
248 del_timer(&l2cap_pi(sk)->monitor_timer);
249 del_timer(&l2cap_pi(sk)->ack_timer);
250
251 skb_queue_purge(SREJ_QUEUE(sk));
252 skb_queue_purge(BUSY_QUEUE(sk));
253
254 list_for_each_entry_safe(l, tmp, SREJ_LIST(sk), list) {
255 list_del(&l->list);
256 kfree(l);
257 }
258 }
Marcel Holtmann01394182006-07-03 10:02:46 +0200259}
260
Johan Hedberg8556edd32011-01-19 12:06:50 +0530261static inline u8 l2cap_get_auth_type(struct sock *sk)
262{
263 if (sk->sk_type == SOCK_RAW) {
264 switch (l2cap_pi(sk)->sec_level) {
265 case BT_SECURITY_HIGH:
266 return HCI_AT_DEDICATED_BONDING_MITM;
267 case BT_SECURITY_MEDIUM:
268 return HCI_AT_DEDICATED_BONDING;
269 default:
270 return HCI_AT_NO_BONDING;
271 }
272 } else if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) {
273 if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW)
274 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
275
276 if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
277 return HCI_AT_NO_BONDING_MITM;
278 else
279 return HCI_AT_NO_BONDING;
280 } else {
281 switch (l2cap_pi(sk)->sec_level) {
282 case BT_SECURITY_HIGH:
283 return HCI_AT_GENERAL_BONDING_MITM;
284 case BT_SECURITY_MEDIUM:
285 return HCI_AT_GENERAL_BONDING;
286 default:
287 return HCI_AT_NO_BONDING;
288 }
289 }
290}
291
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200292/* Service level security */
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100293static inline int l2cap_check_security(struct sock *sk)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200294{
295 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100296 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200297
Johan Hedberg8556edd32011-01-19 12:06:50 +0530298 auth_type = l2cap_get_auth_type(sk);
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100299
300 return hci_conn_security(conn->hcon, l2cap_pi(sk)->sec_level,
301 auth_type);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200302}
303
Gustavo F. Padovan68983252011-02-04 03:02:31 -0200304u8 l2cap_get_ident(struct l2cap_conn *conn)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200305{
306 u8 id;
307
308 /* Get next available identificator.
309 * 1 - 128 are used by kernel.
310 * 129 - 199 are reserved.
311 * 200 - 254 are used by utilities like l2ping, etc.
312 */
313
314 spin_lock_bh(&conn->lock);
315
316 if (++conn->tx_ident > 128)
317 conn->tx_ident = 1;
318
319 id = conn->tx_ident;
320
321 spin_unlock_bh(&conn->lock);
322
323 return id;
324}
325
Gustavo F. Padovan68983252011-02-04 03:02:31 -0200326void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200327{
328 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200329 u8 flags;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200330
331 BT_DBG("code 0x%2.2x", code);
332
333 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300334 return;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200335
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200336 if (lmp_no_flush_capable(conn->hcon->hdev))
337 flags = ACL_START_NO_FLUSH;
338 else
339 flags = ACL_START;
340
341 hci_send_acl(conn->hcon, skb, flags);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200342}
343
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300344static inline void l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300345{
346 struct sk_buff *skb;
347 struct l2cap_hdr *lh;
348 struct l2cap_conn *conn = pi->conn;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300349 struct sock *sk = (struct sock *)pi;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300350 int count, hlen = L2CAP_HDR_SIZE + 2;
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200351 u8 flags;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300352
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300353 if (sk->sk_state != BT_CONNECTED)
354 return;
355
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300356 if (pi->fcs == L2CAP_FCS_CRC16)
357 hlen += 2;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300358
359 BT_DBG("pi %p, control 0x%2.2x", pi, control);
360
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300361 count = min_t(unsigned int, conn->mtu, hlen);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300362 control |= L2CAP_CTRL_FRAME_TYPE;
363
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -0300364 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
365 control |= L2CAP_CTRL_FINAL;
366 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
367 }
368
Gustavo F. Padovanf0946cc2010-05-01 16:15:37 -0300369 if (pi->conn_state & L2CAP_CONN_SEND_PBIT) {
370 control |= L2CAP_CTRL_POLL;
371 pi->conn_state &= ~L2CAP_CONN_SEND_PBIT;
372 }
373
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300374 skb = bt_skb_alloc(count, GFP_ATOMIC);
375 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300376 return;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300377
378 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300379 lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300380 lh->cid = cpu_to_le16(pi->dcid);
381 put_unaligned_le16(control, skb_put(skb, 2));
382
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300383 if (pi->fcs == L2CAP_FCS_CRC16) {
384 u16 fcs = crc16(0, (u8 *)lh, count - 2);
385 put_unaligned_le16(fcs, skb_put(skb, 2));
386 }
387
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200388 if (lmp_no_flush_capable(conn->hcon->hdev))
389 flags = ACL_START_NO_FLUSH;
390 else
391 flags = ACL_START;
392
393 hci_send_acl(pi->conn->hcon, skb, flags);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300394}
395
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300396static inline void l2cap_send_rr_or_rnr(struct l2cap_pinfo *pi, u16 control)
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300397{
Gustavo F. Padovan1890d362010-05-01 16:15:44 -0300398 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300399 control |= L2CAP_SUPER_RCV_NOT_READY;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -0300400 pi->conn_state |= L2CAP_CONN_RNR_SENT;
401 } else
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300402 control |= L2CAP_SUPER_RCV_READY;
403
Gustavo F. Padovan2ab25cd2009-10-03 02:34:40 -0300404 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
405
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300406 l2cap_send_sframe(pi, control);
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300407}
408
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300409static inline int __l2cap_no_conn_pending(struct sock *sk)
410{
411 return !(l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND);
412}
413
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200414static void l2cap_do_start(struct sock *sk)
415{
416 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
417
418 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +0100419 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
420 return;
421
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300422 if (l2cap_check_security(sk) && __l2cap_no_conn_pending(sk)) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200423 struct l2cap_conn_req req;
424 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
425 req.psm = l2cap_pi(sk)->psm;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200426
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200427 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300428 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200429
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200430 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200431 L2CAP_CONN_REQ, sizeof(req), &req);
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200432 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200433 } else {
434 struct l2cap_info_req req;
435 req.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
436
437 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
438 conn->info_ident = l2cap_get_ident(conn);
439
440 mod_timer(&conn->info_timer, jiffies +
441 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
442
443 l2cap_send_cmd(conn, conn->info_ident,
444 L2CAP_INFO_REQ, sizeof(req), &req);
445 }
446}
447
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -0300448static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
449{
450 u32 local_feat_mask = l2cap_feat_mask;
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -0300451 if (!disable_ertm)
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -0300452 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
453
454 switch (mode) {
455 case L2CAP_MODE_ERTM:
456 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
457 case L2CAP_MODE_STREAMING:
458 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
459 default:
460 return 0x00;
461 }
462}
463
Gustavo F. Padovan6de07022011-02-04 03:35:20 -0200464void l2cap_send_disconn_req(struct l2cap_conn *conn, struct sock *sk, int err)
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300465{
466 struct l2cap_disconn_req req;
467
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300468 if (!conn)
469 return;
470
471 skb_queue_purge(TX_QUEUE(sk));
472
473 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
474 del_timer(&l2cap_pi(sk)->retrans_timer);
475 del_timer(&l2cap_pi(sk)->monitor_timer);
476 del_timer(&l2cap_pi(sk)->ack_timer);
477 }
478
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300479 req.dcid = cpu_to_le16(l2cap_pi(sk)->dcid);
480 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
481 l2cap_send_cmd(conn, l2cap_get_ident(conn),
482 L2CAP_DISCONN_REQ, sizeof(req), &req);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300483
484 sk->sk_state = BT_DISCONN;
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -0300485 sk->sk_err = err;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300486}
487
Linus Torvalds1da177e2005-04-16 15:20:36 -0700488/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200489static void l2cap_conn_start(struct l2cap_conn *conn)
490{
491 struct l2cap_chan_list *l = &conn->chan_list;
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -0300492 struct sock_del_list del, *tmp1, *tmp2;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200493 struct sock *sk;
494
495 BT_DBG("conn %p", conn);
496
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -0300497 INIT_LIST_HEAD(&del.list);
498
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200499 read_lock(&l->lock);
500
501 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
502 bh_lock_sock(sk);
503
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300504 if (sk->sk_type != SOCK_SEQPACKET &&
505 sk->sk_type != SOCK_STREAM) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200506 bh_unlock_sock(sk);
507 continue;
508 }
509
510 if (sk->sk_state == BT_CONNECT) {
Gustavo F. Padovan47731de2010-07-09 16:38:35 -0300511 struct l2cap_conn_req req;
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -0300512
Gustavo F. Padovan47731de2010-07-09 16:38:35 -0300513 if (!l2cap_check_security(sk) ||
514 !__l2cap_no_conn_pending(sk)) {
515 bh_unlock_sock(sk);
516 continue;
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200517 }
Gustavo F. Padovan47731de2010-07-09 16:38:35 -0300518
519 if (!l2cap_mode_supported(l2cap_pi(sk)->mode,
520 conn->feat_mask)
521 && l2cap_pi(sk)->conf_state &
522 L2CAP_CONF_STATE2_DEVICE) {
523 tmp1 = kzalloc(sizeof(struct sock_del_list),
524 GFP_ATOMIC);
525 tmp1->sk = sk;
526 list_add_tail(&tmp1->list, &del.list);
527 bh_unlock_sock(sk);
528 continue;
529 }
530
531 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
532 req.psm = l2cap_pi(sk)->psm;
533
534 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
535 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
536
537 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
538 L2CAP_CONN_REQ, sizeof(req), &req);
539
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200540 } else if (sk->sk_state == BT_CONNECT2) {
541 struct l2cap_conn_rsp rsp;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -0300542 char buf[128];
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200543 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
544 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
545
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100546 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100547 if (bt_sk(sk)->defer_setup) {
548 struct sock *parent = bt_sk(sk)->parent;
549 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
550 rsp.status = cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
551 parent->sk_data_ready(parent, 0);
552
553 } else {
554 sk->sk_state = BT_CONFIG;
555 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
556 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
557 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200558 } else {
559 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
560 rsp.status = cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
561 }
562
563 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
564 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -0300565
566 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT ||
567 rsp.result != L2CAP_CR_SUCCESS) {
568 bh_unlock_sock(sk);
569 continue;
570 }
571
572 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
573 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
574 l2cap_build_conf_req(sk, buf), buf);
575 l2cap_pi(sk)->num_conf_req++;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200576 }
577
578 bh_unlock_sock(sk);
579 }
580
581 read_unlock(&l->lock);
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -0300582
583 list_for_each_entry_safe(tmp1, tmp2, &del.list, list) {
584 bh_lock_sock(tmp1->sk);
585 __l2cap_sock_close(tmp1->sk, ECONNRESET);
586 bh_unlock_sock(tmp1->sk);
587 list_del(&tmp1->list);
588 kfree(tmp1);
589 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200590}
591
Ville Tervob62f3282011-02-10 22:38:50 -0300592/* Find socket with cid and source bdaddr.
593 * Returns closest match, locked.
594 */
595static struct sock *l2cap_get_sock_by_scid(int state, __le16 cid, bdaddr_t *src)
596{
597 struct sock *s, *sk = NULL, *sk1 = NULL;
598 struct hlist_node *node;
599
600 read_lock(&l2cap_sk_list.lock);
601
602 sk_for_each(sk, node, &l2cap_sk_list.head) {
603 if (state && sk->sk_state != state)
604 continue;
605
606 if (l2cap_pi(sk)->scid == cid) {
607 /* Exact match. */
608 if (!bacmp(&bt_sk(sk)->src, src))
609 break;
610
611 /* Closest match */
612 if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY))
613 sk1 = sk;
614 }
615 }
616 s = node ? sk : sk1;
617 if (s)
618 bh_lock_sock(s);
619 read_unlock(&l2cap_sk_list.lock);
620
621 return s;
622}
623
624static void l2cap_le_conn_ready(struct l2cap_conn *conn)
625{
626 struct l2cap_chan_list *list = &conn->chan_list;
627 struct sock *parent, *uninitialized_var(sk);
628
629 BT_DBG("");
630
631 /* Check if we have socket listening on cid */
632 parent = l2cap_get_sock_by_scid(BT_LISTEN, L2CAP_CID_LE_DATA,
633 conn->src);
634 if (!parent)
635 return;
636
637 /* Check for backlog size */
638 if (sk_acceptq_is_full(parent)) {
639 BT_DBG("backlog full %d", parent->sk_ack_backlog);
640 goto clean;
641 }
642
643 sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, GFP_ATOMIC);
644 if (!sk)
645 goto clean;
646
647 write_lock_bh(&list->lock);
648
649 hci_conn_hold(conn->hcon);
650
651 l2cap_sock_init(sk, parent);
652 bacpy(&bt_sk(sk)->src, conn->src);
653 bacpy(&bt_sk(sk)->dst, conn->dst);
654
655 __l2cap_chan_add(conn, sk, parent);
656
657 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
658
659 sk->sk_state = BT_CONNECTED;
660 parent->sk_data_ready(parent, 0);
661
662 write_unlock_bh(&list->lock);
663
664clean:
665 bh_unlock_sock(parent);
666}
667
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200668static void l2cap_conn_ready(struct l2cap_conn *conn)
669{
670 struct l2cap_chan_list *l = &conn->chan_list;
671 struct sock *sk;
672
673 BT_DBG("conn %p", conn);
674
Ville Tervob62f3282011-02-10 22:38:50 -0300675 if (!conn->hcon->out && conn->hcon->type == LE_LINK)
676 l2cap_le_conn_ready(conn);
677
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200678 read_lock(&l->lock);
679
680 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
681 bh_lock_sock(sk);
682
Ville Tervoacd7d372011-02-10 22:38:49 -0300683 if (conn->hcon->type == LE_LINK) {
684 l2cap_sock_clear_timer(sk);
685 sk->sk_state = BT_CONNECTED;
686 sk->sk_state_change(sk);
687 }
688
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300689 if (sk->sk_type != SOCK_SEQPACKET &&
690 sk->sk_type != SOCK_STREAM) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200691 l2cap_sock_clear_timer(sk);
692 sk->sk_state = BT_CONNECTED;
693 sk->sk_state_change(sk);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200694 } else if (sk->sk_state == BT_CONNECT)
695 l2cap_do_start(sk);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200696
697 bh_unlock_sock(sk);
698 }
699
700 read_unlock(&l->lock);
701}
702
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200703/* Notify sockets that we cannot guaranty reliability anymore */
704static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
705{
706 struct l2cap_chan_list *l = &conn->chan_list;
707 struct sock *sk;
708
709 BT_DBG("conn %p", conn);
710
711 read_lock(&l->lock);
712
713 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100714 if (l2cap_pi(sk)->force_reliable)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200715 sk->sk_err = err;
716 }
717
718 read_unlock(&l->lock);
719}
720
721static void l2cap_info_timeout(unsigned long arg)
722{
723 struct l2cap_conn *conn = (void *) arg;
724
Marcel Holtmann984947d2009-02-06 23:35:19 +0100725 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +0100726 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +0100727
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200728 l2cap_conn_start(conn);
729}
730
Linus Torvalds1da177e2005-04-16 15:20:36 -0700731static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
732{
Marcel Holtmann01394182006-07-03 10:02:46 +0200733 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700734
Marcel Holtmann01394182006-07-03 10:02:46 +0200735 if (conn || status)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700736 return conn;
737
Marcel Holtmann01394182006-07-03 10:02:46 +0200738 conn = kzalloc(sizeof(struct l2cap_conn), GFP_ATOMIC);
739 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700740 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700741
742 hcon->l2cap_data = conn;
743 conn->hcon = hcon;
744
Marcel Holtmann01394182006-07-03 10:02:46 +0200745 BT_DBG("hcon %p conn %p", hcon, conn);
746
Ville Tervoacd7d372011-02-10 22:38:49 -0300747 if (hcon->hdev->le_mtu && hcon->type == LE_LINK)
748 conn->mtu = hcon->hdev->le_mtu;
749 else
750 conn->mtu = hcon->hdev->acl_mtu;
751
Linus Torvalds1da177e2005-04-16 15:20:36 -0700752 conn->src = &hcon->hdev->bdaddr;
753 conn->dst = &hcon->dst;
754
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200755 conn->feat_mask = 0;
756
Linus Torvalds1da177e2005-04-16 15:20:36 -0700757 spin_lock_init(&conn->lock);
758 rwlock_init(&conn->chan_list.lock);
759
Ville Tervob62f3282011-02-10 22:38:50 -0300760 if (hcon->type != LE_LINK)
761 setup_timer(&conn->info_timer, l2cap_info_timeout,
Dave Young45054dc2009-10-18 20:28:30 +0000762 (unsigned long) conn);
763
Marcel Holtmann2950f212009-02-12 14:02:50 +0100764 conn->disc_reason = 0x13;
765
Linus Torvalds1da177e2005-04-16 15:20:36 -0700766 return conn;
767}
768
Marcel Holtmann01394182006-07-03 10:02:46 +0200769static void l2cap_conn_del(struct hci_conn *hcon, int err)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700770{
Marcel Holtmann01394182006-07-03 10:02:46 +0200771 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700772 struct sock *sk;
773
Marcel Holtmann01394182006-07-03 10:02:46 +0200774 if (!conn)
775 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700776
777 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
778
Wei Yongjun7585b972009-02-25 18:29:52 +0800779 kfree_skb(conn->rx_skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700780
781 /* Kill channels */
782 while ((sk = conn->chan_list.head)) {
783 bh_lock_sock(sk);
784 l2cap_chan_del(sk, err);
785 bh_unlock_sock(sk);
786 l2cap_sock_kill(sk);
787 }
788
Dave Young8e8440f2008-03-03 12:18:55 -0800789 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
790 del_timer_sync(&conn->info_timer);
Thomas Gleixner3ab22732008-02-26 17:42:56 -0800791
Linus Torvalds1da177e2005-04-16 15:20:36 -0700792 hcon->l2cap_data = NULL;
793 kfree(conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700794}
795
796static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
797{
798 struct l2cap_chan_list *l = &conn->chan_list;
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200799 write_lock_bh(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700800 __l2cap_chan_add(conn, sk, parent);
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200801 write_unlock_bh(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700802}
803
Linus Torvalds1da177e2005-04-16 15:20:36 -0700804/* ---- Socket interface ---- */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700805
806/* Find socket with psm and source bdaddr.
807 * Returns closest match.
808 */
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +0000809static struct sock *l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700810{
811 struct sock *sk = NULL, *sk1 = NULL;
812 struct hlist_node *node;
813
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +0000814 read_lock(&l2cap_sk_list.lock);
815
Linus Torvalds1da177e2005-04-16 15:20:36 -0700816 sk_for_each(sk, node, &l2cap_sk_list.head) {
817 if (state && sk->sk_state != state)
818 continue;
819
820 if (l2cap_pi(sk)->psm == psm) {
821 /* Exact match. */
822 if (!bacmp(&bt_sk(sk)->src, src))
823 break;
824
825 /* Closest match */
826 if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY))
827 sk1 = sk;
828 }
829 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700830
Linus Torvalds1da177e2005-04-16 15:20:36 -0700831 read_unlock(&l2cap_sk_list.lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +0000832
833 return node ? sk : sk1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700834}
835
Gustavo F. Padovan4e34c502011-02-04 02:56:13 -0200836int l2cap_do_connect(struct sock *sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700837{
838 bdaddr_t *src = &bt_sk(sk)->src;
839 bdaddr_t *dst = &bt_sk(sk)->dst;
840 struct l2cap_conn *conn;
841 struct hci_conn *hcon;
842 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200843 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +0200844 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700845
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100846 BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst),
847 l2cap_pi(sk)->psm);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700848
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300849 hdev = hci_get_route(dst, src);
850 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700851 return -EHOSTUNREACH;
852
853 hci_dev_lock_bh(hdev);
854
855 err = -ENOMEM;
856
Johan Hedberg8556edd32011-01-19 12:06:50 +0530857 auth_type = l2cap_get_auth_type(sk);
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200858
Ville Tervoacd7d372011-02-10 22:38:49 -0300859 if (l2cap_pi(sk)->dcid == L2CAP_CID_LE_DATA)
860 hcon = hci_connect(hdev, LE_LINK, dst,
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100861 l2cap_pi(sk)->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -0300862 else
863 hcon = hci_connect(hdev, ACL_LINK, dst,
864 l2cap_pi(sk)->sec_level, auth_type);
865
Linus Torvalds1da177e2005-04-16 15:20:36 -0700866 if (!hcon)
867 goto done;
868
869 conn = l2cap_conn_add(hcon, 0);
870 if (!conn) {
871 hci_conn_put(hcon);
872 goto done;
873 }
874
875 err = 0;
876
877 /* Update source addr of the socket */
878 bacpy(src, conn->src);
879
880 l2cap_chan_add(conn, sk, NULL);
881
882 sk->sk_state = BT_CONNECT;
883 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
884
885 if (hcon->state == BT_CONNECTED) {
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300886 if (sk->sk_type != SOCK_SEQPACKET &&
887 sk->sk_type != SOCK_STREAM) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700888 l2cap_sock_clear_timer(sk);
Johan Hedbergd00ef242011-01-19 12:06:51 +0530889 if (l2cap_check_security(sk))
890 sk->sk_state = BT_CONNECTED;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200891 } else
892 l2cap_do_start(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700893 }
894
895done:
896 hci_dev_unlock_bh(hdev);
897 hci_dev_put(hdev);
898 return err;
899}
900
Gustavo F. Padovandcba0db2011-02-04 03:08:36 -0200901int __l2cap_wait_ack(struct sock *sk)
Gustavo F. Padovan6161c032010-05-01 16:15:44 -0300902{
903 DECLARE_WAITQUEUE(wait, current);
904 int err = 0;
905 int timeo = HZ/5;
906
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +0200907 add_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -0300908 while ((l2cap_pi(sk)->unacked_frames > 0 && l2cap_pi(sk)->conn)) {
909 set_current_state(TASK_INTERRUPTIBLE);
910
911 if (!timeo)
912 timeo = HZ/5;
913
914 if (signal_pending(current)) {
915 err = sock_intr_errno(timeo);
916 break;
917 }
918
919 release_sock(sk);
920 timeo = schedule_timeout(timeo);
921 lock_sock(sk);
922
923 err = sock_error(sk);
924 if (err)
925 break;
926 }
927 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +0200928 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -0300929 return err;
930}
931
Gustavo F. Padovane90bac02009-08-20 22:26:00 -0300932static void l2cap_monitor_timeout(unsigned long arg)
933{
934 struct sock *sk = (void *) arg;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -0300935
Gustavo F. Padovan0e989582010-04-19 14:45:38 -0300936 BT_DBG("sk %p", sk);
937
Gustavo F. Padovane6862192009-08-24 00:45:19 -0300938 bh_lock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -0300939 if (l2cap_pi(sk)->retry_count >= l2cap_pi(sk)->remote_max_tx) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -0300940 l2cap_send_disconn_req(l2cap_pi(sk)->conn, sk, ECONNABORTED);
Andrei Emeltchenkob13f5862009-12-15 11:38:04 +0200941 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -0300942 return;
943 }
944
945 l2cap_pi(sk)->retry_count++;
946 __mod_monitor_timer();
947
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -0300948 l2cap_send_rr_or_rnr(l2cap_pi(sk), L2CAP_CTRL_POLL);
Gustavo F. Padovane6862192009-08-24 00:45:19 -0300949 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -0300950}
951
952static void l2cap_retrans_timeout(unsigned long arg)
953{
954 struct sock *sk = (void *) arg;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -0300955
Gustavo F. Padovan0e989582010-04-19 14:45:38 -0300956 BT_DBG("sk %p", sk);
957
Gustavo F. Padovane6862192009-08-24 00:45:19 -0300958 bh_lock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -0300959 l2cap_pi(sk)->retry_count = 1;
960 __mod_monitor_timer();
961
962 l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
963
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -0300964 l2cap_send_rr_or_rnr(l2cap_pi(sk), L2CAP_CTRL_POLL);
Gustavo F. Padovane6862192009-08-24 00:45:19 -0300965 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -0300966}
967
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300968static void l2cap_drop_acked_frames(struct sock *sk)
969{
970 struct sk_buff *skb;
971
Gustavo F. Padovan812e7372010-05-01 16:15:42 -0300972 while ((skb = skb_peek(TX_QUEUE(sk))) &&
973 l2cap_pi(sk)->unacked_frames) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300974 if (bt_cb(skb)->tx_seq == l2cap_pi(sk)->expected_ack_seq)
975 break;
976
977 skb = skb_dequeue(TX_QUEUE(sk));
978 kfree_skb(skb);
979
980 l2cap_pi(sk)->unacked_frames--;
981 }
982
Gustavo F. Padovane90bac02009-08-20 22:26:00 -0300983 if (!l2cap_pi(sk)->unacked_frames)
984 del_timer(&l2cap_pi(sk)->retrans_timer);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300985}
986
Gustavo F. Padovanfd83ccd2011-02-04 03:20:52 -0200987void l2cap_do_send(struct sock *sk, struct sk_buff *skb)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300988{
989 struct l2cap_pinfo *pi = l2cap_pi(sk);
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200990 struct hci_conn *hcon = pi->conn->hcon;
991 u16 flags;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300992
993 BT_DBG("sk %p, skb %p len %d", sk, skb, skb->len);
994
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200995 if (!pi->flushable && lmp_no_flush_capable(hcon->hdev))
996 flags = ACL_START_NO_FLUSH;
997 else
998 flags = ACL_START;
999
1000 hci_send_acl(hcon, skb, flags);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001001}
1002
Gustavo F. Padovanfd83ccd2011-02-04 03:20:52 -02001003void l2cap_streaming_send(struct sock *sk)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001004{
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001005 struct sk_buff *skb;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001006 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001007 u16 control, fcs;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001008
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001009 while ((skb = skb_dequeue(TX_QUEUE(sk)))) {
1010 control = get_unaligned_le16(skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001011 control |= pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT;
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001012 put_unaligned_le16(control, skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001013
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001014 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001015 fcs = crc16(0, (u8 *)skb->data, skb->len - 2);
1016 put_unaligned_le16(fcs, skb->data + skb->len - 2);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001017 }
1018
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001019 l2cap_do_send(sk, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001020
1021 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001022 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001023}
1024
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001025static void l2cap_retransmit_one_frame(struct sock *sk, u8 tx_seq)
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001026{
1027 struct l2cap_pinfo *pi = l2cap_pi(sk);
1028 struct sk_buff *skb, *tx_skb;
1029 u16 control, fcs;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001030
1031 skb = skb_peek(TX_QUEUE(sk));
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001032 if (!skb)
1033 return;
1034
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001035 do {
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001036 if (bt_cb(skb)->tx_seq == tx_seq)
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001037 break;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001038
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001039 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1040 return;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001041
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001042 } while ((skb = skb_queue_next(TX_QUEUE(sk), skb)));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001043
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001044 if (pi->remote_max_tx &&
1045 bt_cb(skb)->retries == pi->remote_max_tx) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03001046 l2cap_send_disconn_req(pi->conn, sk, ECONNABORTED);
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001047 return;
1048 }
1049
1050 tx_skb = skb_clone(skb, GFP_ATOMIC);
1051 bt_cb(skb)->retries++;
1052 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03001053
1054 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
1055 control |= L2CAP_CTRL_FINAL;
1056 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
1057 }
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03001058
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001059 control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
1060 | (tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03001061
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001062 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1063
1064 if (pi->fcs == L2CAP_FCS_CRC16) {
1065 fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
1066 put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
1067 }
1068
1069 l2cap_do_send(sk, tx_skb);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001070}
1071
Gustavo F. Padovanfd83ccd2011-02-04 03:20:52 -02001072int l2cap_ertm_send(struct sock *sk)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001073{
1074 struct sk_buff *skb, *tx_skb;
1075 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001076 u16 control, fcs;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001077 int nsent = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001078
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001079 if (sk->sk_state != BT_CONNECTED)
1080 return -ENOTCONN;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001081
Gustavo F. Padovan6e2b6722010-06-01 18:52:58 -03001082 while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(sk))) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001083
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001084 if (pi->remote_max_tx &&
1085 bt_cb(skb)->retries == pi->remote_max_tx) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03001086 l2cap_send_disconn_req(pi->conn, sk, ECONNABORTED);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001087 break;
1088 }
1089
Andrei Emeltchenkoe420aba2009-12-23 13:07:14 +02001090 tx_skb = skb_clone(skb, GFP_ATOMIC);
1091
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001092 bt_cb(skb)->retries++;
1093
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001094 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03001095 control &= L2CAP_CTRL_SAR;
1096
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001097 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
1098 control |= L2CAP_CTRL_FINAL;
1099 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
1100 }
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03001101 control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001102 | (pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
1103 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1104
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001105
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001106 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001107 fcs = crc16(0, (u8 *)skb->data, tx_skb->len - 2);
1108 put_unaligned_le16(fcs, skb->data + tx_skb->len - 2);
1109 }
1110
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001111 l2cap_do_send(sk, tx_skb);
1112
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001113 __mod_retrans_timer();
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001114
1115 bt_cb(skb)->tx_seq = pi->next_tx_seq;
1116 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
1117
1118 pi->unacked_frames++;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001119 pi->frames_sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001120
1121 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1122 sk->sk_send_head = NULL;
1123 else
1124 sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001125
1126 nsent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001127 }
1128
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001129 return nsent;
1130}
1131
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001132static int l2cap_retransmit_frames(struct sock *sk)
1133{
1134 struct l2cap_pinfo *pi = l2cap_pi(sk);
1135 int ret;
1136
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001137 if (!skb_queue_empty(TX_QUEUE(sk)))
1138 sk->sk_send_head = TX_QUEUE(sk)->next;
1139
1140 pi->next_tx_seq = pi->expected_ack_seq;
1141 ret = l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001142 return ret;
1143}
1144
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001145static void l2cap_send_ack(struct l2cap_pinfo *pi)
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001146{
1147 struct sock *sk = (struct sock *)pi;
1148 u16 control = 0;
1149
1150 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1151
1152 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
1153 control |= L2CAP_SUPER_RCV_NOT_READY;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03001154 pi->conn_state |= L2CAP_CONN_RNR_SENT;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001155 l2cap_send_sframe(pi, control);
1156 return;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001157 }
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001158
Gustavo F. Padovane0f66212010-06-21 18:50:49 -03001159 if (l2cap_ertm_send(sk) > 0)
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001160 return;
1161
1162 control |= L2CAP_SUPER_RCV_READY;
1163 l2cap_send_sframe(pi, control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001164}
1165
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001166static void l2cap_send_srejtail(struct sock *sk)
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03001167{
1168 struct srej_list *tail;
1169 u16 control;
1170
1171 control = L2CAP_SUPER_SELECT_REJECT;
1172 control |= L2CAP_CTRL_FINAL;
1173
1174 tail = list_entry(SREJ_LIST(sk)->prev, struct srej_list, list);
1175 control |= tail->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1176
1177 l2cap_send_sframe(l2cap_pi(sk), control);
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03001178}
1179
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001180static inline int l2cap_skbuff_fromiovec(struct sock *sk, struct msghdr *msg, int len, int count, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001181{
1182 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001183 struct sk_buff **frag;
1184 int err, sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001185
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03001186 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001187 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001188
1189 sent += count;
1190 len -= count;
1191
1192 /* Continuation fragments (no L2CAP header) */
1193 frag = &skb_shinfo(skb)->frag_list;
1194 while (len) {
1195 count = min_t(unsigned int, conn->mtu, len);
1196
1197 *frag = bt_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err);
1198 if (!*frag)
Gustavo F. Padovan0175d622010-09-24 20:30:57 -03001199 return err;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001200 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
1201 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001202
1203 sent += count;
1204 len -= count;
1205
1206 frag = &(*frag)->next;
1207 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001208
1209 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001210}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001211
Gustavo F. Padovanfd83ccd2011-02-04 03:20:52 -02001212struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, size_t len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001213{
1214 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1215 struct sk_buff *skb;
1216 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1217 struct l2cap_hdr *lh;
1218
1219 BT_DBG("sk %p len %d", sk, (int)len);
1220
1221 count = min_t(unsigned int, (conn->mtu - hlen), len);
1222 skb = bt_skb_send_alloc(sk, count + hlen,
1223 msg->msg_flags & MSG_DONTWAIT, &err);
1224 if (!skb)
Gustavo F. Padovan0175d622010-09-24 20:30:57 -03001225 return ERR_PTR(err);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001226
1227 /* Create L2CAP header */
1228 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1229 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1230 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1231 put_unaligned_le16(l2cap_pi(sk)->psm, skb_put(skb, 2));
1232
1233 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1234 if (unlikely(err < 0)) {
1235 kfree_skb(skb);
1236 return ERR_PTR(err);
1237 }
1238 return skb;
1239}
1240
Gustavo F. Padovanfd83ccd2011-02-04 03:20:52 -02001241struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *msg, size_t len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001242{
1243 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1244 struct sk_buff *skb;
1245 int err, count, hlen = L2CAP_HDR_SIZE;
1246 struct l2cap_hdr *lh;
1247
1248 BT_DBG("sk %p len %d", sk, (int)len);
1249
1250 count = min_t(unsigned int, (conn->mtu - hlen), len);
1251 skb = bt_skb_send_alloc(sk, count + hlen,
1252 msg->msg_flags & MSG_DONTWAIT, &err);
1253 if (!skb)
Gustavo F. Padovan0175d622010-09-24 20:30:57 -03001254 return ERR_PTR(err);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001255
1256 /* Create L2CAP header */
1257 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1258 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1259 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1260
1261 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1262 if (unlikely(err < 0)) {
1263 kfree_skb(skb);
1264 return ERR_PTR(err);
1265 }
1266 return skb;
1267}
1268
Gustavo F. Padovanfd83ccd2011-02-04 03:20:52 -02001269struct sk_buff *l2cap_create_iframe_pdu(struct sock *sk, struct msghdr *msg, size_t len, u16 control, u16 sdulen)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001270{
1271 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1272 struct sk_buff *skb;
1273 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1274 struct l2cap_hdr *lh;
1275
1276 BT_DBG("sk %p len %d", sk, (int)len);
1277
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03001278 if (!conn)
1279 return ERR_PTR(-ENOTCONN);
1280
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001281 if (sdulen)
1282 hlen += 2;
1283
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001284 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1285 hlen += 2;
1286
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001287 count = min_t(unsigned int, (conn->mtu - hlen), len);
1288 skb = bt_skb_send_alloc(sk, count + hlen,
1289 msg->msg_flags & MSG_DONTWAIT, &err);
1290 if (!skb)
Gustavo F. Padovan0175d622010-09-24 20:30:57 -03001291 return ERR_PTR(err);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001292
1293 /* Create L2CAP header */
1294 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1295 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1296 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1297 put_unaligned_le16(control, skb_put(skb, 2));
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001298 if (sdulen)
1299 put_unaligned_le16(sdulen, skb_put(skb, 2));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001300
1301 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1302 if (unlikely(err < 0)) {
1303 kfree_skb(skb);
1304 return ERR_PTR(err);
1305 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001306
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001307 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1308 put_unaligned_le16(0, skb_put(skb, 2));
1309
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001310 bt_cb(skb)->retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001311 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001312}
1313
Gustavo F. Padovanfd83ccd2011-02-04 03:20:52 -02001314int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001315{
1316 struct l2cap_pinfo *pi = l2cap_pi(sk);
1317 struct sk_buff *skb;
1318 struct sk_buff_head sar_queue;
1319 u16 control;
1320 size_t size = 0;
1321
Gustavo F. Padovanff12fd62010-05-05 22:09:15 -03001322 skb_queue_head_init(&sar_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001323 control = L2CAP_SDU_START;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001324 skb = l2cap_create_iframe_pdu(sk, msg, pi->remote_mps, control, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001325 if (IS_ERR(skb))
1326 return PTR_ERR(skb);
1327
1328 __skb_queue_tail(&sar_queue, skb);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001329 len -= pi->remote_mps;
1330 size += pi->remote_mps;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001331
1332 while (len > 0) {
1333 size_t buflen;
1334
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001335 if (len > pi->remote_mps) {
Gustavo F. Padovan44651b82010-05-01 16:15:43 -03001336 control = L2CAP_SDU_CONTINUE;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001337 buflen = pi->remote_mps;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001338 } else {
Gustavo F. Padovan44651b82010-05-01 16:15:43 -03001339 control = L2CAP_SDU_END;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001340 buflen = len;
1341 }
1342
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001343 skb = l2cap_create_iframe_pdu(sk, msg, buflen, control, 0);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001344 if (IS_ERR(skb)) {
1345 skb_queue_purge(&sar_queue);
1346 return PTR_ERR(skb);
1347 }
1348
1349 __skb_queue_tail(&sar_queue, skb);
1350 len -= buflen;
1351 size += buflen;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001352 }
1353 skb_queue_splice_tail(&sar_queue, TX_QUEUE(sk));
1354 if (sk->sk_send_head == NULL)
1355 sk->sk_send_head = sar_queue.next;
1356
1357 return size;
1358}
1359
Linus Torvalds1da177e2005-04-16 15:20:36 -07001360static void l2cap_chan_ready(struct sock *sk)
1361{
1362 struct sock *parent = bt_sk(sk)->parent;
1363
1364 BT_DBG("sk %p, parent %p", sk, parent);
1365
1366 l2cap_pi(sk)->conf_state = 0;
1367 l2cap_sock_clear_timer(sk);
1368
1369 if (!parent) {
1370 /* Outgoing channel.
1371 * Wake up socket sleeping on connect.
1372 */
1373 sk->sk_state = BT_CONNECTED;
1374 sk->sk_state_change(sk);
1375 } else {
1376 /* Incoming channel.
1377 * Wake up socket sleeping on accept.
1378 */
1379 parent->sk_data_ready(parent, 0);
1380 }
1381}
1382
1383/* Copy frame to all raw sockets on that connection */
1384static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
1385{
1386 struct l2cap_chan_list *l = &conn->chan_list;
1387 struct sk_buff *nskb;
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001388 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001389
1390 BT_DBG("conn %p", conn);
1391
1392 read_lock(&l->lock);
1393 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
1394 if (sk->sk_type != SOCK_RAW)
1395 continue;
1396
1397 /* Don't send frame to the socket it came from */
1398 if (skb->sk == sk)
1399 continue;
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001400 nskb = skb_clone(skb, GFP_ATOMIC);
1401 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001402 continue;
1403
1404 if (sock_queue_rcv_skb(sk, nskb))
1405 kfree_skb(nskb);
1406 }
1407 read_unlock(&l->lock);
1408}
1409
1410/* ---- L2CAP signalling commands ---- */
1411static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
1412 u8 code, u8 ident, u16 dlen, void *data)
1413{
1414 struct sk_buff *skb, **frag;
1415 struct l2cap_cmd_hdr *cmd;
1416 struct l2cap_hdr *lh;
1417 int len, count;
1418
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001419 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d",
1420 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001421
1422 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
1423 count = min_t(unsigned int, conn->mtu, len);
1424
1425 skb = bt_skb_alloc(count, GFP_ATOMIC);
1426 if (!skb)
1427 return NULL;
1428
1429 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07001430 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02001431
1432 if (conn->hcon->type == LE_LINK)
1433 lh->cid = cpu_to_le16(L2CAP_CID_LE_SIGNALING);
1434 else
1435 lh->cid = cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001436
1437 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
1438 cmd->code = code;
1439 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07001440 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001441
1442 if (dlen) {
1443 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
1444 memcpy(skb_put(skb, count), data, count);
1445 data += count;
1446 }
1447
1448 len -= skb->len;
1449
1450 /* Continuation fragments (no L2CAP header) */
1451 frag = &skb_shinfo(skb)->frag_list;
1452 while (len) {
1453 count = min_t(unsigned int, conn->mtu, len);
1454
1455 *frag = bt_skb_alloc(count, GFP_ATOMIC);
1456 if (!*frag)
1457 goto fail;
1458
1459 memcpy(skb_put(*frag, count), data, count);
1460
1461 len -= count;
1462 data += count;
1463
1464 frag = &(*frag)->next;
1465 }
1466
1467 return skb;
1468
1469fail:
1470 kfree_skb(skb);
1471 return NULL;
1472}
1473
1474static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned long *val)
1475{
1476 struct l2cap_conf_opt *opt = *ptr;
1477 int len;
1478
1479 len = L2CAP_CONF_OPT_SIZE + opt->len;
1480 *ptr += len;
1481
1482 *type = opt->type;
1483 *olen = opt->len;
1484
1485 switch (opt->len) {
1486 case 1:
1487 *val = *((u8 *) opt->val);
1488 break;
1489
1490 case 2:
steven miaobfaaeb32010-10-16 18:29:47 -04001491 *val = get_unaligned_le16(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001492 break;
1493
1494 case 4:
steven miaobfaaeb32010-10-16 18:29:47 -04001495 *val = get_unaligned_le32(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001496 break;
1497
1498 default:
1499 *val = (unsigned long) opt->val;
1500 break;
1501 }
1502
1503 BT_DBG("type 0x%2.2x len %d val 0x%lx", *type, opt->len, *val);
1504 return len;
1505}
1506
Linus Torvalds1da177e2005-04-16 15:20:36 -07001507static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
1508{
1509 struct l2cap_conf_opt *opt = *ptr;
1510
1511 BT_DBG("type 0x%2.2x len %d val 0x%lx", type, len, val);
1512
1513 opt->type = type;
1514 opt->len = len;
1515
1516 switch (len) {
1517 case 1:
1518 *((u8 *) opt->val) = val;
1519 break;
1520
1521 case 2:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02001522 put_unaligned_le16(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001523 break;
1524
1525 case 4:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02001526 put_unaligned_le32(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001527 break;
1528
1529 default:
1530 memcpy(opt->val, (void *) val, len);
1531 break;
1532 }
1533
1534 *ptr += L2CAP_CONF_OPT_SIZE + len;
1535}
1536
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03001537static void l2cap_ack_timeout(unsigned long arg)
1538{
1539 struct sock *sk = (void *) arg;
1540
1541 bh_lock_sock(sk);
1542 l2cap_send_ack(l2cap_pi(sk));
1543 bh_unlock_sock(sk);
1544}
1545
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03001546static inline void l2cap_ertm_init(struct sock *sk)
1547{
1548 l2cap_pi(sk)->expected_ack_seq = 0;
1549 l2cap_pi(sk)->unacked_frames = 0;
1550 l2cap_pi(sk)->buffer_seq = 0;
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03001551 l2cap_pi(sk)->num_acked = 0;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001552 l2cap_pi(sk)->frames_sent = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03001553
1554 setup_timer(&l2cap_pi(sk)->retrans_timer,
1555 l2cap_retrans_timeout, (unsigned long) sk);
1556 setup_timer(&l2cap_pi(sk)->monitor_timer,
1557 l2cap_monitor_timeout, (unsigned long) sk);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03001558 setup_timer(&l2cap_pi(sk)->ack_timer,
1559 l2cap_ack_timeout, (unsigned long) sk);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03001560
1561 __skb_queue_head_init(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03001562 __skb_queue_head_init(BUSY_QUEUE(sk));
1563
1564 INIT_WORK(&l2cap_pi(sk)->busy_work, l2cap_busy_work);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03001565
1566 sk->sk_backlog_rcv = l2cap_ertm_data_rcv;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03001567}
1568
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001569static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
1570{
1571 switch (mode) {
1572 case L2CAP_MODE_STREAMING:
1573 case L2CAP_MODE_ERTM:
1574 if (l2cap_mode_supported(mode, remote_feat_mask))
1575 return mode;
1576 /* fall through */
1577 default:
1578 return L2CAP_MODE_BASIC;
1579 }
1580}
1581
Gustavo F. Padovan68983252011-02-04 03:02:31 -02001582int l2cap_build_conf_req(struct sock *sk, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001583{
1584 struct l2cap_pinfo *pi = l2cap_pi(sk);
1585 struct l2cap_conf_req *req = data;
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001586 struct l2cap_conf_rfc rfc = { .mode = pi->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07001587 void *ptr = req->data;
1588
1589 BT_DBG("sk %p", sk);
1590
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001591 if (pi->num_conf_req || pi->num_conf_rsp)
1592 goto done;
1593
1594 switch (pi->mode) {
1595 case L2CAP_MODE_STREAMING:
1596 case L2CAP_MODE_ERTM:
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03001597 if (pi->conf_state & L2CAP_CONF_STATE2_DEVICE)
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03001598 break;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03001599
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03001600 /* fall through */
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001601 default:
1602 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
1603 break;
1604 }
1605
1606done:
Gustavo F. Padovan7990681c2011-01-24 16:01:43 -02001607 if (pi->imtu != L2CAP_DEFAULT_MTU)
1608 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
1609
Marcel Holtmann65c7c492009-05-02 23:07:53 -07001610 switch (pi->mode) {
1611 case L2CAP_MODE_BASIC:
Gustavo F. Padovan63406502010-08-03 23:49:29 -03001612 if (!(pi->conn->feat_mask & L2CAP_FEAT_ERTM) &&
1613 !(pi->conn->feat_mask & L2CAP_FEAT_STREAMING))
1614 break;
1615
Gustavo F. Padovan62547752010-06-08 20:05:31 -03001616 rfc.mode = L2CAP_MODE_BASIC;
1617 rfc.txwin_size = 0;
1618 rfc.max_transmit = 0;
1619 rfc.retrans_timeout = 0;
1620 rfc.monitor_timeout = 0;
1621 rfc.max_pdu_size = 0;
1622
Gustavo F. Padovan63406502010-08-03 23:49:29 -03001623 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
1624 (unsigned long) &rfc);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07001625 break;
1626
1627 case L2CAP_MODE_ERTM:
1628 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03001629 rfc.txwin_size = pi->tx_win;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03001630 rfc.max_transmit = pi->max_tx;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001631 rfc.retrans_timeout = 0;
1632 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001633 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03001634 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001635 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001636
Gustavo F. Padovan63406502010-08-03 23:49:29 -03001637 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
1638 (unsigned long) &rfc);
1639
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001640 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
1641 break;
1642
1643 if (pi->fcs == L2CAP_FCS_NONE ||
1644 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
1645 pi->fcs = L2CAP_FCS_NONE;
1646 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
1647 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001648 break;
1649
1650 case L2CAP_MODE_STREAMING:
1651 rfc.mode = L2CAP_MODE_STREAMING;
1652 rfc.txwin_size = 0;
1653 rfc.max_transmit = 0;
1654 rfc.retrans_timeout = 0;
1655 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001656 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03001657 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001658 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07001659
Gustavo F. Padovan63406502010-08-03 23:49:29 -03001660 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
1661 (unsigned long) &rfc);
1662
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001663 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
1664 break;
1665
1666 if (pi->fcs == L2CAP_FCS_NONE ||
1667 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
1668 pi->fcs = L2CAP_FCS_NONE;
1669 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
1670 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07001671 break;
1672 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001673
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07001674 req->dcid = cpu_to_le16(pi->dcid);
1675 req->flags = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001676
1677 return ptr - data;
1678}
1679
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001680static int l2cap_parse_conf_req(struct sock *sk, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001681{
1682 struct l2cap_pinfo *pi = l2cap_pi(sk);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001683 struct l2cap_conf_rsp *rsp = data;
1684 void *ptr = rsp->data;
1685 void *req = pi->conf_req;
1686 int len = pi->conf_len;
1687 int type, hint, olen;
1688 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02001689 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Marcel Holtmann861d6882007-10-20 13:37:06 +02001690 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001691 u16 result = L2CAP_CONF_SUCCESS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001692
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001693 BT_DBG("sk %p", sk);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01001694
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001695 while (len >= L2CAP_CONF_OPT_SIZE) {
1696 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001697
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03001698 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07001699 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001700
1701 switch (type) {
1702 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02001703 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001704 break;
1705
1706 case L2CAP_CONF_FLUSH_TO:
1707 pi->flush_to = val;
1708 break;
1709
1710 case L2CAP_CONF_QOS:
1711 break;
1712
Marcel Holtmann6464f352007-10-20 13:39:51 +02001713 case L2CAP_CONF_RFC:
1714 if (olen == sizeof(rfc))
1715 memcpy(&rfc, (void *) val, olen);
1716 break;
1717
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001718 case L2CAP_CONF_FCS:
1719 if (val == L2CAP_FCS_NONE)
1720 pi->conf_state |= L2CAP_CONF_NO_FCS_RECV;
1721
1722 break;
1723
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001724 default:
1725 if (hint)
1726 break;
1727
1728 result = L2CAP_CONF_UNKNOWN;
1729 *((u8 *) ptr++) = type;
1730 break;
1731 }
1732 }
1733
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001734 if (pi->num_conf_rsp || pi->num_conf_req > 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001735 goto done;
1736
1737 switch (pi->mode) {
1738 case L2CAP_MODE_STREAMING:
1739 case L2CAP_MODE_ERTM:
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03001740 if (!(pi->conf_state & L2CAP_CONF_STATE2_DEVICE)) {
1741 pi->mode = l2cap_select_mode(rfc.mode,
1742 pi->conn->feat_mask);
1743 break;
1744 }
1745
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03001746 if (pi->mode != rfc.mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001747 return -ECONNREFUSED;
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03001748
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001749 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001750 }
1751
1752done:
1753 if (pi->mode != rfc.mode) {
1754 result = L2CAP_CONF_UNACCEPT;
1755 rfc.mode = pi->mode;
1756
1757 if (pi->num_conf_rsp == 1)
1758 return -ECONNREFUSED;
1759
1760 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
1761 sizeof(rfc), (unsigned long) &rfc);
1762 }
1763
1764
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001765 if (result == L2CAP_CONF_SUCCESS) {
1766 /* Configure output options and let the other side know
1767 * which ones we don't like. */
1768
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001769 if (mtu < L2CAP_DEFAULT_MIN_MTU)
1770 result = L2CAP_CONF_UNACCEPT;
1771 else {
1772 pi->omtu = mtu;
1773 pi->conf_state |= L2CAP_CONF_MTU_DONE;
1774 }
1775 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001776
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001777 switch (rfc.mode) {
1778 case L2CAP_MODE_BASIC:
1779 pi->fcs = L2CAP_FCS_NONE;
1780 pi->conf_state |= L2CAP_CONF_MODE_DONE;
1781 break;
1782
1783 case L2CAP_MODE_ERTM:
1784 pi->remote_tx_win = rfc.txwin_size;
1785 pi->remote_max_tx = rfc.max_transmit;
Mat Martineau86b1b262010-08-05 15:54:22 -07001786
1787 if (le16_to_cpu(rfc.max_pdu_size) > pi->conn->mtu - 10)
1788 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001789
1790 pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001791
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03001792 rfc.retrans_timeout =
1793 le16_to_cpu(L2CAP_DEFAULT_RETRANS_TO);
1794 rfc.monitor_timeout =
1795 le16_to_cpu(L2CAP_DEFAULT_MONITOR_TO);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001796
1797 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03001798
1799 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
1800 sizeof(rfc), (unsigned long) &rfc);
1801
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001802 break;
1803
1804 case L2CAP_MODE_STREAMING:
Mat Martineau86b1b262010-08-05 15:54:22 -07001805 if (le16_to_cpu(rfc.max_pdu_size) > pi->conn->mtu - 10)
1806 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001807
1808 pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001809
1810 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03001811
1812 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
1813 sizeof(rfc), (unsigned long) &rfc);
1814
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001815 break;
1816
1817 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02001818 result = L2CAP_CONF_UNACCEPT;
1819
1820 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001821 rfc.mode = pi->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02001822 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001823
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001824 if (result == L2CAP_CONF_SUCCESS)
1825 pi->conf_state |= L2CAP_CONF_OUTPUT_DONE;
1826 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001827 rsp->scid = cpu_to_le16(pi->dcid);
1828 rsp->result = cpu_to_le16(result);
1829 rsp->flags = cpu_to_le16(0x0000);
1830
1831 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001832}
1833
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001834static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data, u16 *result)
1835{
1836 struct l2cap_pinfo *pi = l2cap_pi(sk);
1837 struct l2cap_conf_req *req = data;
1838 void *ptr = req->data;
1839 int type, olen;
1840 unsigned long val;
1841 struct l2cap_conf_rfc rfc;
1842
1843 BT_DBG("sk %p, rsp %p, len %d, req %p", sk, rsp, len, data);
1844
1845 while (len >= L2CAP_CONF_OPT_SIZE) {
1846 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
1847
1848 switch (type) {
1849 case L2CAP_CONF_MTU:
1850 if (val < L2CAP_DEFAULT_MIN_MTU) {
1851 *result = L2CAP_CONF_UNACCEPT;
Andrei Emeltchenko8183b772010-09-01 15:17:25 +03001852 pi->imtu = L2CAP_DEFAULT_MIN_MTU;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001853 } else
Andrei Emeltchenko8183b772010-09-01 15:17:25 +03001854 pi->imtu = val;
1855 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001856 break;
1857
1858 case L2CAP_CONF_FLUSH_TO:
1859 pi->flush_to = val;
1860 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
1861 2, pi->flush_to);
1862 break;
1863
1864 case L2CAP_CONF_RFC:
1865 if (olen == sizeof(rfc))
1866 memcpy(&rfc, (void *)val, olen);
1867
1868 if ((pi->conf_state & L2CAP_CONF_STATE2_DEVICE) &&
1869 rfc.mode != pi->mode)
1870 return -ECONNREFUSED;
1871
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001872 pi->fcs = 0;
1873
1874 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
1875 sizeof(rfc), (unsigned long) &rfc);
1876 break;
1877 }
1878 }
1879
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03001880 if (pi->mode == L2CAP_MODE_BASIC && pi->mode != rfc.mode)
1881 return -ECONNREFUSED;
1882
1883 pi->mode = rfc.mode;
1884
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001885 if (*result == L2CAP_CONF_SUCCESS) {
1886 switch (rfc.mode) {
1887 case L2CAP_MODE_ERTM:
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03001888 pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
1889 pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001890 pi->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001891 break;
1892 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001893 pi->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001894 }
1895 }
1896
1897 req->dcid = cpu_to_le16(pi->dcid);
1898 req->flags = cpu_to_le16(0x0000);
1899
1900 return ptr - data;
1901}
1902
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001903static int l2cap_build_conf_rsp(struct sock *sk, void *data, u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001904{
1905 struct l2cap_conf_rsp *rsp = data;
1906 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001907
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001908 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001909
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07001910 rsp->scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001911 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07001912 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001913
1914 return ptr - data;
1915}
1916
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03001917static void l2cap_conf_rfc_get(struct sock *sk, void *rsp, int len)
1918{
1919 struct l2cap_pinfo *pi = l2cap_pi(sk);
1920 int type, olen;
1921 unsigned long val;
1922 struct l2cap_conf_rfc rfc;
1923
1924 BT_DBG("sk %p, rsp %p, len %d", sk, rsp, len);
1925
1926 if ((pi->mode != L2CAP_MODE_ERTM) && (pi->mode != L2CAP_MODE_STREAMING))
1927 return;
1928
1929 while (len >= L2CAP_CONF_OPT_SIZE) {
1930 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
1931
1932 switch (type) {
1933 case L2CAP_CONF_RFC:
1934 if (olen == sizeof(rfc))
1935 memcpy(&rfc, (void *)val, olen);
1936 goto done;
1937 }
1938 }
1939
1940done:
1941 switch (rfc.mode) {
1942 case L2CAP_MODE_ERTM:
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03001943 pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
1944 pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03001945 pi->mps = le16_to_cpu(rfc.max_pdu_size);
1946 break;
1947 case L2CAP_MODE_STREAMING:
1948 pi->mps = le16_to_cpu(rfc.max_pdu_size);
1949 }
1950}
1951
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001952static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
1953{
1954 struct l2cap_cmd_rej *rej = (struct l2cap_cmd_rej *) data;
1955
1956 if (rej->reason != 0x0000)
1957 return 0;
1958
1959 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
1960 cmd->ident == conn->info_ident) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001961 del_timer(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01001962
1963 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01001964 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01001965
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001966 l2cap_conn_start(conn);
1967 }
1968
1969 return 0;
1970}
1971
Linus Torvalds1da177e2005-04-16 15:20:36 -07001972static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
1973{
1974 struct l2cap_chan_list *list = &conn->chan_list;
1975 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
1976 struct l2cap_conn_rsp rsp;
Nathan Holsteind793fe82010-10-15 11:54:02 -04001977 struct sock *parent, *sk = NULL;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02001978 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001979
1980 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02001981 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001982
1983 BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
1984
1985 /* Check if we have socket listening on psm */
1986 parent = l2cap_get_sock_by_psm(BT_LISTEN, psm, conn->src);
1987 if (!parent) {
1988 result = L2CAP_CR_BAD_PSM;
1989 goto sendresp;
1990 }
1991
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001992 bh_lock_sock(parent);
1993
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02001994 /* Check if the ACL is secure enough (if not SDP) */
1995 if (psm != cpu_to_le16(0x0001) &&
1996 !hci_conn_check_link_mode(conn->hcon)) {
Marcel Holtmann2950f212009-02-12 14:02:50 +01001997 conn->disc_reason = 0x05;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02001998 result = L2CAP_CR_SEC_BLOCK;
1999 goto response;
2000 }
2001
Linus Torvalds1da177e2005-04-16 15:20:36 -07002002 result = L2CAP_CR_NO_MEM;
2003
2004 /* Check for backlog size */
2005 if (sk_acceptq_is_full(parent)) {
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09002006 BT_DBG("backlog full %d", parent->sk_ack_backlog);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002007 goto response;
2008 }
2009
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09002010 sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002011 if (!sk)
2012 goto response;
2013
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002014 write_lock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002015
2016 /* Check if we already have channel with that dcid */
2017 if (__l2cap_get_chan_by_dcid(list, scid)) {
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002018 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002019 sock_set_flag(sk, SOCK_ZAPPED);
2020 l2cap_sock_kill(sk);
2021 goto response;
2022 }
2023
2024 hci_conn_hold(conn->hcon);
2025
2026 l2cap_sock_init(sk, parent);
2027 bacpy(&bt_sk(sk)->src, conn->src);
2028 bacpy(&bt_sk(sk)->dst, conn->dst);
2029 l2cap_pi(sk)->psm = psm;
2030 l2cap_pi(sk)->dcid = scid;
2031
2032 __l2cap_chan_add(conn, sk, parent);
2033 dcid = l2cap_pi(sk)->scid;
2034
2035 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
2036
Linus Torvalds1da177e2005-04-16 15:20:36 -07002037 l2cap_pi(sk)->ident = cmd->ident;
2038
Marcel Holtmann984947d2009-02-06 23:35:19 +01002039 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002040 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002041 if (bt_sk(sk)->defer_setup) {
2042 sk->sk_state = BT_CONNECT2;
2043 result = L2CAP_CR_PEND;
2044 status = L2CAP_CS_AUTHOR_PEND;
2045 parent->sk_data_ready(parent, 0);
2046 } else {
2047 sk->sk_state = BT_CONFIG;
2048 result = L2CAP_CR_SUCCESS;
2049 status = L2CAP_CS_NO_INFO;
2050 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002051 } else {
2052 sk->sk_state = BT_CONNECT2;
2053 result = L2CAP_CR_PEND;
2054 status = L2CAP_CS_AUTHEN_PEND;
2055 }
2056 } else {
2057 sk->sk_state = BT_CONNECT2;
2058 result = L2CAP_CR_PEND;
2059 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002060 }
2061
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002062 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002063
2064response:
2065 bh_unlock_sock(parent);
2066
2067sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002068 rsp.scid = cpu_to_le16(scid);
2069 rsp.dcid = cpu_to_le16(dcid);
2070 rsp.result = cpu_to_le16(result);
2071 rsp.status = cpu_to_le16(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002072 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002073
2074 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
2075 struct l2cap_info_req info;
2076 info.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
2077
2078 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
2079 conn->info_ident = l2cap_get_ident(conn);
2080
2081 mod_timer(&conn->info_timer, jiffies +
2082 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
2083
2084 l2cap_send_cmd(conn, conn->info_ident,
2085 L2CAP_INFO_REQ, sizeof(info), &info);
2086 }
2087
Nathan Holsteind793fe82010-10-15 11:54:02 -04002088 if (sk && !(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) &&
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03002089 result == L2CAP_CR_SUCCESS) {
2090 u8 buf[128];
2091 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
2092 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
2093 l2cap_build_conf_req(sk, buf), buf);
2094 l2cap_pi(sk)->num_conf_req++;
2095 }
2096
Linus Torvalds1da177e2005-04-16 15:20:36 -07002097 return 0;
2098}
2099
2100static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2101{
2102 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
2103 u16 scid, dcid, result, status;
2104 struct sock *sk;
2105 u8 req[128];
2106
2107 scid = __le16_to_cpu(rsp->scid);
2108 dcid = __le16_to_cpu(rsp->dcid);
2109 result = __le16_to_cpu(rsp->result);
2110 status = __le16_to_cpu(rsp->status);
2111
2112 BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
2113
2114 if (scid) {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002115 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2116 if (!sk)
João Paulo Rechi Vita57d3b222010-06-22 13:56:26 -03002117 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002118 } else {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002119 sk = l2cap_get_chan_by_ident(&conn->chan_list, cmd->ident);
2120 if (!sk)
João Paulo Rechi Vita57d3b222010-06-22 13:56:26 -03002121 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002122 }
2123
2124 switch (result) {
2125 case L2CAP_CR_SUCCESS:
2126 sk->sk_state = BT_CONFIG;
2127 l2cap_pi(sk)->ident = 0;
2128 l2cap_pi(sk)->dcid = dcid;
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002129 l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_CONNECT_PEND;
2130
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03002131 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)
2132 break;
2133
2134 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
2135
Linus Torvalds1da177e2005-04-16 15:20:36 -07002136 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
2137 l2cap_build_conf_req(sk, req), req);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002138 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002139 break;
2140
2141 case L2CAP_CR_PEND:
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002142 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002143 break;
2144
2145 default:
Andrei Emeltchenkoa49184c2010-11-03 12:32:44 +02002146 /* don't delete l2cap channel if sk is owned by user */
2147 if (sock_owned_by_user(sk)) {
2148 sk->sk_state = BT_DISCONN;
2149 l2cap_sock_clear_timer(sk);
2150 l2cap_sock_set_timer(sk, HZ / 5);
2151 break;
2152 }
2153
Linus Torvalds1da177e2005-04-16 15:20:36 -07002154 l2cap_chan_del(sk, ECONNREFUSED);
2155 break;
2156 }
2157
2158 bh_unlock_sock(sk);
2159 return 0;
2160}
2161
Mat Martineau8c462b62010-08-24 15:35:42 -07002162static inline void set_default_fcs(struct l2cap_pinfo *pi)
2163{
2164 /* FCS is enabled only in ERTM or streaming mode, if one or both
2165 * sides request it.
2166 */
2167 if (pi->mode != L2CAP_MODE_ERTM && pi->mode != L2CAP_MODE_STREAMING)
2168 pi->fcs = L2CAP_FCS_NONE;
2169 else if (!(pi->conf_state & L2CAP_CONF_NO_FCS_RECV))
2170 pi->fcs = L2CAP_FCS_CRC16;
2171}
2172
Al Viro88219a02007-07-29 00:17:25 -07002173static 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 -07002174{
2175 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
2176 u16 dcid, flags;
2177 u8 rsp[64];
2178 struct sock *sk;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002179 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002180
2181 dcid = __le16_to_cpu(req->dcid);
2182 flags = __le16_to_cpu(req->flags);
2183
2184 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
2185
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002186 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
2187 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002188 return -ENOENT;
2189
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03002190 if (sk->sk_state != BT_CONFIG) {
2191 struct l2cap_cmd_rej rej;
2192
2193 rej.reason = cpu_to_le16(0x0002);
2194 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
2195 sizeof(rej), &rej);
Marcel Holtmann354f60a2006-11-18 22:15:20 +01002196 goto unlock;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03002197 }
Marcel Holtmann354f60a2006-11-18 22:15:20 +01002198
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002199 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07002200 len = cmd_len - sizeof(*req);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002201 if (l2cap_pi(sk)->conf_len + len > sizeof(l2cap_pi(sk)->conf_req)) {
2202 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
2203 l2cap_build_conf_rsp(sk, rsp,
2204 L2CAP_CONF_REJECT, flags), rsp);
2205 goto unlock;
2206 }
2207
2208 /* Store config. */
2209 memcpy(l2cap_pi(sk)->conf_req + l2cap_pi(sk)->conf_len, req->data, len);
2210 l2cap_pi(sk)->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002211
2212 if (flags & 0x0001) {
2213 /* Incomplete config. Send empty response. */
2214 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002215 l2cap_build_conf_rsp(sk, rsp,
2216 L2CAP_CONF_SUCCESS, 0x0001), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002217 goto unlock;
2218 }
2219
2220 /* Complete config. */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002221 len = l2cap_parse_conf_req(sk, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002222 if (len < 0) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03002223 l2cap_send_disconn_req(conn, sk, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002224 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002225 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002226
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002227 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002228 l2cap_pi(sk)->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002229
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002230 /* Reset config buffer. */
2231 l2cap_pi(sk)->conf_len = 0;
2232
Marcel Holtmann876d9482007-10-20 13:35:42 +02002233 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE))
2234 goto unlock;
2235
Linus Torvalds1da177e2005-04-16 15:20:36 -07002236 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) {
Mat Martineau8c462b62010-08-24 15:35:42 -07002237 set_default_fcs(l2cap_pi(sk));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002238
Linus Torvalds1da177e2005-04-16 15:20:36 -07002239 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002240
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002241 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002242 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002243 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002244 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
2245 l2cap_ertm_init(sk);
2246
Linus Torvalds1da177e2005-04-16 15:20:36 -07002247 l2cap_chan_ready(sk);
Marcel Holtmann876d9482007-10-20 13:35:42 +02002248 goto unlock;
2249 }
2250
2251 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002252 u8 buf[64];
Haijun Liuab3e5712010-09-30 16:52:40 +08002253 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002254 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002255 l2cap_build_conf_req(sk, buf), buf);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002256 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002257 }
2258
2259unlock:
2260 bh_unlock_sock(sk);
2261 return 0;
2262}
2263
2264static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2265{
2266 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
2267 u16 scid, flags, result;
2268 struct sock *sk;
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002269 int len = cmd->len - sizeof(*rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002270
2271 scid = __le16_to_cpu(rsp->scid);
2272 flags = __le16_to_cpu(rsp->flags);
2273 result = __le16_to_cpu(rsp->result);
2274
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002275 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x",
2276 scid, flags, result);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002277
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002278 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2279 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002280 return 0;
2281
2282 switch (result) {
2283 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002284 l2cap_conf_rfc_get(sk, rsp->data, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002285 break;
2286
2287 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002288 if (l2cap_pi(sk)->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002289 char req[64];
2290
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02002291 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03002292 l2cap_send_disconn_req(conn, sk, ECONNRESET);
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02002293 goto done;
2294 }
2295
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002296 /* throw out any old stored conf requests */
2297 result = L2CAP_CONF_SUCCESS;
2298 len = l2cap_parse_conf_rsp(sk, rsp->data,
2299 len, req, &result);
2300 if (len < 0) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03002301 l2cap_send_disconn_req(conn, sk, ECONNRESET);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002302 goto done;
2303 }
2304
2305 l2cap_send_cmd(conn, l2cap_get_ident(conn),
2306 L2CAP_CONF_REQ, len, req);
2307 l2cap_pi(sk)->num_conf_req++;
2308 if (result != L2CAP_CONF_SUCCESS)
2309 goto done;
2310 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002311 }
2312
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09002313 default:
Marcel Holtmannb1235d72008-07-14 20:13:54 +02002314 sk->sk_err = ECONNRESET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002315 l2cap_sock_set_timer(sk, HZ * 5);
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03002316 l2cap_send_disconn_req(conn, sk, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002317 goto done;
2318 }
2319
2320 if (flags & 0x01)
2321 goto done;
2322
Linus Torvalds1da177e2005-04-16 15:20:36 -07002323 l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE;
2324
2325 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) {
Mat Martineau8c462b62010-08-24 15:35:42 -07002326 set_default_fcs(l2cap_pi(sk));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002327
Linus Torvalds1da177e2005-04-16 15:20:36 -07002328 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002329 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002330 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002331 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002332 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
2333 l2cap_ertm_init(sk);
2334
Linus Torvalds1da177e2005-04-16 15:20:36 -07002335 l2cap_chan_ready(sk);
2336 }
2337
2338done:
2339 bh_unlock_sock(sk);
2340 return 0;
2341}
2342
2343static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2344{
2345 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
2346 struct l2cap_disconn_rsp rsp;
2347 u16 dcid, scid;
2348 struct sock *sk;
2349
2350 scid = __le16_to_cpu(req->scid);
2351 dcid = __le16_to_cpu(req->dcid);
2352
2353 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
2354
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002355 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
2356 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002357 return 0;
2358
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002359 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
2360 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002361 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
2362
2363 sk->sk_shutdown = SHUTDOWN_MASK;
2364
Andrei Emeltchenkoa49184c2010-11-03 12:32:44 +02002365 /* don't delete l2cap channel if sk is owned by user */
2366 if (sock_owned_by_user(sk)) {
2367 sk->sk_state = BT_DISCONN;
2368 l2cap_sock_clear_timer(sk);
2369 l2cap_sock_set_timer(sk, HZ / 5);
2370 bh_unlock_sock(sk);
2371 return 0;
2372 }
2373
Linus Torvalds1da177e2005-04-16 15:20:36 -07002374 l2cap_chan_del(sk, ECONNRESET);
2375 bh_unlock_sock(sk);
2376
2377 l2cap_sock_kill(sk);
2378 return 0;
2379}
2380
2381static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2382{
2383 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
2384 u16 dcid, scid;
2385 struct sock *sk;
2386
2387 scid = __le16_to_cpu(rsp->scid);
2388 dcid = __le16_to_cpu(rsp->dcid);
2389
2390 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
2391
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002392 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2393 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002394 return 0;
2395
Andrei Emeltchenkoa49184c2010-11-03 12:32:44 +02002396 /* don't delete l2cap channel if sk is owned by user */
2397 if (sock_owned_by_user(sk)) {
2398 sk->sk_state = BT_DISCONN;
2399 l2cap_sock_clear_timer(sk);
2400 l2cap_sock_set_timer(sk, HZ / 5);
2401 bh_unlock_sock(sk);
2402 return 0;
2403 }
2404
Linus Torvalds1da177e2005-04-16 15:20:36 -07002405 l2cap_chan_del(sk, 0);
2406 bh_unlock_sock(sk);
2407
2408 l2cap_sock_kill(sk);
2409 return 0;
2410}
2411
2412static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2413{
2414 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002415 u16 type;
2416
2417 type = __le16_to_cpu(req->type);
2418
2419 BT_DBG("type 0x%4.4x", type);
2420
Marcel Holtmannf0709e02007-10-20 13:38:51 +02002421 if (type == L2CAP_IT_FEAT_MASK) {
2422 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07002423 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02002424 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
2425 rsp->type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
2426 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03002427 if (!disable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002428 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
2429 | L2CAP_FEAT_FCS;
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03002430 put_unaligned_le32(feat_mask, rsp->data);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02002431 l2cap_send_cmd(conn, cmd->ident,
2432 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002433 } else if (type == L2CAP_IT_FIXED_CHAN) {
2434 u8 buf[12];
2435 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
2436 rsp->type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
2437 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
2438 memcpy(buf + 4, l2cap_fixed_chan, 8);
2439 l2cap_send_cmd(conn, cmd->ident,
2440 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02002441 } else {
2442 struct l2cap_info_rsp rsp;
2443 rsp.type = cpu_to_le16(type);
2444 rsp.result = cpu_to_le16(L2CAP_IR_NOTSUPP);
2445 l2cap_send_cmd(conn, cmd->ident,
2446 L2CAP_INFO_RSP, sizeof(rsp), &rsp);
2447 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002448
2449 return 0;
2450}
2451
2452static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2453{
2454 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
2455 u16 type, result;
2456
2457 type = __le16_to_cpu(rsp->type);
2458 result = __le16_to_cpu(rsp->result);
2459
2460 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
2461
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002462 del_timer(&conn->info_timer);
2463
Ville Tervoadb08ed2010-08-04 09:43:33 +03002464 if (result != L2CAP_IR_SUCCESS) {
2465 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
2466 conn->info_ident = 0;
2467
2468 l2cap_conn_start(conn);
2469
2470 return 0;
2471 }
2472
Marcel Holtmann984947d2009-02-06 23:35:19 +01002473 if (type == L2CAP_IT_FEAT_MASK) {
Harvey Harrison83985312008-05-02 16:25:46 -07002474 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002475
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07002476 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002477 struct l2cap_info_req req;
2478 req.type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
2479
2480 conn->info_ident = l2cap_get_ident(conn);
2481
2482 l2cap_send_cmd(conn, conn->info_ident,
2483 L2CAP_INFO_REQ, sizeof(req), &req);
2484 } else {
2485 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
2486 conn->info_ident = 0;
2487
2488 l2cap_conn_start(conn);
2489 }
2490 } else if (type == L2CAP_IT_FIXED_CHAN) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01002491 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002492 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01002493
2494 l2cap_conn_start(conn);
2495 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002496
Linus Torvalds1da177e2005-04-16 15:20:36 -07002497 return 0;
2498}
2499
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03002500static inline int l2cap_check_conn_param(u16 min, u16 max, u16 latency,
Claudio Takahaside731152011-02-11 19:28:55 -02002501 u16 to_multiplier)
2502{
2503 u16 max_latency;
2504
2505 if (min > max || min < 6 || max > 3200)
2506 return -EINVAL;
2507
2508 if (to_multiplier < 10 || to_multiplier > 3200)
2509 return -EINVAL;
2510
2511 if (max >= to_multiplier * 8)
2512 return -EINVAL;
2513
2514 max_latency = (to_multiplier * 8 / max) - 1;
2515 if (latency > 499 || latency > max_latency)
2516 return -EINVAL;
2517
2518 return 0;
2519}
2520
2521static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
2522 struct l2cap_cmd_hdr *cmd, u8 *data)
2523{
2524 struct hci_conn *hcon = conn->hcon;
2525 struct l2cap_conn_param_update_req *req;
2526 struct l2cap_conn_param_update_rsp rsp;
2527 u16 min, max, latency, to_multiplier, cmd_len;
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02002528 int err;
Claudio Takahaside731152011-02-11 19:28:55 -02002529
2530 if (!(hcon->link_mode & HCI_LM_MASTER))
2531 return -EINVAL;
2532
2533 cmd_len = __le16_to_cpu(cmd->len);
2534 if (cmd_len != sizeof(struct l2cap_conn_param_update_req))
2535 return -EPROTO;
2536
2537 req = (struct l2cap_conn_param_update_req *) data;
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03002538 min = __le16_to_cpu(req->min);
2539 max = __le16_to_cpu(req->max);
Claudio Takahaside731152011-02-11 19:28:55 -02002540 latency = __le16_to_cpu(req->latency);
2541 to_multiplier = __le16_to_cpu(req->to_multiplier);
2542
2543 BT_DBG("min 0x%4.4x max 0x%4.4x latency: 0x%4.4x Timeout: 0x%4.4x",
2544 min, max, latency, to_multiplier);
2545
2546 memset(&rsp, 0, sizeof(rsp));
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02002547
2548 err = l2cap_check_conn_param(min, max, latency, to_multiplier);
2549 if (err)
Claudio Takahaside731152011-02-11 19:28:55 -02002550 rsp.result = cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
2551 else
2552 rsp.result = cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED);
2553
2554 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP,
2555 sizeof(rsp), &rsp);
2556
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02002557 if (!err)
2558 hci_le_conn_update(hcon, min, max, latency, to_multiplier);
2559
Claudio Takahaside731152011-02-11 19:28:55 -02002560 return 0;
2561}
2562
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002563static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
2564 struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
2565{
2566 int err = 0;
2567
2568 switch (cmd->code) {
2569 case L2CAP_COMMAND_REJ:
2570 l2cap_command_rej(conn, cmd, data);
2571 break;
2572
2573 case L2CAP_CONN_REQ:
2574 err = l2cap_connect_req(conn, cmd, data);
2575 break;
2576
2577 case L2CAP_CONN_RSP:
2578 err = l2cap_connect_rsp(conn, cmd, data);
2579 break;
2580
2581 case L2CAP_CONF_REQ:
2582 err = l2cap_config_req(conn, cmd, cmd_len, data);
2583 break;
2584
2585 case L2CAP_CONF_RSP:
2586 err = l2cap_config_rsp(conn, cmd, data);
2587 break;
2588
2589 case L2CAP_DISCONN_REQ:
2590 err = l2cap_disconnect_req(conn, cmd, data);
2591 break;
2592
2593 case L2CAP_DISCONN_RSP:
2594 err = l2cap_disconnect_rsp(conn, cmd, data);
2595 break;
2596
2597 case L2CAP_ECHO_REQ:
2598 l2cap_send_cmd(conn, cmd->ident, L2CAP_ECHO_RSP, cmd_len, data);
2599 break;
2600
2601 case L2CAP_ECHO_RSP:
2602 break;
2603
2604 case L2CAP_INFO_REQ:
2605 err = l2cap_information_req(conn, cmd, data);
2606 break;
2607
2608 case L2CAP_INFO_RSP:
2609 err = l2cap_information_rsp(conn, cmd, data);
2610 break;
2611
2612 default:
2613 BT_ERR("Unknown BR/EDR signaling command 0x%2.2x", cmd->code);
2614 err = -EINVAL;
2615 break;
2616 }
2617
2618 return err;
2619}
2620
2621static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn,
2622 struct l2cap_cmd_hdr *cmd, u8 *data)
2623{
2624 switch (cmd->code) {
2625 case L2CAP_COMMAND_REJ:
2626 return 0;
2627
2628 case L2CAP_CONN_PARAM_UPDATE_REQ:
Claudio Takahaside731152011-02-11 19:28:55 -02002629 return l2cap_conn_param_update_req(conn, cmd, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002630
2631 case L2CAP_CONN_PARAM_UPDATE_RSP:
2632 return 0;
2633
2634 default:
2635 BT_ERR("Unknown LE signaling command 0x%2.2x", cmd->code);
2636 return -EINVAL;
2637 }
2638}
2639
2640static inline void l2cap_sig_channel(struct l2cap_conn *conn,
2641 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002642{
2643 u8 *data = skb->data;
2644 int len = skb->len;
2645 struct l2cap_cmd_hdr cmd;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002646 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002647
2648 l2cap_raw_recv(conn, skb);
2649
2650 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07002651 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002652 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
2653 data += L2CAP_CMD_HDR_SIZE;
2654 len -= L2CAP_CMD_HDR_SIZE;
2655
Al Viro88219a02007-07-29 00:17:25 -07002656 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002657
Al Viro88219a02007-07-29 00:17:25 -07002658 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 -07002659
Al Viro88219a02007-07-29 00:17:25 -07002660 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002661 BT_DBG("corrupted command");
2662 break;
2663 }
2664
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002665 if (conn->hcon->type == LE_LINK)
2666 err = l2cap_le_sig_cmd(conn, &cmd, data);
2667 else
2668 err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002669
2670 if (err) {
2671 struct l2cap_cmd_rej rej;
2672 BT_DBG("error %d", err);
2673
2674 /* FIXME: Map err to a valid reason */
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002675 rej.reason = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002676 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
2677 }
2678
Al Viro88219a02007-07-29 00:17:25 -07002679 data += cmd_len;
2680 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002681 }
2682
2683 kfree_skb(skb);
2684}
2685
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002686static int l2cap_check_fcs(struct l2cap_pinfo *pi, struct sk_buff *skb)
2687{
2688 u16 our_fcs, rcv_fcs;
2689 int hdr_size = L2CAP_HDR_SIZE + 2;
2690
2691 if (pi->fcs == L2CAP_FCS_CRC16) {
2692 skb_trim(skb, skb->len - 2);
2693 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
2694 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
2695
2696 if (our_fcs != rcv_fcs)
João Paulo Rechi Vita7a560e52010-06-22 13:56:27 -03002697 return -EBADMSG;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002698 }
2699 return 0;
2700}
2701
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03002702static inline void l2cap_send_i_or_rr_or_rnr(struct sock *sk)
2703{
2704 struct l2cap_pinfo *pi = l2cap_pi(sk);
2705 u16 control = 0;
2706
2707 pi->frames_sent = 0;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03002708
2709 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
2710
2711 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
Gustavo F. Padovan64988862010-05-10 14:54:14 -03002712 control |= L2CAP_SUPER_RCV_NOT_READY;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03002713 l2cap_send_sframe(pi, control);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002714 pi->conn_state |= L2CAP_CONN_RNR_SENT;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03002715 }
2716
Gustavo F. Padovan4ea727e2010-06-03 16:34:20 -03002717 if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY)
2718 l2cap_retransmit_frames(sk);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03002719
2720 l2cap_ertm_send(sk);
2721
2722 if (!(pi->conn_state & L2CAP_CONN_LOCAL_BUSY) &&
2723 pi->frames_sent == 0) {
2724 control |= L2CAP_SUPER_RCV_READY;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03002725 l2cap_send_sframe(pi, control);
2726 }
2727}
2728
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03002729static 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 -03002730{
2731 struct sk_buff *next_skb;
João Paulo Rechi Vitabfbacc12010-05-31 18:35:44 -03002732 struct l2cap_pinfo *pi = l2cap_pi(sk);
2733 int tx_seq_offset, next_tx_seq_offset;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03002734
2735 bt_cb(skb)->tx_seq = tx_seq;
2736 bt_cb(skb)->sar = sar;
2737
2738 next_skb = skb_peek(SREJ_QUEUE(sk));
2739 if (!next_skb) {
2740 __skb_queue_tail(SREJ_QUEUE(sk), skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03002741 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03002742 }
2743
João Paulo Rechi Vitabfbacc12010-05-31 18:35:44 -03002744 tx_seq_offset = (tx_seq - pi->buffer_seq) % 64;
2745 if (tx_seq_offset < 0)
2746 tx_seq_offset += 64;
2747
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03002748 do {
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03002749 if (bt_cb(next_skb)->tx_seq == tx_seq)
2750 return -EINVAL;
2751
João Paulo Rechi Vitabfbacc12010-05-31 18:35:44 -03002752 next_tx_seq_offset = (bt_cb(next_skb)->tx_seq -
2753 pi->buffer_seq) % 64;
2754 if (next_tx_seq_offset < 0)
2755 next_tx_seq_offset += 64;
2756
2757 if (next_tx_seq_offset > tx_seq_offset) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03002758 __skb_queue_before(SREJ_QUEUE(sk), next_skb, skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03002759 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03002760 }
2761
2762 if (skb_queue_is_last(SREJ_QUEUE(sk), next_skb))
2763 break;
2764
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03002765 } while ((next_skb = skb_queue_next(SREJ_QUEUE(sk), next_skb)));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03002766
2767 __skb_queue_tail(SREJ_QUEUE(sk), skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03002768
2769 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03002770}
2771
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002772static int l2cap_ertm_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
2773{
2774 struct l2cap_pinfo *pi = l2cap_pi(sk);
2775 struct sk_buff *_skb;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002776 int err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002777
2778 switch (control & L2CAP_CTRL_SAR) {
2779 case L2CAP_SDU_UNSEGMENTED:
2780 if (pi->conn_state & L2CAP_CONN_SAR_SDU)
2781 goto drop;
2782
2783 err = sock_queue_rcv_skb(sk, skb);
2784 if (!err)
2785 return err;
2786
2787 break;
2788
2789 case L2CAP_SDU_START:
2790 if (pi->conn_state & L2CAP_CONN_SAR_SDU)
2791 goto drop;
2792
2793 pi->sdu_len = get_unaligned_le16(skb->data);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002794
2795 if (pi->sdu_len > pi->imtu)
2796 goto disconnect;
2797
2798 pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002799 if (!pi->sdu)
2800 return -ENOMEM;
2801
2802 /* pull sdu_len bytes only after alloc, because of Local Busy
2803 * condition we have to be sure that this will be executed
2804 * only once, i.e., when alloc does not fail */
2805 skb_pull(skb, 2);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002806
2807 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
2808
2809 pi->conn_state |= L2CAP_CONN_SAR_SDU;
2810 pi->partial_sdu_len = skb->len;
2811 break;
2812
2813 case L2CAP_SDU_CONTINUE:
2814 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
2815 goto disconnect;
2816
2817 if (!pi->sdu)
2818 goto disconnect;
2819
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002820 pi->partial_sdu_len += skb->len;
2821 if (pi->partial_sdu_len > pi->sdu_len)
2822 goto drop;
2823
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03002824 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
2825
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002826 break;
2827
2828 case L2CAP_SDU_END:
2829 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
2830 goto disconnect;
2831
2832 if (!pi->sdu)
2833 goto disconnect;
2834
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002835 if (!(pi->conn_state & L2CAP_CONN_SAR_RETRY)) {
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002836 pi->partial_sdu_len += skb->len;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002837
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002838 if (pi->partial_sdu_len > pi->imtu)
2839 goto drop;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002840
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002841 if (pi->partial_sdu_len != pi->sdu_len)
2842 goto drop;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03002843
2844 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002845 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002846
2847 _skb = skb_clone(pi->sdu, GFP_ATOMIC);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002848 if (!_skb) {
2849 pi->conn_state |= L2CAP_CONN_SAR_RETRY;
2850 return -ENOMEM;
2851 }
2852
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002853 err = sock_queue_rcv_skb(sk, _skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002854 if (err < 0) {
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002855 kfree_skb(_skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002856 pi->conn_state |= L2CAP_CONN_SAR_RETRY;
2857 return err;
2858 }
2859
2860 pi->conn_state &= ~L2CAP_CONN_SAR_RETRY;
2861 pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002862
2863 kfree_skb(pi->sdu);
2864 break;
2865 }
2866
2867 kfree_skb(skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002868 return 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002869
2870drop:
2871 kfree_skb(pi->sdu);
2872 pi->sdu = NULL;
2873
2874disconnect:
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03002875 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002876 kfree_skb(skb);
2877 return 0;
2878}
2879
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03002880static int l2cap_try_push_rx_skb(struct sock *sk)
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002881{
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03002882 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002883 struct sk_buff *skb;
2884 u16 control;
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03002885 int err;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002886
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03002887 while ((skb = skb_dequeue(BUSY_QUEUE(sk)))) {
2888 control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
2889 err = l2cap_ertm_reassembly_sdu(sk, skb, control);
2890 if (err < 0) {
2891 skb_queue_head(BUSY_QUEUE(sk), skb);
2892 return -EBUSY;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002893 }
2894
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03002895 pi->buffer_seq = (pi->buffer_seq + 1) % 64;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002896 }
2897
2898 if (!(pi->conn_state & L2CAP_CONN_RNR_SENT))
2899 goto done;
2900
2901 control = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
2902 control |= L2CAP_SUPER_RCV_READY | L2CAP_CTRL_POLL;
2903 l2cap_send_sframe(pi, control);
2904 l2cap_pi(sk)->retry_count = 1;
2905
2906 del_timer(&pi->retrans_timer);
2907 __mod_monitor_timer();
2908
2909 l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
2910
2911done:
2912 pi->conn_state &= ~L2CAP_CONN_LOCAL_BUSY;
2913 pi->conn_state &= ~L2CAP_CONN_RNR_SENT;
2914
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03002915 BT_DBG("sk %p, Exit local busy", sk);
2916
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03002917 return 0;
2918}
2919
2920static void l2cap_busy_work(struct work_struct *work)
2921{
2922 DECLARE_WAITQUEUE(wait, current);
2923 struct l2cap_pinfo *pi =
2924 container_of(work, struct l2cap_pinfo, busy_work);
2925 struct sock *sk = (struct sock *)pi;
2926 int n_tries = 0, timeo = HZ/5, err;
2927 struct sk_buff *skb;
2928
2929 lock_sock(sk);
2930
2931 add_wait_queue(sk_sleep(sk), &wait);
2932 while ((skb = skb_peek(BUSY_QUEUE(sk)))) {
2933 set_current_state(TASK_INTERRUPTIBLE);
2934
2935 if (n_tries++ > L2CAP_LOCAL_BUSY_TRIES) {
2936 err = -EBUSY;
2937 l2cap_send_disconn_req(pi->conn, sk, EBUSY);
2938 break;
2939 }
2940
2941 if (!timeo)
2942 timeo = HZ/5;
2943
2944 if (signal_pending(current)) {
2945 err = sock_intr_errno(timeo);
2946 break;
2947 }
2948
2949 release_sock(sk);
2950 timeo = schedule_timeout(timeo);
2951 lock_sock(sk);
2952
2953 err = sock_error(sk);
2954 if (err)
2955 break;
2956
2957 if (l2cap_try_push_rx_skb(sk) == 0)
2958 break;
2959 }
2960
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002961 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02002962 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002963
2964 release_sock(sk);
2965}
2966
2967static int l2cap_push_rx_skb(struct sock *sk, struct sk_buff *skb, u16 control)
2968{
2969 struct l2cap_pinfo *pi = l2cap_pi(sk);
2970 int sctrl, err;
2971
2972 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
2973 bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT;
2974 __skb_queue_tail(BUSY_QUEUE(sk), skb);
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03002975 return l2cap_try_push_rx_skb(sk);
2976
2977
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002978 }
2979
2980 err = l2cap_ertm_reassembly_sdu(sk, skb, control);
2981 if (err >= 0) {
2982 pi->buffer_seq = (pi->buffer_seq + 1) % 64;
2983 return err;
2984 }
2985
2986 /* Busy Condition */
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03002987 BT_DBG("sk %p, Enter local busy", sk);
2988
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002989 pi->conn_state |= L2CAP_CONN_LOCAL_BUSY;
2990 bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT;
2991 __skb_queue_tail(BUSY_QUEUE(sk), skb);
2992
2993 sctrl = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
2994 sctrl |= L2CAP_SUPER_RCV_NOT_READY;
2995 l2cap_send_sframe(pi, sctrl);
2996
2997 pi->conn_state |= L2CAP_CONN_RNR_SENT;
2998
Gustavo F. Padovan7fe9b292010-05-12 18:32:04 -03002999 del_timer(&pi->ack_timer);
3000
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003001 queue_work(_busy_wq, &pi->busy_work);
3002
3003 return err;
3004}
3005
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003006static int l2cap_streaming_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003007{
3008 struct l2cap_pinfo *pi = l2cap_pi(sk);
3009 struct sk_buff *_skb;
3010 int err = -EINVAL;
3011
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003012 /*
3013 * TODO: We have to notify the userland if some data is lost with the
3014 * Streaming Mode.
3015 */
3016
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003017 switch (control & L2CAP_CTRL_SAR) {
3018 case L2CAP_SDU_UNSEGMENTED:
3019 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3020 kfree_skb(pi->sdu);
3021 break;
3022 }
3023
3024 err = sock_queue_rcv_skb(sk, skb);
3025 if (!err)
3026 return 0;
3027
3028 break;
3029
3030 case L2CAP_SDU_START:
3031 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3032 kfree_skb(pi->sdu);
3033 break;
3034 }
3035
3036 pi->sdu_len = get_unaligned_le16(skb->data);
3037 skb_pull(skb, 2);
3038
Gustavo F. Padovan052897c2010-05-01 16:15:40 -03003039 if (pi->sdu_len > pi->imtu) {
3040 err = -EMSGSIZE;
3041 break;
3042 }
3043
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003044 pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
3045 if (!pi->sdu) {
3046 err = -ENOMEM;
3047 break;
3048 }
3049
3050 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3051
3052 pi->conn_state |= L2CAP_CONN_SAR_SDU;
3053 pi->partial_sdu_len = skb->len;
3054 err = 0;
3055 break;
3056
3057 case L2CAP_SDU_CONTINUE:
3058 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3059 break;
3060
3061 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3062
3063 pi->partial_sdu_len += skb->len;
3064 if (pi->partial_sdu_len > pi->sdu_len)
3065 kfree_skb(pi->sdu);
3066 else
3067 err = 0;
3068
3069 break;
3070
3071 case L2CAP_SDU_END:
3072 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3073 break;
3074
3075 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3076
3077 pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
3078 pi->partial_sdu_len += skb->len;
3079
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003080 if (pi->partial_sdu_len > pi->imtu)
3081 goto drop;
3082
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003083 if (pi->partial_sdu_len == pi->sdu_len) {
3084 _skb = skb_clone(pi->sdu, GFP_ATOMIC);
3085 err = sock_queue_rcv_skb(sk, _skb);
3086 if (err < 0)
3087 kfree_skb(_skb);
3088 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003089 err = 0;
3090
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003091drop:
3092 kfree_skb(pi->sdu);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003093 break;
3094 }
3095
3096 kfree_skb(skb);
3097 return err;
3098}
3099
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003100static void l2cap_check_srej_gap(struct sock *sk, u8 tx_seq)
3101{
3102 struct sk_buff *skb;
Gustavo F. Padovanafefdbc2010-05-01 16:15:43 -03003103 u16 control;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003104
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003105 while ((skb = skb_peek(SREJ_QUEUE(sk)))) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003106 if (bt_cb(skb)->tx_seq != tx_seq)
3107 break;
3108
3109 skb = skb_dequeue(SREJ_QUEUE(sk));
Gustavo F. Padovanafefdbc2010-05-01 16:15:43 -03003110 control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003111 l2cap_ertm_reassembly_sdu(sk, skb, control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003112 l2cap_pi(sk)->buffer_seq_srej =
3113 (l2cap_pi(sk)->buffer_seq_srej + 1) % 64;
Gustavo F. Padovan8ff50ec2010-05-10 19:34:11 -03003114 tx_seq = (tx_seq + 1) % 64;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003115 }
3116}
3117
3118static void l2cap_resend_srejframe(struct sock *sk, u8 tx_seq)
3119{
3120 struct l2cap_pinfo *pi = l2cap_pi(sk);
3121 struct srej_list *l, *tmp;
3122 u16 control;
3123
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003124 list_for_each_entry_safe(l, tmp, SREJ_LIST(sk), list) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003125 if (l->tx_seq == tx_seq) {
3126 list_del(&l->list);
3127 kfree(l);
3128 return;
3129 }
3130 control = L2CAP_SUPER_SELECT_REJECT;
3131 control |= l->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3132 l2cap_send_sframe(pi, control);
3133 list_del(&l->list);
3134 list_add_tail(&l->list, SREJ_LIST(sk));
3135 }
3136}
3137
3138static void l2cap_send_srejframe(struct sock *sk, u8 tx_seq)
3139{
3140 struct l2cap_pinfo *pi = l2cap_pi(sk);
3141 struct srej_list *new;
3142 u16 control;
3143
3144 while (tx_seq != pi->expected_tx_seq) {
3145 control = L2CAP_SUPER_SELECT_REJECT;
3146 control |= pi->expected_tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3147 l2cap_send_sframe(pi, control);
3148
3149 new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC);
Gustavo F. Padovan8ff50ec2010-05-10 19:34:11 -03003150 new->tx_seq = pi->expected_tx_seq;
3151 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003152 list_add_tail(&new->list, SREJ_LIST(sk));
3153 }
Gustavo F. Padovan8ff50ec2010-05-10 19:34:11 -03003154 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003155}
3156
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003157static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
3158{
3159 struct l2cap_pinfo *pi = l2cap_pi(sk);
3160 u8 tx_seq = __get_txseq(rx_control);
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003161 u8 req_seq = __get_reqseq(rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003162 u8 sar = rx_control >> L2CAP_CTRL_SAR_SHIFT;
Gustavo F. Padovanf6337c72010-05-10 18:32:04 -03003163 int tx_seq_offset, expected_tx_seq_offset;
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03003164 int num_to_ack = (pi->tx_win/6) + 1;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003165 int err = 0;
3166
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003167 BT_DBG("sk %p len %d tx_seq %d rx_control 0x%4.4x", sk, skb->len, tx_seq,
3168 rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003169
Gustavo F. Padovan9b16dc62010-05-05 20:05:57 -03003170 if (L2CAP_CTRL_FINAL & rx_control &&
3171 l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) {
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003172 del_timer(&pi->monitor_timer);
3173 if (pi->unacked_frames > 0)
3174 __mod_retrans_timer();
3175 pi->conn_state &= ~L2CAP_CONN_WAIT_F;
3176 }
3177
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003178 pi->expected_ack_seq = req_seq;
3179 l2cap_drop_acked_frames(sk);
3180
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003181 if (tx_seq == pi->expected_tx_seq)
3182 goto expected;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003183
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003184 tx_seq_offset = (tx_seq - pi->buffer_seq) % 64;
3185 if (tx_seq_offset < 0)
3186 tx_seq_offset += 64;
3187
3188 /* invalid tx_seq */
3189 if (tx_seq_offset >= pi->tx_win) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03003190 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003191 goto drop;
3192 }
3193
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003194 if (pi->conn_state == L2CAP_CONN_LOCAL_BUSY)
3195 goto drop;
3196
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003197 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3198 struct srej_list *first;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003199
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003200 first = list_first_entry(SREJ_LIST(sk),
3201 struct srej_list, list);
3202 if (tx_seq == first->tx_seq) {
3203 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3204 l2cap_check_srej_gap(sk, tx_seq);
3205
3206 list_del(&first->list);
3207 kfree(first);
3208
3209 if (list_empty(SREJ_LIST(sk))) {
3210 pi->buffer_seq = pi->buffer_seq_srej;
3211 pi->conn_state &= ~L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan855666cc2010-05-01 16:15:40 -03003212 l2cap_send_ack(pi);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003213 BT_DBG("sk %p, Exit SREJ_SENT", sk);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003214 }
3215 } else {
3216 struct srej_list *l;
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003217
3218 /* duplicated tx_seq */
3219 if (l2cap_add_to_srej_queue(sk, skb, tx_seq, sar) < 0)
3220 goto drop;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003221
3222 list_for_each_entry(l, SREJ_LIST(sk), list) {
3223 if (l->tx_seq == tx_seq) {
3224 l2cap_resend_srejframe(sk, tx_seq);
3225 return 0;
3226 }
3227 }
3228 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003229 }
3230 } else {
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003231 expected_tx_seq_offset =
3232 (pi->expected_tx_seq - pi->buffer_seq) % 64;
3233 if (expected_tx_seq_offset < 0)
3234 expected_tx_seq_offset += 64;
3235
3236 /* duplicated tx_seq */
3237 if (tx_seq_offset < expected_tx_seq_offset)
3238 goto drop;
3239
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003240 pi->conn_state |= L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003241
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003242 BT_DBG("sk %p, Enter SREJ", sk);
3243
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003244 INIT_LIST_HEAD(SREJ_LIST(sk));
3245 pi->buffer_seq_srej = pi->buffer_seq;
3246
3247 __skb_queue_head_init(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003248 __skb_queue_head_init(BUSY_QUEUE(sk));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003249 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3250
Gustavo F. Padovanef54fd92009-08-20 22:26:04 -03003251 pi->conn_state |= L2CAP_CONN_SEND_PBIT;
3252
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003253 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan7fe9b292010-05-12 18:32:04 -03003254
3255 del_timer(&pi->ack_timer);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003256 }
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003257 return 0;
3258
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003259expected:
3260 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
3261
3262 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
Gustavo F. Padovan3b1a9f32010-05-01 16:15:42 -03003263 bt_cb(skb)->tx_seq = tx_seq;
3264 bt_cb(skb)->sar = sar;
3265 __skb_queue_tail(SREJ_QUEUE(sk), skb);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003266 return 0;
3267 }
3268
Gustavo F. Padovan2ece3682010-06-16 17:21:44 -03003269 err = l2cap_push_rx_skb(sk, skb, rx_control);
3270 if (err < 0)
3271 return 0;
3272
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03003273 if (rx_control & L2CAP_CTRL_FINAL) {
3274 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3275 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003276 else
3277 l2cap_retransmit_frames(sk);
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03003278 }
3279
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003280 __mod_ack_timer();
3281
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03003282 pi->num_acked = (pi->num_acked + 1) % num_to_ack;
3283 if (pi->num_acked == num_to_ack - 1)
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03003284 l2cap_send_ack(pi);
3285
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003286 return 0;
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003287
3288drop:
3289 kfree_skb(skb);
3290 return 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003291}
3292
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003293static inline void l2cap_data_channel_rrframe(struct sock *sk, u16 rx_control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003294{
3295 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan6e3a5982010-05-01 16:15:38 -03003296
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003297 BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, __get_reqseq(rx_control),
3298 rx_control);
3299
Gustavo F. Padovan6e3a5982010-05-01 16:15:38 -03003300 pi->expected_ack_seq = __get_reqseq(rx_control);
3301 l2cap_drop_acked_frames(sk);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003302
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003303 if (rx_control & L2CAP_CTRL_POLL) {
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03003304 pi->conn_state |= L2CAP_CONN_SEND_FBIT;
Gustavo F. Padovan05fbd892010-05-01 16:15:39 -03003305 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3306 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
3307 (pi->unacked_frames > 0))
3308 __mod_retrans_timer();
3309
3310 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3311 l2cap_send_srejtail(sk);
3312 } else {
3313 l2cap_send_i_or_rr_or_rnr(sk);
Gustavo F. Padovan05fbd892010-05-01 16:15:39 -03003314 }
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003315
3316 } else if (rx_control & L2CAP_CTRL_FINAL) {
3317 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003318
3319 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3320 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003321 else
3322 l2cap_retransmit_frames(sk);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003323
3324 } else {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003325 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
3326 (pi->unacked_frames > 0))
3327 __mod_retrans_timer();
3328
3329 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
Andrei Emeltchenko894718a2010-12-01 16:58:24 +02003330 if (pi->conn_state & L2CAP_CONN_SREJ_SENT)
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003331 l2cap_send_ack(pi);
Andrei Emeltchenko894718a2010-12-01 16:58:24 +02003332 else
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003333 l2cap_ertm_send(sk);
3334 }
3335}
3336
3337static inline void l2cap_data_channel_rejframe(struct sock *sk, u16 rx_control)
3338{
3339 struct l2cap_pinfo *pi = l2cap_pi(sk);
3340 u8 tx_seq = __get_reqseq(rx_control);
3341
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003342 BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, tx_seq, rx_control);
3343
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003344 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3345
Gustavo F. Padovan8abb52e2010-05-01 16:15:38 -03003346 pi->expected_ack_seq = tx_seq;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003347 l2cap_drop_acked_frames(sk);
3348
3349 if (rx_control & L2CAP_CTRL_FINAL) {
3350 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3351 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003352 else
3353 l2cap_retransmit_frames(sk);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003354 } else {
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003355 l2cap_retransmit_frames(sk);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003356
Gustavo F. Padovan0301ef02010-05-05 20:56:43 -03003357 if (pi->conn_state & L2CAP_CONN_WAIT_F)
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003358 pi->conn_state |= L2CAP_CONN_REJ_ACT;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003359 }
3360}
3361static inline void l2cap_data_channel_srejframe(struct sock *sk, u16 rx_control)
3362{
3363 struct l2cap_pinfo *pi = l2cap_pi(sk);
3364 u8 tx_seq = __get_reqseq(rx_control);
3365
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003366 BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, tx_seq, rx_control);
3367
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003368 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3369
3370 if (rx_control & L2CAP_CTRL_POLL) {
3371 pi->expected_ack_seq = tx_seq;
3372 l2cap_drop_acked_frames(sk);
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03003373
3374 pi->conn_state |= L2CAP_CONN_SEND_FBIT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003375 l2cap_retransmit_one_frame(sk, tx_seq);
3376
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003377 l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003378
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003379 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
3380 pi->srej_save_reqseq = tx_seq;
3381 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
3382 }
3383 } else if (rx_control & L2CAP_CTRL_FINAL) {
3384 if ((pi->conn_state & L2CAP_CONN_SREJ_ACT) &&
3385 pi->srej_save_reqseq == tx_seq)
3386 pi->conn_state &= ~L2CAP_CONN_SREJ_ACT;
3387 else
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003388 l2cap_retransmit_one_frame(sk, tx_seq);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003389 } 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 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
3392 pi->srej_save_reqseq = tx_seq;
3393 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
3394 }
3395 }
3396}
3397
3398static inline void l2cap_data_channel_rnrframe(struct sock *sk, u16 rx_control)
3399{
3400 struct l2cap_pinfo *pi = l2cap_pi(sk);
3401 u8 tx_seq = __get_reqseq(rx_control);
3402
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003403 BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, tx_seq, rx_control);
3404
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003405 pi->conn_state |= L2CAP_CONN_REMOTE_BUSY;
3406 pi->expected_ack_seq = tx_seq;
3407 l2cap_drop_acked_frames(sk);
3408
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03003409 if (rx_control & L2CAP_CTRL_POLL)
3410 pi->conn_state |= L2CAP_CONN_SEND_FBIT;
3411
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03003412 if (!(pi->conn_state & L2CAP_CONN_SREJ_SENT)) {
3413 del_timer(&pi->retrans_timer);
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -03003414 if (rx_control & L2CAP_CTRL_POLL)
3415 l2cap_send_rr_or_rnr(pi, L2CAP_CTRL_FINAL);
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03003416 return;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003417 }
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03003418
3419 if (rx_control & L2CAP_CTRL_POLL)
3420 l2cap_send_srejtail(sk);
3421 else
3422 l2cap_send_sframe(pi, L2CAP_SUPER_RCV_READY);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003423}
3424
3425static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
3426{
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003427 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
3428
Gustavo F. Padovan9b16dc62010-05-05 20:05:57 -03003429 if (L2CAP_CTRL_FINAL & rx_control &&
3430 l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003431 del_timer(&l2cap_pi(sk)->monitor_timer);
3432 if (l2cap_pi(sk)->unacked_frames > 0)
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003433 __mod_retrans_timer();
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003434 l2cap_pi(sk)->conn_state &= ~L2CAP_CONN_WAIT_F;
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003435 }
3436
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003437 switch (rx_control & L2CAP_CTRL_SUPERVISE) {
3438 case L2CAP_SUPER_RCV_READY:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003439 l2cap_data_channel_rrframe(sk, rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003440 break;
3441
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003442 case L2CAP_SUPER_REJECT:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003443 l2cap_data_channel_rejframe(sk, rx_control);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003444 break;
3445
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003446 case L2CAP_SUPER_SELECT_REJECT:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003447 l2cap_data_channel_srejframe(sk, rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003448 break;
3449
3450 case L2CAP_SUPER_RCV_NOT_READY:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003451 l2cap_data_channel_rnrframe(sk, rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003452 break;
3453 }
3454
Gustavo F. Padovanfaaebd12010-05-01 16:15:35 -03003455 kfree_skb(skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003456 return 0;
3457}
3458
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03003459static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb)
3460{
3461 struct l2cap_pinfo *pi = l2cap_pi(sk);
3462 u16 control;
3463 u8 req_seq;
3464 int len, next_tx_seq_offset, req_seq_offset;
3465
3466 control = get_unaligned_le16(skb->data);
3467 skb_pull(skb, 2);
3468 len = skb->len;
3469
3470 /*
3471 * We can just drop the corrupted I-frame here.
3472 * Receiver will miss it and start proper recovery
3473 * procedures and ask retransmission.
3474 */
3475 if (l2cap_check_fcs(pi, skb))
3476 goto drop;
3477
3478 if (__is_sar_start(control) && __is_iframe(control))
3479 len -= 2;
3480
3481 if (pi->fcs == L2CAP_FCS_CRC16)
3482 len -= 2;
3483
3484 if (len > pi->mps) {
3485 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
3486 goto drop;
3487 }
3488
3489 req_seq = __get_reqseq(control);
3490 req_seq_offset = (req_seq - pi->expected_ack_seq) % 64;
3491 if (req_seq_offset < 0)
3492 req_seq_offset += 64;
3493
3494 next_tx_seq_offset =
3495 (pi->next_tx_seq - pi->expected_ack_seq) % 64;
3496 if (next_tx_seq_offset < 0)
3497 next_tx_seq_offset += 64;
3498
3499 /* check for invalid req-seq */
3500 if (req_seq_offset > next_tx_seq_offset) {
3501 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
3502 goto drop;
3503 }
3504
3505 if (__is_iframe(control)) {
3506 if (len < 0) {
3507 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
3508 goto drop;
3509 }
3510
3511 l2cap_data_channel_iframe(sk, control, skb);
3512 } else {
3513 if (len != 0) {
3514 BT_ERR("%d", len);
3515 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
3516 goto drop;
3517 }
3518
3519 l2cap_data_channel_sframe(sk, control, skb);
3520 }
3521
3522 return 0;
3523
3524drop:
3525 kfree_skb(skb);
3526 return 0;
3527}
3528
Linus Torvalds1da177e2005-04-16 15:20:36 -07003529static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk_buff *skb)
3530{
3531 struct sock *sk;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003532 struct l2cap_pinfo *pi;
Nathan Holstein51893f82010-06-09 15:46:25 -04003533 u16 control;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03003534 u8 tx_seq;
3535 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003536
3537 sk = l2cap_get_chan_by_scid(&conn->chan_list, cid);
3538 if (!sk) {
3539 BT_DBG("unknown cid 0x%4.4x", cid);
3540 goto drop;
3541 }
3542
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003543 pi = l2cap_pi(sk);
3544
Linus Torvalds1da177e2005-04-16 15:20:36 -07003545 BT_DBG("sk %p, len %d", sk, skb->len);
3546
3547 if (sk->sk_state != BT_CONNECTED)
3548 goto drop;
3549
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003550 switch (pi->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003551 case L2CAP_MODE_BASIC:
3552 /* If socket recv buffers overflows we drop data here
3553 * which is *bad* because L2CAP has to be reliable.
3554 * But we don't have any other choice. L2CAP doesn't
3555 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003556
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003557 if (pi->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003558 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003559
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003560 if (!sock_queue_rcv_skb(sk, skb))
3561 goto done;
3562 break;
3563
3564 case L2CAP_MODE_ERTM:
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03003565 if (!sock_owned_by_user(sk)) {
3566 l2cap_ertm_data_rcv(sk, skb);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03003567 } else {
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03003568 if (sk_add_backlog(sk, skb))
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03003569 goto drop;
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03003570 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003571
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02003572 goto done;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003573
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003574 case L2CAP_MODE_STREAMING:
3575 control = get_unaligned_le16(skb->data);
3576 skb_pull(skb, 2);
3577 len = skb->len;
3578
Gustavo F. Padovan26000082010-05-11 22:02:00 -03003579 if (l2cap_check_fcs(pi, skb))
3580 goto drop;
3581
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003582 if (__is_sar_start(control))
3583 len -= 2;
3584
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003585 if (pi->fcs == L2CAP_FCS_CRC16)
3586 len -= 2;
3587
Nathan Holstein51893f82010-06-09 15:46:25 -04003588 if (len > pi->mps || len < 0 || __is_sframe(control))
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003589 goto drop;
3590
3591 tx_seq = __get_txseq(control);
3592
3593 if (pi->expected_tx_seq == tx_seq)
3594 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
3595 else
Gustavo F. Padovan7dffe422010-05-01 16:15:36 -03003596 pi->expected_tx_seq = (tx_seq + 1) % 64;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003597
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003598 l2cap_streaming_reassembly_sdu(sk, skb, control);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003599
3600 goto done;
3601
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003602 default:
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03003603 BT_DBG("sk %p: bad mode 0x%2.2x", sk, pi->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003604 break;
3605 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003606
3607drop:
3608 kfree_skb(skb);
3609
3610done:
Marcel Holtmann01394182006-07-03 10:02:46 +02003611 if (sk)
3612 bh_unlock_sock(sk);
3613
Linus Torvalds1da177e2005-04-16 15:20:36 -07003614 return 0;
3615}
3616
Al Viro8e036fc2007-07-29 00:16:36 -07003617static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003618{
3619 struct sock *sk;
3620
3621 sk = l2cap_get_sock_by_psm(0, psm, conn->src);
3622 if (!sk)
3623 goto drop;
3624
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00003625 bh_lock_sock(sk);
3626
Linus Torvalds1da177e2005-04-16 15:20:36 -07003627 BT_DBG("sk %p, len %d", sk, skb->len);
3628
3629 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_CONNECTED)
3630 goto drop;
3631
3632 if (l2cap_pi(sk)->imtu < skb->len)
3633 goto drop;
3634
3635 if (!sock_queue_rcv_skb(sk, skb))
3636 goto done;
3637
3638drop:
3639 kfree_skb(skb);
3640
3641done:
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003642 if (sk)
3643 bh_unlock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003644 return 0;
3645}
3646
3647static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
3648{
3649 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07003650 u16 cid, len;
3651 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003652
3653 skb_pull(skb, L2CAP_HDR_SIZE);
3654 cid = __le16_to_cpu(lh->cid);
3655 len = __le16_to_cpu(lh->len);
3656
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003657 if (len != skb->len) {
3658 kfree_skb(skb);
3659 return;
3660 }
3661
Linus Torvalds1da177e2005-04-16 15:20:36 -07003662 BT_DBG("len %d, cid 0x%4.4x", len, cid);
3663
3664 switch (cid) {
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02003665 case L2CAP_CID_LE_SIGNALING:
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03003666 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07003667 l2cap_sig_channel(conn, skb);
3668 break;
3669
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03003670 case L2CAP_CID_CONN_LESS:
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03003671 psm = get_unaligned_le16(skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003672 skb_pull(skb, 2);
3673 l2cap_conless_channel(conn, psm, skb);
3674 break;
3675
3676 default:
3677 l2cap_data_channel(conn, cid, skb);
3678 break;
3679 }
3680}
3681
3682/* ---- L2CAP interface with lower layer (HCI) ---- */
3683
3684static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
3685{
3686 int exact = 0, lm1 = 0, lm2 = 0;
3687 register struct sock *sk;
3688 struct hlist_node *node;
3689
3690 if (type != ACL_LINK)
João Paulo Rechi Vita963cf682010-06-22 13:56:28 -03003691 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003692
3693 BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
3694
3695 /* Find listening sockets and check their link_mode */
3696 read_lock(&l2cap_sk_list.lock);
3697 sk_for_each(sk, node, &l2cap_sk_list.head) {
3698 if (sk->sk_state != BT_LISTEN)
3699 continue;
3700
3701 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01003702 lm1 |= HCI_LM_ACCEPT;
3703 if (l2cap_pi(sk)->role_switch)
3704 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003705 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01003706 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
3707 lm2 |= HCI_LM_ACCEPT;
3708 if (l2cap_pi(sk)->role_switch)
3709 lm2 |= HCI_LM_MASTER;
3710 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003711 }
3712 read_unlock(&l2cap_sk_list.lock);
3713
3714 return exact ? lm1 : lm2;
3715}
3716
3717static int l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
3718{
Marcel Holtmann01394182006-07-03 10:02:46 +02003719 struct l2cap_conn *conn;
3720
Linus Torvalds1da177e2005-04-16 15:20:36 -07003721 BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
3722
Ville Tervoacd7d372011-02-10 22:38:49 -03003723 if (!(hcon->type == ACL_LINK || hcon->type == LE_LINK))
João Paulo Rechi Vita963cf682010-06-22 13:56:28 -03003724 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003725
3726 if (!status) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003727 conn = l2cap_conn_add(hcon, status);
3728 if (conn)
3729 l2cap_conn_ready(conn);
Marcel Holtmann01394182006-07-03 10:02:46 +02003730 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -07003731 l2cap_conn_del(hcon, bt_err(status));
3732
3733 return 0;
3734}
3735
Marcel Holtmann2950f212009-02-12 14:02:50 +01003736static int l2cap_disconn_ind(struct hci_conn *hcon)
3737{
3738 struct l2cap_conn *conn = hcon->l2cap_data;
3739
3740 BT_DBG("hcon %p", hcon);
3741
3742 if (hcon->type != ACL_LINK || !conn)
3743 return 0x13;
3744
3745 return conn->disc_reason;
3746}
3747
3748static int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003749{
3750 BT_DBG("hcon %p reason %d", hcon, reason);
3751
Ville Tervoacd7d372011-02-10 22:38:49 -03003752 if (!(hcon->type == ACL_LINK || hcon->type == LE_LINK))
João Paulo Rechi Vita963cf682010-06-22 13:56:28 -03003753 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003754
3755 l2cap_conn_del(hcon, bt_err(reason));
Marcel Holtmann01394182006-07-03 10:02:46 +02003756
Linus Torvalds1da177e2005-04-16 15:20:36 -07003757 return 0;
3758}
3759
Marcel Holtmannf62e4322009-01-15 21:58:44 +01003760static inline void l2cap_check_encryption(struct sock *sk, u8 encrypt)
3761{
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03003762 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM)
Marcel Holtmann255c7602009-02-04 21:07:19 +01003763 return;
3764
Marcel Holtmannf62e4322009-01-15 21:58:44 +01003765 if (encrypt == 0x00) {
3766 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM) {
3767 l2cap_sock_clear_timer(sk);
3768 l2cap_sock_set_timer(sk, HZ * 5);
3769 } else if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
3770 __l2cap_sock_close(sk, ECONNREFUSED);
3771 } else {
3772 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM)
3773 l2cap_sock_clear_timer(sk);
3774 }
3775}
3776
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01003777static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003778{
3779 struct l2cap_chan_list *l;
Marcel Holtmann40be4922008-07-14 20:13:50 +02003780 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003781 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003782
Marcel Holtmann01394182006-07-03 10:02:46 +02003783 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003784 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02003785
Linus Torvalds1da177e2005-04-16 15:20:36 -07003786 l = &conn->chan_list;
3787
3788 BT_DBG("conn %p", conn);
3789
3790 read_lock(&l->lock);
3791
3792 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
3793 bh_lock_sock(sk);
3794
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003795 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND) {
3796 bh_unlock_sock(sk);
3797 continue;
3798 }
3799
Marcel Holtmannf62e4322009-01-15 21:58:44 +01003800 if (!status && (sk->sk_state == BT_CONNECTED ||
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01003801 sk->sk_state == BT_CONFIG)) {
Marcel Holtmannf62e4322009-01-15 21:58:44 +01003802 l2cap_check_encryption(sk, encrypt);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02003803 bh_unlock_sock(sk);
3804 continue;
3805 }
3806
Marcel Holtmannb1235d72008-07-14 20:13:54 +02003807 if (sk->sk_state == BT_CONNECT) {
3808 if (!status) {
3809 struct l2cap_conn_req req;
3810 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
3811 req.psm = l2cap_pi(sk)->psm;
3812
3813 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03003814 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02003815
3816 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
3817 L2CAP_CONN_REQ, sizeof(req), &req);
3818 } else {
3819 l2cap_sock_clear_timer(sk);
3820 l2cap_sock_set_timer(sk, HZ / 10);
3821 }
3822 } else if (sk->sk_state == BT_CONNECT2) {
3823 struct l2cap_conn_rsp rsp;
3824 __u16 result;
3825
3826 if (!status) {
3827 sk->sk_state = BT_CONFIG;
3828 result = L2CAP_CR_SUCCESS;
3829 } else {
3830 sk->sk_state = BT_DISCONN;
3831 l2cap_sock_set_timer(sk, HZ / 10);
3832 result = L2CAP_CR_SEC_BLOCK;
3833 }
3834
3835 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
3836 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
3837 rsp.result = cpu_to_le16(result);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003838 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02003839 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
3840 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003841 }
3842
Linus Torvalds1da177e2005-04-16 15:20:36 -07003843 bh_unlock_sock(sk);
3844 }
3845
3846 read_unlock(&l->lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02003847
Linus Torvalds1da177e2005-04-16 15:20:36 -07003848 return 0;
3849}
3850
3851static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
3852{
3853 struct l2cap_conn *conn = hcon->l2cap_data;
3854
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02003855 if (!conn)
3856 conn = l2cap_conn_add(hcon, 0);
3857
3858 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003859 goto drop;
3860
3861 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
3862
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +02003863 if (!(flags & ACL_CONT)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003864 struct l2cap_hdr *hdr;
Andrei Emeltchenko89794812010-09-15 14:28:44 +03003865 struct sock *sk;
3866 u16 cid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003867 int len;
3868
3869 if (conn->rx_len) {
3870 BT_ERR("Unexpected start frame (len %d)", skb->len);
3871 kfree_skb(conn->rx_skb);
3872 conn->rx_skb = NULL;
3873 conn->rx_len = 0;
3874 l2cap_conn_unreliable(conn, ECOMM);
3875 }
3876
Andrei Emeltchenkoaae7fe22010-09-15 14:28:43 +03003877 /* Start fragment always begin with Basic L2CAP header */
3878 if (skb->len < L2CAP_HDR_SIZE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003879 BT_ERR("Frame is too short (len %d)", skb->len);
3880 l2cap_conn_unreliable(conn, ECOMM);
3881 goto drop;
3882 }
3883
3884 hdr = (struct l2cap_hdr *) skb->data;
3885 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
Andrei Emeltchenko89794812010-09-15 14:28:44 +03003886 cid = __le16_to_cpu(hdr->cid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003887
3888 if (len == skb->len) {
3889 /* Complete frame received */
3890 l2cap_recv_frame(conn, skb);
3891 return 0;
3892 }
3893
3894 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
3895
3896 if (skb->len > len) {
3897 BT_ERR("Frame is too long (len %d, expected len %d)",
3898 skb->len, len);
3899 l2cap_conn_unreliable(conn, ECOMM);
3900 goto drop;
3901 }
3902
Andrei Emeltchenko89794812010-09-15 14:28:44 +03003903 sk = l2cap_get_chan_by_scid(&conn->chan_list, cid);
3904
3905 if (sk && l2cap_pi(sk)->imtu < len - L2CAP_HDR_SIZE) {
3906 BT_ERR("Frame exceeding recv MTU (len %d, MTU %d)",
3907 len, l2cap_pi(sk)->imtu);
3908 bh_unlock_sock(sk);
3909 l2cap_conn_unreliable(conn, ECOMM);
3910 goto drop;
3911 }
3912
3913 if (sk)
3914 bh_unlock_sock(sk);
3915
Linus Torvalds1da177e2005-04-16 15:20:36 -07003916 /* Allocate skb for the complete frame (with header) */
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003917 conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC);
3918 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003919 goto drop;
3920
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03003921 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003922 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003923 conn->rx_len = len - skb->len;
3924 } else {
3925 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
3926
3927 if (!conn->rx_len) {
3928 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
3929 l2cap_conn_unreliable(conn, ECOMM);
3930 goto drop;
3931 }
3932
3933 if (skb->len > conn->rx_len) {
3934 BT_ERR("Fragment is too long (len %d, expected %d)",
3935 skb->len, conn->rx_len);
3936 kfree_skb(conn->rx_skb);
3937 conn->rx_skb = NULL;
3938 conn->rx_len = 0;
3939 l2cap_conn_unreliable(conn, ECOMM);
3940 goto drop;
3941 }
3942
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03003943 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003944 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003945 conn->rx_len -= skb->len;
3946
3947 if (!conn->rx_len) {
3948 /* Complete frame received */
3949 l2cap_recv_frame(conn, conn->rx_skb);
3950 conn->rx_skb = NULL;
3951 }
3952 }
3953
3954drop:
3955 kfree_skb(skb);
3956 return 0;
3957}
3958
Marcel Holtmannaef7d972010-03-21 05:27:45 +01003959static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003960{
3961 struct sock *sk;
3962 struct hlist_node *node;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003963
3964 read_lock_bh(&l2cap_sk_list.lock);
3965
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08003966 sk_for_each(sk, node, &l2cap_sk_list.head) {
3967 struct l2cap_pinfo *pi = l2cap_pi(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003968
Gustavo F. Padovan903d3432011-02-10 14:16:06 -02003969 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 +01003970 batostr(&bt_sk(sk)->src),
3971 batostr(&bt_sk(sk)->dst),
3972 sk->sk_state, __le16_to_cpu(pi->psm),
3973 pi->scid, pi->dcid,
Gustavo F. Padovan903d3432011-02-10 14:16:06 -02003974 pi->imtu, pi->omtu, pi->sec_level,
3975 pi->mode);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08003976 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003977
Linus Torvalds1da177e2005-04-16 15:20:36 -07003978 read_unlock_bh(&l2cap_sk_list.lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08003979
Marcel Holtmannaef7d972010-03-21 05:27:45 +01003980 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003981}
3982
Marcel Holtmannaef7d972010-03-21 05:27:45 +01003983static int l2cap_debugfs_open(struct inode *inode, struct file *file)
3984{
3985 return single_open(file, l2cap_debugfs_show, inode->i_private);
3986}
3987
3988static const struct file_operations l2cap_debugfs_fops = {
3989 .open = l2cap_debugfs_open,
3990 .read = seq_read,
3991 .llseek = seq_lseek,
3992 .release = single_release,
3993};
3994
3995static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003996
Linus Torvalds1da177e2005-04-16 15:20:36 -07003997static struct hci_proto l2cap_hci_proto = {
3998 .name = "L2CAP",
3999 .id = HCI_PROTO_L2CAP,
4000 .connect_ind = l2cap_connect_ind,
4001 .connect_cfm = l2cap_connect_cfm,
4002 .disconn_ind = l2cap_disconn_ind,
Marcel Holtmann2950f212009-02-12 14:02:50 +01004003 .disconn_cfm = l2cap_disconn_cfm,
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004004 .security_cfm = l2cap_security_cfm,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004005 .recv_acldata = l2cap_recv_acldata
4006};
4007
Gustavo F. Padovan64274512011-02-07 20:08:52 -02004008int __init l2cap_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004009{
4010 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004011
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02004012 err = l2cap_init_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07004013 if (err < 0)
4014 return err;
4015
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004016 _busy_wq = create_singlethread_workqueue("l2cap");
Anderson Lizardob78d7b4f2010-11-29 12:15:50 -04004017 if (!_busy_wq) {
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02004018 err = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004019 goto error;
4020 }
4021
4022 err = hci_register_proto(&l2cap_hci_proto);
4023 if (err < 0) {
4024 BT_ERR("L2CAP protocol registration failed");
4025 bt_sock_unregister(BTPROTO_L2CAP);
4026 goto error;
4027 }
4028
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004029 if (bt_debugfs) {
4030 l2cap_debugfs = debugfs_create_file("l2cap", 0444,
4031 bt_debugfs, NULL, &l2cap_debugfs_fops);
4032 if (!l2cap_debugfs)
4033 BT_ERR("Failed to create L2CAP debug file");
4034 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004035
Linus Torvalds1da177e2005-04-16 15:20:36 -07004036 BT_INFO("L2CAP socket layer initialized");
4037
4038 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");