blob: c3cebed205ccfec22759191bb359b103e914f3e5 [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
Gustavo F. Padovand1010242011-03-25 00:39:48 -0300172static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk)
Marcel Holtmann01394182006-07-03 10:02:46 +0200173{
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);
Marcel Holtmann01394182006-07-03 10:02:46 +0200207}
208
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900209/* Delete channel.
Marcel Holtmann01394182006-07-03 10:02:46 +0200210 * Must be called on the locked socket. */
Gustavo F. Padovan6de07022011-02-04 03:35:20 -0200211void l2cap_chan_del(struct sock *sk, int err)
Marcel Holtmann01394182006-07-03 10:02:46 +0200212{
213 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
214 struct sock *parent = bt_sk(sk)->parent;
215
216 l2cap_sock_clear_timer(sk);
217
218 BT_DBG("sk %p, conn %p, err %d", sk, conn, err);
219
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900220 if (conn) {
Marcel Holtmann01394182006-07-03 10:02:46 +0200221 /* Unlink from channel list */
222 l2cap_chan_unlink(&conn->chan_list, sk);
223 l2cap_pi(sk)->conn = NULL;
224 hci_conn_put(conn->hcon);
225 }
226
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200227 sk->sk_state = BT_CLOSED;
Marcel Holtmann01394182006-07-03 10:02:46 +0200228 sock_set_flag(sk, SOCK_ZAPPED);
229
230 if (err)
231 sk->sk_err = err;
232
233 if (parent) {
234 bt_accept_unlink(sk);
235 parent->sk_data_ready(parent, 0);
236 } else
237 sk->sk_state_change(sk);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300238
239 skb_queue_purge(TX_QUEUE(sk));
240
241 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
242 struct srej_list *l, *tmp;
243
244 del_timer(&l2cap_pi(sk)->retrans_timer);
245 del_timer(&l2cap_pi(sk)->monitor_timer);
246 del_timer(&l2cap_pi(sk)->ack_timer);
247
248 skb_queue_purge(SREJ_QUEUE(sk));
249 skb_queue_purge(BUSY_QUEUE(sk));
250
251 list_for_each_entry_safe(l, tmp, SREJ_LIST(sk), list) {
252 list_del(&l->list);
253 kfree(l);
254 }
255 }
Marcel Holtmann01394182006-07-03 10:02:46 +0200256}
257
Johan Hedberg8556edd32011-01-19 12:06:50 +0530258static inline u8 l2cap_get_auth_type(struct sock *sk)
259{
260 if (sk->sk_type == SOCK_RAW) {
261 switch (l2cap_pi(sk)->sec_level) {
262 case BT_SECURITY_HIGH:
263 return HCI_AT_DEDICATED_BONDING_MITM;
264 case BT_SECURITY_MEDIUM:
265 return HCI_AT_DEDICATED_BONDING;
266 default:
267 return HCI_AT_NO_BONDING;
268 }
269 } else if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) {
270 if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW)
271 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
272
273 if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
274 return HCI_AT_NO_BONDING_MITM;
275 else
276 return HCI_AT_NO_BONDING;
277 } else {
278 switch (l2cap_pi(sk)->sec_level) {
279 case BT_SECURITY_HIGH:
280 return HCI_AT_GENERAL_BONDING_MITM;
281 case BT_SECURITY_MEDIUM:
282 return HCI_AT_GENERAL_BONDING;
283 default:
284 return HCI_AT_NO_BONDING;
285 }
286 }
287}
288
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200289/* Service level security */
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100290static inline int l2cap_check_security(struct sock *sk)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200291{
292 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100293 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200294
Johan Hedberg8556edd32011-01-19 12:06:50 +0530295 auth_type = l2cap_get_auth_type(sk);
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100296
297 return hci_conn_security(conn->hcon, l2cap_pi(sk)->sec_level,
298 auth_type);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200299}
300
Gustavo F. Padovan68983252011-02-04 03:02:31 -0200301u8 l2cap_get_ident(struct l2cap_conn *conn)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200302{
303 u8 id;
304
305 /* Get next available identificator.
306 * 1 - 128 are used by kernel.
307 * 129 - 199 are reserved.
308 * 200 - 254 are used by utilities like l2ping, etc.
309 */
310
311 spin_lock_bh(&conn->lock);
312
313 if (++conn->tx_ident > 128)
314 conn->tx_ident = 1;
315
316 id = conn->tx_ident;
317
318 spin_unlock_bh(&conn->lock);
319
320 return id;
321}
322
Gustavo F. Padovan68983252011-02-04 03:02:31 -0200323void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200324{
325 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200326 u8 flags;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200327
328 BT_DBG("code 0x%2.2x", code);
329
330 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300331 return;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200332
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200333 if (lmp_no_flush_capable(conn->hcon->hdev))
334 flags = ACL_START_NO_FLUSH;
335 else
336 flags = ACL_START;
337
338 hci_send_acl(conn->hcon, skb, flags);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200339}
340
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300341static inline void l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300342{
343 struct sk_buff *skb;
344 struct l2cap_hdr *lh;
345 struct l2cap_conn *conn = pi->conn;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300346 struct sock *sk = (struct sock *)pi;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300347 int count, hlen = L2CAP_HDR_SIZE + 2;
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200348 u8 flags;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300349
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300350 if (sk->sk_state != BT_CONNECTED)
351 return;
352
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300353 if (pi->fcs == L2CAP_FCS_CRC16)
354 hlen += 2;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300355
356 BT_DBG("pi %p, control 0x%2.2x", pi, control);
357
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300358 count = min_t(unsigned int, conn->mtu, hlen);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300359 control |= L2CAP_CTRL_FRAME_TYPE;
360
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -0300361 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
362 control |= L2CAP_CTRL_FINAL;
363 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
364 }
365
Gustavo F. Padovanf0946cc2010-05-01 16:15:37 -0300366 if (pi->conn_state & L2CAP_CONN_SEND_PBIT) {
367 control |= L2CAP_CTRL_POLL;
368 pi->conn_state &= ~L2CAP_CONN_SEND_PBIT;
369 }
370
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300371 skb = bt_skb_alloc(count, GFP_ATOMIC);
372 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300373 return;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300374
375 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300376 lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300377 lh->cid = cpu_to_le16(pi->dcid);
378 put_unaligned_le16(control, skb_put(skb, 2));
379
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300380 if (pi->fcs == L2CAP_FCS_CRC16) {
381 u16 fcs = crc16(0, (u8 *)lh, count - 2);
382 put_unaligned_le16(fcs, skb_put(skb, 2));
383 }
384
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200385 if (lmp_no_flush_capable(conn->hcon->hdev))
386 flags = ACL_START_NO_FLUSH;
387 else
388 flags = ACL_START;
389
390 hci_send_acl(pi->conn->hcon, skb, flags);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300391}
392
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300393static inline void l2cap_send_rr_or_rnr(struct l2cap_pinfo *pi, u16 control)
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300394{
Gustavo F. Padovan1890d362010-05-01 16:15:44 -0300395 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300396 control |= L2CAP_SUPER_RCV_NOT_READY;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -0300397 pi->conn_state |= L2CAP_CONN_RNR_SENT;
398 } else
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300399 control |= L2CAP_SUPER_RCV_READY;
400
Gustavo F. Padovan2ab25cd2009-10-03 02:34:40 -0300401 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
402
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300403 l2cap_send_sframe(pi, control);
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300404}
405
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300406static inline int __l2cap_no_conn_pending(struct sock *sk)
407{
408 return !(l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND);
409}
410
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200411static void l2cap_do_start(struct sock *sk)
412{
413 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
414
415 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +0100416 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
417 return;
418
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300419 if (l2cap_check_security(sk) && __l2cap_no_conn_pending(sk)) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200420 struct l2cap_conn_req req;
421 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
422 req.psm = l2cap_pi(sk)->psm;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200423
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200424 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300425 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200426
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200427 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200428 L2CAP_CONN_REQ, sizeof(req), &req);
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200429 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200430 } else {
431 struct l2cap_info_req req;
432 req.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
433
434 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
435 conn->info_ident = l2cap_get_ident(conn);
436
437 mod_timer(&conn->info_timer, jiffies +
438 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
439
440 l2cap_send_cmd(conn, conn->info_ident,
441 L2CAP_INFO_REQ, sizeof(req), &req);
442 }
443}
444
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -0300445static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
446{
447 u32 local_feat_mask = l2cap_feat_mask;
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -0300448 if (!disable_ertm)
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -0300449 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
450
451 switch (mode) {
452 case L2CAP_MODE_ERTM:
453 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
454 case L2CAP_MODE_STREAMING:
455 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
456 default:
457 return 0x00;
458 }
459}
460
Gustavo F. Padovan6de07022011-02-04 03:35:20 -0200461void l2cap_send_disconn_req(struct l2cap_conn *conn, struct sock *sk, int err)
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300462{
463 struct l2cap_disconn_req req;
464
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300465 if (!conn)
466 return;
467
468 skb_queue_purge(TX_QUEUE(sk));
469
470 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
471 del_timer(&l2cap_pi(sk)->retrans_timer);
472 del_timer(&l2cap_pi(sk)->monitor_timer);
473 del_timer(&l2cap_pi(sk)->ack_timer);
474 }
475
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300476 req.dcid = cpu_to_le16(l2cap_pi(sk)->dcid);
477 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
478 l2cap_send_cmd(conn, l2cap_get_ident(conn),
479 L2CAP_DISCONN_REQ, sizeof(req), &req);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300480
481 sk->sk_state = BT_DISCONN;
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -0300482 sk->sk_err = err;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300483}
484
Linus Torvalds1da177e2005-04-16 15:20:36 -0700485/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200486static void l2cap_conn_start(struct l2cap_conn *conn)
487{
488 struct l2cap_chan_list *l = &conn->chan_list;
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -0300489 struct sock_del_list del, *tmp1, *tmp2;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200490 struct sock *sk;
491
492 BT_DBG("conn %p", conn);
493
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -0300494 INIT_LIST_HEAD(&del.list);
495
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200496 read_lock(&l->lock);
497
498 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
499 bh_lock_sock(sk);
500
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300501 if (sk->sk_type != SOCK_SEQPACKET &&
502 sk->sk_type != SOCK_STREAM) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200503 bh_unlock_sock(sk);
504 continue;
505 }
506
507 if (sk->sk_state == BT_CONNECT) {
Gustavo F. Padovan47731de2010-07-09 16:38:35 -0300508 struct l2cap_conn_req req;
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -0300509
Gustavo F. Padovan47731de2010-07-09 16:38:35 -0300510 if (!l2cap_check_security(sk) ||
511 !__l2cap_no_conn_pending(sk)) {
512 bh_unlock_sock(sk);
513 continue;
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200514 }
Gustavo F. Padovan47731de2010-07-09 16:38:35 -0300515
516 if (!l2cap_mode_supported(l2cap_pi(sk)->mode,
517 conn->feat_mask)
518 && l2cap_pi(sk)->conf_state &
519 L2CAP_CONF_STATE2_DEVICE) {
520 tmp1 = kzalloc(sizeof(struct sock_del_list),
521 GFP_ATOMIC);
522 tmp1->sk = sk;
523 list_add_tail(&tmp1->list, &del.list);
524 bh_unlock_sock(sk);
525 continue;
526 }
527
528 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
529 req.psm = l2cap_pi(sk)->psm;
530
531 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
532 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
533
534 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
535 L2CAP_CONN_REQ, sizeof(req), &req);
536
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200537 } else if (sk->sk_state == BT_CONNECT2) {
538 struct l2cap_conn_rsp rsp;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -0300539 char buf[128];
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200540 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
541 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
542
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100543 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100544 if (bt_sk(sk)->defer_setup) {
545 struct sock *parent = bt_sk(sk)->parent;
546 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
547 rsp.status = cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
548 parent->sk_data_ready(parent, 0);
549
550 } else {
551 sk->sk_state = BT_CONFIG;
552 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
553 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
554 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200555 } else {
556 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
557 rsp.status = cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
558 }
559
560 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
561 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -0300562
563 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT ||
564 rsp.result != L2CAP_CR_SUCCESS) {
565 bh_unlock_sock(sk);
566 continue;
567 }
568
569 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
570 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
571 l2cap_build_conf_req(sk, buf), buf);
572 l2cap_pi(sk)->num_conf_req++;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200573 }
574
575 bh_unlock_sock(sk);
576 }
577
578 read_unlock(&l->lock);
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -0300579
580 list_for_each_entry_safe(tmp1, tmp2, &del.list, list) {
581 bh_lock_sock(tmp1->sk);
582 __l2cap_sock_close(tmp1->sk, ECONNRESET);
583 bh_unlock_sock(tmp1->sk);
584 list_del(&tmp1->list);
585 kfree(tmp1);
586 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200587}
588
Ville Tervob62f3282011-02-10 22:38:50 -0300589/* Find socket with cid and source bdaddr.
590 * Returns closest match, locked.
591 */
592static struct sock *l2cap_get_sock_by_scid(int state, __le16 cid, bdaddr_t *src)
593{
594 struct sock *s, *sk = NULL, *sk1 = NULL;
595 struct hlist_node *node;
596
597 read_lock(&l2cap_sk_list.lock);
598
599 sk_for_each(sk, node, &l2cap_sk_list.head) {
600 if (state && sk->sk_state != state)
601 continue;
602
603 if (l2cap_pi(sk)->scid == cid) {
604 /* Exact match. */
605 if (!bacmp(&bt_sk(sk)->src, src))
606 break;
607
608 /* Closest match */
609 if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY))
610 sk1 = sk;
611 }
612 }
613 s = node ? sk : sk1;
614 if (s)
615 bh_lock_sock(s);
616 read_unlock(&l2cap_sk_list.lock);
617
618 return s;
619}
620
621static void l2cap_le_conn_ready(struct l2cap_conn *conn)
622{
623 struct l2cap_chan_list *list = &conn->chan_list;
624 struct sock *parent, *uninitialized_var(sk);
625
626 BT_DBG("");
627
628 /* Check if we have socket listening on cid */
629 parent = l2cap_get_sock_by_scid(BT_LISTEN, L2CAP_CID_LE_DATA,
630 conn->src);
631 if (!parent)
632 return;
633
634 /* Check for backlog size */
635 if (sk_acceptq_is_full(parent)) {
636 BT_DBG("backlog full %d", parent->sk_ack_backlog);
637 goto clean;
638 }
639
640 sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, GFP_ATOMIC);
641 if (!sk)
642 goto clean;
643
644 write_lock_bh(&list->lock);
645
646 hci_conn_hold(conn->hcon);
647
648 l2cap_sock_init(sk, parent);
649 bacpy(&bt_sk(sk)->src, conn->src);
650 bacpy(&bt_sk(sk)->dst, conn->dst);
651
Gustavo F. Padovand1010242011-03-25 00:39:48 -0300652 bt_accept_enqueue(parent, sk);
653
654 __l2cap_chan_add(conn, sk);
Ville Tervob62f3282011-02-10 22:38:50 -0300655
656 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
657
658 sk->sk_state = BT_CONNECTED;
659 parent->sk_data_ready(parent, 0);
660
661 write_unlock_bh(&list->lock);
662
663clean:
664 bh_unlock_sock(parent);
665}
666
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200667static void l2cap_conn_ready(struct l2cap_conn *conn)
668{
669 struct l2cap_chan_list *l = &conn->chan_list;
670 struct sock *sk;
671
672 BT_DBG("conn %p", conn);
673
Ville Tervob62f3282011-02-10 22:38:50 -0300674 if (!conn->hcon->out && conn->hcon->type == LE_LINK)
675 l2cap_le_conn_ready(conn);
676
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200677 read_lock(&l->lock);
678
679 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
680 bh_lock_sock(sk);
681
Ville Tervoacd7d372011-02-10 22:38:49 -0300682 if (conn->hcon->type == LE_LINK) {
683 l2cap_sock_clear_timer(sk);
684 sk->sk_state = BT_CONNECTED;
685 sk->sk_state_change(sk);
686 }
687
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300688 if (sk->sk_type != SOCK_SEQPACKET &&
689 sk->sk_type != SOCK_STREAM) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200690 l2cap_sock_clear_timer(sk);
691 sk->sk_state = BT_CONNECTED;
692 sk->sk_state_change(sk);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200693 } else if (sk->sk_state == BT_CONNECT)
694 l2cap_do_start(sk);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200695
696 bh_unlock_sock(sk);
697 }
698
699 read_unlock(&l->lock);
700}
701
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200702/* Notify sockets that we cannot guaranty reliability anymore */
703static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
704{
705 struct l2cap_chan_list *l = &conn->chan_list;
706 struct sock *sk;
707
708 BT_DBG("conn %p", conn);
709
710 read_lock(&l->lock);
711
712 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100713 if (l2cap_pi(sk)->force_reliable)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200714 sk->sk_err = err;
715 }
716
717 read_unlock(&l->lock);
718}
719
720static void l2cap_info_timeout(unsigned long arg)
721{
722 struct l2cap_conn *conn = (void *) arg;
723
Marcel Holtmann984947d2009-02-06 23:35:19 +0100724 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +0100725 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +0100726
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200727 l2cap_conn_start(conn);
728}
729
Linus Torvalds1da177e2005-04-16 15:20:36 -0700730static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
731{
Marcel Holtmann01394182006-07-03 10:02:46 +0200732 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700733
Marcel Holtmann01394182006-07-03 10:02:46 +0200734 if (conn || status)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700735 return conn;
736
Marcel Holtmann01394182006-07-03 10:02:46 +0200737 conn = kzalloc(sizeof(struct l2cap_conn), GFP_ATOMIC);
738 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700739 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700740
741 hcon->l2cap_data = conn;
742 conn->hcon = hcon;
743
Marcel Holtmann01394182006-07-03 10:02:46 +0200744 BT_DBG("hcon %p conn %p", hcon, conn);
745
Ville Tervoacd7d372011-02-10 22:38:49 -0300746 if (hcon->hdev->le_mtu && hcon->type == LE_LINK)
747 conn->mtu = hcon->hdev->le_mtu;
748 else
749 conn->mtu = hcon->hdev->acl_mtu;
750
Linus Torvalds1da177e2005-04-16 15:20:36 -0700751 conn->src = &hcon->hdev->bdaddr;
752 conn->dst = &hcon->dst;
753
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200754 conn->feat_mask = 0;
755
Linus Torvalds1da177e2005-04-16 15:20:36 -0700756 spin_lock_init(&conn->lock);
757 rwlock_init(&conn->chan_list.lock);
758
Ville Tervob62f3282011-02-10 22:38:50 -0300759 if (hcon->type != LE_LINK)
760 setup_timer(&conn->info_timer, l2cap_info_timeout,
Dave Young45054dc2009-10-18 20:28:30 +0000761 (unsigned long) conn);
762
Marcel Holtmann2950f212009-02-12 14:02:50 +0100763 conn->disc_reason = 0x13;
764
Linus Torvalds1da177e2005-04-16 15:20:36 -0700765 return conn;
766}
767
Marcel Holtmann01394182006-07-03 10:02:46 +0200768static void l2cap_conn_del(struct hci_conn *hcon, int err)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700769{
Marcel Holtmann01394182006-07-03 10:02:46 +0200770 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700771 struct sock *sk;
772
Marcel Holtmann01394182006-07-03 10:02:46 +0200773 if (!conn)
774 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700775
776 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
777
Wei Yongjun7585b972009-02-25 18:29:52 +0800778 kfree_skb(conn->rx_skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700779
780 /* Kill channels */
781 while ((sk = conn->chan_list.head)) {
782 bh_lock_sock(sk);
783 l2cap_chan_del(sk, err);
784 bh_unlock_sock(sk);
785 l2cap_sock_kill(sk);
786 }
787
Dave Young8e8440f2008-03-03 12:18:55 -0800788 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
789 del_timer_sync(&conn->info_timer);
Thomas Gleixner3ab22732008-02-26 17:42:56 -0800790
Linus Torvalds1da177e2005-04-16 15:20:36 -0700791 hcon->l2cap_data = NULL;
792 kfree(conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700793}
794
Gustavo F. Padovand1010242011-03-25 00:39:48 -0300795static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700796{
797 struct l2cap_chan_list *l = &conn->chan_list;
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200798 write_lock_bh(&l->lock);
Gustavo F. Padovand1010242011-03-25 00:39:48 -0300799 __l2cap_chan_add(conn, sk);
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200800 write_unlock_bh(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700801}
802
Linus Torvalds1da177e2005-04-16 15:20:36 -0700803/* ---- Socket interface ---- */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700804
805/* Find socket with psm and source bdaddr.
806 * Returns closest match.
807 */
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +0000808static struct sock *l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700809{
810 struct sock *sk = NULL, *sk1 = NULL;
811 struct hlist_node *node;
812
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +0000813 read_lock(&l2cap_sk_list.lock);
814
Linus Torvalds1da177e2005-04-16 15:20:36 -0700815 sk_for_each(sk, node, &l2cap_sk_list.head) {
816 if (state && sk->sk_state != state)
817 continue;
818
819 if (l2cap_pi(sk)->psm == psm) {
820 /* Exact match. */
821 if (!bacmp(&bt_sk(sk)->src, src))
822 break;
823
824 /* Closest match */
825 if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY))
826 sk1 = sk;
827 }
828 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700829
Linus Torvalds1da177e2005-04-16 15:20:36 -0700830 read_unlock(&l2cap_sk_list.lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +0000831
832 return node ? sk : sk1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700833}
834
Gustavo F. Padovan4e34c502011-02-04 02:56:13 -0200835int l2cap_do_connect(struct sock *sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700836{
837 bdaddr_t *src = &bt_sk(sk)->src;
838 bdaddr_t *dst = &bt_sk(sk)->dst;
839 struct l2cap_conn *conn;
840 struct hci_conn *hcon;
841 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200842 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +0200843 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700844
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100845 BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst),
846 l2cap_pi(sk)->psm);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700847
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300848 hdev = hci_get_route(dst, src);
849 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700850 return -EHOSTUNREACH;
851
852 hci_dev_lock_bh(hdev);
853
Johan Hedberg8556edd32011-01-19 12:06:50 +0530854 auth_type = l2cap_get_auth_type(sk);
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200855
Ville Tervoacd7d372011-02-10 22:38:49 -0300856 if (l2cap_pi(sk)->dcid == L2CAP_CID_LE_DATA)
857 hcon = hci_connect(hdev, LE_LINK, dst,
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100858 l2cap_pi(sk)->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -0300859 else
860 hcon = hci_connect(hdev, ACL_LINK, dst,
861 l2cap_pi(sk)->sec_level, auth_type);
862
Ville Tervo30e76272011-02-22 16:10:53 -0300863 if (IS_ERR(hcon)) {
864 err = PTR_ERR(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700865 goto done;
Ville Tervo30e76272011-02-22 16:10:53 -0300866 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700867
868 conn = l2cap_conn_add(hcon, 0);
869 if (!conn) {
870 hci_conn_put(hcon);
Ville Tervo30e76272011-02-22 16:10:53 -0300871 err = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700872 goto done;
873 }
874
Linus Torvalds1da177e2005-04-16 15:20:36 -0700875 /* Update source addr of the socket */
876 bacpy(src, conn->src);
877
Gustavo F. Padovand1010242011-03-25 00:39:48 -0300878 l2cap_chan_add(conn, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700879
880 sk->sk_state = BT_CONNECT;
881 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
882
883 if (hcon->state == BT_CONNECTED) {
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300884 if (sk->sk_type != SOCK_SEQPACKET &&
885 sk->sk_type != SOCK_STREAM) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700886 l2cap_sock_clear_timer(sk);
Johan Hedbergd00ef242011-01-19 12:06:51 +0530887 if (l2cap_check_security(sk))
888 sk->sk_state = BT_CONNECTED;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200889 } else
890 l2cap_do_start(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700891 }
892
Ville Tervo30e76272011-02-22 16:10:53 -0300893 err = 0;
894
Linus Torvalds1da177e2005-04-16 15:20:36 -0700895done:
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
Suraj Sumangala23e9fde2011-03-09 14:44:05 +05301118 if (bt_cb(skb)->retries == 1)
1119 pi->unacked_frames++;
1120
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001121 pi->frames_sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001122
1123 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1124 sk->sk_send_head = NULL;
1125 else
1126 sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001127
1128 nsent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001129 }
1130
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001131 return nsent;
1132}
1133
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001134static int l2cap_retransmit_frames(struct sock *sk)
1135{
1136 struct l2cap_pinfo *pi = l2cap_pi(sk);
1137 int ret;
1138
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001139 if (!skb_queue_empty(TX_QUEUE(sk)))
1140 sk->sk_send_head = TX_QUEUE(sk)->next;
1141
1142 pi->next_tx_seq = pi->expected_ack_seq;
1143 ret = l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001144 return ret;
1145}
1146
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001147static void l2cap_send_ack(struct l2cap_pinfo *pi)
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001148{
1149 struct sock *sk = (struct sock *)pi;
1150 u16 control = 0;
1151
1152 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1153
1154 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
1155 control |= L2CAP_SUPER_RCV_NOT_READY;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03001156 pi->conn_state |= L2CAP_CONN_RNR_SENT;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001157 l2cap_send_sframe(pi, control);
1158 return;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001159 }
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001160
Gustavo F. Padovane0f66212010-06-21 18:50:49 -03001161 if (l2cap_ertm_send(sk) > 0)
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001162 return;
1163
1164 control |= L2CAP_SUPER_RCV_READY;
1165 l2cap_send_sframe(pi, control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001166}
1167
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001168static void l2cap_send_srejtail(struct sock *sk)
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03001169{
1170 struct srej_list *tail;
1171 u16 control;
1172
1173 control = L2CAP_SUPER_SELECT_REJECT;
1174 control |= L2CAP_CTRL_FINAL;
1175
1176 tail = list_entry(SREJ_LIST(sk)->prev, struct srej_list, list);
1177 control |= tail->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1178
1179 l2cap_send_sframe(l2cap_pi(sk), control);
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03001180}
1181
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001182static 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 -07001183{
1184 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001185 struct sk_buff **frag;
1186 int err, sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001187
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03001188 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001189 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001190
1191 sent += count;
1192 len -= count;
1193
1194 /* Continuation fragments (no L2CAP header) */
1195 frag = &skb_shinfo(skb)->frag_list;
1196 while (len) {
1197 count = min_t(unsigned int, conn->mtu, len);
1198
1199 *frag = bt_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err);
1200 if (!*frag)
Gustavo F. Padovan0175d622010-09-24 20:30:57 -03001201 return err;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001202 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
1203 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001204
1205 sent += count;
1206 len -= count;
1207
1208 frag = &(*frag)->next;
1209 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001210
1211 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001212}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001213
Gustavo F. Padovanfd83ccd2011-02-04 03:20:52 -02001214struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, size_t len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001215{
1216 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1217 struct sk_buff *skb;
1218 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1219 struct l2cap_hdr *lh;
1220
1221 BT_DBG("sk %p len %d", sk, (int)len);
1222
1223 count = min_t(unsigned int, (conn->mtu - hlen), len);
1224 skb = bt_skb_send_alloc(sk, count + hlen,
1225 msg->msg_flags & MSG_DONTWAIT, &err);
1226 if (!skb)
Gustavo F. Padovan0175d622010-09-24 20:30:57 -03001227 return ERR_PTR(err);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001228
1229 /* Create L2CAP header */
1230 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1231 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1232 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1233 put_unaligned_le16(l2cap_pi(sk)->psm, skb_put(skb, 2));
1234
1235 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1236 if (unlikely(err < 0)) {
1237 kfree_skb(skb);
1238 return ERR_PTR(err);
1239 }
1240 return skb;
1241}
1242
Gustavo F. Padovanfd83ccd2011-02-04 03:20:52 -02001243struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *msg, size_t len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001244{
1245 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1246 struct sk_buff *skb;
1247 int err, count, hlen = L2CAP_HDR_SIZE;
1248 struct l2cap_hdr *lh;
1249
1250 BT_DBG("sk %p len %d", sk, (int)len);
1251
1252 count = min_t(unsigned int, (conn->mtu - hlen), len);
1253 skb = bt_skb_send_alloc(sk, count + hlen,
1254 msg->msg_flags & MSG_DONTWAIT, &err);
1255 if (!skb)
Gustavo F. Padovan0175d622010-09-24 20:30:57 -03001256 return ERR_PTR(err);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001257
1258 /* Create L2CAP header */
1259 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1260 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1261 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1262
1263 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1264 if (unlikely(err < 0)) {
1265 kfree_skb(skb);
1266 return ERR_PTR(err);
1267 }
1268 return skb;
1269}
1270
Gustavo F. Padovanfd83ccd2011-02-04 03:20:52 -02001271struct 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 -03001272{
1273 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1274 struct sk_buff *skb;
1275 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1276 struct l2cap_hdr *lh;
1277
1278 BT_DBG("sk %p len %d", sk, (int)len);
1279
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03001280 if (!conn)
1281 return ERR_PTR(-ENOTCONN);
1282
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001283 if (sdulen)
1284 hlen += 2;
1285
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001286 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1287 hlen += 2;
1288
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001289 count = min_t(unsigned int, (conn->mtu - hlen), len);
1290 skb = bt_skb_send_alloc(sk, count + hlen,
1291 msg->msg_flags & MSG_DONTWAIT, &err);
1292 if (!skb)
Gustavo F. Padovan0175d622010-09-24 20:30:57 -03001293 return ERR_PTR(err);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001294
1295 /* Create L2CAP header */
1296 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1297 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1298 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1299 put_unaligned_le16(control, skb_put(skb, 2));
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001300 if (sdulen)
1301 put_unaligned_le16(sdulen, skb_put(skb, 2));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001302
1303 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1304 if (unlikely(err < 0)) {
1305 kfree_skb(skb);
1306 return ERR_PTR(err);
1307 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001308
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001309 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1310 put_unaligned_le16(0, skb_put(skb, 2));
1311
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001312 bt_cb(skb)->retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001313 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001314}
1315
Gustavo F. Padovanfd83ccd2011-02-04 03:20:52 -02001316int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001317{
1318 struct l2cap_pinfo *pi = l2cap_pi(sk);
1319 struct sk_buff *skb;
1320 struct sk_buff_head sar_queue;
1321 u16 control;
1322 size_t size = 0;
1323
Gustavo F. Padovanff12fd62010-05-05 22:09:15 -03001324 skb_queue_head_init(&sar_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001325 control = L2CAP_SDU_START;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001326 skb = l2cap_create_iframe_pdu(sk, msg, pi->remote_mps, control, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001327 if (IS_ERR(skb))
1328 return PTR_ERR(skb);
1329
1330 __skb_queue_tail(&sar_queue, skb);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001331 len -= pi->remote_mps;
1332 size += pi->remote_mps;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001333
1334 while (len > 0) {
1335 size_t buflen;
1336
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001337 if (len > pi->remote_mps) {
Gustavo F. Padovan44651b82010-05-01 16:15:43 -03001338 control = L2CAP_SDU_CONTINUE;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001339 buflen = pi->remote_mps;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001340 } else {
Gustavo F. Padovan44651b82010-05-01 16:15:43 -03001341 control = L2CAP_SDU_END;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001342 buflen = len;
1343 }
1344
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001345 skb = l2cap_create_iframe_pdu(sk, msg, buflen, control, 0);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001346 if (IS_ERR(skb)) {
1347 skb_queue_purge(&sar_queue);
1348 return PTR_ERR(skb);
1349 }
1350
1351 __skb_queue_tail(&sar_queue, skb);
1352 len -= buflen;
1353 size += buflen;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001354 }
1355 skb_queue_splice_tail(&sar_queue, TX_QUEUE(sk));
1356 if (sk->sk_send_head == NULL)
1357 sk->sk_send_head = sar_queue.next;
1358
1359 return size;
1360}
1361
Linus Torvalds1da177e2005-04-16 15:20:36 -07001362static void l2cap_chan_ready(struct sock *sk)
1363{
1364 struct sock *parent = bt_sk(sk)->parent;
1365
1366 BT_DBG("sk %p, parent %p", sk, parent);
1367
1368 l2cap_pi(sk)->conf_state = 0;
1369 l2cap_sock_clear_timer(sk);
1370
1371 if (!parent) {
1372 /* Outgoing channel.
1373 * Wake up socket sleeping on connect.
1374 */
1375 sk->sk_state = BT_CONNECTED;
1376 sk->sk_state_change(sk);
1377 } else {
1378 /* Incoming channel.
1379 * Wake up socket sleeping on accept.
1380 */
1381 parent->sk_data_ready(parent, 0);
1382 }
1383}
1384
1385/* Copy frame to all raw sockets on that connection */
1386static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
1387{
1388 struct l2cap_chan_list *l = &conn->chan_list;
1389 struct sk_buff *nskb;
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001390 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001391
1392 BT_DBG("conn %p", conn);
1393
1394 read_lock(&l->lock);
1395 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
1396 if (sk->sk_type != SOCK_RAW)
1397 continue;
1398
1399 /* Don't send frame to the socket it came from */
1400 if (skb->sk == sk)
1401 continue;
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001402 nskb = skb_clone(skb, GFP_ATOMIC);
1403 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001404 continue;
1405
1406 if (sock_queue_rcv_skb(sk, nskb))
1407 kfree_skb(nskb);
1408 }
1409 read_unlock(&l->lock);
1410}
1411
1412/* ---- L2CAP signalling commands ---- */
1413static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
1414 u8 code, u8 ident, u16 dlen, void *data)
1415{
1416 struct sk_buff *skb, **frag;
1417 struct l2cap_cmd_hdr *cmd;
1418 struct l2cap_hdr *lh;
1419 int len, count;
1420
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001421 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d",
1422 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001423
1424 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
1425 count = min_t(unsigned int, conn->mtu, len);
1426
1427 skb = bt_skb_alloc(count, GFP_ATOMIC);
1428 if (!skb)
1429 return NULL;
1430
1431 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07001432 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02001433
1434 if (conn->hcon->type == LE_LINK)
1435 lh->cid = cpu_to_le16(L2CAP_CID_LE_SIGNALING);
1436 else
1437 lh->cid = cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001438
1439 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
1440 cmd->code = code;
1441 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07001442 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001443
1444 if (dlen) {
1445 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
1446 memcpy(skb_put(skb, count), data, count);
1447 data += count;
1448 }
1449
1450 len -= skb->len;
1451
1452 /* Continuation fragments (no L2CAP header) */
1453 frag = &skb_shinfo(skb)->frag_list;
1454 while (len) {
1455 count = min_t(unsigned int, conn->mtu, len);
1456
1457 *frag = bt_skb_alloc(count, GFP_ATOMIC);
1458 if (!*frag)
1459 goto fail;
1460
1461 memcpy(skb_put(*frag, count), data, count);
1462
1463 len -= count;
1464 data += count;
1465
1466 frag = &(*frag)->next;
1467 }
1468
1469 return skb;
1470
1471fail:
1472 kfree_skb(skb);
1473 return NULL;
1474}
1475
1476static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned long *val)
1477{
1478 struct l2cap_conf_opt *opt = *ptr;
1479 int len;
1480
1481 len = L2CAP_CONF_OPT_SIZE + opt->len;
1482 *ptr += len;
1483
1484 *type = opt->type;
1485 *olen = opt->len;
1486
1487 switch (opt->len) {
1488 case 1:
1489 *val = *((u8 *) opt->val);
1490 break;
1491
1492 case 2:
steven miaobfaaeb32010-10-16 18:29:47 -04001493 *val = get_unaligned_le16(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001494 break;
1495
1496 case 4:
steven miaobfaaeb32010-10-16 18:29:47 -04001497 *val = get_unaligned_le32(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001498 break;
1499
1500 default:
1501 *val = (unsigned long) opt->val;
1502 break;
1503 }
1504
1505 BT_DBG("type 0x%2.2x len %d val 0x%lx", *type, opt->len, *val);
1506 return len;
1507}
1508
Linus Torvalds1da177e2005-04-16 15:20:36 -07001509static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
1510{
1511 struct l2cap_conf_opt *opt = *ptr;
1512
1513 BT_DBG("type 0x%2.2x len %d val 0x%lx", type, len, val);
1514
1515 opt->type = type;
1516 opt->len = len;
1517
1518 switch (len) {
1519 case 1:
1520 *((u8 *) opt->val) = val;
1521 break;
1522
1523 case 2:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02001524 put_unaligned_le16(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001525 break;
1526
1527 case 4:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02001528 put_unaligned_le32(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001529 break;
1530
1531 default:
1532 memcpy(opt->val, (void *) val, len);
1533 break;
1534 }
1535
1536 *ptr += L2CAP_CONF_OPT_SIZE + len;
1537}
1538
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03001539static void l2cap_ack_timeout(unsigned long arg)
1540{
1541 struct sock *sk = (void *) arg;
1542
1543 bh_lock_sock(sk);
1544 l2cap_send_ack(l2cap_pi(sk));
1545 bh_unlock_sock(sk);
1546}
1547
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03001548static inline void l2cap_ertm_init(struct sock *sk)
1549{
1550 l2cap_pi(sk)->expected_ack_seq = 0;
1551 l2cap_pi(sk)->unacked_frames = 0;
1552 l2cap_pi(sk)->buffer_seq = 0;
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03001553 l2cap_pi(sk)->num_acked = 0;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001554 l2cap_pi(sk)->frames_sent = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03001555
1556 setup_timer(&l2cap_pi(sk)->retrans_timer,
1557 l2cap_retrans_timeout, (unsigned long) sk);
1558 setup_timer(&l2cap_pi(sk)->monitor_timer,
1559 l2cap_monitor_timeout, (unsigned long) sk);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03001560 setup_timer(&l2cap_pi(sk)->ack_timer,
1561 l2cap_ack_timeout, (unsigned long) sk);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03001562
1563 __skb_queue_head_init(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03001564 __skb_queue_head_init(BUSY_QUEUE(sk));
1565
1566 INIT_WORK(&l2cap_pi(sk)->busy_work, l2cap_busy_work);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03001567
1568 sk->sk_backlog_rcv = l2cap_ertm_data_rcv;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03001569}
1570
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001571static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
1572{
1573 switch (mode) {
1574 case L2CAP_MODE_STREAMING:
1575 case L2CAP_MODE_ERTM:
1576 if (l2cap_mode_supported(mode, remote_feat_mask))
1577 return mode;
1578 /* fall through */
1579 default:
1580 return L2CAP_MODE_BASIC;
1581 }
1582}
1583
Gustavo F. Padovan68983252011-02-04 03:02:31 -02001584int l2cap_build_conf_req(struct sock *sk, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001585{
1586 struct l2cap_pinfo *pi = l2cap_pi(sk);
1587 struct l2cap_conf_req *req = data;
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001588 struct l2cap_conf_rfc rfc = { .mode = pi->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07001589 void *ptr = req->data;
1590
1591 BT_DBG("sk %p", sk);
1592
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001593 if (pi->num_conf_req || pi->num_conf_rsp)
1594 goto done;
1595
1596 switch (pi->mode) {
1597 case L2CAP_MODE_STREAMING:
1598 case L2CAP_MODE_ERTM:
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03001599 if (pi->conf_state & L2CAP_CONF_STATE2_DEVICE)
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03001600 break;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03001601
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03001602 /* fall through */
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001603 default:
1604 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
1605 break;
1606 }
1607
1608done:
Gustavo F. Padovan7990681c2011-01-24 16:01:43 -02001609 if (pi->imtu != L2CAP_DEFAULT_MTU)
1610 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
1611
Marcel Holtmann65c7c492009-05-02 23:07:53 -07001612 switch (pi->mode) {
1613 case L2CAP_MODE_BASIC:
Gustavo F. Padovan63406502010-08-03 23:49:29 -03001614 if (!(pi->conn->feat_mask & L2CAP_FEAT_ERTM) &&
1615 !(pi->conn->feat_mask & L2CAP_FEAT_STREAMING))
1616 break;
1617
Gustavo F. Padovan62547752010-06-08 20:05:31 -03001618 rfc.mode = L2CAP_MODE_BASIC;
1619 rfc.txwin_size = 0;
1620 rfc.max_transmit = 0;
1621 rfc.retrans_timeout = 0;
1622 rfc.monitor_timeout = 0;
1623 rfc.max_pdu_size = 0;
1624
Gustavo F. Padovan63406502010-08-03 23:49:29 -03001625 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
1626 (unsigned long) &rfc);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07001627 break;
1628
1629 case L2CAP_MODE_ERTM:
1630 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03001631 rfc.txwin_size = pi->tx_win;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03001632 rfc.max_transmit = pi->max_tx;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001633 rfc.retrans_timeout = 0;
1634 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001635 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03001636 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001637 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001638
Gustavo F. Padovan63406502010-08-03 23:49:29 -03001639 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
1640 (unsigned long) &rfc);
1641
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001642 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
1643 break;
1644
1645 if (pi->fcs == L2CAP_FCS_NONE ||
1646 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
1647 pi->fcs = L2CAP_FCS_NONE;
1648 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
1649 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001650 break;
1651
1652 case L2CAP_MODE_STREAMING:
1653 rfc.mode = L2CAP_MODE_STREAMING;
1654 rfc.txwin_size = 0;
1655 rfc.max_transmit = 0;
1656 rfc.retrans_timeout = 0;
1657 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001658 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03001659 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001660 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07001661
Gustavo F. Padovan63406502010-08-03 23:49:29 -03001662 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
1663 (unsigned long) &rfc);
1664
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001665 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
1666 break;
1667
1668 if (pi->fcs == L2CAP_FCS_NONE ||
1669 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
1670 pi->fcs = L2CAP_FCS_NONE;
1671 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
1672 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07001673 break;
1674 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001675
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07001676 req->dcid = cpu_to_le16(pi->dcid);
1677 req->flags = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001678
1679 return ptr - data;
1680}
1681
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001682static int l2cap_parse_conf_req(struct sock *sk, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001683{
1684 struct l2cap_pinfo *pi = l2cap_pi(sk);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001685 struct l2cap_conf_rsp *rsp = data;
1686 void *ptr = rsp->data;
1687 void *req = pi->conf_req;
1688 int len = pi->conf_len;
1689 int type, hint, olen;
1690 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02001691 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Marcel Holtmann861d6882007-10-20 13:37:06 +02001692 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001693 u16 result = L2CAP_CONF_SUCCESS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001694
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001695 BT_DBG("sk %p", sk);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01001696
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001697 while (len >= L2CAP_CONF_OPT_SIZE) {
1698 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001699
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03001700 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07001701 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001702
1703 switch (type) {
1704 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02001705 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001706 break;
1707
1708 case L2CAP_CONF_FLUSH_TO:
1709 pi->flush_to = val;
1710 break;
1711
1712 case L2CAP_CONF_QOS:
1713 break;
1714
Marcel Holtmann6464f352007-10-20 13:39:51 +02001715 case L2CAP_CONF_RFC:
1716 if (olen == sizeof(rfc))
1717 memcpy(&rfc, (void *) val, olen);
1718 break;
1719
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001720 case L2CAP_CONF_FCS:
1721 if (val == L2CAP_FCS_NONE)
1722 pi->conf_state |= L2CAP_CONF_NO_FCS_RECV;
1723
1724 break;
1725
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001726 default:
1727 if (hint)
1728 break;
1729
1730 result = L2CAP_CONF_UNKNOWN;
1731 *((u8 *) ptr++) = type;
1732 break;
1733 }
1734 }
1735
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001736 if (pi->num_conf_rsp || pi->num_conf_req > 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001737 goto done;
1738
1739 switch (pi->mode) {
1740 case L2CAP_MODE_STREAMING:
1741 case L2CAP_MODE_ERTM:
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03001742 if (!(pi->conf_state & L2CAP_CONF_STATE2_DEVICE)) {
1743 pi->mode = l2cap_select_mode(rfc.mode,
1744 pi->conn->feat_mask);
1745 break;
1746 }
1747
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03001748 if (pi->mode != rfc.mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001749 return -ECONNREFUSED;
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03001750
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001751 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001752 }
1753
1754done:
1755 if (pi->mode != rfc.mode) {
1756 result = L2CAP_CONF_UNACCEPT;
1757 rfc.mode = pi->mode;
1758
1759 if (pi->num_conf_rsp == 1)
1760 return -ECONNREFUSED;
1761
1762 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
1763 sizeof(rfc), (unsigned long) &rfc);
1764 }
1765
1766
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001767 if (result == L2CAP_CONF_SUCCESS) {
1768 /* Configure output options and let the other side know
1769 * which ones we don't like. */
1770
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001771 if (mtu < L2CAP_DEFAULT_MIN_MTU)
1772 result = L2CAP_CONF_UNACCEPT;
1773 else {
1774 pi->omtu = mtu;
1775 pi->conf_state |= L2CAP_CONF_MTU_DONE;
1776 }
1777 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001778
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001779 switch (rfc.mode) {
1780 case L2CAP_MODE_BASIC:
1781 pi->fcs = L2CAP_FCS_NONE;
1782 pi->conf_state |= L2CAP_CONF_MODE_DONE;
1783 break;
1784
1785 case L2CAP_MODE_ERTM:
1786 pi->remote_tx_win = rfc.txwin_size;
1787 pi->remote_max_tx = rfc.max_transmit;
Mat Martineau86b1b262010-08-05 15:54:22 -07001788
1789 if (le16_to_cpu(rfc.max_pdu_size) > pi->conn->mtu - 10)
1790 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001791
1792 pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001793
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03001794 rfc.retrans_timeout =
1795 le16_to_cpu(L2CAP_DEFAULT_RETRANS_TO);
1796 rfc.monitor_timeout =
1797 le16_to_cpu(L2CAP_DEFAULT_MONITOR_TO);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001798
1799 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03001800
1801 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
1802 sizeof(rfc), (unsigned long) &rfc);
1803
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001804 break;
1805
1806 case L2CAP_MODE_STREAMING:
Mat Martineau86b1b262010-08-05 15:54:22 -07001807 if (le16_to_cpu(rfc.max_pdu_size) > pi->conn->mtu - 10)
1808 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001809
1810 pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001811
1812 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03001813
1814 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
1815 sizeof(rfc), (unsigned long) &rfc);
1816
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001817 break;
1818
1819 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02001820 result = L2CAP_CONF_UNACCEPT;
1821
1822 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001823 rfc.mode = pi->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02001824 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001825
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001826 if (result == L2CAP_CONF_SUCCESS)
1827 pi->conf_state |= L2CAP_CONF_OUTPUT_DONE;
1828 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001829 rsp->scid = cpu_to_le16(pi->dcid);
1830 rsp->result = cpu_to_le16(result);
1831 rsp->flags = cpu_to_le16(0x0000);
1832
1833 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001834}
1835
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001836static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data, u16 *result)
1837{
1838 struct l2cap_pinfo *pi = l2cap_pi(sk);
1839 struct l2cap_conf_req *req = data;
1840 void *ptr = req->data;
1841 int type, olen;
1842 unsigned long val;
1843 struct l2cap_conf_rfc rfc;
1844
1845 BT_DBG("sk %p, rsp %p, len %d, req %p", sk, rsp, len, data);
1846
1847 while (len >= L2CAP_CONF_OPT_SIZE) {
1848 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
1849
1850 switch (type) {
1851 case L2CAP_CONF_MTU:
1852 if (val < L2CAP_DEFAULT_MIN_MTU) {
1853 *result = L2CAP_CONF_UNACCEPT;
Andrei Emeltchenko8183b772010-09-01 15:17:25 +03001854 pi->imtu = L2CAP_DEFAULT_MIN_MTU;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001855 } else
Andrei Emeltchenko8183b772010-09-01 15:17:25 +03001856 pi->imtu = val;
1857 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001858 break;
1859
1860 case L2CAP_CONF_FLUSH_TO:
1861 pi->flush_to = val;
1862 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
1863 2, pi->flush_to);
1864 break;
1865
1866 case L2CAP_CONF_RFC:
1867 if (olen == sizeof(rfc))
1868 memcpy(&rfc, (void *)val, olen);
1869
1870 if ((pi->conf_state & L2CAP_CONF_STATE2_DEVICE) &&
1871 rfc.mode != pi->mode)
1872 return -ECONNREFUSED;
1873
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001874 pi->fcs = 0;
1875
1876 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
1877 sizeof(rfc), (unsigned long) &rfc);
1878 break;
1879 }
1880 }
1881
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03001882 if (pi->mode == L2CAP_MODE_BASIC && pi->mode != rfc.mode)
1883 return -ECONNREFUSED;
1884
1885 pi->mode = rfc.mode;
1886
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001887 if (*result == L2CAP_CONF_SUCCESS) {
1888 switch (rfc.mode) {
1889 case L2CAP_MODE_ERTM:
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03001890 pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
1891 pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001892 pi->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001893 break;
1894 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001895 pi->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001896 }
1897 }
1898
1899 req->dcid = cpu_to_le16(pi->dcid);
1900 req->flags = cpu_to_le16(0x0000);
1901
1902 return ptr - data;
1903}
1904
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001905static int l2cap_build_conf_rsp(struct sock *sk, void *data, u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001906{
1907 struct l2cap_conf_rsp *rsp = data;
1908 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001909
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001910 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001911
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07001912 rsp->scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001913 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07001914 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001915
1916 return ptr - data;
1917}
1918
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03001919static void l2cap_conf_rfc_get(struct sock *sk, void *rsp, int len)
1920{
1921 struct l2cap_pinfo *pi = l2cap_pi(sk);
1922 int type, olen;
1923 unsigned long val;
1924 struct l2cap_conf_rfc rfc;
1925
1926 BT_DBG("sk %p, rsp %p, len %d", sk, rsp, len);
1927
1928 if ((pi->mode != L2CAP_MODE_ERTM) && (pi->mode != L2CAP_MODE_STREAMING))
1929 return;
1930
1931 while (len >= L2CAP_CONF_OPT_SIZE) {
1932 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
1933
1934 switch (type) {
1935 case L2CAP_CONF_RFC:
1936 if (olen == sizeof(rfc))
1937 memcpy(&rfc, (void *)val, olen);
1938 goto done;
1939 }
1940 }
1941
1942done:
1943 switch (rfc.mode) {
1944 case L2CAP_MODE_ERTM:
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03001945 pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
1946 pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03001947 pi->mps = le16_to_cpu(rfc.max_pdu_size);
1948 break;
1949 case L2CAP_MODE_STREAMING:
1950 pi->mps = le16_to_cpu(rfc.max_pdu_size);
1951 }
1952}
1953
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001954static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
1955{
1956 struct l2cap_cmd_rej *rej = (struct l2cap_cmd_rej *) data;
1957
1958 if (rej->reason != 0x0000)
1959 return 0;
1960
1961 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
1962 cmd->ident == conn->info_ident) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001963 del_timer(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01001964
1965 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01001966 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01001967
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001968 l2cap_conn_start(conn);
1969 }
1970
1971 return 0;
1972}
1973
Linus Torvalds1da177e2005-04-16 15:20:36 -07001974static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
1975{
1976 struct l2cap_chan_list *list = &conn->chan_list;
1977 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
1978 struct l2cap_conn_rsp rsp;
Nathan Holsteind793fe82010-10-15 11:54:02 -04001979 struct sock *parent, *sk = NULL;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02001980 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001981
1982 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02001983 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001984
1985 BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
1986
1987 /* Check if we have socket listening on psm */
1988 parent = l2cap_get_sock_by_psm(BT_LISTEN, psm, conn->src);
1989 if (!parent) {
1990 result = L2CAP_CR_BAD_PSM;
1991 goto sendresp;
1992 }
1993
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001994 bh_lock_sock(parent);
1995
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02001996 /* Check if the ACL is secure enough (if not SDP) */
1997 if (psm != cpu_to_le16(0x0001) &&
1998 !hci_conn_check_link_mode(conn->hcon)) {
Marcel Holtmann2950f212009-02-12 14:02:50 +01001999 conn->disc_reason = 0x05;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002000 result = L2CAP_CR_SEC_BLOCK;
2001 goto response;
2002 }
2003
Linus Torvalds1da177e2005-04-16 15:20:36 -07002004 result = L2CAP_CR_NO_MEM;
2005
2006 /* Check for backlog size */
2007 if (sk_acceptq_is_full(parent)) {
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09002008 BT_DBG("backlog full %d", parent->sk_ack_backlog);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002009 goto response;
2010 }
2011
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09002012 sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002013 if (!sk)
2014 goto response;
2015
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002016 write_lock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002017
2018 /* Check if we already have channel with that dcid */
2019 if (__l2cap_get_chan_by_dcid(list, scid)) {
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002020 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002021 sock_set_flag(sk, SOCK_ZAPPED);
2022 l2cap_sock_kill(sk);
2023 goto response;
2024 }
2025
2026 hci_conn_hold(conn->hcon);
2027
2028 l2cap_sock_init(sk, parent);
2029 bacpy(&bt_sk(sk)->src, conn->src);
2030 bacpy(&bt_sk(sk)->dst, conn->dst);
2031 l2cap_pi(sk)->psm = psm;
2032 l2cap_pi(sk)->dcid = scid;
2033
Gustavo F. Padovand1010242011-03-25 00:39:48 -03002034 bt_accept_enqueue(parent, sk);
2035
2036 __l2cap_chan_add(conn, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002037 dcid = l2cap_pi(sk)->scid;
2038
2039 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
2040
Linus Torvalds1da177e2005-04-16 15:20:36 -07002041 l2cap_pi(sk)->ident = cmd->ident;
2042
Marcel Holtmann984947d2009-02-06 23:35:19 +01002043 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002044 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002045 if (bt_sk(sk)->defer_setup) {
2046 sk->sk_state = BT_CONNECT2;
2047 result = L2CAP_CR_PEND;
2048 status = L2CAP_CS_AUTHOR_PEND;
2049 parent->sk_data_ready(parent, 0);
2050 } else {
2051 sk->sk_state = BT_CONFIG;
2052 result = L2CAP_CR_SUCCESS;
2053 status = L2CAP_CS_NO_INFO;
2054 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002055 } else {
2056 sk->sk_state = BT_CONNECT2;
2057 result = L2CAP_CR_PEND;
2058 status = L2CAP_CS_AUTHEN_PEND;
2059 }
2060 } else {
2061 sk->sk_state = BT_CONNECT2;
2062 result = L2CAP_CR_PEND;
2063 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002064 }
2065
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002066 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002067
2068response:
2069 bh_unlock_sock(parent);
2070
2071sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002072 rsp.scid = cpu_to_le16(scid);
2073 rsp.dcid = cpu_to_le16(dcid);
2074 rsp.result = cpu_to_le16(result);
2075 rsp.status = cpu_to_le16(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002076 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002077
2078 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
2079 struct l2cap_info_req info;
2080 info.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
2081
2082 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
2083 conn->info_ident = l2cap_get_ident(conn);
2084
2085 mod_timer(&conn->info_timer, jiffies +
2086 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
2087
2088 l2cap_send_cmd(conn, conn->info_ident,
2089 L2CAP_INFO_REQ, sizeof(info), &info);
2090 }
2091
Nathan Holsteind793fe82010-10-15 11:54:02 -04002092 if (sk && !(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) &&
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03002093 result == L2CAP_CR_SUCCESS) {
2094 u8 buf[128];
2095 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
2096 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
2097 l2cap_build_conf_req(sk, buf), buf);
2098 l2cap_pi(sk)->num_conf_req++;
2099 }
2100
Linus Torvalds1da177e2005-04-16 15:20:36 -07002101 return 0;
2102}
2103
2104static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2105{
2106 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
2107 u16 scid, dcid, result, status;
2108 struct sock *sk;
2109 u8 req[128];
2110
2111 scid = __le16_to_cpu(rsp->scid);
2112 dcid = __le16_to_cpu(rsp->dcid);
2113 result = __le16_to_cpu(rsp->result);
2114 status = __le16_to_cpu(rsp->status);
2115
2116 BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
2117
2118 if (scid) {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002119 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2120 if (!sk)
João Paulo Rechi Vita57d3b222010-06-22 13:56:26 -03002121 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002122 } else {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002123 sk = l2cap_get_chan_by_ident(&conn->chan_list, cmd->ident);
2124 if (!sk)
João Paulo Rechi Vita57d3b222010-06-22 13:56:26 -03002125 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002126 }
2127
2128 switch (result) {
2129 case L2CAP_CR_SUCCESS:
2130 sk->sk_state = BT_CONFIG;
2131 l2cap_pi(sk)->ident = 0;
2132 l2cap_pi(sk)->dcid = dcid;
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002133 l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_CONNECT_PEND;
2134
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03002135 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)
2136 break;
2137
2138 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
2139
Linus Torvalds1da177e2005-04-16 15:20:36 -07002140 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
2141 l2cap_build_conf_req(sk, req), req);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002142 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002143 break;
2144
2145 case L2CAP_CR_PEND:
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002146 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002147 break;
2148
2149 default:
Andrei Emeltchenkoa49184c2010-11-03 12:32:44 +02002150 /* don't delete l2cap channel if sk is owned by user */
2151 if (sock_owned_by_user(sk)) {
2152 sk->sk_state = BT_DISCONN;
2153 l2cap_sock_clear_timer(sk);
2154 l2cap_sock_set_timer(sk, HZ / 5);
2155 break;
2156 }
2157
Linus Torvalds1da177e2005-04-16 15:20:36 -07002158 l2cap_chan_del(sk, ECONNREFUSED);
2159 break;
2160 }
2161
2162 bh_unlock_sock(sk);
2163 return 0;
2164}
2165
Mat Martineau8c462b62010-08-24 15:35:42 -07002166static inline void set_default_fcs(struct l2cap_pinfo *pi)
2167{
2168 /* FCS is enabled only in ERTM or streaming mode, if one or both
2169 * sides request it.
2170 */
2171 if (pi->mode != L2CAP_MODE_ERTM && pi->mode != L2CAP_MODE_STREAMING)
2172 pi->fcs = L2CAP_FCS_NONE;
2173 else if (!(pi->conf_state & L2CAP_CONF_NO_FCS_RECV))
2174 pi->fcs = L2CAP_FCS_CRC16;
2175}
2176
Al Viro88219a02007-07-29 00:17:25 -07002177static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002178{
2179 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
2180 u16 dcid, flags;
2181 u8 rsp[64];
2182 struct sock *sk;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002183 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002184
2185 dcid = __le16_to_cpu(req->dcid);
2186 flags = __le16_to_cpu(req->flags);
2187
2188 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
2189
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002190 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
2191 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002192 return -ENOENT;
2193
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03002194 if (sk->sk_state != BT_CONFIG) {
2195 struct l2cap_cmd_rej rej;
2196
2197 rej.reason = cpu_to_le16(0x0002);
2198 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
2199 sizeof(rej), &rej);
Marcel Holtmann354f60a2006-11-18 22:15:20 +01002200 goto unlock;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03002201 }
Marcel Holtmann354f60a2006-11-18 22:15:20 +01002202
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002203 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07002204 len = cmd_len - sizeof(*req);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002205 if (l2cap_pi(sk)->conf_len + len > sizeof(l2cap_pi(sk)->conf_req)) {
2206 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
2207 l2cap_build_conf_rsp(sk, rsp,
2208 L2CAP_CONF_REJECT, flags), rsp);
2209 goto unlock;
2210 }
2211
2212 /* Store config. */
2213 memcpy(l2cap_pi(sk)->conf_req + l2cap_pi(sk)->conf_len, req->data, len);
2214 l2cap_pi(sk)->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002215
2216 if (flags & 0x0001) {
2217 /* Incomplete config. Send empty response. */
2218 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002219 l2cap_build_conf_rsp(sk, rsp,
2220 L2CAP_CONF_SUCCESS, 0x0001), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002221 goto unlock;
2222 }
2223
2224 /* Complete config. */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002225 len = l2cap_parse_conf_req(sk, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002226 if (len < 0) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03002227 l2cap_send_disconn_req(conn, sk, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002228 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002229 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002230
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002231 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002232 l2cap_pi(sk)->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002233
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002234 /* Reset config buffer. */
2235 l2cap_pi(sk)->conf_len = 0;
2236
Marcel Holtmann876d9482007-10-20 13:35:42 +02002237 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE))
2238 goto unlock;
2239
Linus Torvalds1da177e2005-04-16 15:20:36 -07002240 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) {
Mat Martineau8c462b62010-08-24 15:35:42 -07002241 set_default_fcs(l2cap_pi(sk));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002242
Linus Torvalds1da177e2005-04-16 15:20:36 -07002243 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002244
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002245 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002246 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002247 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002248 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
2249 l2cap_ertm_init(sk);
2250
Linus Torvalds1da177e2005-04-16 15:20:36 -07002251 l2cap_chan_ready(sk);
Marcel Holtmann876d9482007-10-20 13:35:42 +02002252 goto unlock;
2253 }
2254
2255 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002256 u8 buf[64];
Haijun Liuab3e5712010-09-30 16:52:40 +08002257 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002258 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002259 l2cap_build_conf_req(sk, buf), buf);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002260 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002261 }
2262
2263unlock:
2264 bh_unlock_sock(sk);
2265 return 0;
2266}
2267
2268static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2269{
2270 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
2271 u16 scid, flags, result;
2272 struct sock *sk;
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002273 int len = cmd->len - sizeof(*rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002274
2275 scid = __le16_to_cpu(rsp->scid);
2276 flags = __le16_to_cpu(rsp->flags);
2277 result = __le16_to_cpu(rsp->result);
2278
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002279 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x",
2280 scid, flags, result);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002281
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002282 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2283 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002284 return 0;
2285
2286 switch (result) {
2287 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002288 l2cap_conf_rfc_get(sk, rsp->data, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002289 break;
2290
2291 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002292 if (l2cap_pi(sk)->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002293 char req[64];
2294
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02002295 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03002296 l2cap_send_disconn_req(conn, sk, ECONNRESET);
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02002297 goto done;
2298 }
2299
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002300 /* throw out any old stored conf requests */
2301 result = L2CAP_CONF_SUCCESS;
2302 len = l2cap_parse_conf_rsp(sk, rsp->data,
2303 len, req, &result);
2304 if (len < 0) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03002305 l2cap_send_disconn_req(conn, sk, ECONNRESET);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002306 goto done;
2307 }
2308
2309 l2cap_send_cmd(conn, l2cap_get_ident(conn),
2310 L2CAP_CONF_REQ, len, req);
2311 l2cap_pi(sk)->num_conf_req++;
2312 if (result != L2CAP_CONF_SUCCESS)
2313 goto done;
2314 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002315 }
2316
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09002317 default:
Marcel Holtmannb1235d72008-07-14 20:13:54 +02002318 sk->sk_err = ECONNRESET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002319 l2cap_sock_set_timer(sk, HZ * 5);
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03002320 l2cap_send_disconn_req(conn, sk, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002321 goto done;
2322 }
2323
2324 if (flags & 0x01)
2325 goto done;
2326
Linus Torvalds1da177e2005-04-16 15:20:36 -07002327 l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE;
2328
2329 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) {
Mat Martineau8c462b62010-08-24 15:35:42 -07002330 set_default_fcs(l2cap_pi(sk));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002331
Linus Torvalds1da177e2005-04-16 15:20:36 -07002332 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002333 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002334 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002335 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002336 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
2337 l2cap_ertm_init(sk);
2338
Linus Torvalds1da177e2005-04-16 15:20:36 -07002339 l2cap_chan_ready(sk);
2340 }
2341
2342done:
2343 bh_unlock_sock(sk);
2344 return 0;
2345}
2346
2347static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2348{
2349 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
2350 struct l2cap_disconn_rsp rsp;
2351 u16 dcid, scid;
2352 struct sock *sk;
2353
2354 scid = __le16_to_cpu(req->scid);
2355 dcid = __le16_to_cpu(req->dcid);
2356
2357 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
2358
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002359 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
2360 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002361 return 0;
2362
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002363 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
2364 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002365 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
2366
2367 sk->sk_shutdown = SHUTDOWN_MASK;
2368
Andrei Emeltchenkoa49184c2010-11-03 12:32:44 +02002369 /* don't delete l2cap channel if sk is owned by user */
2370 if (sock_owned_by_user(sk)) {
2371 sk->sk_state = BT_DISCONN;
2372 l2cap_sock_clear_timer(sk);
2373 l2cap_sock_set_timer(sk, HZ / 5);
2374 bh_unlock_sock(sk);
2375 return 0;
2376 }
2377
Linus Torvalds1da177e2005-04-16 15:20:36 -07002378 l2cap_chan_del(sk, ECONNRESET);
2379 bh_unlock_sock(sk);
2380
2381 l2cap_sock_kill(sk);
2382 return 0;
2383}
2384
2385static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2386{
2387 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
2388 u16 dcid, scid;
2389 struct sock *sk;
2390
2391 scid = __le16_to_cpu(rsp->scid);
2392 dcid = __le16_to_cpu(rsp->dcid);
2393
2394 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
2395
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002396 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2397 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002398 return 0;
2399
Andrei Emeltchenkoa49184c2010-11-03 12:32:44 +02002400 /* don't delete l2cap channel if sk is owned by user */
2401 if (sock_owned_by_user(sk)) {
2402 sk->sk_state = BT_DISCONN;
2403 l2cap_sock_clear_timer(sk);
2404 l2cap_sock_set_timer(sk, HZ / 5);
2405 bh_unlock_sock(sk);
2406 return 0;
2407 }
2408
Linus Torvalds1da177e2005-04-16 15:20:36 -07002409 l2cap_chan_del(sk, 0);
2410 bh_unlock_sock(sk);
2411
2412 l2cap_sock_kill(sk);
2413 return 0;
2414}
2415
2416static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2417{
2418 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002419 u16 type;
2420
2421 type = __le16_to_cpu(req->type);
2422
2423 BT_DBG("type 0x%4.4x", type);
2424
Marcel Holtmannf0709e02007-10-20 13:38:51 +02002425 if (type == L2CAP_IT_FEAT_MASK) {
2426 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07002427 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02002428 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
2429 rsp->type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
2430 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03002431 if (!disable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002432 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
2433 | L2CAP_FEAT_FCS;
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03002434 put_unaligned_le32(feat_mask, rsp->data);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02002435 l2cap_send_cmd(conn, cmd->ident,
2436 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002437 } else if (type == L2CAP_IT_FIXED_CHAN) {
2438 u8 buf[12];
2439 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
2440 rsp->type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
2441 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
2442 memcpy(buf + 4, l2cap_fixed_chan, 8);
2443 l2cap_send_cmd(conn, cmd->ident,
2444 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02002445 } else {
2446 struct l2cap_info_rsp rsp;
2447 rsp.type = cpu_to_le16(type);
2448 rsp.result = cpu_to_le16(L2CAP_IR_NOTSUPP);
2449 l2cap_send_cmd(conn, cmd->ident,
2450 L2CAP_INFO_RSP, sizeof(rsp), &rsp);
2451 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002452
2453 return 0;
2454}
2455
2456static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2457{
2458 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
2459 u16 type, result;
2460
2461 type = __le16_to_cpu(rsp->type);
2462 result = __le16_to_cpu(rsp->result);
2463
2464 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
2465
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02002466 /* L2CAP Info req/rsp are unbound to channels, add extra checks */
2467 if (cmd->ident != conn->info_ident ||
2468 conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)
2469 return 0;
2470
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002471 del_timer(&conn->info_timer);
2472
Ville Tervoadb08ed2010-08-04 09:43:33 +03002473 if (result != L2CAP_IR_SUCCESS) {
2474 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
2475 conn->info_ident = 0;
2476
2477 l2cap_conn_start(conn);
2478
2479 return 0;
2480 }
2481
Marcel Holtmann984947d2009-02-06 23:35:19 +01002482 if (type == L2CAP_IT_FEAT_MASK) {
Harvey Harrison83985312008-05-02 16:25:46 -07002483 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002484
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07002485 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002486 struct l2cap_info_req req;
2487 req.type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
2488
2489 conn->info_ident = l2cap_get_ident(conn);
2490
2491 l2cap_send_cmd(conn, conn->info_ident,
2492 L2CAP_INFO_REQ, sizeof(req), &req);
2493 } else {
2494 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
2495 conn->info_ident = 0;
2496
2497 l2cap_conn_start(conn);
2498 }
2499 } else if (type == L2CAP_IT_FIXED_CHAN) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01002500 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002501 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01002502
2503 l2cap_conn_start(conn);
2504 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002505
Linus Torvalds1da177e2005-04-16 15:20:36 -07002506 return 0;
2507}
2508
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03002509static inline int l2cap_check_conn_param(u16 min, u16 max, u16 latency,
Claudio Takahaside731152011-02-11 19:28:55 -02002510 u16 to_multiplier)
2511{
2512 u16 max_latency;
2513
2514 if (min > max || min < 6 || max > 3200)
2515 return -EINVAL;
2516
2517 if (to_multiplier < 10 || to_multiplier > 3200)
2518 return -EINVAL;
2519
2520 if (max >= to_multiplier * 8)
2521 return -EINVAL;
2522
2523 max_latency = (to_multiplier * 8 / max) - 1;
2524 if (latency > 499 || latency > max_latency)
2525 return -EINVAL;
2526
2527 return 0;
2528}
2529
2530static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
2531 struct l2cap_cmd_hdr *cmd, u8 *data)
2532{
2533 struct hci_conn *hcon = conn->hcon;
2534 struct l2cap_conn_param_update_req *req;
2535 struct l2cap_conn_param_update_rsp rsp;
2536 u16 min, max, latency, to_multiplier, cmd_len;
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02002537 int err;
Claudio Takahaside731152011-02-11 19:28:55 -02002538
2539 if (!(hcon->link_mode & HCI_LM_MASTER))
2540 return -EINVAL;
2541
2542 cmd_len = __le16_to_cpu(cmd->len);
2543 if (cmd_len != sizeof(struct l2cap_conn_param_update_req))
2544 return -EPROTO;
2545
2546 req = (struct l2cap_conn_param_update_req *) data;
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03002547 min = __le16_to_cpu(req->min);
2548 max = __le16_to_cpu(req->max);
Claudio Takahaside731152011-02-11 19:28:55 -02002549 latency = __le16_to_cpu(req->latency);
2550 to_multiplier = __le16_to_cpu(req->to_multiplier);
2551
2552 BT_DBG("min 0x%4.4x max 0x%4.4x latency: 0x%4.4x Timeout: 0x%4.4x",
2553 min, max, latency, to_multiplier);
2554
2555 memset(&rsp, 0, sizeof(rsp));
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02002556
2557 err = l2cap_check_conn_param(min, max, latency, to_multiplier);
2558 if (err)
Claudio Takahaside731152011-02-11 19:28:55 -02002559 rsp.result = cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
2560 else
2561 rsp.result = cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED);
2562
2563 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP,
2564 sizeof(rsp), &rsp);
2565
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02002566 if (!err)
2567 hci_le_conn_update(hcon, min, max, latency, to_multiplier);
2568
Claudio Takahaside731152011-02-11 19:28:55 -02002569 return 0;
2570}
2571
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002572static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
2573 struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
2574{
2575 int err = 0;
2576
2577 switch (cmd->code) {
2578 case L2CAP_COMMAND_REJ:
2579 l2cap_command_rej(conn, cmd, data);
2580 break;
2581
2582 case L2CAP_CONN_REQ:
2583 err = l2cap_connect_req(conn, cmd, data);
2584 break;
2585
2586 case L2CAP_CONN_RSP:
2587 err = l2cap_connect_rsp(conn, cmd, data);
2588 break;
2589
2590 case L2CAP_CONF_REQ:
2591 err = l2cap_config_req(conn, cmd, cmd_len, data);
2592 break;
2593
2594 case L2CAP_CONF_RSP:
2595 err = l2cap_config_rsp(conn, cmd, data);
2596 break;
2597
2598 case L2CAP_DISCONN_REQ:
2599 err = l2cap_disconnect_req(conn, cmd, data);
2600 break;
2601
2602 case L2CAP_DISCONN_RSP:
2603 err = l2cap_disconnect_rsp(conn, cmd, data);
2604 break;
2605
2606 case L2CAP_ECHO_REQ:
2607 l2cap_send_cmd(conn, cmd->ident, L2CAP_ECHO_RSP, cmd_len, data);
2608 break;
2609
2610 case L2CAP_ECHO_RSP:
2611 break;
2612
2613 case L2CAP_INFO_REQ:
2614 err = l2cap_information_req(conn, cmd, data);
2615 break;
2616
2617 case L2CAP_INFO_RSP:
2618 err = l2cap_information_rsp(conn, cmd, data);
2619 break;
2620
2621 default:
2622 BT_ERR("Unknown BR/EDR signaling command 0x%2.2x", cmd->code);
2623 err = -EINVAL;
2624 break;
2625 }
2626
2627 return err;
2628}
2629
2630static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn,
2631 struct l2cap_cmd_hdr *cmd, u8 *data)
2632{
2633 switch (cmd->code) {
2634 case L2CAP_COMMAND_REJ:
2635 return 0;
2636
2637 case L2CAP_CONN_PARAM_UPDATE_REQ:
Claudio Takahaside731152011-02-11 19:28:55 -02002638 return l2cap_conn_param_update_req(conn, cmd, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002639
2640 case L2CAP_CONN_PARAM_UPDATE_RSP:
2641 return 0;
2642
2643 default:
2644 BT_ERR("Unknown LE signaling command 0x%2.2x", cmd->code);
2645 return -EINVAL;
2646 }
2647}
2648
2649static inline void l2cap_sig_channel(struct l2cap_conn *conn,
2650 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002651{
2652 u8 *data = skb->data;
2653 int len = skb->len;
2654 struct l2cap_cmd_hdr cmd;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002655 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002656
2657 l2cap_raw_recv(conn, skb);
2658
2659 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07002660 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002661 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
2662 data += L2CAP_CMD_HDR_SIZE;
2663 len -= L2CAP_CMD_HDR_SIZE;
2664
Al Viro88219a02007-07-29 00:17:25 -07002665 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002666
Al Viro88219a02007-07-29 00:17:25 -07002667 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 -07002668
Al Viro88219a02007-07-29 00:17:25 -07002669 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002670 BT_DBG("corrupted command");
2671 break;
2672 }
2673
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002674 if (conn->hcon->type == LE_LINK)
2675 err = l2cap_le_sig_cmd(conn, &cmd, data);
2676 else
2677 err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002678
2679 if (err) {
2680 struct l2cap_cmd_rej rej;
Gustavo F. Padovan2c6d1a22011-03-23 14:38:32 -03002681
2682 BT_ERR("Wrong link type (%d)", err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002683
2684 /* FIXME: Map err to a valid reason */
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002685 rej.reason = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002686 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
2687 }
2688
Al Viro88219a02007-07-29 00:17:25 -07002689 data += cmd_len;
2690 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002691 }
2692
2693 kfree_skb(skb);
2694}
2695
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002696static int l2cap_check_fcs(struct l2cap_pinfo *pi, struct sk_buff *skb)
2697{
2698 u16 our_fcs, rcv_fcs;
2699 int hdr_size = L2CAP_HDR_SIZE + 2;
2700
2701 if (pi->fcs == L2CAP_FCS_CRC16) {
2702 skb_trim(skb, skb->len - 2);
2703 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
2704 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
2705
2706 if (our_fcs != rcv_fcs)
João Paulo Rechi Vita7a560e52010-06-22 13:56:27 -03002707 return -EBADMSG;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002708 }
2709 return 0;
2710}
2711
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03002712static inline void l2cap_send_i_or_rr_or_rnr(struct sock *sk)
2713{
2714 struct l2cap_pinfo *pi = l2cap_pi(sk);
2715 u16 control = 0;
2716
2717 pi->frames_sent = 0;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03002718
2719 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
2720
2721 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
Gustavo F. Padovan64988862010-05-10 14:54:14 -03002722 control |= L2CAP_SUPER_RCV_NOT_READY;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03002723 l2cap_send_sframe(pi, control);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002724 pi->conn_state |= L2CAP_CONN_RNR_SENT;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03002725 }
2726
Gustavo F. Padovan4ea727e2010-06-03 16:34:20 -03002727 if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY)
2728 l2cap_retransmit_frames(sk);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03002729
2730 l2cap_ertm_send(sk);
2731
2732 if (!(pi->conn_state & L2CAP_CONN_LOCAL_BUSY) &&
2733 pi->frames_sent == 0) {
2734 control |= L2CAP_SUPER_RCV_READY;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03002735 l2cap_send_sframe(pi, control);
2736 }
2737}
2738
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03002739static 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 -03002740{
2741 struct sk_buff *next_skb;
João Paulo Rechi Vitabfbacc112010-05-31 18:35:44 -03002742 struct l2cap_pinfo *pi = l2cap_pi(sk);
2743 int tx_seq_offset, next_tx_seq_offset;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03002744
2745 bt_cb(skb)->tx_seq = tx_seq;
2746 bt_cb(skb)->sar = sar;
2747
2748 next_skb = skb_peek(SREJ_QUEUE(sk));
2749 if (!next_skb) {
2750 __skb_queue_tail(SREJ_QUEUE(sk), skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03002751 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03002752 }
2753
João Paulo Rechi Vitabfbacc112010-05-31 18:35:44 -03002754 tx_seq_offset = (tx_seq - pi->buffer_seq) % 64;
2755 if (tx_seq_offset < 0)
2756 tx_seq_offset += 64;
2757
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03002758 do {
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03002759 if (bt_cb(next_skb)->tx_seq == tx_seq)
2760 return -EINVAL;
2761
João Paulo Rechi Vitabfbacc112010-05-31 18:35:44 -03002762 next_tx_seq_offset = (bt_cb(next_skb)->tx_seq -
2763 pi->buffer_seq) % 64;
2764 if (next_tx_seq_offset < 0)
2765 next_tx_seq_offset += 64;
2766
2767 if (next_tx_seq_offset > tx_seq_offset) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03002768 __skb_queue_before(SREJ_QUEUE(sk), next_skb, skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03002769 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03002770 }
2771
2772 if (skb_queue_is_last(SREJ_QUEUE(sk), next_skb))
2773 break;
2774
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03002775 } while ((next_skb = skb_queue_next(SREJ_QUEUE(sk), next_skb)));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03002776
2777 __skb_queue_tail(SREJ_QUEUE(sk), skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03002778
2779 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03002780}
2781
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002782static int l2cap_ertm_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
2783{
2784 struct l2cap_pinfo *pi = l2cap_pi(sk);
2785 struct sk_buff *_skb;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002786 int err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002787
2788 switch (control & L2CAP_CTRL_SAR) {
2789 case L2CAP_SDU_UNSEGMENTED:
2790 if (pi->conn_state & L2CAP_CONN_SAR_SDU)
2791 goto drop;
2792
2793 err = sock_queue_rcv_skb(sk, skb);
2794 if (!err)
2795 return err;
2796
2797 break;
2798
2799 case L2CAP_SDU_START:
2800 if (pi->conn_state & L2CAP_CONN_SAR_SDU)
2801 goto drop;
2802
2803 pi->sdu_len = get_unaligned_le16(skb->data);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002804
2805 if (pi->sdu_len > pi->imtu)
2806 goto disconnect;
2807
2808 pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002809 if (!pi->sdu)
2810 return -ENOMEM;
2811
2812 /* pull sdu_len bytes only after alloc, because of Local Busy
2813 * condition we have to be sure that this will be executed
2814 * only once, i.e., when alloc does not fail */
2815 skb_pull(skb, 2);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002816
2817 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
2818
2819 pi->conn_state |= L2CAP_CONN_SAR_SDU;
2820 pi->partial_sdu_len = skb->len;
2821 break;
2822
2823 case L2CAP_SDU_CONTINUE:
2824 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
2825 goto disconnect;
2826
2827 if (!pi->sdu)
2828 goto disconnect;
2829
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002830 pi->partial_sdu_len += skb->len;
2831 if (pi->partial_sdu_len > pi->sdu_len)
2832 goto drop;
2833
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03002834 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
2835
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002836 break;
2837
2838 case L2CAP_SDU_END:
2839 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
2840 goto disconnect;
2841
2842 if (!pi->sdu)
2843 goto disconnect;
2844
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002845 if (!(pi->conn_state & L2CAP_CONN_SAR_RETRY)) {
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002846 pi->partial_sdu_len += skb->len;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002847
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002848 if (pi->partial_sdu_len > pi->imtu)
2849 goto drop;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002850
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002851 if (pi->partial_sdu_len != pi->sdu_len)
2852 goto drop;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03002853
2854 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002855 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002856
2857 _skb = skb_clone(pi->sdu, GFP_ATOMIC);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002858 if (!_skb) {
2859 pi->conn_state |= L2CAP_CONN_SAR_RETRY;
2860 return -ENOMEM;
2861 }
2862
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002863 err = sock_queue_rcv_skb(sk, _skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002864 if (err < 0) {
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002865 kfree_skb(_skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002866 pi->conn_state |= L2CAP_CONN_SAR_RETRY;
2867 return err;
2868 }
2869
2870 pi->conn_state &= ~L2CAP_CONN_SAR_RETRY;
2871 pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002872
2873 kfree_skb(pi->sdu);
2874 break;
2875 }
2876
2877 kfree_skb(skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002878 return 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002879
2880drop:
2881 kfree_skb(pi->sdu);
2882 pi->sdu = NULL;
2883
2884disconnect:
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03002885 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03002886 kfree_skb(skb);
2887 return 0;
2888}
2889
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03002890static int l2cap_try_push_rx_skb(struct sock *sk)
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002891{
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03002892 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002893 struct sk_buff *skb;
2894 u16 control;
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03002895 int err;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002896
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03002897 while ((skb = skb_dequeue(BUSY_QUEUE(sk)))) {
2898 control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
2899 err = l2cap_ertm_reassembly_sdu(sk, skb, control);
2900 if (err < 0) {
2901 skb_queue_head(BUSY_QUEUE(sk), skb);
2902 return -EBUSY;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002903 }
2904
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03002905 pi->buffer_seq = (pi->buffer_seq + 1) % 64;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002906 }
2907
2908 if (!(pi->conn_state & L2CAP_CONN_RNR_SENT))
2909 goto done;
2910
2911 control = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
2912 control |= L2CAP_SUPER_RCV_READY | L2CAP_CTRL_POLL;
2913 l2cap_send_sframe(pi, control);
2914 l2cap_pi(sk)->retry_count = 1;
2915
2916 del_timer(&pi->retrans_timer);
2917 __mod_monitor_timer();
2918
2919 l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
2920
2921done:
2922 pi->conn_state &= ~L2CAP_CONN_LOCAL_BUSY;
2923 pi->conn_state &= ~L2CAP_CONN_RNR_SENT;
2924
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03002925 BT_DBG("sk %p, Exit local busy", sk);
2926
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03002927 return 0;
2928}
2929
2930static void l2cap_busy_work(struct work_struct *work)
2931{
2932 DECLARE_WAITQUEUE(wait, current);
2933 struct l2cap_pinfo *pi =
2934 container_of(work, struct l2cap_pinfo, busy_work);
2935 struct sock *sk = (struct sock *)pi;
2936 int n_tries = 0, timeo = HZ/5, err;
2937 struct sk_buff *skb;
2938
2939 lock_sock(sk);
2940
2941 add_wait_queue(sk_sleep(sk), &wait);
2942 while ((skb = skb_peek(BUSY_QUEUE(sk)))) {
2943 set_current_state(TASK_INTERRUPTIBLE);
2944
2945 if (n_tries++ > L2CAP_LOCAL_BUSY_TRIES) {
2946 err = -EBUSY;
2947 l2cap_send_disconn_req(pi->conn, sk, EBUSY);
2948 break;
2949 }
2950
2951 if (!timeo)
2952 timeo = HZ/5;
2953
2954 if (signal_pending(current)) {
2955 err = sock_intr_errno(timeo);
2956 break;
2957 }
2958
2959 release_sock(sk);
2960 timeo = schedule_timeout(timeo);
2961 lock_sock(sk);
2962
2963 err = sock_error(sk);
2964 if (err)
2965 break;
2966
2967 if (l2cap_try_push_rx_skb(sk) == 0)
2968 break;
2969 }
2970
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002971 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02002972 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002973
2974 release_sock(sk);
2975}
2976
2977static int l2cap_push_rx_skb(struct sock *sk, struct sk_buff *skb, u16 control)
2978{
2979 struct l2cap_pinfo *pi = l2cap_pi(sk);
2980 int sctrl, err;
2981
2982 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
2983 bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT;
2984 __skb_queue_tail(BUSY_QUEUE(sk), skb);
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03002985 return l2cap_try_push_rx_skb(sk);
2986
2987
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002988 }
2989
2990 err = l2cap_ertm_reassembly_sdu(sk, skb, control);
2991 if (err >= 0) {
2992 pi->buffer_seq = (pi->buffer_seq + 1) % 64;
2993 return err;
2994 }
2995
2996 /* Busy Condition */
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03002997 BT_DBG("sk %p, Enter local busy", sk);
2998
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002999 pi->conn_state |= L2CAP_CONN_LOCAL_BUSY;
3000 bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT;
3001 __skb_queue_tail(BUSY_QUEUE(sk), skb);
3002
3003 sctrl = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3004 sctrl |= L2CAP_SUPER_RCV_NOT_READY;
3005 l2cap_send_sframe(pi, sctrl);
3006
3007 pi->conn_state |= L2CAP_CONN_RNR_SENT;
3008
Gustavo F. Padovan7fe9b292010-05-12 18:32:04 -03003009 del_timer(&pi->ack_timer);
3010
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003011 queue_work(_busy_wq, &pi->busy_work);
3012
3013 return err;
3014}
3015
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003016static int l2cap_streaming_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003017{
3018 struct l2cap_pinfo *pi = l2cap_pi(sk);
3019 struct sk_buff *_skb;
3020 int err = -EINVAL;
3021
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003022 /*
3023 * TODO: We have to notify the userland if some data is lost with the
3024 * Streaming Mode.
3025 */
3026
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003027 switch (control & L2CAP_CTRL_SAR) {
3028 case L2CAP_SDU_UNSEGMENTED:
3029 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3030 kfree_skb(pi->sdu);
3031 break;
3032 }
3033
3034 err = sock_queue_rcv_skb(sk, skb);
3035 if (!err)
3036 return 0;
3037
3038 break;
3039
3040 case L2CAP_SDU_START:
3041 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3042 kfree_skb(pi->sdu);
3043 break;
3044 }
3045
3046 pi->sdu_len = get_unaligned_le16(skb->data);
3047 skb_pull(skb, 2);
3048
Gustavo F. Padovan052897c2010-05-01 16:15:40 -03003049 if (pi->sdu_len > pi->imtu) {
3050 err = -EMSGSIZE;
3051 break;
3052 }
3053
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003054 pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
3055 if (!pi->sdu) {
3056 err = -ENOMEM;
3057 break;
3058 }
3059
3060 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3061
3062 pi->conn_state |= L2CAP_CONN_SAR_SDU;
3063 pi->partial_sdu_len = skb->len;
3064 err = 0;
3065 break;
3066
3067 case L2CAP_SDU_CONTINUE:
3068 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3069 break;
3070
3071 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3072
3073 pi->partial_sdu_len += skb->len;
3074 if (pi->partial_sdu_len > pi->sdu_len)
3075 kfree_skb(pi->sdu);
3076 else
3077 err = 0;
3078
3079 break;
3080
3081 case L2CAP_SDU_END:
3082 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3083 break;
3084
3085 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3086
3087 pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
3088 pi->partial_sdu_len += skb->len;
3089
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003090 if (pi->partial_sdu_len > pi->imtu)
3091 goto drop;
3092
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003093 if (pi->partial_sdu_len == pi->sdu_len) {
3094 _skb = skb_clone(pi->sdu, GFP_ATOMIC);
3095 err = sock_queue_rcv_skb(sk, _skb);
3096 if (err < 0)
3097 kfree_skb(_skb);
3098 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003099 err = 0;
3100
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003101drop:
3102 kfree_skb(pi->sdu);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003103 break;
3104 }
3105
3106 kfree_skb(skb);
3107 return err;
3108}
3109
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003110static void l2cap_check_srej_gap(struct sock *sk, u8 tx_seq)
3111{
3112 struct sk_buff *skb;
Gustavo F. Padovanafefdbc2010-05-01 16:15:43 -03003113 u16 control;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003114
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003115 while ((skb = skb_peek(SREJ_QUEUE(sk)))) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003116 if (bt_cb(skb)->tx_seq != tx_seq)
3117 break;
3118
3119 skb = skb_dequeue(SREJ_QUEUE(sk));
Gustavo F. Padovanafefdbc2010-05-01 16:15:43 -03003120 control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003121 l2cap_ertm_reassembly_sdu(sk, skb, control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003122 l2cap_pi(sk)->buffer_seq_srej =
3123 (l2cap_pi(sk)->buffer_seq_srej + 1) % 64;
Gustavo F. Padovan8ff50ec2010-05-10 19:34:11 -03003124 tx_seq = (tx_seq + 1) % 64;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003125 }
3126}
3127
3128static void l2cap_resend_srejframe(struct sock *sk, u8 tx_seq)
3129{
3130 struct l2cap_pinfo *pi = l2cap_pi(sk);
3131 struct srej_list *l, *tmp;
3132 u16 control;
3133
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003134 list_for_each_entry_safe(l, tmp, SREJ_LIST(sk), list) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003135 if (l->tx_seq == tx_seq) {
3136 list_del(&l->list);
3137 kfree(l);
3138 return;
3139 }
3140 control = L2CAP_SUPER_SELECT_REJECT;
3141 control |= l->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3142 l2cap_send_sframe(pi, control);
3143 list_del(&l->list);
3144 list_add_tail(&l->list, SREJ_LIST(sk));
3145 }
3146}
3147
3148static void l2cap_send_srejframe(struct sock *sk, u8 tx_seq)
3149{
3150 struct l2cap_pinfo *pi = l2cap_pi(sk);
3151 struct srej_list *new;
3152 u16 control;
3153
3154 while (tx_seq != pi->expected_tx_seq) {
3155 control = L2CAP_SUPER_SELECT_REJECT;
3156 control |= pi->expected_tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3157 l2cap_send_sframe(pi, control);
3158
3159 new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC);
Gustavo F. Padovan8ff50ec2010-05-10 19:34:11 -03003160 new->tx_seq = pi->expected_tx_seq;
3161 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003162 list_add_tail(&new->list, SREJ_LIST(sk));
3163 }
Gustavo F. Padovan8ff50ec2010-05-10 19:34:11 -03003164 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003165}
3166
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003167static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
3168{
3169 struct l2cap_pinfo *pi = l2cap_pi(sk);
3170 u8 tx_seq = __get_txseq(rx_control);
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003171 u8 req_seq = __get_reqseq(rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003172 u8 sar = rx_control >> L2CAP_CTRL_SAR_SHIFT;
Gustavo F. Padovanf6337c72010-05-10 18:32:04 -03003173 int tx_seq_offset, expected_tx_seq_offset;
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03003174 int num_to_ack = (pi->tx_win/6) + 1;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003175 int err = 0;
3176
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003177 BT_DBG("sk %p len %d tx_seq %d rx_control 0x%4.4x", sk, skb->len, tx_seq,
3178 rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003179
Gustavo F. Padovan9b16dc62010-05-05 20:05:57 -03003180 if (L2CAP_CTRL_FINAL & rx_control &&
3181 l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) {
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003182 del_timer(&pi->monitor_timer);
3183 if (pi->unacked_frames > 0)
3184 __mod_retrans_timer();
3185 pi->conn_state &= ~L2CAP_CONN_WAIT_F;
3186 }
3187
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003188 pi->expected_ack_seq = req_seq;
3189 l2cap_drop_acked_frames(sk);
3190
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003191 if (tx_seq == pi->expected_tx_seq)
3192 goto expected;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003193
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003194 tx_seq_offset = (tx_seq - pi->buffer_seq) % 64;
3195 if (tx_seq_offset < 0)
3196 tx_seq_offset += 64;
3197
3198 /* invalid tx_seq */
3199 if (tx_seq_offset >= pi->tx_win) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03003200 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003201 goto drop;
3202 }
3203
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003204 if (pi->conn_state == L2CAP_CONN_LOCAL_BUSY)
3205 goto drop;
3206
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003207 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3208 struct srej_list *first;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003209
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003210 first = list_first_entry(SREJ_LIST(sk),
3211 struct srej_list, list);
3212 if (tx_seq == first->tx_seq) {
3213 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3214 l2cap_check_srej_gap(sk, tx_seq);
3215
3216 list_del(&first->list);
3217 kfree(first);
3218
3219 if (list_empty(SREJ_LIST(sk))) {
3220 pi->buffer_seq = pi->buffer_seq_srej;
3221 pi->conn_state &= ~L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan855666c2010-05-01 16:15:40 -03003222 l2cap_send_ack(pi);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003223 BT_DBG("sk %p, Exit SREJ_SENT", sk);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003224 }
3225 } else {
3226 struct srej_list *l;
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003227
3228 /* duplicated tx_seq */
3229 if (l2cap_add_to_srej_queue(sk, skb, tx_seq, sar) < 0)
3230 goto drop;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003231
3232 list_for_each_entry(l, SREJ_LIST(sk), list) {
3233 if (l->tx_seq == tx_seq) {
3234 l2cap_resend_srejframe(sk, tx_seq);
3235 return 0;
3236 }
3237 }
3238 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003239 }
3240 } else {
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003241 expected_tx_seq_offset =
3242 (pi->expected_tx_seq - pi->buffer_seq) % 64;
3243 if (expected_tx_seq_offset < 0)
3244 expected_tx_seq_offset += 64;
3245
3246 /* duplicated tx_seq */
3247 if (tx_seq_offset < expected_tx_seq_offset)
3248 goto drop;
3249
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003250 pi->conn_state |= L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003251
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003252 BT_DBG("sk %p, Enter SREJ", sk);
3253
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003254 INIT_LIST_HEAD(SREJ_LIST(sk));
3255 pi->buffer_seq_srej = pi->buffer_seq;
3256
3257 __skb_queue_head_init(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003258 __skb_queue_head_init(BUSY_QUEUE(sk));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003259 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3260
Gustavo F. Padovanef54fd92009-08-20 22:26:04 -03003261 pi->conn_state |= L2CAP_CONN_SEND_PBIT;
3262
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003263 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan7fe9b292010-05-12 18:32:04 -03003264
3265 del_timer(&pi->ack_timer);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003266 }
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003267 return 0;
3268
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003269expected:
3270 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
3271
3272 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
Gustavo F. Padovan3b1a9f32010-05-01 16:15:42 -03003273 bt_cb(skb)->tx_seq = tx_seq;
3274 bt_cb(skb)->sar = sar;
3275 __skb_queue_tail(SREJ_QUEUE(sk), skb);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003276 return 0;
3277 }
3278
Gustavo F. Padovan2ece3682010-06-16 17:21:44 -03003279 err = l2cap_push_rx_skb(sk, skb, rx_control);
3280 if (err < 0)
3281 return 0;
3282
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03003283 if (rx_control & L2CAP_CTRL_FINAL) {
3284 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3285 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003286 else
3287 l2cap_retransmit_frames(sk);
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03003288 }
3289
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003290 __mod_ack_timer();
3291
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03003292 pi->num_acked = (pi->num_acked + 1) % num_to_ack;
3293 if (pi->num_acked == num_to_ack - 1)
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03003294 l2cap_send_ack(pi);
3295
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003296 return 0;
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003297
3298drop:
3299 kfree_skb(skb);
3300 return 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003301}
3302
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003303static inline void l2cap_data_channel_rrframe(struct sock *sk, u16 rx_control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003304{
3305 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan6e3a5982010-05-01 16:15:38 -03003306
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003307 BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, __get_reqseq(rx_control),
3308 rx_control);
3309
Gustavo F. Padovan6e3a5982010-05-01 16:15:38 -03003310 pi->expected_ack_seq = __get_reqseq(rx_control);
3311 l2cap_drop_acked_frames(sk);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003312
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003313 if (rx_control & L2CAP_CTRL_POLL) {
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03003314 pi->conn_state |= L2CAP_CONN_SEND_FBIT;
Gustavo F. Padovan05fbd892010-05-01 16:15:39 -03003315 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3316 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
3317 (pi->unacked_frames > 0))
3318 __mod_retrans_timer();
3319
3320 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3321 l2cap_send_srejtail(sk);
3322 } else {
3323 l2cap_send_i_or_rr_or_rnr(sk);
Gustavo F. Padovan05fbd892010-05-01 16:15:39 -03003324 }
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003325
3326 } else if (rx_control & L2CAP_CTRL_FINAL) {
3327 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003328
3329 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3330 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003331 else
3332 l2cap_retransmit_frames(sk);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003333
3334 } else {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003335 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
3336 (pi->unacked_frames > 0))
3337 __mod_retrans_timer();
3338
3339 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
Andrei Emeltchenko894718a2010-12-01 16:58:24 +02003340 if (pi->conn_state & L2CAP_CONN_SREJ_SENT)
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003341 l2cap_send_ack(pi);
Andrei Emeltchenko894718a2010-12-01 16:58:24 +02003342 else
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003343 l2cap_ertm_send(sk);
3344 }
3345}
3346
3347static inline void l2cap_data_channel_rejframe(struct sock *sk, u16 rx_control)
3348{
3349 struct l2cap_pinfo *pi = l2cap_pi(sk);
3350 u8 tx_seq = __get_reqseq(rx_control);
3351
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003352 BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, tx_seq, rx_control);
3353
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003354 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3355
Gustavo F. Padovan8abb52e2010-05-01 16:15:38 -03003356 pi->expected_ack_seq = tx_seq;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003357 l2cap_drop_acked_frames(sk);
3358
3359 if (rx_control & L2CAP_CTRL_FINAL) {
3360 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3361 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003362 else
3363 l2cap_retransmit_frames(sk);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003364 } else {
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003365 l2cap_retransmit_frames(sk);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003366
Gustavo F. Padovan0301ef02010-05-05 20:56:43 -03003367 if (pi->conn_state & L2CAP_CONN_WAIT_F)
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003368 pi->conn_state |= L2CAP_CONN_REJ_ACT;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003369 }
3370}
3371static inline void l2cap_data_channel_srejframe(struct sock *sk, u16 rx_control)
3372{
3373 struct l2cap_pinfo *pi = l2cap_pi(sk);
3374 u8 tx_seq = __get_reqseq(rx_control);
3375
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003376 BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, tx_seq, rx_control);
3377
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003378 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3379
3380 if (rx_control & L2CAP_CTRL_POLL) {
3381 pi->expected_ack_seq = tx_seq;
3382 l2cap_drop_acked_frames(sk);
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03003383
3384 pi->conn_state |= L2CAP_CONN_SEND_FBIT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003385 l2cap_retransmit_one_frame(sk, tx_seq);
3386
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003387 l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003388
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003389 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
3390 pi->srej_save_reqseq = tx_seq;
3391 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
3392 }
3393 } else if (rx_control & L2CAP_CTRL_FINAL) {
3394 if ((pi->conn_state & L2CAP_CONN_SREJ_ACT) &&
3395 pi->srej_save_reqseq == tx_seq)
3396 pi->conn_state &= ~L2CAP_CONN_SREJ_ACT;
3397 else
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003398 l2cap_retransmit_one_frame(sk, tx_seq);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003399 } else {
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003400 l2cap_retransmit_one_frame(sk, tx_seq);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003401 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
3402 pi->srej_save_reqseq = tx_seq;
3403 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
3404 }
3405 }
3406}
3407
3408static inline void l2cap_data_channel_rnrframe(struct sock *sk, u16 rx_control)
3409{
3410 struct l2cap_pinfo *pi = l2cap_pi(sk);
3411 u8 tx_seq = __get_reqseq(rx_control);
3412
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003413 BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, tx_seq, rx_control);
3414
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003415 pi->conn_state |= L2CAP_CONN_REMOTE_BUSY;
3416 pi->expected_ack_seq = tx_seq;
3417 l2cap_drop_acked_frames(sk);
3418
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03003419 if (rx_control & L2CAP_CTRL_POLL)
3420 pi->conn_state |= L2CAP_CONN_SEND_FBIT;
3421
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03003422 if (!(pi->conn_state & L2CAP_CONN_SREJ_SENT)) {
3423 del_timer(&pi->retrans_timer);
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -03003424 if (rx_control & L2CAP_CTRL_POLL)
3425 l2cap_send_rr_or_rnr(pi, L2CAP_CTRL_FINAL);
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03003426 return;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003427 }
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03003428
3429 if (rx_control & L2CAP_CTRL_POLL)
3430 l2cap_send_srejtail(sk);
3431 else
3432 l2cap_send_sframe(pi, L2CAP_SUPER_RCV_READY);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003433}
3434
3435static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
3436{
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003437 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
3438
Gustavo F. Padovan9b16dc62010-05-05 20:05:57 -03003439 if (L2CAP_CTRL_FINAL & rx_control &&
3440 l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003441 del_timer(&l2cap_pi(sk)->monitor_timer);
3442 if (l2cap_pi(sk)->unacked_frames > 0)
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003443 __mod_retrans_timer();
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003444 l2cap_pi(sk)->conn_state &= ~L2CAP_CONN_WAIT_F;
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003445 }
3446
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003447 switch (rx_control & L2CAP_CTRL_SUPERVISE) {
3448 case L2CAP_SUPER_RCV_READY:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003449 l2cap_data_channel_rrframe(sk, rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003450 break;
3451
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003452 case L2CAP_SUPER_REJECT:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003453 l2cap_data_channel_rejframe(sk, rx_control);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003454 break;
3455
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003456 case L2CAP_SUPER_SELECT_REJECT:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003457 l2cap_data_channel_srejframe(sk, rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003458 break;
3459
3460 case L2CAP_SUPER_RCV_NOT_READY:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003461 l2cap_data_channel_rnrframe(sk, rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003462 break;
3463 }
3464
Gustavo F. Padovanfaaebd12010-05-01 16:15:35 -03003465 kfree_skb(skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003466 return 0;
3467}
3468
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03003469static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb)
3470{
3471 struct l2cap_pinfo *pi = l2cap_pi(sk);
3472 u16 control;
3473 u8 req_seq;
3474 int len, next_tx_seq_offset, req_seq_offset;
3475
3476 control = get_unaligned_le16(skb->data);
3477 skb_pull(skb, 2);
3478 len = skb->len;
3479
3480 /*
3481 * We can just drop the corrupted I-frame here.
3482 * Receiver will miss it and start proper recovery
3483 * procedures and ask retransmission.
3484 */
3485 if (l2cap_check_fcs(pi, skb))
3486 goto drop;
3487
3488 if (__is_sar_start(control) && __is_iframe(control))
3489 len -= 2;
3490
3491 if (pi->fcs == L2CAP_FCS_CRC16)
3492 len -= 2;
3493
3494 if (len > pi->mps) {
3495 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
3496 goto drop;
3497 }
3498
3499 req_seq = __get_reqseq(control);
3500 req_seq_offset = (req_seq - pi->expected_ack_seq) % 64;
3501 if (req_seq_offset < 0)
3502 req_seq_offset += 64;
3503
3504 next_tx_seq_offset =
3505 (pi->next_tx_seq - pi->expected_ack_seq) % 64;
3506 if (next_tx_seq_offset < 0)
3507 next_tx_seq_offset += 64;
3508
3509 /* check for invalid req-seq */
3510 if (req_seq_offset > next_tx_seq_offset) {
3511 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
3512 goto drop;
3513 }
3514
3515 if (__is_iframe(control)) {
3516 if (len < 0) {
3517 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
3518 goto drop;
3519 }
3520
3521 l2cap_data_channel_iframe(sk, control, skb);
3522 } else {
3523 if (len != 0) {
3524 BT_ERR("%d", len);
3525 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
3526 goto drop;
3527 }
3528
3529 l2cap_data_channel_sframe(sk, control, skb);
3530 }
3531
3532 return 0;
3533
3534drop:
3535 kfree_skb(skb);
3536 return 0;
3537}
3538
Linus Torvalds1da177e2005-04-16 15:20:36 -07003539static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk_buff *skb)
3540{
3541 struct sock *sk;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003542 struct l2cap_pinfo *pi;
Nathan Holstein51893f82010-06-09 15:46:25 -04003543 u16 control;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03003544 u8 tx_seq;
3545 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003546
3547 sk = l2cap_get_chan_by_scid(&conn->chan_list, cid);
3548 if (!sk) {
3549 BT_DBG("unknown cid 0x%4.4x", cid);
3550 goto drop;
3551 }
3552
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003553 pi = l2cap_pi(sk);
3554
Linus Torvalds1da177e2005-04-16 15:20:36 -07003555 BT_DBG("sk %p, len %d", sk, skb->len);
3556
3557 if (sk->sk_state != BT_CONNECTED)
3558 goto drop;
3559
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003560 switch (pi->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003561 case L2CAP_MODE_BASIC:
3562 /* If socket recv buffers overflows we drop data here
3563 * which is *bad* because L2CAP has to be reliable.
3564 * But we don't have any other choice. L2CAP doesn't
3565 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003566
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003567 if (pi->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003568 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003569
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003570 if (!sock_queue_rcv_skb(sk, skb))
3571 goto done;
3572 break;
3573
3574 case L2CAP_MODE_ERTM:
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03003575 if (!sock_owned_by_user(sk)) {
3576 l2cap_ertm_data_rcv(sk, skb);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03003577 } else {
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03003578 if (sk_add_backlog(sk, skb))
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03003579 goto drop;
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03003580 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003581
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02003582 goto done;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003583
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003584 case L2CAP_MODE_STREAMING:
3585 control = get_unaligned_le16(skb->data);
3586 skb_pull(skb, 2);
3587 len = skb->len;
3588
Gustavo F. Padovan26000082010-05-11 22:02:00 -03003589 if (l2cap_check_fcs(pi, skb))
3590 goto drop;
3591
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003592 if (__is_sar_start(control))
3593 len -= 2;
3594
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003595 if (pi->fcs == L2CAP_FCS_CRC16)
3596 len -= 2;
3597
Nathan Holstein51893f82010-06-09 15:46:25 -04003598 if (len > pi->mps || len < 0 || __is_sframe(control))
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003599 goto drop;
3600
3601 tx_seq = __get_txseq(control);
3602
3603 if (pi->expected_tx_seq == tx_seq)
3604 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
3605 else
Gustavo F. Padovan7dffe422010-05-01 16:15:36 -03003606 pi->expected_tx_seq = (tx_seq + 1) % 64;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003607
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003608 l2cap_streaming_reassembly_sdu(sk, skb, control);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003609
3610 goto done;
3611
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003612 default:
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03003613 BT_DBG("sk %p: bad mode 0x%2.2x", sk, pi->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003614 break;
3615 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003616
3617drop:
3618 kfree_skb(skb);
3619
3620done:
Marcel Holtmann01394182006-07-03 10:02:46 +02003621 if (sk)
3622 bh_unlock_sock(sk);
3623
Linus Torvalds1da177e2005-04-16 15:20:36 -07003624 return 0;
3625}
3626
Al Viro8e036fc2007-07-29 00:16:36 -07003627static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003628{
3629 struct sock *sk;
3630
3631 sk = l2cap_get_sock_by_psm(0, psm, conn->src);
3632 if (!sk)
3633 goto drop;
3634
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00003635 bh_lock_sock(sk);
3636
Linus Torvalds1da177e2005-04-16 15:20:36 -07003637 BT_DBG("sk %p, len %d", sk, skb->len);
3638
3639 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_CONNECTED)
3640 goto drop;
3641
3642 if (l2cap_pi(sk)->imtu < skb->len)
3643 goto drop;
3644
3645 if (!sock_queue_rcv_skb(sk, skb))
3646 goto done;
3647
3648drop:
3649 kfree_skb(skb);
3650
3651done:
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003652 if (sk)
3653 bh_unlock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003654 return 0;
3655}
3656
3657static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
3658{
3659 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07003660 u16 cid, len;
3661 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003662
3663 skb_pull(skb, L2CAP_HDR_SIZE);
3664 cid = __le16_to_cpu(lh->cid);
3665 len = __le16_to_cpu(lh->len);
3666
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003667 if (len != skb->len) {
3668 kfree_skb(skb);
3669 return;
3670 }
3671
Linus Torvalds1da177e2005-04-16 15:20:36 -07003672 BT_DBG("len %d, cid 0x%4.4x", len, cid);
3673
3674 switch (cid) {
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02003675 case L2CAP_CID_LE_SIGNALING:
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03003676 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07003677 l2cap_sig_channel(conn, skb);
3678 break;
3679
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03003680 case L2CAP_CID_CONN_LESS:
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03003681 psm = get_unaligned_le16(skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003682 skb_pull(skb, 2);
3683 l2cap_conless_channel(conn, psm, skb);
3684 break;
3685
3686 default:
3687 l2cap_data_channel(conn, cid, skb);
3688 break;
3689 }
3690}
3691
3692/* ---- L2CAP interface with lower layer (HCI) ---- */
3693
3694static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
3695{
3696 int exact = 0, lm1 = 0, lm2 = 0;
3697 register struct sock *sk;
3698 struct hlist_node *node;
3699
3700 if (type != ACL_LINK)
João Paulo Rechi Vita963cf682010-06-22 13:56:28 -03003701 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003702
3703 BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
3704
3705 /* Find listening sockets and check their link_mode */
3706 read_lock(&l2cap_sk_list.lock);
3707 sk_for_each(sk, node, &l2cap_sk_list.head) {
3708 if (sk->sk_state != BT_LISTEN)
3709 continue;
3710
3711 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01003712 lm1 |= HCI_LM_ACCEPT;
3713 if (l2cap_pi(sk)->role_switch)
3714 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003715 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01003716 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
3717 lm2 |= HCI_LM_ACCEPT;
3718 if (l2cap_pi(sk)->role_switch)
3719 lm2 |= HCI_LM_MASTER;
3720 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003721 }
3722 read_unlock(&l2cap_sk_list.lock);
3723
3724 return exact ? lm1 : lm2;
3725}
3726
3727static int l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
3728{
Marcel Holtmann01394182006-07-03 10:02:46 +02003729 struct l2cap_conn *conn;
3730
Linus Torvalds1da177e2005-04-16 15:20:36 -07003731 BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
3732
Ville Tervoacd7d372011-02-10 22:38:49 -03003733 if (!(hcon->type == ACL_LINK || hcon->type == LE_LINK))
João Paulo Rechi Vita963cf682010-06-22 13:56:28 -03003734 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003735
3736 if (!status) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003737 conn = l2cap_conn_add(hcon, status);
3738 if (conn)
3739 l2cap_conn_ready(conn);
Marcel Holtmann01394182006-07-03 10:02:46 +02003740 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -07003741 l2cap_conn_del(hcon, bt_err(status));
3742
3743 return 0;
3744}
3745
Marcel Holtmann2950f212009-02-12 14:02:50 +01003746static int l2cap_disconn_ind(struct hci_conn *hcon)
3747{
3748 struct l2cap_conn *conn = hcon->l2cap_data;
3749
3750 BT_DBG("hcon %p", hcon);
3751
3752 if (hcon->type != ACL_LINK || !conn)
3753 return 0x13;
3754
3755 return conn->disc_reason;
3756}
3757
3758static int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003759{
3760 BT_DBG("hcon %p reason %d", hcon, reason);
3761
Ville Tervoacd7d372011-02-10 22:38:49 -03003762 if (!(hcon->type == ACL_LINK || hcon->type == LE_LINK))
João Paulo Rechi Vita963cf682010-06-22 13:56:28 -03003763 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003764
3765 l2cap_conn_del(hcon, bt_err(reason));
Marcel Holtmann01394182006-07-03 10:02:46 +02003766
Linus Torvalds1da177e2005-04-16 15:20:36 -07003767 return 0;
3768}
3769
Marcel Holtmannf62e4322009-01-15 21:58:44 +01003770static inline void l2cap_check_encryption(struct sock *sk, u8 encrypt)
3771{
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03003772 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM)
Marcel Holtmann255c7602009-02-04 21:07:19 +01003773 return;
3774
Marcel Holtmannf62e4322009-01-15 21:58:44 +01003775 if (encrypt == 0x00) {
3776 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM) {
3777 l2cap_sock_clear_timer(sk);
3778 l2cap_sock_set_timer(sk, HZ * 5);
3779 } else if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
3780 __l2cap_sock_close(sk, ECONNREFUSED);
3781 } else {
3782 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM)
3783 l2cap_sock_clear_timer(sk);
3784 }
3785}
3786
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01003787static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003788{
3789 struct l2cap_chan_list *l;
Marcel Holtmann40be4922008-07-14 20:13:50 +02003790 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003791 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003792
Marcel Holtmann01394182006-07-03 10:02:46 +02003793 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003794 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02003795
Linus Torvalds1da177e2005-04-16 15:20:36 -07003796 l = &conn->chan_list;
3797
3798 BT_DBG("conn %p", conn);
3799
3800 read_lock(&l->lock);
3801
3802 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
3803 bh_lock_sock(sk);
3804
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003805 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND) {
3806 bh_unlock_sock(sk);
3807 continue;
3808 }
3809
Marcel Holtmannf62e4322009-01-15 21:58:44 +01003810 if (!status && (sk->sk_state == BT_CONNECTED ||
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01003811 sk->sk_state == BT_CONFIG)) {
Marcel Holtmannf62e4322009-01-15 21:58:44 +01003812 l2cap_check_encryption(sk, encrypt);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02003813 bh_unlock_sock(sk);
3814 continue;
3815 }
3816
Marcel Holtmannb1235d72008-07-14 20:13:54 +02003817 if (sk->sk_state == BT_CONNECT) {
3818 if (!status) {
3819 struct l2cap_conn_req req;
3820 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
3821 req.psm = l2cap_pi(sk)->psm;
3822
3823 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03003824 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02003825
3826 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
3827 L2CAP_CONN_REQ, sizeof(req), &req);
3828 } else {
3829 l2cap_sock_clear_timer(sk);
3830 l2cap_sock_set_timer(sk, HZ / 10);
3831 }
3832 } else if (sk->sk_state == BT_CONNECT2) {
3833 struct l2cap_conn_rsp rsp;
3834 __u16 result;
3835
3836 if (!status) {
3837 sk->sk_state = BT_CONFIG;
3838 result = L2CAP_CR_SUCCESS;
3839 } else {
3840 sk->sk_state = BT_DISCONN;
3841 l2cap_sock_set_timer(sk, HZ / 10);
3842 result = L2CAP_CR_SEC_BLOCK;
3843 }
3844
3845 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
3846 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
3847 rsp.result = cpu_to_le16(result);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003848 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02003849 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
3850 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003851 }
3852
Linus Torvalds1da177e2005-04-16 15:20:36 -07003853 bh_unlock_sock(sk);
3854 }
3855
3856 read_unlock(&l->lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02003857
Linus Torvalds1da177e2005-04-16 15:20:36 -07003858 return 0;
3859}
3860
3861static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
3862{
3863 struct l2cap_conn *conn = hcon->l2cap_data;
3864
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02003865 if (!conn)
3866 conn = l2cap_conn_add(hcon, 0);
3867
3868 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003869 goto drop;
3870
3871 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
3872
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +02003873 if (!(flags & ACL_CONT)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003874 struct l2cap_hdr *hdr;
Andrei Emeltchenko89794812010-09-15 14:28:44 +03003875 struct sock *sk;
3876 u16 cid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003877 int len;
3878
3879 if (conn->rx_len) {
3880 BT_ERR("Unexpected start frame (len %d)", skb->len);
3881 kfree_skb(conn->rx_skb);
3882 conn->rx_skb = NULL;
3883 conn->rx_len = 0;
3884 l2cap_conn_unreliable(conn, ECOMM);
3885 }
3886
Andrei Emeltchenkoaae7fe22010-09-15 14:28:43 +03003887 /* Start fragment always begin with Basic L2CAP header */
3888 if (skb->len < L2CAP_HDR_SIZE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003889 BT_ERR("Frame is too short (len %d)", skb->len);
3890 l2cap_conn_unreliable(conn, ECOMM);
3891 goto drop;
3892 }
3893
3894 hdr = (struct l2cap_hdr *) skb->data;
3895 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
Andrei Emeltchenko89794812010-09-15 14:28:44 +03003896 cid = __le16_to_cpu(hdr->cid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003897
3898 if (len == skb->len) {
3899 /* Complete frame received */
3900 l2cap_recv_frame(conn, skb);
3901 return 0;
3902 }
3903
3904 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
3905
3906 if (skb->len > len) {
3907 BT_ERR("Frame is too long (len %d, expected len %d)",
3908 skb->len, len);
3909 l2cap_conn_unreliable(conn, ECOMM);
3910 goto drop;
3911 }
3912
Andrei Emeltchenko89794812010-09-15 14:28:44 +03003913 sk = l2cap_get_chan_by_scid(&conn->chan_list, cid);
3914
3915 if (sk && l2cap_pi(sk)->imtu < len - L2CAP_HDR_SIZE) {
3916 BT_ERR("Frame exceeding recv MTU (len %d, MTU %d)",
3917 len, l2cap_pi(sk)->imtu);
3918 bh_unlock_sock(sk);
3919 l2cap_conn_unreliable(conn, ECOMM);
3920 goto drop;
3921 }
3922
3923 if (sk)
3924 bh_unlock_sock(sk);
3925
Linus Torvalds1da177e2005-04-16 15:20:36 -07003926 /* Allocate skb for the complete frame (with header) */
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003927 conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC);
3928 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003929 goto drop;
3930
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03003931 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003932 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003933 conn->rx_len = len - skb->len;
3934 } else {
3935 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
3936
3937 if (!conn->rx_len) {
3938 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
3939 l2cap_conn_unreliable(conn, ECOMM);
3940 goto drop;
3941 }
3942
3943 if (skb->len > conn->rx_len) {
3944 BT_ERR("Fragment is too long (len %d, expected %d)",
3945 skb->len, conn->rx_len);
3946 kfree_skb(conn->rx_skb);
3947 conn->rx_skb = NULL;
3948 conn->rx_len = 0;
3949 l2cap_conn_unreliable(conn, ECOMM);
3950 goto drop;
3951 }
3952
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03003953 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003954 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003955 conn->rx_len -= skb->len;
3956
3957 if (!conn->rx_len) {
3958 /* Complete frame received */
3959 l2cap_recv_frame(conn, conn->rx_skb);
3960 conn->rx_skb = NULL;
3961 }
3962 }
3963
3964drop:
3965 kfree_skb(skb);
3966 return 0;
3967}
3968
Marcel Holtmannaef7d972010-03-21 05:27:45 +01003969static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003970{
3971 struct sock *sk;
3972 struct hlist_node *node;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003973
3974 read_lock_bh(&l2cap_sk_list.lock);
3975
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08003976 sk_for_each(sk, node, &l2cap_sk_list.head) {
3977 struct l2cap_pinfo *pi = l2cap_pi(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003978
Gustavo F. Padovan903d3432011-02-10 14:16:06 -02003979 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 +01003980 batostr(&bt_sk(sk)->src),
3981 batostr(&bt_sk(sk)->dst),
3982 sk->sk_state, __le16_to_cpu(pi->psm),
3983 pi->scid, pi->dcid,
Gustavo F. Padovan903d3432011-02-10 14:16:06 -02003984 pi->imtu, pi->omtu, pi->sec_level,
3985 pi->mode);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08003986 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003987
Linus Torvalds1da177e2005-04-16 15:20:36 -07003988 read_unlock_bh(&l2cap_sk_list.lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08003989
Marcel Holtmannaef7d972010-03-21 05:27:45 +01003990 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003991}
3992
Marcel Holtmannaef7d972010-03-21 05:27:45 +01003993static int l2cap_debugfs_open(struct inode *inode, struct file *file)
3994{
3995 return single_open(file, l2cap_debugfs_show, inode->i_private);
3996}
3997
3998static const struct file_operations l2cap_debugfs_fops = {
3999 .open = l2cap_debugfs_open,
4000 .read = seq_read,
4001 .llseek = seq_lseek,
4002 .release = single_release,
4003};
4004
4005static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004006
Linus Torvalds1da177e2005-04-16 15:20:36 -07004007static struct hci_proto l2cap_hci_proto = {
4008 .name = "L2CAP",
4009 .id = HCI_PROTO_L2CAP,
4010 .connect_ind = l2cap_connect_ind,
4011 .connect_cfm = l2cap_connect_cfm,
4012 .disconn_ind = l2cap_disconn_ind,
Marcel Holtmann2950f212009-02-12 14:02:50 +01004013 .disconn_cfm = l2cap_disconn_cfm,
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004014 .security_cfm = l2cap_security_cfm,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004015 .recv_acldata = l2cap_recv_acldata
4016};
4017
Gustavo F. Padovan64274512011-02-07 20:08:52 -02004018int __init l2cap_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004019{
4020 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004021
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02004022 err = l2cap_init_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07004023 if (err < 0)
4024 return err;
4025
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004026 _busy_wq = create_singlethread_workqueue("l2cap");
Anderson Lizardob78d7b4f2010-11-29 12:15:50 -04004027 if (!_busy_wq) {
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02004028 err = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004029 goto error;
4030 }
4031
4032 err = hci_register_proto(&l2cap_hci_proto);
4033 if (err < 0) {
4034 BT_ERR("L2CAP protocol registration failed");
4035 bt_sock_unregister(BTPROTO_L2CAP);
4036 goto error;
4037 }
4038
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004039 if (bt_debugfs) {
4040 l2cap_debugfs = debugfs_create_file("l2cap", 0444,
4041 bt_debugfs, NULL, &l2cap_debugfs_fops);
4042 if (!l2cap_debugfs)
4043 BT_ERR("Failed to create L2CAP debug file");
4044 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004045
Linus Torvalds1da177e2005-04-16 15:20:36 -07004046 return 0;
4047
4048error:
Anderson Lizardob78d7b4f2010-11-29 12:15:50 -04004049 destroy_workqueue(_busy_wq);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02004050 l2cap_cleanup_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07004051 return err;
4052}
4053
Gustavo F. Padovan64274512011-02-07 20:08:52 -02004054void l2cap_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004055{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004056 debugfs_remove(l2cap_debugfs);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004057
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004058 flush_workqueue(_busy_wq);
4059 destroy_workqueue(_busy_wq);
4060
Linus Torvalds1da177e2005-04-16 15:20:36 -07004061 if (hci_unregister_proto(&l2cap_hci_proto) < 0)
4062 BT_ERR("L2CAP protocol unregistration failed");
4063
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02004064 l2cap_cleanup_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07004065}
4066
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03004067module_param(disable_ertm, bool, 0644);
4068MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode");