blob: cdd608d72741ae3f6d00ff2e8553890636a5f4a1 [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>
Linus Torvalds1da177e2005-04-16 15:20:36 -07005
6 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License version 2 as
10 published by the Free Software Foundation;
11
12 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
13 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
15 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090016 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
17 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Linus Torvalds1da177e2005-04-16 15:20:36 -070019 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090021 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
22 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
Linus Torvalds1da177e2005-04-16 15:20:36 -070023 SOFTWARE IS DISCLAIMED.
24*/
25
26/* Bluetooth L2CAP core and sockets. */
27
Linus Torvalds1da177e2005-04-16 15:20:36 -070028#include <linux/module.h>
29
30#include <linux/types.h>
Randy Dunlap4fc268d2006-01-11 12:17:47 -080031#include <linux/capability.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070032#include <linux/errno.h>
33#include <linux/kernel.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070034#include <linux/sched.h>
35#include <linux/slab.h>
36#include <linux/poll.h>
37#include <linux/fcntl.h>
38#include <linux/init.h>
39#include <linux/interrupt.h>
40#include <linux/socket.h>
41#include <linux/skbuff.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070042#include <linux/list.h>
Marcel Holtmannbe9d1222005-11-08 09:57:38 -080043#include <linux/device.h>
Marcel Holtmannaef7d972010-03-21 05:27:45 +010044#include <linux/debugfs.h>
45#include <linux/seq_file.h>
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -030046#include <linux/uaccess.h>
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -030047#include <linux/crc16.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070048#include <net/sock.h>
49
50#include <asm/system.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070051#include <asm/unaligned.h>
52
53#include <net/bluetooth/bluetooth.h>
54#include <net/bluetooth/hci_core.h>
55#include <net/bluetooth/l2cap.h>
56
Gustavo F. Padovandd135242010-07-13 11:57:12 -030057#define VERSION "2.15"
Marcel Holtmann44dd46d2009-05-02 19:09:01 -070058
59static int enable_ertm = 0;
Marcel Holtmannf0709e02007-10-20 13:38:51 +020060
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -070061static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN;
Marcel Holtmanne1027a72009-02-09 09:18:02 +010062static u8 l2cap_fixed_chan[8] = { 0x02, };
Linus Torvalds1da177e2005-04-16 15:20:36 -070063
Eric Dumazet90ddc4f2005-12-22 12:49:22 -080064static const struct proto_ops l2cap_sock_ops;
Linus Torvalds1da177e2005-04-16 15:20:36 -070065
Gustavo F. Padovan1890d362010-05-01 16:15:44 -030066static struct workqueue_struct *_busy_wq;
67
Linus Torvalds1da177e2005-04-16 15:20:36 -070068static struct bt_sock_list l2cap_sk_list = {
Robert P. J. Dayd5fb2962008-03-28 16:17:38 -070069 .lock = __RW_LOCK_UNLOCKED(l2cap_sk_list.lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -070070};
71
Gustavo F. Padovan1890d362010-05-01 16:15:44 -030072static void l2cap_busy_work(struct work_struct *work);
73
Linus Torvalds1da177e2005-04-16 15:20:36 -070074static void __l2cap_sock_close(struct sock *sk, int reason);
75static void l2cap_sock_close(struct sock *sk);
76static void l2cap_sock_kill(struct sock *sk);
77
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -030078static int l2cap_build_conf_req(struct sock *sk, void *data);
Linus Torvalds1da177e2005-04-16 15:20:36 -070079static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
80 u8 code, u8 ident, u16 dlen, void *data);
81
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -030082static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb);
83
Linus Torvalds1da177e2005-04-16 15:20:36 -070084/* ---- L2CAP timers ---- */
85static void l2cap_sock_timeout(unsigned long arg)
86{
87 struct sock *sk = (struct sock *) arg;
Marcel Holtmannb1235d72008-07-14 20:13:54 +020088 int reason;
Linus Torvalds1da177e2005-04-16 15:20:36 -070089
90 BT_DBG("sock %p state %d", sk, sk->sk_state);
91
92 bh_lock_sock(sk);
Marcel Holtmannb1235d72008-07-14 20:13:54 +020093
Marcel Holtmannf62e4322009-01-15 21:58:44 +010094 if (sk->sk_state == BT_CONNECTED || sk->sk_state == BT_CONFIG)
95 reason = ECONNREFUSED;
96 else if (sk->sk_state == BT_CONNECT &&
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +010097 l2cap_pi(sk)->sec_level != BT_SECURITY_SDP)
Marcel Holtmannb1235d72008-07-14 20:13:54 +020098 reason = ECONNREFUSED;
99 else
100 reason = ETIMEDOUT;
101
102 __l2cap_sock_close(sk, reason);
103
Linus Torvalds1da177e2005-04-16 15:20:36 -0700104 bh_unlock_sock(sk);
105
106 l2cap_sock_kill(sk);
107 sock_put(sk);
108}
109
110static void l2cap_sock_set_timer(struct sock *sk, long timeout)
111{
112 BT_DBG("sk %p state %d timeout %ld", sk, sk->sk_state, timeout);
113 sk_reset_timer(sk, &sk->sk_timer, jiffies + timeout);
114}
115
116static void l2cap_sock_clear_timer(struct sock *sk)
117{
118 BT_DBG("sock %p state %d", sk, sk->sk_state);
119 sk_stop_timer(sk, &sk->sk_timer);
120}
121
Marcel Holtmann01394182006-07-03 10:02:46 +0200122/* ---- L2CAP channels ---- */
123static struct sock *__l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, u16 cid)
124{
125 struct sock *s;
126 for (s = l->head; s; s = l2cap_pi(s)->next_c) {
127 if (l2cap_pi(s)->dcid == cid)
128 break;
129 }
130 return s;
131}
132
133static struct sock *__l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid)
134{
135 struct sock *s;
136 for (s = l->head; s; s = l2cap_pi(s)->next_c) {
137 if (l2cap_pi(s)->scid == cid)
138 break;
139 }
140 return s;
141}
142
143/* Find channel with given SCID.
144 * Returns locked socket */
145static inline struct sock *l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid)
146{
147 struct sock *s;
148 read_lock(&l->lock);
149 s = __l2cap_get_chan_by_scid(l, cid);
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -0300150 if (s)
151 bh_lock_sock(s);
Marcel Holtmann01394182006-07-03 10:02:46 +0200152 read_unlock(&l->lock);
153 return s;
154}
155
156static struct sock *__l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 ident)
157{
158 struct sock *s;
159 for (s = l->head; s; s = l2cap_pi(s)->next_c) {
160 if (l2cap_pi(s)->ident == ident)
161 break;
162 }
163 return s;
164}
165
166static inline struct sock *l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 ident)
167{
168 struct sock *s;
169 read_lock(&l->lock);
170 s = __l2cap_get_chan_by_ident(l, ident);
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -0300171 if (s)
172 bh_lock_sock(s);
Marcel Holtmann01394182006-07-03 10:02:46 +0200173 read_unlock(&l->lock);
174 return s;
175}
176
177static u16 l2cap_alloc_cid(struct l2cap_chan_list *l)
178{
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300179 u16 cid = L2CAP_CID_DYN_START;
Marcel Holtmann01394182006-07-03 10:02:46 +0200180
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300181 for (; cid < L2CAP_CID_DYN_END; cid++) {
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -0300182 if (!__l2cap_get_chan_by_scid(l, cid))
Marcel Holtmann01394182006-07-03 10:02:46 +0200183 return cid;
184 }
185
186 return 0;
187}
188
189static inline void __l2cap_chan_link(struct l2cap_chan_list *l, struct sock *sk)
190{
191 sock_hold(sk);
192
193 if (l->head)
194 l2cap_pi(l->head)->prev_c = sk;
195
196 l2cap_pi(sk)->next_c = l->head;
197 l2cap_pi(sk)->prev_c = NULL;
198 l->head = sk;
199}
200
201static inline void l2cap_chan_unlink(struct l2cap_chan_list *l, struct sock *sk)
202{
203 struct sock *next = l2cap_pi(sk)->next_c, *prev = l2cap_pi(sk)->prev_c;
204
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200205 write_lock_bh(&l->lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200206 if (sk == l->head)
207 l->head = next;
208
209 if (next)
210 l2cap_pi(next)->prev_c = prev;
211 if (prev)
212 l2cap_pi(prev)->next_c = next;
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200213 write_unlock_bh(&l->lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200214
215 __sock_put(sk);
216}
217
218static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
219{
220 struct l2cap_chan_list *l = &conn->chan_list;
221
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -0300222 BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
223 l2cap_pi(sk)->psm, l2cap_pi(sk)->dcid);
Marcel Holtmann01394182006-07-03 10:02:46 +0200224
Marcel Holtmann2950f212009-02-12 14:02:50 +0100225 conn->disc_reason = 0x13;
226
Marcel Holtmann01394182006-07-03 10:02:46 +0200227 l2cap_pi(sk)->conn = conn;
228
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300229 if (sk->sk_type == SOCK_SEQPACKET || sk->sk_type == SOCK_STREAM) {
Marcel Holtmann01394182006-07-03 10:02:46 +0200230 /* Alloc CID for connection-oriented socket */
231 l2cap_pi(sk)->scid = l2cap_alloc_cid(l);
232 } else if (sk->sk_type == SOCK_DGRAM) {
233 /* Connectionless socket */
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300234 l2cap_pi(sk)->scid = L2CAP_CID_CONN_LESS;
235 l2cap_pi(sk)->dcid = L2CAP_CID_CONN_LESS;
Marcel Holtmann01394182006-07-03 10:02:46 +0200236 l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
237 } else {
238 /* Raw socket can send/recv signalling messages only */
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300239 l2cap_pi(sk)->scid = L2CAP_CID_SIGNALING;
240 l2cap_pi(sk)->dcid = L2CAP_CID_SIGNALING;
Marcel Holtmann01394182006-07-03 10:02:46 +0200241 l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
242 }
243
244 __l2cap_chan_link(l, sk);
245
246 if (parent)
247 bt_accept_enqueue(parent, sk);
248}
249
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900250/* Delete channel.
Marcel Holtmann01394182006-07-03 10:02:46 +0200251 * Must be called on the locked socket. */
252static void l2cap_chan_del(struct sock *sk, int err)
253{
254 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
255 struct sock *parent = bt_sk(sk)->parent;
256
257 l2cap_sock_clear_timer(sk);
258
259 BT_DBG("sk %p, conn %p, err %d", sk, conn, err);
260
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900261 if (conn) {
Marcel Holtmann01394182006-07-03 10:02:46 +0200262 /* Unlink from channel list */
263 l2cap_chan_unlink(&conn->chan_list, sk);
264 l2cap_pi(sk)->conn = NULL;
265 hci_conn_put(conn->hcon);
266 }
267
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200268 sk->sk_state = BT_CLOSED;
Marcel Holtmann01394182006-07-03 10:02:46 +0200269 sock_set_flag(sk, SOCK_ZAPPED);
270
271 if (err)
272 sk->sk_err = err;
273
274 if (parent) {
275 bt_accept_unlink(sk);
276 parent->sk_data_ready(parent, 0);
277 } else
278 sk->sk_state_change(sk);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300279
280 skb_queue_purge(TX_QUEUE(sk));
281
282 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
283 struct srej_list *l, *tmp;
284
285 del_timer(&l2cap_pi(sk)->retrans_timer);
286 del_timer(&l2cap_pi(sk)->monitor_timer);
287 del_timer(&l2cap_pi(sk)->ack_timer);
288
289 skb_queue_purge(SREJ_QUEUE(sk));
290 skb_queue_purge(BUSY_QUEUE(sk));
291
292 list_for_each_entry_safe(l, tmp, SREJ_LIST(sk), list) {
293 list_del(&l->list);
294 kfree(l);
295 }
296 }
Marcel Holtmann01394182006-07-03 10:02:46 +0200297}
298
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200299/* Service level security */
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100300static inline int l2cap_check_security(struct sock *sk)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200301{
302 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100303 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200304
Marcel Holtmann00ae4af2009-02-12 16:19:45 +0100305 if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) {
306 if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
307 auth_type = HCI_AT_NO_BONDING_MITM;
308 else
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -0300309 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann00ae4af2009-02-12 16:19:45 +0100310
311 if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW)
312 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
313 } else {
314 switch (l2cap_pi(sk)->sec_level) {
315 case BT_SECURITY_HIGH:
316 auth_type = HCI_AT_GENERAL_BONDING_MITM;
317 break;
318 case BT_SECURITY_MEDIUM:
319 auth_type = HCI_AT_GENERAL_BONDING;
320 break;
321 default:
322 auth_type = HCI_AT_NO_BONDING;
323 break;
324 }
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100325 }
326
327 return hci_conn_security(conn->hcon, l2cap_pi(sk)->sec_level,
328 auth_type);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200329}
330
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200331static inline u8 l2cap_get_ident(struct l2cap_conn *conn)
332{
333 u8 id;
334
335 /* Get next available identificator.
336 * 1 - 128 are used by kernel.
337 * 129 - 199 are reserved.
338 * 200 - 254 are used by utilities like l2ping, etc.
339 */
340
341 spin_lock_bh(&conn->lock);
342
343 if (++conn->tx_ident > 128)
344 conn->tx_ident = 1;
345
346 id = conn->tx_ident;
347
348 spin_unlock_bh(&conn->lock);
349
350 return id;
351}
352
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300353static inline void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200354{
355 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
356
357 BT_DBG("code 0x%2.2x", code);
358
359 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300360 return;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200361
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300362 hci_send_acl(conn->hcon, skb, 0);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200363}
364
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300365static inline void l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300366{
367 struct sk_buff *skb;
368 struct l2cap_hdr *lh;
369 struct l2cap_conn *conn = pi->conn;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300370 struct sock *sk = (struct sock *)pi;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300371 int count, hlen = L2CAP_HDR_SIZE + 2;
372
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300373 if (sk->sk_state != BT_CONNECTED)
374 return;
375
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300376 if (pi->fcs == L2CAP_FCS_CRC16)
377 hlen += 2;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300378
379 BT_DBG("pi %p, control 0x%2.2x", pi, control);
380
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300381 count = min_t(unsigned int, conn->mtu, hlen);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300382 control |= L2CAP_CTRL_FRAME_TYPE;
383
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -0300384 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
385 control |= L2CAP_CTRL_FINAL;
386 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
387 }
388
Gustavo F. Padovanf0946cc2010-05-01 16:15:37 -0300389 if (pi->conn_state & L2CAP_CONN_SEND_PBIT) {
390 control |= L2CAP_CTRL_POLL;
391 pi->conn_state &= ~L2CAP_CONN_SEND_PBIT;
392 }
393
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300394 skb = bt_skb_alloc(count, GFP_ATOMIC);
395 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300396 return;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300397
398 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300399 lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300400 lh->cid = cpu_to_le16(pi->dcid);
401 put_unaligned_le16(control, skb_put(skb, 2));
402
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300403 if (pi->fcs == L2CAP_FCS_CRC16) {
404 u16 fcs = crc16(0, (u8 *)lh, count - 2);
405 put_unaligned_le16(fcs, skb_put(skb, 2));
406 }
407
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300408 hci_send_acl(pi->conn->hcon, skb, 0);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300409}
410
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300411static inline void l2cap_send_rr_or_rnr(struct l2cap_pinfo *pi, u16 control)
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300412{
Gustavo F. Padovan1890d362010-05-01 16:15:44 -0300413 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300414 control |= L2CAP_SUPER_RCV_NOT_READY;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -0300415 pi->conn_state |= L2CAP_CONN_RNR_SENT;
416 } else
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300417 control |= L2CAP_SUPER_RCV_READY;
418
Gustavo F. Padovan2ab25cd2009-10-03 02:34:40 -0300419 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
420
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300421 l2cap_send_sframe(pi, control);
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300422}
423
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300424static inline int __l2cap_no_conn_pending(struct sock *sk)
425{
426 return !(l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND);
427}
428
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200429static void l2cap_do_start(struct sock *sk)
430{
431 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
432
433 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +0100434 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
435 return;
436
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300437 if (l2cap_check_security(sk) && __l2cap_no_conn_pending(sk)) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200438 struct l2cap_conn_req req;
439 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
440 req.psm = l2cap_pi(sk)->psm;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200441
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200442 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300443 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200444
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200445 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200446 L2CAP_CONN_REQ, sizeof(req), &req);
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200447 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200448 } else {
449 struct l2cap_info_req req;
450 req.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
451
452 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
453 conn->info_ident = l2cap_get_ident(conn);
454
455 mod_timer(&conn->info_timer, jiffies +
456 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
457
458 l2cap_send_cmd(conn, conn->info_ident,
459 L2CAP_INFO_REQ, sizeof(req), &req);
460 }
461}
462
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -0300463static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
464{
465 u32 local_feat_mask = l2cap_feat_mask;
466 if (enable_ertm)
467 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
468
469 switch (mode) {
470 case L2CAP_MODE_ERTM:
471 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
472 case L2CAP_MODE_STREAMING:
473 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
474 default:
475 return 0x00;
476 }
477}
478
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -0300479static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct sock *sk, int err)
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300480{
481 struct l2cap_disconn_req req;
482
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300483 if (!conn)
484 return;
485
486 skb_queue_purge(TX_QUEUE(sk));
487
488 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
489 del_timer(&l2cap_pi(sk)->retrans_timer);
490 del_timer(&l2cap_pi(sk)->monitor_timer);
491 del_timer(&l2cap_pi(sk)->ack_timer);
492 }
493
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300494 req.dcid = cpu_to_le16(l2cap_pi(sk)->dcid);
495 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
496 l2cap_send_cmd(conn, l2cap_get_ident(conn),
497 L2CAP_DISCONN_REQ, sizeof(req), &req);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300498
499 sk->sk_state = BT_DISCONN;
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -0300500 sk->sk_err = err;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300501}
502
Linus Torvalds1da177e2005-04-16 15:20:36 -0700503/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200504static void l2cap_conn_start(struct l2cap_conn *conn)
505{
506 struct l2cap_chan_list *l = &conn->chan_list;
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -0300507 struct sock_del_list del, *tmp1, *tmp2;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200508 struct sock *sk;
509
510 BT_DBG("conn %p", conn);
511
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -0300512 INIT_LIST_HEAD(&del.list);
513
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200514 read_lock(&l->lock);
515
516 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
517 bh_lock_sock(sk);
518
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300519 if (sk->sk_type != SOCK_SEQPACKET &&
520 sk->sk_type != SOCK_STREAM) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200521 bh_unlock_sock(sk);
522 continue;
523 }
524
525 if (sk->sk_state == BT_CONNECT) {
Gustavo F. Padovan47731de2010-07-09 16:38:35 -0300526 struct l2cap_conn_req req;
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -0300527
Gustavo F. Padovan47731de2010-07-09 16:38:35 -0300528 if (!l2cap_check_security(sk) ||
529 !__l2cap_no_conn_pending(sk)) {
530 bh_unlock_sock(sk);
531 continue;
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200532 }
Gustavo F. Padovan47731de2010-07-09 16:38:35 -0300533
534 if (!l2cap_mode_supported(l2cap_pi(sk)->mode,
535 conn->feat_mask)
536 && l2cap_pi(sk)->conf_state &
537 L2CAP_CONF_STATE2_DEVICE) {
538 tmp1 = kzalloc(sizeof(struct sock_del_list),
539 GFP_ATOMIC);
540 tmp1->sk = sk;
541 list_add_tail(&tmp1->list, &del.list);
542 bh_unlock_sock(sk);
543 continue;
544 }
545
546 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
547 req.psm = l2cap_pi(sk)->psm;
548
549 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
550 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
551
552 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
553 L2CAP_CONN_REQ, sizeof(req), &req);
554
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200555 } else if (sk->sk_state == BT_CONNECT2) {
556 struct l2cap_conn_rsp rsp;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -0300557 char buf[128];
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200558 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
559 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
560
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100561 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100562 if (bt_sk(sk)->defer_setup) {
563 struct sock *parent = bt_sk(sk)->parent;
564 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
565 rsp.status = cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
566 parent->sk_data_ready(parent, 0);
567
568 } else {
569 sk->sk_state = BT_CONFIG;
570 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
571 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
572 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200573 } else {
574 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
575 rsp.status = cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
576 }
577
578 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
579 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -0300580
581 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT ||
582 rsp.result != L2CAP_CR_SUCCESS) {
583 bh_unlock_sock(sk);
584 continue;
585 }
586
587 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
588 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
589 l2cap_build_conf_req(sk, buf), buf);
590 l2cap_pi(sk)->num_conf_req++;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200591 }
592
593 bh_unlock_sock(sk);
594 }
595
596 read_unlock(&l->lock);
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -0300597
598 list_for_each_entry_safe(tmp1, tmp2, &del.list, list) {
599 bh_lock_sock(tmp1->sk);
600 __l2cap_sock_close(tmp1->sk, ECONNRESET);
601 bh_unlock_sock(tmp1->sk);
602 list_del(&tmp1->list);
603 kfree(tmp1);
604 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200605}
606
607static void l2cap_conn_ready(struct l2cap_conn *conn)
608{
609 struct l2cap_chan_list *l = &conn->chan_list;
610 struct sock *sk;
611
612 BT_DBG("conn %p", conn);
613
614 read_lock(&l->lock);
615
616 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
617 bh_lock_sock(sk);
618
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300619 if (sk->sk_type != SOCK_SEQPACKET &&
620 sk->sk_type != SOCK_STREAM) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200621 l2cap_sock_clear_timer(sk);
622 sk->sk_state = BT_CONNECTED;
623 sk->sk_state_change(sk);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200624 } else if (sk->sk_state == BT_CONNECT)
625 l2cap_do_start(sk);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200626
627 bh_unlock_sock(sk);
628 }
629
630 read_unlock(&l->lock);
631}
632
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200633/* Notify sockets that we cannot guaranty reliability anymore */
634static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
635{
636 struct l2cap_chan_list *l = &conn->chan_list;
637 struct sock *sk;
638
639 BT_DBG("conn %p", conn);
640
641 read_lock(&l->lock);
642
643 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100644 if (l2cap_pi(sk)->force_reliable)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200645 sk->sk_err = err;
646 }
647
648 read_unlock(&l->lock);
649}
650
651static void l2cap_info_timeout(unsigned long arg)
652{
653 struct l2cap_conn *conn = (void *) arg;
654
Marcel Holtmann984947d2009-02-06 23:35:19 +0100655 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +0100656 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +0100657
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200658 l2cap_conn_start(conn);
659}
660
Linus Torvalds1da177e2005-04-16 15:20:36 -0700661static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
662{
Marcel Holtmann01394182006-07-03 10:02:46 +0200663 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700664
Marcel Holtmann01394182006-07-03 10:02:46 +0200665 if (conn || status)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700666 return conn;
667
Marcel Holtmann01394182006-07-03 10:02:46 +0200668 conn = kzalloc(sizeof(struct l2cap_conn), GFP_ATOMIC);
669 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700670 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700671
672 hcon->l2cap_data = conn;
673 conn->hcon = hcon;
674
Marcel Holtmann01394182006-07-03 10:02:46 +0200675 BT_DBG("hcon %p conn %p", hcon, conn);
676
Linus Torvalds1da177e2005-04-16 15:20:36 -0700677 conn->mtu = hcon->hdev->acl_mtu;
678 conn->src = &hcon->hdev->bdaddr;
679 conn->dst = &hcon->dst;
680
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200681 conn->feat_mask = 0;
682
Linus Torvalds1da177e2005-04-16 15:20:36 -0700683 spin_lock_init(&conn->lock);
684 rwlock_init(&conn->chan_list.lock);
685
Dave Young45054dc2009-10-18 20:28:30 +0000686 setup_timer(&conn->info_timer, l2cap_info_timeout,
687 (unsigned long) conn);
688
Marcel Holtmann2950f212009-02-12 14:02:50 +0100689 conn->disc_reason = 0x13;
690
Linus Torvalds1da177e2005-04-16 15:20:36 -0700691 return conn;
692}
693
Marcel Holtmann01394182006-07-03 10:02:46 +0200694static void l2cap_conn_del(struct hci_conn *hcon, int err)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700695{
Marcel Holtmann01394182006-07-03 10:02:46 +0200696 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700697 struct sock *sk;
698
Marcel Holtmann01394182006-07-03 10:02:46 +0200699 if (!conn)
700 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700701
702 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
703
Wei Yongjun7585b972009-02-25 18:29:52 +0800704 kfree_skb(conn->rx_skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700705
706 /* Kill channels */
707 while ((sk = conn->chan_list.head)) {
708 bh_lock_sock(sk);
709 l2cap_chan_del(sk, err);
710 bh_unlock_sock(sk);
711 l2cap_sock_kill(sk);
712 }
713
Dave Young8e8440f2008-03-03 12:18:55 -0800714 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
715 del_timer_sync(&conn->info_timer);
Thomas Gleixner3ab22732008-02-26 17:42:56 -0800716
Linus Torvalds1da177e2005-04-16 15:20:36 -0700717 hcon->l2cap_data = NULL;
718 kfree(conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700719}
720
721static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
722{
723 struct l2cap_chan_list *l = &conn->chan_list;
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200724 write_lock_bh(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700725 __l2cap_chan_add(conn, sk, parent);
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200726 write_unlock_bh(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700727}
728
Linus Torvalds1da177e2005-04-16 15:20:36 -0700729/* ---- Socket interface ---- */
Al Viro8e036fc2007-07-29 00:16:36 -0700730static struct sock *__l2cap_get_sock_by_addr(__le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700731{
732 struct sock *sk;
733 struct hlist_node *node;
734 sk_for_each(sk, node, &l2cap_sk_list.head)
735 if (l2cap_pi(sk)->sport == psm && !bacmp(&bt_sk(sk)->src, src))
736 goto found;
737 sk = NULL;
738found:
739 return sk;
740}
741
742/* Find socket with psm and source bdaddr.
743 * Returns closest match.
744 */
Al Viro8e036fc2007-07-29 00:16:36 -0700745static struct sock *__l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700746{
747 struct sock *sk = NULL, *sk1 = NULL;
748 struct hlist_node *node;
749
750 sk_for_each(sk, node, &l2cap_sk_list.head) {
751 if (state && sk->sk_state != state)
752 continue;
753
754 if (l2cap_pi(sk)->psm == psm) {
755 /* Exact match. */
756 if (!bacmp(&bt_sk(sk)->src, src))
757 break;
758
759 /* Closest match */
760 if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY))
761 sk1 = sk;
762 }
763 }
764 return node ? sk : sk1;
765}
766
767/* Find socket with given address (psm, src).
768 * Returns locked socket */
Al Viro8e036fc2007-07-29 00:16:36 -0700769static inline struct sock *l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700770{
771 struct sock *s;
772 read_lock(&l2cap_sk_list.lock);
773 s = __l2cap_get_sock_by_psm(state, psm, src);
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -0300774 if (s)
775 bh_lock_sock(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700776 read_unlock(&l2cap_sk_list.lock);
777 return s;
778}
779
780static void l2cap_sock_destruct(struct sock *sk)
781{
782 BT_DBG("sk %p", sk);
783
784 skb_queue_purge(&sk->sk_receive_queue);
785 skb_queue_purge(&sk->sk_write_queue);
786}
787
788static void l2cap_sock_cleanup_listen(struct sock *parent)
789{
790 struct sock *sk;
791
792 BT_DBG("parent %p", parent);
793
794 /* Close not yet accepted channels */
795 while ((sk = bt_accept_dequeue(parent, NULL)))
796 l2cap_sock_close(sk);
797
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200798 parent->sk_state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700799 sock_set_flag(parent, SOCK_ZAPPED);
800}
801
802/* Kill socket (only if zapped and orphan)
803 * Must be called on unlocked socket.
804 */
805static void l2cap_sock_kill(struct sock *sk)
806{
807 if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket)
808 return;
809
810 BT_DBG("sk %p state %d", sk, sk->sk_state);
811
812 /* Kill poor orphan */
813 bt_sock_unlink(&l2cap_sk_list, sk);
814 sock_set_flag(sk, SOCK_DEAD);
815 sock_put(sk);
816}
817
818static void __l2cap_sock_close(struct sock *sk, int reason)
819{
820 BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket);
821
822 switch (sk->sk_state) {
823 case BT_LISTEN:
824 l2cap_sock_cleanup_listen(sk);
825 break;
826
827 case BT_CONNECTED:
828 case BT_CONFIG:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300829 if (sk->sk_type == SOCK_SEQPACKET ||
830 sk->sk_type == SOCK_STREAM) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700831 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700832
Linus Torvalds1da177e2005-04-16 15:20:36 -0700833 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -0300834 l2cap_send_disconn_req(conn, sk, reason);
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200835 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -0700836 l2cap_chan_del(sk, reason);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700837 break;
838
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100839 case BT_CONNECT2:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300840 if (sk->sk_type == SOCK_SEQPACKET ||
841 sk->sk_type == SOCK_STREAM) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100842 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
843 struct l2cap_conn_rsp rsp;
844 __u16 result;
845
846 if (bt_sk(sk)->defer_setup)
847 result = L2CAP_CR_SEC_BLOCK;
848 else
849 result = L2CAP_CR_BAD_PSM;
850
851 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
852 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
853 rsp.result = cpu_to_le16(result);
854 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
855 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
856 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
857 } else
858 l2cap_chan_del(sk, reason);
859 break;
860
Linus Torvalds1da177e2005-04-16 15:20:36 -0700861 case BT_CONNECT:
862 case BT_DISCONN:
863 l2cap_chan_del(sk, reason);
864 break;
865
866 default:
867 sock_set_flag(sk, SOCK_ZAPPED);
868 break;
869 }
870}
871
872/* Must be called on unlocked socket. */
873static void l2cap_sock_close(struct sock *sk)
874{
875 l2cap_sock_clear_timer(sk);
876 lock_sock(sk);
877 __l2cap_sock_close(sk, ECONNRESET);
878 release_sock(sk);
879 l2cap_sock_kill(sk);
880}
881
882static void l2cap_sock_init(struct sock *sk, struct sock *parent)
883{
884 struct l2cap_pinfo *pi = l2cap_pi(sk);
885
886 BT_DBG("sk %p", sk);
887
888 if (parent) {
889 sk->sk_type = parent->sk_type;
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100890 bt_sk(sk)->defer_setup = bt_sk(parent)->defer_setup;
891
Linus Torvalds1da177e2005-04-16 15:20:36 -0700892 pi->imtu = l2cap_pi(parent)->imtu;
893 pi->omtu = l2cap_pi(parent)->omtu;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -0300894 pi->conf_state = l2cap_pi(parent)->conf_state;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -0700895 pi->mode = l2cap_pi(parent)->mode;
896 pi->fcs = l2cap_pi(parent)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -0300897 pi->max_tx = l2cap_pi(parent)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -0300898 pi->tx_win = l2cap_pi(parent)->tx_win;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100899 pi->sec_level = l2cap_pi(parent)->sec_level;
900 pi->role_switch = l2cap_pi(parent)->role_switch;
901 pi->force_reliable = l2cap_pi(parent)->force_reliable;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700902 } else {
903 pi->imtu = L2CAP_DEFAULT_MTU;
904 pi->omtu = 0;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -0300905 if (enable_ertm && sk->sk_type == SOCK_STREAM) {
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300906 pi->mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -0300907 pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
908 } else {
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300909 pi->mode = L2CAP_MODE_BASIC;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -0300910 }
Gustavo F. Padovanfd059b92010-05-10 14:22:56 -0300911 pi->max_tx = L2CAP_DEFAULT_MAX_TX;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -0700912 pi->fcs = L2CAP_FCS_CRC16;
Gustavo F. Padovanfd059b92010-05-10 14:22:56 -0300913 pi->tx_win = L2CAP_DEFAULT_TX_WINDOW;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100914 pi->sec_level = BT_SECURITY_LOW;
915 pi->role_switch = 0;
916 pi->force_reliable = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700917 }
918
919 /* Default config options */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +0200920 pi->conf_len = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700921 pi->flush_to = L2CAP_DEFAULT_FLUSH_TO;
Dave Young45054dc2009-10-18 20:28:30 +0000922 skb_queue_head_init(TX_QUEUE(sk));
923 skb_queue_head_init(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -0300924 skb_queue_head_init(BUSY_QUEUE(sk));
Dave Young45054dc2009-10-18 20:28:30 +0000925 INIT_LIST_HEAD(SREJ_LIST(sk));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700926}
927
928static struct proto l2cap_proto = {
929 .name = "L2CAP",
930 .owner = THIS_MODULE,
931 .obj_size = sizeof(struct l2cap_pinfo)
932};
933
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700934static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700935{
936 struct sock *sk;
937
Pavel Emelyanov6257ff22007-11-01 00:39:31 -0700938 sk = sk_alloc(net, PF_BLUETOOTH, prio, &l2cap_proto);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700939 if (!sk)
940 return NULL;
941
942 sock_init_data(sock, sk);
943 INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
944
945 sk->sk_destruct = l2cap_sock_destruct;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200946 sk->sk_sndtimeo = msecs_to_jiffies(L2CAP_CONN_TIMEOUT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700947
948 sock_reset_flag(sk, SOCK_ZAPPED);
949
950 sk->sk_protocol = proto;
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200951 sk->sk_state = BT_OPEN;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700952
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200953 setup_timer(&sk->sk_timer, l2cap_sock_timeout, (unsigned long) sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700954
955 bt_sock_link(&l2cap_sk_list, sk);
956 return sk;
957}
958
Eric Paris3f378b62009-11-05 22:18:14 -0800959static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol,
960 int kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700961{
962 struct sock *sk;
963
964 BT_DBG("sock %p", sock);
965
966 sock->state = SS_UNCONNECTED;
967
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300968 if (sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM &&
Linus Torvalds1da177e2005-04-16 15:20:36 -0700969 sock->type != SOCK_DGRAM && sock->type != SOCK_RAW)
970 return -ESOCKTNOSUPPORT;
971
Eric Parisc84b3262009-11-05 20:45:52 -0800972 if (sock->type == SOCK_RAW && !kern && !capable(CAP_NET_RAW))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700973 return -EPERM;
974
975 sock->ops = &l2cap_sock_ops;
976
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700977 sk = l2cap_sock_alloc(net, sock, protocol, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700978 if (!sk)
979 return -ENOMEM;
980
981 l2cap_sock_init(sk, NULL);
982 return 0;
983}
984
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100985static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700986{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700987 struct sock *sk = sock->sk;
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100988 struct sockaddr_l2 la;
989 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700990
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100991 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700992
993 if (!addr || addr->sa_family != AF_BLUETOOTH)
994 return -EINVAL;
995
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100996 memset(&la, 0, sizeof(la));
997 len = min_t(unsigned int, sizeof(la), alen);
998 memcpy(&la, addr, len);
999
Marcel Holtmann2a517ca2009-02-16 03:20:31 +01001000 if (la.l2_cid)
1001 return -EINVAL;
1002
Linus Torvalds1da177e2005-04-16 15:20:36 -07001003 lock_sock(sk);
1004
1005 if (sk->sk_state != BT_OPEN) {
1006 err = -EBADFD;
1007 goto done;
1008 }
1009
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001010 if (la.l2_psm && __le16_to_cpu(la.l2_psm) < 0x1001 &&
Marcel Holtmann847641d2007-01-22 22:00:45 +01001011 !capable(CAP_NET_BIND_SERVICE)) {
1012 err = -EACCES;
1013 goto done;
1014 }
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001015
Linus Torvalds1da177e2005-04-16 15:20:36 -07001016 write_lock_bh(&l2cap_sk_list.lock);
1017
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001018 if (la.l2_psm && __l2cap_get_sock_by_addr(la.l2_psm, &la.l2_bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001019 err = -EADDRINUSE;
1020 } else {
1021 /* Save source address */
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001022 bacpy(&bt_sk(sk)->src, &la.l2_bdaddr);
1023 l2cap_pi(sk)->psm = la.l2_psm;
1024 l2cap_pi(sk)->sport = la.l2_psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001025 sk->sk_state = BT_BOUND;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001026
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001027 if (__le16_to_cpu(la.l2_psm) == 0x0001 ||
1028 __le16_to_cpu(la.l2_psm) == 0x0003)
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001029 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001030 }
1031
1032 write_unlock_bh(&l2cap_sk_list.lock);
1033
1034done:
1035 release_sock(sk);
1036 return err;
1037}
1038
1039static int l2cap_do_connect(struct sock *sk)
1040{
1041 bdaddr_t *src = &bt_sk(sk)->src;
1042 bdaddr_t *dst = &bt_sk(sk)->dst;
1043 struct l2cap_conn *conn;
1044 struct hci_conn *hcon;
1045 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001046 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +02001047 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001048
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001049 BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst),
1050 l2cap_pi(sk)->psm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001051
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03001052 hdev = hci_get_route(dst, src);
1053 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001054 return -EHOSTUNREACH;
1055
1056 hci_dev_lock_bh(hdev);
1057
1058 err = -ENOMEM;
1059
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001060 if (sk->sk_type == SOCK_RAW) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001061 switch (l2cap_pi(sk)->sec_level) {
1062 case BT_SECURITY_HIGH:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001063 auth_type = HCI_AT_DEDICATED_BONDING_MITM;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001064 break;
1065 case BT_SECURITY_MEDIUM:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001066 auth_type = HCI_AT_DEDICATED_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001067 break;
1068 default:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001069 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001070 break;
1071 }
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001072 } else if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001073 if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001074 auth_type = HCI_AT_NO_BONDING_MITM;
1075 else
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001076 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann435fef22009-02-09 03:55:28 +01001077
1078 if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW)
1079 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001080 } else {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001081 switch (l2cap_pi(sk)->sec_level) {
1082 case BT_SECURITY_HIGH:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001083 auth_type = HCI_AT_GENERAL_BONDING_MITM;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001084 break;
1085 case BT_SECURITY_MEDIUM:
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001086 auth_type = HCI_AT_GENERAL_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001087 break;
1088 default:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001089 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001090 break;
1091 }
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001092 }
1093
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001094 hcon = hci_connect(hdev, ACL_LINK, dst,
1095 l2cap_pi(sk)->sec_level, auth_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001096 if (!hcon)
1097 goto done;
1098
1099 conn = l2cap_conn_add(hcon, 0);
1100 if (!conn) {
1101 hci_conn_put(hcon);
1102 goto done;
1103 }
1104
1105 err = 0;
1106
1107 /* Update source addr of the socket */
1108 bacpy(src, conn->src);
1109
1110 l2cap_chan_add(conn, sk, NULL);
1111
1112 sk->sk_state = BT_CONNECT;
1113 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
1114
1115 if (hcon->state == BT_CONNECTED) {
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001116 if (sk->sk_type != SOCK_SEQPACKET &&
1117 sk->sk_type != SOCK_STREAM) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001118 l2cap_sock_clear_timer(sk);
1119 sk->sk_state = BT_CONNECTED;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001120 } else
1121 l2cap_do_start(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001122 }
1123
1124done:
1125 hci_dev_unlock_bh(hdev);
1126 hci_dev_put(hdev);
1127 return err;
1128}
1129
1130static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
1131{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001132 struct sock *sk = sock->sk;
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001133 struct sockaddr_l2 la;
1134 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001135
Linus Torvalds1da177e2005-04-16 15:20:36 -07001136 BT_DBG("sk %p", sk);
1137
Changli Gao6503d962010-03-31 22:58:26 +00001138 if (!addr || alen < sizeof(addr->sa_family) ||
1139 addr->sa_family != AF_BLUETOOTH)
Marcel Holtmann2a517ca2009-02-16 03:20:31 +01001140 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001141
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001142 memset(&la, 0, sizeof(la));
1143 len = min_t(unsigned int, sizeof(la), alen);
1144 memcpy(&la, addr, len);
1145
Marcel Holtmann2a517ca2009-02-16 03:20:31 +01001146 if (la.l2_cid)
1147 return -EINVAL;
1148
1149 lock_sock(sk);
1150
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001151 if ((sk->sk_type == SOCK_SEQPACKET || sk->sk_type == SOCK_STREAM)
1152 && !la.l2_psm) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001153 err = -EINVAL;
1154 goto done;
1155 }
1156
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001157 switch (l2cap_pi(sk)->mode) {
1158 case L2CAP_MODE_BASIC:
1159 break;
1160 case L2CAP_MODE_ERTM:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001161 case L2CAP_MODE_STREAMING:
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001162 if (enable_ertm)
1163 break;
1164 /* fall through */
1165 default:
1166 err = -ENOTSUPP;
1167 goto done;
1168 }
1169
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03001170 switch (sk->sk_state) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001171 case BT_CONNECT:
1172 case BT_CONNECT2:
1173 case BT_CONFIG:
1174 /* Already connecting */
1175 goto wait;
1176
1177 case BT_CONNECTED:
1178 /* Already connected */
João Paulo Rechi Vita8b0dc6d2010-06-22 13:56:22 -03001179 err = -EISCONN;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001180 goto done;
1181
1182 case BT_OPEN:
1183 case BT_BOUND:
1184 /* Can connect */
1185 break;
1186
1187 default:
1188 err = -EBADFD;
1189 goto done;
1190 }
1191
1192 /* Set destination address and psm */
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001193 bacpy(&bt_sk(sk)->dst, &la.l2_bdaddr);
1194 l2cap_pi(sk)->psm = la.l2_psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001195
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03001196 err = l2cap_do_connect(sk);
1197 if (err)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001198 goto done;
1199
1200wait:
1201 err = bt_sock_wait_state(sk, BT_CONNECTED,
1202 sock_sndtimeo(sk, flags & O_NONBLOCK));
1203done:
1204 release_sock(sk);
1205 return err;
1206}
1207
1208static int l2cap_sock_listen(struct socket *sock, int backlog)
1209{
1210 struct sock *sk = sock->sk;
1211 int err = 0;
1212
1213 BT_DBG("sk %p backlog %d", sk, backlog);
1214
1215 lock_sock(sk);
1216
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001217 if ((sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM)
1218 || sk->sk_state != BT_BOUND) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001219 err = -EBADFD;
1220 goto done;
1221 }
1222
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001223 switch (l2cap_pi(sk)->mode) {
1224 case L2CAP_MODE_BASIC:
1225 break;
1226 case L2CAP_MODE_ERTM:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001227 case L2CAP_MODE_STREAMING:
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001228 if (enable_ertm)
1229 break;
1230 /* fall through */
1231 default:
1232 err = -ENOTSUPP;
1233 goto done;
1234 }
1235
Linus Torvalds1da177e2005-04-16 15:20:36 -07001236 if (!l2cap_pi(sk)->psm) {
1237 bdaddr_t *src = &bt_sk(sk)->src;
1238 u16 psm;
1239
1240 err = -EINVAL;
1241
1242 write_lock_bh(&l2cap_sk_list.lock);
1243
1244 for (psm = 0x1001; psm < 0x1100; psm += 2)
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001245 if (!__l2cap_get_sock_by_addr(cpu_to_le16(psm), src)) {
1246 l2cap_pi(sk)->psm = cpu_to_le16(psm);
1247 l2cap_pi(sk)->sport = cpu_to_le16(psm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001248 err = 0;
1249 break;
1250 }
1251
1252 write_unlock_bh(&l2cap_sk_list.lock);
1253
1254 if (err < 0)
1255 goto done;
1256 }
1257
1258 sk->sk_max_ack_backlog = backlog;
1259 sk->sk_ack_backlog = 0;
1260 sk->sk_state = BT_LISTEN;
1261
1262done:
1263 release_sock(sk);
1264 return err;
1265}
1266
1267static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int flags)
1268{
1269 DECLARE_WAITQUEUE(wait, current);
1270 struct sock *sk = sock->sk, *nsk;
1271 long timeo;
1272 int err = 0;
1273
Peter Zijlstrafcc70d52006-11-08 22:44:35 -08001274 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001275
1276 if (sk->sk_state != BT_LISTEN) {
1277 err = -EBADFD;
1278 goto done;
1279 }
1280
1281 timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
1282
1283 BT_DBG("sk %p timeo %ld", sk, timeo);
1284
1285 /* Wait for an incoming connection. (wake-one). */
Eric Dumazetaa395142010-04-20 13:03:51 +00001286 add_wait_queue_exclusive(sk_sleep(sk), &wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001287 while (!(nsk = bt_accept_dequeue(sk, newsock))) {
1288 set_current_state(TASK_INTERRUPTIBLE);
1289 if (!timeo) {
1290 err = -EAGAIN;
1291 break;
1292 }
1293
1294 release_sock(sk);
1295 timeo = schedule_timeout(timeo);
Peter Zijlstrafcc70d52006-11-08 22:44:35 -08001296 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001297
1298 if (sk->sk_state != BT_LISTEN) {
1299 err = -EBADFD;
1300 break;
1301 }
1302
1303 if (signal_pending(current)) {
1304 err = sock_intr_errno(timeo);
1305 break;
1306 }
1307 }
1308 set_current_state(TASK_RUNNING);
Eric Dumazetaa395142010-04-20 13:03:51 +00001309 remove_wait_queue(sk_sleep(sk), &wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001310
1311 if (err)
1312 goto done;
1313
1314 newsock->state = SS_CONNECTED;
1315
1316 BT_DBG("new socket %p", nsk);
1317
1318done:
1319 release_sock(sk);
1320 return err;
1321}
1322
1323static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
1324{
1325 struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
1326 struct sock *sk = sock->sk;
1327
1328 BT_DBG("sock %p, sk %p", sock, sk);
1329
1330 addr->sa_family = AF_BLUETOOTH;
1331 *len = sizeof(struct sockaddr_l2);
1332
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001333 if (peer) {
1334 la->l2_psm = l2cap_pi(sk)->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001335 bacpy(&la->l2_bdaddr, &bt_sk(sk)->dst);
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001336 la->l2_cid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001337 } else {
1338 la->l2_psm = l2cap_pi(sk)->sport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001339 bacpy(&la->l2_bdaddr, &bt_sk(sk)->src);
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001340 la->l2_cid = cpu_to_le16(l2cap_pi(sk)->scid);
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001341 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001342
Linus Torvalds1da177e2005-04-16 15:20:36 -07001343 return 0;
1344}
1345
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001346static int __l2cap_wait_ack(struct sock *sk)
1347{
1348 DECLARE_WAITQUEUE(wait, current);
1349 int err = 0;
1350 int timeo = HZ/5;
1351
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001352 add_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001353 while ((l2cap_pi(sk)->unacked_frames > 0 && l2cap_pi(sk)->conn)) {
1354 set_current_state(TASK_INTERRUPTIBLE);
1355
1356 if (!timeo)
1357 timeo = HZ/5;
1358
1359 if (signal_pending(current)) {
1360 err = sock_intr_errno(timeo);
1361 break;
1362 }
1363
1364 release_sock(sk);
1365 timeo = schedule_timeout(timeo);
1366 lock_sock(sk);
1367
1368 err = sock_error(sk);
1369 if (err)
1370 break;
1371 }
1372 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001373 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001374 return err;
1375}
1376
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001377static void l2cap_monitor_timeout(unsigned long arg)
1378{
1379 struct sock *sk = (void *) arg;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001380
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001381 BT_DBG("sk %p", sk);
1382
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001383 bh_lock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001384 if (l2cap_pi(sk)->retry_count >= l2cap_pi(sk)->remote_max_tx) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03001385 l2cap_send_disconn_req(l2cap_pi(sk)->conn, sk, ECONNABORTED);
Andrei Emeltchenkob13f5862009-12-15 11:38:04 +02001386 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001387 return;
1388 }
1389
1390 l2cap_pi(sk)->retry_count++;
1391 __mod_monitor_timer();
1392
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -03001393 l2cap_send_rr_or_rnr(l2cap_pi(sk), L2CAP_CTRL_POLL);
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001394 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001395}
1396
1397static void l2cap_retrans_timeout(unsigned long arg)
1398{
1399 struct sock *sk = (void *) arg;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001400
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001401 BT_DBG("sk %p", sk);
1402
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001403 bh_lock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001404 l2cap_pi(sk)->retry_count = 1;
1405 __mod_monitor_timer();
1406
1407 l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
1408
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -03001409 l2cap_send_rr_or_rnr(l2cap_pi(sk), L2CAP_CTRL_POLL);
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001410 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001411}
1412
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001413static void l2cap_drop_acked_frames(struct sock *sk)
1414{
1415 struct sk_buff *skb;
1416
Gustavo F. Padovan812e7372010-05-01 16:15:42 -03001417 while ((skb = skb_peek(TX_QUEUE(sk))) &&
1418 l2cap_pi(sk)->unacked_frames) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001419 if (bt_cb(skb)->tx_seq == l2cap_pi(sk)->expected_ack_seq)
1420 break;
1421
1422 skb = skb_dequeue(TX_QUEUE(sk));
1423 kfree_skb(skb);
1424
1425 l2cap_pi(sk)->unacked_frames--;
1426 }
1427
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001428 if (!l2cap_pi(sk)->unacked_frames)
1429 del_timer(&l2cap_pi(sk)->retrans_timer);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001430}
1431
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001432static inline void l2cap_do_send(struct sock *sk, struct sk_buff *skb)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001433{
1434 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001435
1436 BT_DBG("sk %p, skb %p len %d", sk, skb, skb->len);
1437
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001438 hci_send_acl(pi->conn->hcon, skb, 0);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001439}
1440
João Paulo Rechi Vita305682e2010-06-22 13:56:23 -03001441static void l2cap_streaming_send(struct sock *sk)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001442{
1443 struct sk_buff *skb, *tx_skb;
1444 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001445 u16 control, fcs;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001446
1447 while ((skb = sk->sk_send_head)) {
1448 tx_skb = skb_clone(skb, GFP_ATOMIC);
1449
1450 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
1451 control |= pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT;
1452 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1453
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001454 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001455 fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
1456 put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
1457 }
1458
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001459 l2cap_do_send(sk, tx_skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001460
1461 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
1462
1463 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1464 sk->sk_send_head = NULL;
1465 else
1466 sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
1467
1468 skb = skb_dequeue(TX_QUEUE(sk));
1469 kfree_skb(skb);
1470 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001471}
1472
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001473static void l2cap_retransmit_one_frame(struct sock *sk, u8 tx_seq)
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001474{
1475 struct l2cap_pinfo *pi = l2cap_pi(sk);
1476 struct sk_buff *skb, *tx_skb;
1477 u16 control, fcs;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001478
1479 skb = skb_peek(TX_QUEUE(sk));
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001480 if (!skb)
1481 return;
1482
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001483 do {
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001484 if (bt_cb(skb)->tx_seq == tx_seq)
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001485 break;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001486
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001487 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1488 return;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001489
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001490 } while ((skb = skb_queue_next(TX_QUEUE(sk), skb)));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001491
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001492 if (pi->remote_max_tx &&
1493 bt_cb(skb)->retries == pi->remote_max_tx) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03001494 l2cap_send_disconn_req(pi->conn, sk, ECONNABORTED);
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001495 return;
1496 }
1497
1498 tx_skb = skb_clone(skb, GFP_ATOMIC);
1499 bt_cb(skb)->retries++;
1500 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03001501
1502 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
1503 control |= L2CAP_CTRL_FINAL;
1504 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
1505 }
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03001506
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001507 control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
1508 | (tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03001509
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001510 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1511
1512 if (pi->fcs == L2CAP_FCS_CRC16) {
1513 fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
1514 put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
1515 }
1516
1517 l2cap_do_send(sk, tx_skb);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001518}
1519
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001520static int l2cap_ertm_send(struct sock *sk)
1521{
1522 struct sk_buff *skb, *tx_skb;
1523 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001524 u16 control, fcs;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001525 int nsent = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001526
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001527 if (sk->sk_state != BT_CONNECTED)
1528 return -ENOTCONN;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001529
Gustavo F. Padovan6e2b6722010-06-01 18:52:58 -03001530 while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(sk))) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001531
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001532 if (pi->remote_max_tx &&
1533 bt_cb(skb)->retries == pi->remote_max_tx) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03001534 l2cap_send_disconn_req(pi->conn, sk, ECONNABORTED);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001535 break;
1536 }
1537
Andrei Emeltchenkoe420aba2009-12-23 13:07:14 +02001538 tx_skb = skb_clone(skb, GFP_ATOMIC);
1539
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001540 bt_cb(skb)->retries++;
1541
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001542 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03001543 control &= L2CAP_CTRL_SAR;
1544
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001545 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
1546 control |= L2CAP_CTRL_FINAL;
1547 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
1548 }
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03001549 control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001550 | (pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
1551 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1552
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001553
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001554 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001555 fcs = crc16(0, (u8 *)skb->data, tx_skb->len - 2);
1556 put_unaligned_le16(fcs, skb->data + tx_skb->len - 2);
1557 }
1558
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001559 l2cap_do_send(sk, tx_skb);
1560
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001561 __mod_retrans_timer();
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001562
1563 bt_cb(skb)->tx_seq = pi->next_tx_seq;
1564 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
1565
1566 pi->unacked_frames++;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001567 pi->frames_sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001568
1569 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1570 sk->sk_send_head = NULL;
1571 else
1572 sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001573
1574 nsent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001575 }
1576
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001577 return nsent;
1578}
1579
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001580static int l2cap_retransmit_frames(struct sock *sk)
1581{
1582 struct l2cap_pinfo *pi = l2cap_pi(sk);
1583 int ret;
1584
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001585 if (!skb_queue_empty(TX_QUEUE(sk)))
1586 sk->sk_send_head = TX_QUEUE(sk)->next;
1587
1588 pi->next_tx_seq = pi->expected_ack_seq;
1589 ret = l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001590 return ret;
1591}
1592
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001593static void l2cap_send_ack(struct l2cap_pinfo *pi)
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001594{
1595 struct sock *sk = (struct sock *)pi;
1596 u16 control = 0;
1597
1598 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1599
1600 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
1601 control |= L2CAP_SUPER_RCV_NOT_READY;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03001602 pi->conn_state |= L2CAP_CONN_RNR_SENT;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001603 l2cap_send_sframe(pi, control);
1604 return;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001605 }
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001606
Gustavo F. Padovane0f66212010-06-21 18:50:49 -03001607 if (l2cap_ertm_send(sk) > 0)
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001608 return;
1609
1610 control |= L2CAP_SUPER_RCV_READY;
1611 l2cap_send_sframe(pi, control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001612}
1613
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001614static void l2cap_send_srejtail(struct sock *sk)
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03001615{
1616 struct srej_list *tail;
1617 u16 control;
1618
1619 control = L2CAP_SUPER_SELECT_REJECT;
1620 control |= L2CAP_CTRL_FINAL;
1621
1622 tail = list_entry(SREJ_LIST(sk)->prev, struct srej_list, list);
1623 control |= tail->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1624
1625 l2cap_send_sframe(l2cap_pi(sk), control);
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03001626}
1627
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001628static 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 -07001629{
1630 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001631 struct sk_buff **frag;
1632 int err, sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001633
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03001634 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001635 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001636
1637 sent += count;
1638 len -= count;
1639
1640 /* Continuation fragments (no L2CAP header) */
1641 frag = &skb_shinfo(skb)->frag_list;
1642 while (len) {
1643 count = min_t(unsigned int, conn->mtu, len);
1644
1645 *frag = bt_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err);
1646 if (!*frag)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001647 return -EFAULT;
1648 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
1649 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001650
1651 sent += count;
1652 len -= count;
1653
1654 frag = &(*frag)->next;
1655 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001656
1657 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001658}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001659
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001660static struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, size_t len)
1661{
1662 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1663 struct sk_buff *skb;
1664 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1665 struct l2cap_hdr *lh;
1666
1667 BT_DBG("sk %p len %d", sk, (int)len);
1668
1669 count = min_t(unsigned int, (conn->mtu - hlen), len);
1670 skb = bt_skb_send_alloc(sk, count + hlen,
1671 msg->msg_flags & MSG_DONTWAIT, &err);
1672 if (!skb)
1673 return ERR_PTR(-ENOMEM);
1674
1675 /* Create L2CAP header */
1676 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1677 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1678 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1679 put_unaligned_le16(l2cap_pi(sk)->psm, skb_put(skb, 2));
1680
1681 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1682 if (unlikely(err < 0)) {
1683 kfree_skb(skb);
1684 return ERR_PTR(err);
1685 }
1686 return skb;
1687}
1688
1689static struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *msg, size_t len)
1690{
1691 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1692 struct sk_buff *skb;
1693 int err, count, hlen = L2CAP_HDR_SIZE;
1694 struct l2cap_hdr *lh;
1695
1696 BT_DBG("sk %p len %d", sk, (int)len);
1697
1698 count = min_t(unsigned int, (conn->mtu - hlen), len);
1699 skb = bt_skb_send_alloc(sk, count + hlen,
1700 msg->msg_flags & MSG_DONTWAIT, &err);
1701 if (!skb)
1702 return ERR_PTR(-ENOMEM);
1703
1704 /* Create L2CAP header */
1705 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1706 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1707 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1708
1709 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1710 if (unlikely(err < 0)) {
1711 kfree_skb(skb);
1712 return ERR_PTR(err);
1713 }
1714 return skb;
1715}
1716
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001717static struct 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 -03001718{
1719 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1720 struct sk_buff *skb;
1721 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1722 struct l2cap_hdr *lh;
1723
1724 BT_DBG("sk %p len %d", sk, (int)len);
1725
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03001726 if (!conn)
1727 return ERR_PTR(-ENOTCONN);
1728
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001729 if (sdulen)
1730 hlen += 2;
1731
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001732 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1733 hlen += 2;
1734
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001735 count = min_t(unsigned int, (conn->mtu - hlen), len);
1736 skb = bt_skb_send_alloc(sk, count + hlen,
1737 msg->msg_flags & MSG_DONTWAIT, &err);
1738 if (!skb)
1739 return ERR_PTR(-ENOMEM);
1740
1741 /* Create L2CAP header */
1742 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1743 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1744 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1745 put_unaligned_le16(control, skb_put(skb, 2));
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001746 if (sdulen)
1747 put_unaligned_le16(sdulen, skb_put(skb, 2));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001748
1749 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1750 if (unlikely(err < 0)) {
1751 kfree_skb(skb);
1752 return ERR_PTR(err);
1753 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001754
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001755 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1756 put_unaligned_le16(0, skb_put(skb, 2));
1757
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001758 bt_cb(skb)->retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001759 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001760}
1761
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001762static inline int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len)
1763{
1764 struct l2cap_pinfo *pi = l2cap_pi(sk);
1765 struct sk_buff *skb;
1766 struct sk_buff_head sar_queue;
1767 u16 control;
1768 size_t size = 0;
1769
Gustavo F. Padovanff12fd62010-05-05 22:09:15 -03001770 skb_queue_head_init(&sar_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001771 control = L2CAP_SDU_START;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001772 skb = l2cap_create_iframe_pdu(sk, msg, pi->remote_mps, control, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001773 if (IS_ERR(skb))
1774 return PTR_ERR(skb);
1775
1776 __skb_queue_tail(&sar_queue, skb);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001777 len -= pi->remote_mps;
1778 size += pi->remote_mps;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001779
1780 while (len > 0) {
1781 size_t buflen;
1782
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001783 if (len > pi->remote_mps) {
Gustavo F. Padovan44651b82010-05-01 16:15:43 -03001784 control = L2CAP_SDU_CONTINUE;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001785 buflen = pi->remote_mps;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001786 } else {
Gustavo F. Padovan44651b82010-05-01 16:15:43 -03001787 control = L2CAP_SDU_END;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001788 buflen = len;
1789 }
1790
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001791 skb = l2cap_create_iframe_pdu(sk, msg, buflen, control, 0);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001792 if (IS_ERR(skb)) {
1793 skb_queue_purge(&sar_queue);
1794 return PTR_ERR(skb);
1795 }
1796
1797 __skb_queue_tail(&sar_queue, skb);
1798 len -= buflen;
1799 size += buflen;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001800 }
1801 skb_queue_splice_tail(&sar_queue, TX_QUEUE(sk));
1802 if (sk->sk_send_head == NULL)
1803 sk->sk_send_head = sar_queue.next;
1804
1805 return size;
1806}
1807
Linus Torvalds1da177e2005-04-16 15:20:36 -07001808static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len)
1809{
1810 struct sock *sk = sock->sk;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001811 struct l2cap_pinfo *pi = l2cap_pi(sk);
1812 struct sk_buff *skb;
1813 u16 control;
1814 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001815
1816 BT_DBG("sock %p, sk %p", sock, sk);
1817
Benjamin LaHaisec1cbe4b2005-12-13 23:22:19 -08001818 err = sock_error(sk);
1819 if (err)
1820 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001821
1822 if (msg->msg_flags & MSG_OOB)
1823 return -EOPNOTSUPP;
1824
Linus Torvalds1da177e2005-04-16 15:20:36 -07001825 lock_sock(sk);
1826
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001827 if (sk->sk_state != BT_CONNECTED) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001828 err = -ENOTCONN;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001829 goto done;
1830 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001831
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001832 /* Connectionless channel */
1833 if (sk->sk_type == SOCK_DGRAM) {
1834 skb = l2cap_create_connless_pdu(sk, msg, len);
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001835 if (IS_ERR(skb)) {
Dan Carpenter477fffb2010-04-21 23:52:01 +00001836 err = PTR_ERR(skb);
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001837 } else {
1838 l2cap_do_send(sk, skb);
1839 err = len;
1840 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001841 goto done;
1842 }
1843
1844 switch (pi->mode) {
1845 case L2CAP_MODE_BASIC:
Gustavo F. Padovanc69163e2010-05-01 16:15:35 -03001846 /* Check outgoing MTU */
1847 if (len > pi->omtu) {
João Paulo Rechi Vitaf9dd11b2010-06-22 13:56:24 -03001848 err = -EMSGSIZE;
Gustavo F. Padovanc69163e2010-05-01 16:15:35 -03001849 goto done;
1850 }
1851
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001852 /* Create a basic PDU */
1853 skb = l2cap_create_basic_pdu(sk, msg, len);
1854 if (IS_ERR(skb)) {
1855 err = PTR_ERR(skb);
1856 goto done;
1857 }
1858
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001859 l2cap_do_send(sk, skb);
1860 err = len;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001861 break;
1862
1863 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001864 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001865 /* Entire SDU fits into one PDU */
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001866 if (len <= pi->remote_mps) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001867 control = L2CAP_SDU_UNSEGMENTED;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001868 skb = l2cap_create_iframe_pdu(sk, msg, len, control, 0);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001869 if (IS_ERR(skb)) {
1870 err = PTR_ERR(skb);
1871 goto done;
1872 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001873 __skb_queue_tail(TX_QUEUE(sk), skb);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001874
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001875 if (sk->sk_send_head == NULL)
1876 sk->sk_send_head = skb;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001877
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001878 } else {
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001879 /* Segment SDU into multiples PDUs */
1880 err = l2cap_sar_segment_sdu(sk, msg, len);
1881 if (err < 0)
1882 goto done;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001883 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001884
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001885 if (pi->mode == L2CAP_MODE_STREAMING) {
João Paulo Rechi Vita305682e2010-06-22 13:56:23 -03001886 l2cap_streaming_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001887 } else {
Gustavo F. Padovan6e2b6722010-06-01 18:52:58 -03001888 if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY &&
1889 pi->conn_state && L2CAP_CONN_WAIT_F) {
1890 err = len;
1891 break;
1892 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001893 err = l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001894 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001895
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001896 if (err >= 0)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001897 err = len;
1898 break;
1899
1900 default:
1901 BT_DBG("bad state %1.1x", pi->mode);
João Paulo Rechi Vitabc766db22010-06-22 13:56:25 -03001902 err = -EBADFD;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001903 }
1904
1905done:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001906 release_sock(sk);
1907 return err;
1908}
1909
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001910static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags)
1911{
1912 struct sock *sk = sock->sk;
1913
1914 lock_sock(sk);
1915
1916 if (sk->sk_state == BT_CONNECT2 && bt_sk(sk)->defer_setup) {
1917 struct l2cap_conn_rsp rsp;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001918 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1919 u8 buf[128];
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001920
1921 sk->sk_state = BT_CONFIG;
1922
1923 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
1924 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
1925 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
1926 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
1927 l2cap_send_cmd(l2cap_pi(sk)->conn, l2cap_pi(sk)->ident,
1928 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
1929
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001930 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) {
1931 release_sock(sk);
1932 return 0;
1933 }
1934
1935 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
1936 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
1937 l2cap_build_conf_req(sk, buf), buf);
1938 l2cap_pi(sk)->num_conf_req++;
1939
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001940 release_sock(sk);
1941 return 0;
1942 }
1943
1944 release_sock(sk);
1945
1946 return bt_sock_recvmsg(iocb, sock, msg, len, flags);
1947}
1948
David S. Millerb7058842009-09-30 16:12:20 -07001949static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001950{
1951 struct sock *sk = sock->sk;
1952 struct l2cap_options opts;
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001953 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001954 u32 opt;
1955
1956 BT_DBG("sk %p", sk);
1957
1958 lock_sock(sk);
1959
1960 switch (optname) {
1961 case L2CAP_OPTIONS:
Marcel Holtmann0878b662007-05-05 00:35:59 +02001962 opts.imtu = l2cap_pi(sk)->imtu;
1963 opts.omtu = l2cap_pi(sk)->omtu;
1964 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001965 opts.mode = l2cap_pi(sk)->mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001966 opts.fcs = l2cap_pi(sk)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03001967 opts.max_tx = l2cap_pi(sk)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03001968 opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
Marcel Holtmann0878b662007-05-05 00:35:59 +02001969
Linus Torvalds1da177e2005-04-16 15:20:36 -07001970 len = min_t(unsigned int, sizeof(opts), optlen);
1971 if (copy_from_user((char *) &opts, optval, len)) {
1972 err = -EFAULT;
1973 break;
1974 }
Marcel Holtmann0878b662007-05-05 00:35:59 +02001975
Gustavo F. Padovan45d65c42010-06-07 19:21:30 -03001976 if (opts.txwin_size > L2CAP_DEFAULT_TX_WINDOW) {
1977 err = -EINVAL;
1978 break;
1979 }
1980
João Paulo Rechi Vita0041ecf2010-05-01 16:15:42 -03001981 l2cap_pi(sk)->mode = opts.mode;
1982 switch (l2cap_pi(sk)->mode) {
1983 case L2CAP_MODE_BASIC:
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03001984 l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_STATE2_DEVICE;
João Paulo Rechi Vita0041ecf2010-05-01 16:15:42 -03001985 break;
1986 case L2CAP_MODE_ERTM:
1987 case L2CAP_MODE_STREAMING:
1988 if (enable_ertm)
1989 break;
1990 /* fall through */
1991 default:
1992 err = -EINVAL;
1993 break;
1994 }
1995
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001996 l2cap_pi(sk)->imtu = opts.imtu;
1997 l2cap_pi(sk)->omtu = opts.omtu;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001998 l2cap_pi(sk)->fcs = opts.fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03001999 l2cap_pi(sk)->max_tx = opts.max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03002000 l2cap_pi(sk)->tx_win = (__u8)opts.txwin_size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002001 break;
2002
2003 case L2CAP_LM:
2004 if (get_user(opt, (u32 __user *) optval)) {
2005 err = -EFAULT;
2006 break;
2007 }
2008
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002009 if (opt & L2CAP_LM_AUTH)
2010 l2cap_pi(sk)->sec_level = BT_SECURITY_LOW;
2011 if (opt & L2CAP_LM_ENCRYPT)
2012 l2cap_pi(sk)->sec_level = BT_SECURITY_MEDIUM;
2013 if (opt & L2CAP_LM_SECURE)
2014 l2cap_pi(sk)->sec_level = BT_SECURITY_HIGH;
2015
2016 l2cap_pi(sk)->role_switch = (opt & L2CAP_LM_MASTER);
2017 l2cap_pi(sk)->force_reliable = (opt & L2CAP_LM_RELIABLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002018 break;
2019
2020 default:
2021 err = -ENOPROTOOPT;
2022 break;
2023 }
2024
2025 release_sock(sk);
2026 return err;
2027}
2028
David S. Millerb7058842009-09-30 16:12:20 -07002029static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002030{
2031 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002032 struct bt_security sec;
2033 int len, err = 0;
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002034 u32 opt;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002035
2036 BT_DBG("sk %p", sk);
2037
2038 if (level == SOL_L2CAP)
2039 return l2cap_sock_setsockopt_old(sock, optname, optval, optlen);
2040
Marcel Holtmann0588d942009-01-16 10:06:13 +01002041 if (level != SOL_BLUETOOTH)
2042 return -ENOPROTOOPT;
2043
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002044 lock_sock(sk);
2045
2046 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002047 case BT_SECURITY:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03002048 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
2049 && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01002050 err = -EINVAL;
2051 break;
2052 }
2053
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002054 sec.level = BT_SECURITY_LOW;
2055
2056 len = min_t(unsigned int, sizeof(sec), optlen);
2057 if (copy_from_user((char *) &sec, optval, len)) {
2058 err = -EFAULT;
2059 break;
2060 }
2061
2062 if (sec.level < BT_SECURITY_LOW ||
2063 sec.level > BT_SECURITY_HIGH) {
2064 err = -EINVAL;
2065 break;
2066 }
2067
2068 l2cap_pi(sk)->sec_level = sec.level;
2069 break;
2070
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002071 case BT_DEFER_SETUP:
2072 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
2073 err = -EINVAL;
2074 break;
2075 }
2076
2077 if (get_user(opt, (u32 __user *) optval)) {
2078 err = -EFAULT;
2079 break;
2080 }
2081
2082 bt_sk(sk)->defer_setup = opt;
2083 break;
2084
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002085 default:
2086 err = -ENOPROTOOPT;
2087 break;
2088 }
2089
2090 release_sock(sk);
2091 return err;
2092}
2093
2094static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002095{
2096 struct sock *sk = sock->sk;
2097 struct l2cap_options opts;
2098 struct l2cap_conninfo cinfo;
2099 int len, err = 0;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002100 u32 opt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002101
2102 BT_DBG("sk %p", sk);
2103
2104 if (get_user(len, optlen))
2105 return -EFAULT;
2106
2107 lock_sock(sk);
2108
2109 switch (optname) {
2110 case L2CAP_OPTIONS:
2111 opts.imtu = l2cap_pi(sk)->imtu;
2112 opts.omtu = l2cap_pi(sk)->omtu;
2113 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07002114 opts.mode = l2cap_pi(sk)->mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002115 opts.fcs = l2cap_pi(sk)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03002116 opts.max_tx = l2cap_pi(sk)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03002117 opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002118
2119 len = min_t(unsigned int, len, sizeof(opts));
2120 if (copy_to_user(optval, (char *) &opts, len))
2121 err = -EFAULT;
2122
2123 break;
2124
2125 case L2CAP_LM:
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002126 switch (l2cap_pi(sk)->sec_level) {
2127 case BT_SECURITY_LOW:
2128 opt = L2CAP_LM_AUTH;
2129 break;
2130 case BT_SECURITY_MEDIUM:
2131 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT;
2132 break;
2133 case BT_SECURITY_HIGH:
2134 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT |
2135 L2CAP_LM_SECURE;
2136 break;
2137 default:
2138 opt = 0;
2139 break;
2140 }
2141
2142 if (l2cap_pi(sk)->role_switch)
2143 opt |= L2CAP_LM_MASTER;
2144
2145 if (l2cap_pi(sk)->force_reliable)
2146 opt |= L2CAP_LM_RELIABLE;
2147
2148 if (put_user(opt, (u32 __user *) optval))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002149 err = -EFAULT;
2150 break;
2151
2152 case L2CAP_CONNINFO:
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002153 if (sk->sk_state != BT_CONNECTED &&
2154 !(sk->sk_state == BT_CONNECT2 &&
2155 bt_sk(sk)->defer_setup)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002156 err = -ENOTCONN;
2157 break;
2158 }
2159
2160 cinfo.hci_handle = l2cap_pi(sk)->conn->hcon->handle;
2161 memcpy(cinfo.dev_class, l2cap_pi(sk)->conn->hcon->dev_class, 3);
2162
2163 len = min_t(unsigned int, len, sizeof(cinfo));
2164 if (copy_to_user(optval, (char *) &cinfo, len))
2165 err = -EFAULT;
2166
2167 break;
2168
2169 default:
2170 err = -ENOPROTOOPT;
2171 break;
2172 }
2173
2174 release_sock(sk);
2175 return err;
2176}
2177
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002178static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
2179{
2180 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002181 struct bt_security sec;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002182 int len, err = 0;
2183
2184 BT_DBG("sk %p", sk);
2185
2186 if (level == SOL_L2CAP)
2187 return l2cap_sock_getsockopt_old(sock, optname, optval, optlen);
2188
Marcel Holtmann0588d942009-01-16 10:06:13 +01002189 if (level != SOL_BLUETOOTH)
2190 return -ENOPROTOOPT;
2191
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002192 if (get_user(len, optlen))
2193 return -EFAULT;
2194
2195 lock_sock(sk);
2196
2197 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002198 case BT_SECURITY:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03002199 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
2200 && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01002201 err = -EINVAL;
2202 break;
2203 }
2204
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002205 sec.level = l2cap_pi(sk)->sec_level;
2206
2207 len = min_t(unsigned int, len, sizeof(sec));
2208 if (copy_to_user(optval, (char *) &sec, len))
2209 err = -EFAULT;
2210
2211 break;
2212
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002213 case BT_DEFER_SETUP:
2214 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
2215 err = -EINVAL;
2216 break;
2217 }
2218
2219 if (put_user(bt_sk(sk)->defer_setup, (u32 __user *) optval))
2220 err = -EFAULT;
2221
2222 break;
2223
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002224 default:
2225 err = -ENOPROTOOPT;
2226 break;
2227 }
2228
2229 release_sock(sk);
2230 return err;
2231}
2232
Linus Torvalds1da177e2005-04-16 15:20:36 -07002233static int l2cap_sock_shutdown(struct socket *sock, int how)
2234{
2235 struct sock *sk = sock->sk;
2236 int err = 0;
2237
2238 BT_DBG("sock %p, sk %p", sock, sk);
2239
2240 if (!sk)
2241 return 0;
2242
2243 lock_sock(sk);
2244 if (!sk->sk_shutdown) {
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03002245 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
2246 err = __l2cap_wait_ack(sk);
2247
Linus Torvalds1da177e2005-04-16 15:20:36 -07002248 sk->sk_shutdown = SHUTDOWN_MASK;
2249 l2cap_sock_clear_timer(sk);
2250 __l2cap_sock_close(sk, 0);
2251
2252 if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
Marcel Holtmannb1235d72008-07-14 20:13:54 +02002253 err = bt_sock_wait_state(sk, BT_CLOSED,
2254 sk->sk_lingertime);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002255 }
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03002256
2257 if (!err && sk->sk_err)
2258 err = -sk->sk_err;
2259
Linus Torvalds1da177e2005-04-16 15:20:36 -07002260 release_sock(sk);
2261 return err;
2262}
2263
2264static int l2cap_sock_release(struct socket *sock)
2265{
2266 struct sock *sk = sock->sk;
2267 int err;
2268
2269 BT_DBG("sock %p, sk %p", sock, sk);
2270
2271 if (!sk)
2272 return 0;
2273
2274 err = l2cap_sock_shutdown(sock, 2);
2275
2276 sock_orphan(sk);
2277 l2cap_sock_kill(sk);
2278 return err;
2279}
2280
Linus Torvalds1da177e2005-04-16 15:20:36 -07002281static void l2cap_chan_ready(struct sock *sk)
2282{
2283 struct sock *parent = bt_sk(sk)->parent;
2284
2285 BT_DBG("sk %p, parent %p", sk, parent);
2286
2287 l2cap_pi(sk)->conf_state = 0;
2288 l2cap_sock_clear_timer(sk);
2289
2290 if (!parent) {
2291 /* Outgoing channel.
2292 * Wake up socket sleeping on connect.
2293 */
2294 sk->sk_state = BT_CONNECTED;
2295 sk->sk_state_change(sk);
2296 } else {
2297 /* Incoming channel.
2298 * Wake up socket sleeping on accept.
2299 */
2300 parent->sk_data_ready(parent, 0);
2301 }
2302}
2303
2304/* Copy frame to all raw sockets on that connection */
2305static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2306{
2307 struct l2cap_chan_list *l = &conn->chan_list;
2308 struct sk_buff *nskb;
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002309 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002310
2311 BT_DBG("conn %p", conn);
2312
2313 read_lock(&l->lock);
2314 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
2315 if (sk->sk_type != SOCK_RAW)
2316 continue;
2317
2318 /* Don't send frame to the socket it came from */
2319 if (skb->sk == sk)
2320 continue;
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002321 nskb = skb_clone(skb, GFP_ATOMIC);
2322 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002323 continue;
2324
2325 if (sock_queue_rcv_skb(sk, nskb))
2326 kfree_skb(nskb);
2327 }
2328 read_unlock(&l->lock);
2329}
2330
2331/* ---- L2CAP signalling commands ---- */
2332static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
2333 u8 code, u8 ident, u16 dlen, void *data)
2334{
2335 struct sk_buff *skb, **frag;
2336 struct l2cap_cmd_hdr *cmd;
2337 struct l2cap_hdr *lh;
2338 int len, count;
2339
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002340 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d",
2341 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002342
2343 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2344 count = min_t(unsigned int, conn->mtu, len);
2345
2346 skb = bt_skb_alloc(count, GFP_ATOMIC);
2347 if (!skb)
2348 return NULL;
2349
2350 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002351 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03002352 lh->cid = cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002353
2354 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2355 cmd->code = code;
2356 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002357 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002358
2359 if (dlen) {
2360 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2361 memcpy(skb_put(skb, count), data, count);
2362 data += count;
2363 }
2364
2365 len -= skb->len;
2366
2367 /* Continuation fragments (no L2CAP header) */
2368 frag = &skb_shinfo(skb)->frag_list;
2369 while (len) {
2370 count = min_t(unsigned int, conn->mtu, len);
2371
2372 *frag = bt_skb_alloc(count, GFP_ATOMIC);
2373 if (!*frag)
2374 goto fail;
2375
2376 memcpy(skb_put(*frag, count), data, count);
2377
2378 len -= count;
2379 data += count;
2380
2381 frag = &(*frag)->next;
2382 }
2383
2384 return skb;
2385
2386fail:
2387 kfree_skb(skb);
2388 return NULL;
2389}
2390
2391static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned long *val)
2392{
2393 struct l2cap_conf_opt *opt = *ptr;
2394 int len;
2395
2396 len = L2CAP_CONF_OPT_SIZE + opt->len;
2397 *ptr += len;
2398
2399 *type = opt->type;
2400 *olen = opt->len;
2401
2402 switch (opt->len) {
2403 case 1:
2404 *val = *((u8 *) opt->val);
2405 break;
2406
2407 case 2:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002408 *val = __le16_to_cpu(*((__le16 *) opt->val));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002409 break;
2410
2411 case 4:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002412 *val = __le32_to_cpu(*((__le32 *) opt->val));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002413 break;
2414
2415 default:
2416 *val = (unsigned long) opt->val;
2417 break;
2418 }
2419
2420 BT_DBG("type 0x%2.2x len %d val 0x%lx", *type, opt->len, *val);
2421 return len;
2422}
2423
Linus Torvalds1da177e2005-04-16 15:20:36 -07002424static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2425{
2426 struct l2cap_conf_opt *opt = *ptr;
2427
2428 BT_DBG("type 0x%2.2x len %d val 0x%lx", type, len, val);
2429
2430 opt->type = type;
2431 opt->len = len;
2432
2433 switch (len) {
2434 case 1:
2435 *((u8 *) opt->val) = val;
2436 break;
2437
2438 case 2:
Al Viro8e036fc2007-07-29 00:16:36 -07002439 *((__le16 *) opt->val) = cpu_to_le16(val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002440 break;
2441
2442 case 4:
Al Viro8e036fc2007-07-29 00:16:36 -07002443 *((__le32 *) opt->val) = cpu_to_le32(val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002444 break;
2445
2446 default:
2447 memcpy(opt->val, (void *) val, len);
2448 break;
2449 }
2450
2451 *ptr += L2CAP_CONF_OPT_SIZE + len;
2452}
2453
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002454static void l2cap_ack_timeout(unsigned long arg)
2455{
2456 struct sock *sk = (void *) arg;
2457
2458 bh_lock_sock(sk);
2459 l2cap_send_ack(l2cap_pi(sk));
2460 bh_unlock_sock(sk);
2461}
2462
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002463static inline void l2cap_ertm_init(struct sock *sk)
2464{
2465 l2cap_pi(sk)->expected_ack_seq = 0;
2466 l2cap_pi(sk)->unacked_frames = 0;
2467 l2cap_pi(sk)->buffer_seq = 0;
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03002468 l2cap_pi(sk)->num_acked = 0;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03002469 l2cap_pi(sk)->frames_sent = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002470
2471 setup_timer(&l2cap_pi(sk)->retrans_timer,
2472 l2cap_retrans_timeout, (unsigned long) sk);
2473 setup_timer(&l2cap_pi(sk)->monitor_timer,
2474 l2cap_monitor_timeout, (unsigned long) sk);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002475 setup_timer(&l2cap_pi(sk)->ack_timer,
2476 l2cap_ack_timeout, (unsigned long) sk);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002477
2478 __skb_queue_head_init(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002479 __skb_queue_head_init(BUSY_QUEUE(sk));
2480
2481 INIT_WORK(&l2cap_pi(sk)->busy_work, l2cap_busy_work);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03002482
2483 sk->sk_backlog_rcv = l2cap_ertm_data_rcv;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002484}
2485
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002486static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
2487{
2488 switch (mode) {
2489 case L2CAP_MODE_STREAMING:
2490 case L2CAP_MODE_ERTM:
2491 if (l2cap_mode_supported(mode, remote_feat_mask))
2492 return mode;
2493 /* fall through */
2494 default:
2495 return L2CAP_MODE_BASIC;
2496 }
2497}
2498
Linus Torvalds1da177e2005-04-16 15:20:36 -07002499static int l2cap_build_conf_req(struct sock *sk, void *data)
2500{
2501 struct l2cap_pinfo *pi = l2cap_pi(sk);
2502 struct l2cap_conf_req *req = data;
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03002503 struct l2cap_conf_rfc rfc = { .mode = pi->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07002504 void *ptr = req->data;
2505
2506 BT_DBG("sk %p", sk);
2507
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002508 if (pi->num_conf_req || pi->num_conf_rsp)
2509 goto done;
2510
2511 switch (pi->mode) {
2512 case L2CAP_MODE_STREAMING:
2513 case L2CAP_MODE_ERTM:
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03002514 if (pi->conf_state & L2CAP_CONF_STATE2_DEVICE)
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03002515 break;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03002516
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03002517 /* fall through */
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002518 default:
2519 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
2520 break;
2521 }
2522
2523done:
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002524 switch (pi->mode) {
2525 case L2CAP_MODE_BASIC:
2526 if (pi->imtu != L2CAP_DEFAULT_MTU)
2527 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
Gustavo F. Padovan62547752010-06-08 20:05:31 -03002528
2529 rfc.mode = L2CAP_MODE_BASIC;
2530 rfc.txwin_size = 0;
2531 rfc.max_transmit = 0;
2532 rfc.retrans_timeout = 0;
2533 rfc.monitor_timeout = 0;
2534 rfc.max_pdu_size = 0;
2535
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002536 break;
2537
2538 case L2CAP_MODE_ERTM:
2539 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03002540 rfc.txwin_size = pi->tx_win;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03002541 rfc.max_transmit = pi->max_tx;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002542 rfc.retrans_timeout = 0;
2543 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002544 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03002545 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002546 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002547
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002548 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2549 break;
2550
2551 if (pi->fcs == L2CAP_FCS_NONE ||
2552 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
2553 pi->fcs = L2CAP_FCS_NONE;
2554 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
2555 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002556 break;
2557
2558 case L2CAP_MODE_STREAMING:
2559 rfc.mode = L2CAP_MODE_STREAMING;
2560 rfc.txwin_size = 0;
2561 rfc.max_transmit = 0;
2562 rfc.retrans_timeout = 0;
2563 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002564 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03002565 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002566 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002567
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002568 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2569 break;
2570
2571 if (pi->fcs == L2CAP_FCS_NONE ||
2572 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
2573 pi->fcs = L2CAP_FCS_NONE;
2574 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
2575 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002576 break;
2577 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002578
Gustavo F. Padovan62547752010-06-08 20:05:31 -03002579 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
2580 (unsigned long) &rfc);
2581
Linus Torvalds1da177e2005-04-16 15:20:36 -07002582 /* FIXME: Need actual value of the flush timeout */
2583 //if (flush_to != L2CAP_DEFAULT_FLUSH_TO)
2584 // l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2, pi->flush_to);
2585
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002586 req->dcid = cpu_to_le16(pi->dcid);
2587 req->flags = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002588
2589 return ptr - data;
2590}
2591
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002592static int l2cap_parse_conf_req(struct sock *sk, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002593{
2594 struct l2cap_pinfo *pi = l2cap_pi(sk);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002595 struct l2cap_conf_rsp *rsp = data;
2596 void *ptr = rsp->data;
2597 void *req = pi->conf_req;
2598 int len = pi->conf_len;
2599 int type, hint, olen;
2600 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002601 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Marcel Holtmann861d6882007-10-20 13:37:06 +02002602 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002603 u16 result = L2CAP_CONF_SUCCESS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002604
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002605 BT_DBG("sk %p", sk);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01002606
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002607 while (len >= L2CAP_CONF_OPT_SIZE) {
2608 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002609
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03002610 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07002611 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002612
2613 switch (type) {
2614 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002615 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002616 break;
2617
2618 case L2CAP_CONF_FLUSH_TO:
2619 pi->flush_to = val;
2620 break;
2621
2622 case L2CAP_CONF_QOS:
2623 break;
2624
Marcel Holtmann6464f352007-10-20 13:39:51 +02002625 case L2CAP_CONF_RFC:
2626 if (olen == sizeof(rfc))
2627 memcpy(&rfc, (void *) val, olen);
2628 break;
2629
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002630 case L2CAP_CONF_FCS:
2631 if (val == L2CAP_FCS_NONE)
2632 pi->conf_state |= L2CAP_CONF_NO_FCS_RECV;
2633
2634 break;
2635
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002636 default:
2637 if (hint)
2638 break;
2639
2640 result = L2CAP_CONF_UNKNOWN;
2641 *((u8 *) ptr++) = type;
2642 break;
2643 }
2644 }
2645
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03002646 if (pi->num_conf_rsp || pi->num_conf_req > 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002647 goto done;
2648
2649 switch (pi->mode) {
2650 case L2CAP_MODE_STREAMING:
2651 case L2CAP_MODE_ERTM:
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03002652 if (!(pi->conf_state & L2CAP_CONF_STATE2_DEVICE)) {
2653 pi->mode = l2cap_select_mode(rfc.mode,
2654 pi->conn->feat_mask);
2655 break;
2656 }
2657
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03002658 if (pi->mode != rfc.mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002659 return -ECONNREFUSED;
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03002660
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002661 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002662 }
2663
2664done:
2665 if (pi->mode != rfc.mode) {
2666 result = L2CAP_CONF_UNACCEPT;
2667 rfc.mode = pi->mode;
2668
2669 if (pi->num_conf_rsp == 1)
2670 return -ECONNREFUSED;
2671
2672 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2673 sizeof(rfc), (unsigned long) &rfc);
2674 }
2675
2676
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002677 if (result == L2CAP_CONF_SUCCESS) {
2678 /* Configure output options and let the other side know
2679 * which ones we don't like. */
2680
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002681 if (mtu < L2CAP_DEFAULT_MIN_MTU)
2682 result = L2CAP_CONF_UNACCEPT;
2683 else {
2684 pi->omtu = mtu;
2685 pi->conf_state |= L2CAP_CONF_MTU_DONE;
2686 }
2687 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002688
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002689 switch (rfc.mode) {
2690 case L2CAP_MODE_BASIC:
2691 pi->fcs = L2CAP_FCS_NONE;
2692 pi->conf_state |= L2CAP_CONF_MODE_DONE;
2693 break;
2694
2695 case L2CAP_MODE_ERTM:
2696 pi->remote_tx_win = rfc.txwin_size;
2697 pi->remote_max_tx = rfc.max_transmit;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002698 if (rfc.max_pdu_size > pi->conn->mtu - 10)
2699 rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10);
2700
2701 pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002702
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002703 rfc.retrans_timeout =
2704 le16_to_cpu(L2CAP_DEFAULT_RETRANS_TO);
2705 rfc.monitor_timeout =
2706 le16_to_cpu(L2CAP_DEFAULT_MONITOR_TO);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002707
2708 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03002709
2710 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2711 sizeof(rfc), (unsigned long) &rfc);
2712
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002713 break;
2714
2715 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002716 if (rfc.max_pdu_size > pi->conn->mtu - 10)
2717 rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10);
2718
2719 pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002720
2721 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03002722
2723 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2724 sizeof(rfc), (unsigned long) &rfc);
2725
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002726 break;
2727
2728 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02002729 result = L2CAP_CONF_UNACCEPT;
2730
2731 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002732 rfc.mode = pi->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002733 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002734
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002735 if (result == L2CAP_CONF_SUCCESS)
2736 pi->conf_state |= L2CAP_CONF_OUTPUT_DONE;
2737 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002738 rsp->scid = cpu_to_le16(pi->dcid);
2739 rsp->result = cpu_to_le16(result);
2740 rsp->flags = cpu_to_le16(0x0000);
2741
2742 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002743}
2744
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002745static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data, u16 *result)
2746{
2747 struct l2cap_pinfo *pi = l2cap_pi(sk);
2748 struct l2cap_conf_req *req = data;
2749 void *ptr = req->data;
2750 int type, olen;
2751 unsigned long val;
2752 struct l2cap_conf_rfc rfc;
2753
2754 BT_DBG("sk %p, rsp %p, len %d, req %p", sk, rsp, len, data);
2755
2756 while (len >= L2CAP_CONF_OPT_SIZE) {
2757 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
2758
2759 switch (type) {
2760 case L2CAP_CONF_MTU:
2761 if (val < L2CAP_DEFAULT_MIN_MTU) {
2762 *result = L2CAP_CONF_UNACCEPT;
2763 pi->omtu = L2CAP_DEFAULT_MIN_MTU;
2764 } else
2765 pi->omtu = val;
2766 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
2767 break;
2768
2769 case L2CAP_CONF_FLUSH_TO:
2770 pi->flush_to = val;
2771 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
2772 2, pi->flush_to);
2773 break;
2774
2775 case L2CAP_CONF_RFC:
2776 if (olen == sizeof(rfc))
2777 memcpy(&rfc, (void *)val, olen);
2778
2779 if ((pi->conf_state & L2CAP_CONF_STATE2_DEVICE) &&
2780 rfc.mode != pi->mode)
2781 return -ECONNREFUSED;
2782
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002783 pi->fcs = 0;
2784
2785 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2786 sizeof(rfc), (unsigned long) &rfc);
2787 break;
2788 }
2789 }
2790
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03002791 if (pi->mode == L2CAP_MODE_BASIC && pi->mode != rfc.mode)
2792 return -ECONNREFUSED;
2793
2794 pi->mode = rfc.mode;
2795
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002796 if (*result == L2CAP_CONF_SUCCESS) {
2797 switch (rfc.mode) {
2798 case L2CAP_MODE_ERTM:
2799 pi->remote_tx_win = rfc.txwin_size;
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002800 pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
2801 pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002802 pi->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002803 break;
2804 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002805 pi->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002806 }
2807 }
2808
2809 req->dcid = cpu_to_le16(pi->dcid);
2810 req->flags = cpu_to_le16(0x0000);
2811
2812 return ptr - data;
2813}
2814
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002815static int l2cap_build_conf_rsp(struct sock *sk, void *data, u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002816{
2817 struct l2cap_conf_rsp *rsp = data;
2818 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002819
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002820 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002821
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002822 rsp->scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002823 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002824 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002825
2826 return ptr - data;
2827}
2828
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002829static void l2cap_conf_rfc_get(struct sock *sk, void *rsp, int len)
2830{
2831 struct l2cap_pinfo *pi = l2cap_pi(sk);
2832 int type, olen;
2833 unsigned long val;
2834 struct l2cap_conf_rfc rfc;
2835
2836 BT_DBG("sk %p, rsp %p, len %d", sk, rsp, len);
2837
2838 if ((pi->mode != L2CAP_MODE_ERTM) && (pi->mode != L2CAP_MODE_STREAMING))
2839 return;
2840
2841 while (len >= L2CAP_CONF_OPT_SIZE) {
2842 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
2843
2844 switch (type) {
2845 case L2CAP_CONF_RFC:
2846 if (olen == sizeof(rfc))
2847 memcpy(&rfc, (void *)val, olen);
2848 goto done;
2849 }
2850 }
2851
2852done:
2853 switch (rfc.mode) {
2854 case L2CAP_MODE_ERTM:
2855 pi->remote_tx_win = rfc.txwin_size;
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002856 pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
2857 pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002858 pi->mps = le16_to_cpu(rfc.max_pdu_size);
2859 break;
2860 case L2CAP_MODE_STREAMING:
2861 pi->mps = le16_to_cpu(rfc.max_pdu_size);
2862 }
2863}
2864
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002865static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2866{
2867 struct l2cap_cmd_rej *rej = (struct l2cap_cmd_rej *) data;
2868
2869 if (rej->reason != 0x0000)
2870 return 0;
2871
2872 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
2873 cmd->ident == conn->info_ident) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002874 del_timer(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01002875
2876 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002877 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01002878
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002879 l2cap_conn_start(conn);
2880 }
2881
2882 return 0;
2883}
2884
Linus Torvalds1da177e2005-04-16 15:20:36 -07002885static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2886{
2887 struct l2cap_chan_list *list = &conn->chan_list;
2888 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
2889 struct l2cap_conn_rsp rsp;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03002890 struct sock *parent, *uninitialized_var(sk);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002891 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002892
2893 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002894 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002895
2896 BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
2897
2898 /* Check if we have socket listening on psm */
2899 parent = l2cap_get_sock_by_psm(BT_LISTEN, psm, conn->src);
2900 if (!parent) {
2901 result = L2CAP_CR_BAD_PSM;
2902 goto sendresp;
2903 }
2904
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002905 /* Check if the ACL is secure enough (if not SDP) */
2906 if (psm != cpu_to_le16(0x0001) &&
2907 !hci_conn_check_link_mode(conn->hcon)) {
Marcel Holtmann2950f212009-02-12 14:02:50 +01002908 conn->disc_reason = 0x05;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002909 result = L2CAP_CR_SEC_BLOCK;
2910 goto response;
2911 }
2912
Linus Torvalds1da177e2005-04-16 15:20:36 -07002913 result = L2CAP_CR_NO_MEM;
2914
2915 /* Check for backlog size */
2916 if (sk_acceptq_is_full(parent)) {
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09002917 BT_DBG("backlog full %d", parent->sk_ack_backlog);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002918 goto response;
2919 }
2920
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09002921 sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002922 if (!sk)
2923 goto response;
2924
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002925 write_lock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002926
2927 /* Check if we already have channel with that dcid */
2928 if (__l2cap_get_chan_by_dcid(list, scid)) {
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002929 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002930 sock_set_flag(sk, SOCK_ZAPPED);
2931 l2cap_sock_kill(sk);
2932 goto response;
2933 }
2934
2935 hci_conn_hold(conn->hcon);
2936
2937 l2cap_sock_init(sk, parent);
2938 bacpy(&bt_sk(sk)->src, conn->src);
2939 bacpy(&bt_sk(sk)->dst, conn->dst);
2940 l2cap_pi(sk)->psm = psm;
2941 l2cap_pi(sk)->dcid = scid;
2942
2943 __l2cap_chan_add(conn, sk, parent);
2944 dcid = l2cap_pi(sk)->scid;
2945
2946 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
2947
Linus Torvalds1da177e2005-04-16 15:20:36 -07002948 l2cap_pi(sk)->ident = cmd->ident;
2949
Marcel Holtmann984947d2009-02-06 23:35:19 +01002950 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002951 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002952 if (bt_sk(sk)->defer_setup) {
2953 sk->sk_state = BT_CONNECT2;
2954 result = L2CAP_CR_PEND;
2955 status = L2CAP_CS_AUTHOR_PEND;
2956 parent->sk_data_ready(parent, 0);
2957 } else {
2958 sk->sk_state = BT_CONFIG;
2959 result = L2CAP_CR_SUCCESS;
2960 status = L2CAP_CS_NO_INFO;
2961 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002962 } else {
2963 sk->sk_state = BT_CONNECT2;
2964 result = L2CAP_CR_PEND;
2965 status = L2CAP_CS_AUTHEN_PEND;
2966 }
2967 } else {
2968 sk->sk_state = BT_CONNECT2;
2969 result = L2CAP_CR_PEND;
2970 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002971 }
2972
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002973 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002974
2975response:
2976 bh_unlock_sock(parent);
2977
2978sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002979 rsp.scid = cpu_to_le16(scid);
2980 rsp.dcid = cpu_to_le16(dcid);
2981 rsp.result = cpu_to_le16(result);
2982 rsp.status = cpu_to_le16(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002983 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002984
2985 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
2986 struct l2cap_info_req info;
2987 info.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
2988
2989 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
2990 conn->info_ident = l2cap_get_ident(conn);
2991
2992 mod_timer(&conn->info_timer, jiffies +
2993 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
2994
2995 l2cap_send_cmd(conn, conn->info_ident,
2996 L2CAP_INFO_REQ, sizeof(info), &info);
2997 }
2998
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03002999 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) &&
3000 result == L2CAP_CR_SUCCESS) {
3001 u8 buf[128];
3002 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
3003 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
3004 l2cap_build_conf_req(sk, buf), buf);
3005 l2cap_pi(sk)->num_conf_req++;
3006 }
3007
Linus Torvalds1da177e2005-04-16 15:20:36 -07003008 return 0;
3009}
3010
3011static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3012{
3013 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
3014 u16 scid, dcid, result, status;
3015 struct sock *sk;
3016 u8 req[128];
3017
3018 scid = __le16_to_cpu(rsp->scid);
3019 dcid = __le16_to_cpu(rsp->dcid);
3020 result = __le16_to_cpu(rsp->result);
3021 status = __le16_to_cpu(rsp->status);
3022
3023 BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
3024
3025 if (scid) {
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03003026 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
3027 if (!sk)
João Paulo Rechi Vita57d3b222010-06-22 13:56:26 -03003028 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003029 } else {
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03003030 sk = l2cap_get_chan_by_ident(&conn->chan_list, cmd->ident);
3031 if (!sk)
João Paulo Rechi Vita57d3b222010-06-22 13:56:26 -03003032 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003033 }
3034
3035 switch (result) {
3036 case L2CAP_CR_SUCCESS:
3037 sk->sk_state = BT_CONFIG;
3038 l2cap_pi(sk)->ident = 0;
3039 l2cap_pi(sk)->dcid = dcid;
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003040 l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_CONNECT_PEND;
3041
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003042 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)
3043 break;
3044
3045 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
3046
Linus Torvalds1da177e2005-04-16 15:20:36 -07003047 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
3048 l2cap_build_conf_req(sk, req), req);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003049 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003050 break;
3051
3052 case L2CAP_CR_PEND:
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003053 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003054 break;
3055
3056 default:
3057 l2cap_chan_del(sk, ECONNREFUSED);
3058 break;
3059 }
3060
3061 bh_unlock_sock(sk);
3062 return 0;
3063}
3064
Al Viro88219a02007-07-29 00:17:25 -07003065static 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 -07003066{
3067 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
3068 u16 dcid, flags;
3069 u8 rsp[64];
3070 struct sock *sk;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003071 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003072
3073 dcid = __le16_to_cpu(req->dcid);
3074 flags = __le16_to_cpu(req->flags);
3075
3076 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
3077
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03003078 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
3079 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003080 return -ENOENT;
3081
Gustavo F. Padovan8cb8e6f2010-06-14 02:26:15 -03003082 if (sk->sk_state != BT_CONFIG) {
3083 struct l2cap_cmd_rej rej;
3084
3085 rej.reason = cpu_to_le16(0x0002);
3086 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
3087 sizeof(rej), &rej);
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003088 goto unlock;
Gustavo F. Padovan8cb8e6f2010-06-14 02:26:15 -03003089 }
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003090
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003091 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07003092 len = cmd_len - sizeof(*req);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003093 if (l2cap_pi(sk)->conf_len + len > sizeof(l2cap_pi(sk)->conf_req)) {
3094 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
3095 l2cap_build_conf_rsp(sk, rsp,
3096 L2CAP_CONF_REJECT, flags), rsp);
3097 goto unlock;
3098 }
3099
3100 /* Store config. */
3101 memcpy(l2cap_pi(sk)->conf_req + l2cap_pi(sk)->conf_len, req->data, len);
3102 l2cap_pi(sk)->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003103
3104 if (flags & 0x0001) {
3105 /* Incomplete config. Send empty response. */
3106 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003107 l2cap_build_conf_rsp(sk, rsp,
3108 L2CAP_CONF_SUCCESS, 0x0001), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003109 goto unlock;
3110 }
3111
3112 /* Complete config. */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003113 len = l2cap_parse_conf_req(sk, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003114 if (len < 0) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03003115 l2cap_send_disconn_req(conn, sk, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003116 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003117 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003118
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003119 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003120 l2cap_pi(sk)->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003121
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003122 /* Reset config buffer. */
3123 l2cap_pi(sk)->conf_len = 0;
3124
Marcel Holtmann876d9482007-10-20 13:35:42 +02003125 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE))
3126 goto unlock;
3127
Linus Torvalds1da177e2005-04-16 15:20:36 -07003128 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) {
Joe Perchesf64f9e72009-11-29 16:55:45 -08003129 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) ||
3130 l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003131 l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
3132
Linus Torvalds1da177e2005-04-16 15:20:36 -07003133 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003134
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003135 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003136 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003137 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003138 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
3139 l2cap_ertm_init(sk);
3140
Linus Torvalds1da177e2005-04-16 15:20:36 -07003141 l2cap_chan_ready(sk);
Marcel Holtmann876d9482007-10-20 13:35:42 +02003142 goto unlock;
3143 }
3144
3145 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003146 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003147 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003148 l2cap_build_conf_req(sk, buf), buf);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003149 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003150 }
3151
3152unlock:
3153 bh_unlock_sock(sk);
3154 return 0;
3155}
3156
3157static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3158{
3159 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
3160 u16 scid, flags, result;
3161 struct sock *sk;
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003162 int len = cmd->len - sizeof(*rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003163
3164 scid = __le16_to_cpu(rsp->scid);
3165 flags = __le16_to_cpu(rsp->flags);
3166 result = __le16_to_cpu(rsp->result);
3167
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03003168 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x",
3169 scid, flags, result);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003170
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03003171 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
3172 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003173 return 0;
3174
3175 switch (result) {
3176 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003177 l2cap_conf_rfc_get(sk, rsp->data, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003178 break;
3179
3180 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003181 if (l2cap_pi(sk)->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003182 char req[64];
3183
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02003184 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03003185 l2cap_send_disconn_req(conn, sk, ECONNRESET);
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02003186 goto done;
3187 }
3188
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003189 /* throw out any old stored conf requests */
3190 result = L2CAP_CONF_SUCCESS;
3191 len = l2cap_parse_conf_rsp(sk, rsp->data,
3192 len, req, &result);
3193 if (len < 0) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03003194 l2cap_send_disconn_req(conn, sk, ECONNRESET);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003195 goto done;
3196 }
3197
3198 l2cap_send_cmd(conn, l2cap_get_ident(conn),
3199 L2CAP_CONF_REQ, len, req);
3200 l2cap_pi(sk)->num_conf_req++;
3201 if (result != L2CAP_CONF_SUCCESS)
3202 goto done;
3203 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003204 }
3205
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09003206 default:
Marcel Holtmannb1235d72008-07-14 20:13:54 +02003207 sk->sk_err = ECONNRESET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003208 l2cap_sock_set_timer(sk, HZ * 5);
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03003209 l2cap_send_disconn_req(conn, sk, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003210 goto done;
3211 }
3212
3213 if (flags & 0x01)
3214 goto done;
3215
Linus Torvalds1da177e2005-04-16 15:20:36 -07003216 l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE;
3217
3218 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) {
Joe Perchesf64f9e72009-11-29 16:55:45 -08003219 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) ||
3220 l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003221 l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
3222
Linus Torvalds1da177e2005-04-16 15:20:36 -07003223 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003224 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003225 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003226 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003227 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
3228 l2cap_ertm_init(sk);
3229
Linus Torvalds1da177e2005-04-16 15:20:36 -07003230 l2cap_chan_ready(sk);
3231 }
3232
3233done:
3234 bh_unlock_sock(sk);
3235 return 0;
3236}
3237
3238static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3239{
3240 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
3241 struct l2cap_disconn_rsp rsp;
3242 u16 dcid, scid;
3243 struct sock *sk;
3244
3245 scid = __le16_to_cpu(req->scid);
3246 dcid = __le16_to_cpu(req->dcid);
3247
3248 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
3249
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03003250 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
3251 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003252 return 0;
3253
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003254 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
3255 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003256 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
3257
3258 sk->sk_shutdown = SHUTDOWN_MASK;
3259
3260 l2cap_chan_del(sk, ECONNRESET);
3261 bh_unlock_sock(sk);
3262
3263 l2cap_sock_kill(sk);
3264 return 0;
3265}
3266
3267static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3268{
3269 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
3270 u16 dcid, scid;
3271 struct sock *sk;
3272
3273 scid = __le16_to_cpu(rsp->scid);
3274 dcid = __le16_to_cpu(rsp->dcid);
3275
3276 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
3277
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03003278 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
3279 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003280 return 0;
3281
3282 l2cap_chan_del(sk, 0);
3283 bh_unlock_sock(sk);
3284
3285 l2cap_sock_kill(sk);
3286 return 0;
3287}
3288
3289static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3290{
3291 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003292 u16 type;
3293
3294 type = __le16_to_cpu(req->type);
3295
3296 BT_DBG("type 0x%4.4x", type);
3297
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003298 if (type == L2CAP_IT_FEAT_MASK) {
3299 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003300 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003301 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
3302 rsp->type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
3303 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003304 if (enable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003305 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
3306 | L2CAP_FEAT_FCS;
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03003307 put_unaligned_le32(feat_mask, rsp->data);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003308 l2cap_send_cmd(conn, cmd->ident,
3309 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003310 } else if (type == L2CAP_IT_FIXED_CHAN) {
3311 u8 buf[12];
3312 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
3313 rsp->type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3314 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
3315 memcpy(buf + 4, l2cap_fixed_chan, 8);
3316 l2cap_send_cmd(conn, cmd->ident,
3317 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003318 } else {
3319 struct l2cap_info_rsp rsp;
3320 rsp.type = cpu_to_le16(type);
3321 rsp.result = cpu_to_le16(L2CAP_IR_NOTSUPP);
3322 l2cap_send_cmd(conn, cmd->ident,
3323 L2CAP_INFO_RSP, sizeof(rsp), &rsp);
3324 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003325
3326 return 0;
3327}
3328
3329static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3330{
3331 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
3332 u16 type, result;
3333
3334 type = __le16_to_cpu(rsp->type);
3335 result = __le16_to_cpu(rsp->result);
3336
3337 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
3338
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003339 del_timer(&conn->info_timer);
3340
Marcel Holtmann984947d2009-02-06 23:35:19 +01003341 if (type == L2CAP_IT_FEAT_MASK) {
Harvey Harrison83985312008-05-02 16:25:46 -07003342 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003343
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003344 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003345 struct l2cap_info_req req;
3346 req.type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3347
3348 conn->info_ident = l2cap_get_ident(conn);
3349
3350 l2cap_send_cmd(conn, conn->info_ident,
3351 L2CAP_INFO_REQ, sizeof(req), &req);
3352 } else {
3353 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
3354 conn->info_ident = 0;
3355
3356 l2cap_conn_start(conn);
3357 }
3358 } else if (type == L2CAP_IT_FIXED_CHAN) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01003359 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003360 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003361
3362 l2cap_conn_start(conn);
3363 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003364
Linus Torvalds1da177e2005-04-16 15:20:36 -07003365 return 0;
3366}
3367
3368static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
3369{
3370 u8 *data = skb->data;
3371 int len = skb->len;
3372 struct l2cap_cmd_hdr cmd;
3373 int err = 0;
3374
3375 l2cap_raw_recv(conn, skb);
3376
3377 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07003378 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003379 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
3380 data += L2CAP_CMD_HDR_SIZE;
3381 len -= L2CAP_CMD_HDR_SIZE;
3382
Al Viro88219a02007-07-29 00:17:25 -07003383 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003384
Al Viro88219a02007-07-29 00:17:25 -07003385 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 -07003386
Al Viro88219a02007-07-29 00:17:25 -07003387 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003388 BT_DBG("corrupted command");
3389 break;
3390 }
3391
3392 switch (cmd.code) {
3393 case L2CAP_COMMAND_REJ:
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003394 l2cap_command_rej(conn, &cmd, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003395 break;
3396
3397 case L2CAP_CONN_REQ:
3398 err = l2cap_connect_req(conn, &cmd, data);
3399 break;
3400
3401 case L2CAP_CONN_RSP:
3402 err = l2cap_connect_rsp(conn, &cmd, data);
3403 break;
3404
3405 case L2CAP_CONF_REQ:
Al Viro88219a02007-07-29 00:17:25 -07003406 err = l2cap_config_req(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003407 break;
3408
3409 case L2CAP_CONF_RSP:
3410 err = l2cap_config_rsp(conn, &cmd, data);
3411 break;
3412
3413 case L2CAP_DISCONN_REQ:
3414 err = l2cap_disconnect_req(conn, &cmd, data);
3415 break;
3416
3417 case L2CAP_DISCONN_RSP:
3418 err = l2cap_disconnect_rsp(conn, &cmd, data);
3419 break;
3420
3421 case L2CAP_ECHO_REQ:
Al Viro88219a02007-07-29 00:17:25 -07003422 l2cap_send_cmd(conn, cmd.ident, L2CAP_ECHO_RSP, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003423 break;
3424
3425 case L2CAP_ECHO_RSP:
3426 break;
3427
3428 case L2CAP_INFO_REQ:
3429 err = l2cap_information_req(conn, &cmd, data);
3430 break;
3431
3432 case L2CAP_INFO_RSP:
3433 err = l2cap_information_rsp(conn, &cmd, data);
3434 break;
3435
3436 default:
3437 BT_ERR("Unknown signaling command 0x%2.2x", cmd.code);
3438 err = -EINVAL;
3439 break;
3440 }
3441
3442 if (err) {
3443 struct l2cap_cmd_rej rej;
3444 BT_DBG("error %d", err);
3445
3446 /* FIXME: Map err to a valid reason */
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003447 rej.reason = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003448 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
3449 }
3450
Al Viro88219a02007-07-29 00:17:25 -07003451 data += cmd_len;
3452 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003453 }
3454
3455 kfree_skb(skb);
3456}
3457
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003458static int l2cap_check_fcs(struct l2cap_pinfo *pi, struct sk_buff *skb)
3459{
3460 u16 our_fcs, rcv_fcs;
3461 int hdr_size = L2CAP_HDR_SIZE + 2;
3462
3463 if (pi->fcs == L2CAP_FCS_CRC16) {
3464 skb_trim(skb, skb->len - 2);
3465 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
3466 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
3467
3468 if (our_fcs != rcv_fcs)
João Paulo Rechi Vita7a560e52010-06-22 13:56:27 -03003469 return -EBADMSG;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003470 }
3471 return 0;
3472}
3473
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003474static inline void l2cap_send_i_or_rr_or_rnr(struct sock *sk)
3475{
3476 struct l2cap_pinfo *pi = l2cap_pi(sk);
3477 u16 control = 0;
3478
3479 pi->frames_sent = 0;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003480
3481 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3482
3483 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
Gustavo F. Padovan64988862010-05-10 14:54:14 -03003484 control |= L2CAP_SUPER_RCV_NOT_READY;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003485 l2cap_send_sframe(pi, control);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003486 pi->conn_state |= L2CAP_CONN_RNR_SENT;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003487 }
3488
Gustavo F. Padovan4ea727e2010-06-03 16:34:20 -03003489 if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY)
3490 l2cap_retransmit_frames(sk);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003491
3492 l2cap_ertm_send(sk);
3493
3494 if (!(pi->conn_state & L2CAP_CONN_LOCAL_BUSY) &&
3495 pi->frames_sent == 0) {
3496 control |= L2CAP_SUPER_RCV_READY;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003497 l2cap_send_sframe(pi, control);
3498 }
3499}
3500
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003501static 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 -03003502{
3503 struct sk_buff *next_skb;
João Paulo Rechi Vitabfbacc12010-05-31 18:35:44 -03003504 struct l2cap_pinfo *pi = l2cap_pi(sk);
3505 int tx_seq_offset, next_tx_seq_offset;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003506
3507 bt_cb(skb)->tx_seq = tx_seq;
3508 bt_cb(skb)->sar = sar;
3509
3510 next_skb = skb_peek(SREJ_QUEUE(sk));
3511 if (!next_skb) {
3512 __skb_queue_tail(SREJ_QUEUE(sk), skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003513 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003514 }
3515
João Paulo Rechi Vitabfbacc12010-05-31 18:35:44 -03003516 tx_seq_offset = (tx_seq - pi->buffer_seq) % 64;
3517 if (tx_seq_offset < 0)
3518 tx_seq_offset += 64;
3519
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003520 do {
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003521 if (bt_cb(next_skb)->tx_seq == tx_seq)
3522 return -EINVAL;
3523
João Paulo Rechi Vitabfbacc12010-05-31 18:35:44 -03003524 next_tx_seq_offset = (bt_cb(next_skb)->tx_seq -
3525 pi->buffer_seq) % 64;
3526 if (next_tx_seq_offset < 0)
3527 next_tx_seq_offset += 64;
3528
3529 if (next_tx_seq_offset > tx_seq_offset) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003530 __skb_queue_before(SREJ_QUEUE(sk), next_skb, skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003531 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003532 }
3533
3534 if (skb_queue_is_last(SREJ_QUEUE(sk), next_skb))
3535 break;
3536
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003537 } while ((next_skb = skb_queue_next(SREJ_QUEUE(sk), next_skb)));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003538
3539 __skb_queue_tail(SREJ_QUEUE(sk), skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003540
3541 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003542}
3543
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003544static int l2cap_ertm_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
3545{
3546 struct l2cap_pinfo *pi = l2cap_pi(sk);
3547 struct sk_buff *_skb;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003548 int err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003549
3550 switch (control & L2CAP_CTRL_SAR) {
3551 case L2CAP_SDU_UNSEGMENTED:
3552 if (pi->conn_state & L2CAP_CONN_SAR_SDU)
3553 goto drop;
3554
3555 err = sock_queue_rcv_skb(sk, skb);
3556 if (!err)
3557 return err;
3558
3559 break;
3560
3561 case L2CAP_SDU_START:
3562 if (pi->conn_state & L2CAP_CONN_SAR_SDU)
3563 goto drop;
3564
3565 pi->sdu_len = get_unaligned_le16(skb->data);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003566
3567 if (pi->sdu_len > pi->imtu)
3568 goto disconnect;
3569
3570 pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003571 if (!pi->sdu)
3572 return -ENOMEM;
3573
3574 /* pull sdu_len bytes only after alloc, because of Local Busy
3575 * condition we have to be sure that this will be executed
3576 * only once, i.e., when alloc does not fail */
3577 skb_pull(skb, 2);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003578
3579 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3580
3581 pi->conn_state |= L2CAP_CONN_SAR_SDU;
3582 pi->partial_sdu_len = skb->len;
3583 break;
3584
3585 case L2CAP_SDU_CONTINUE:
3586 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3587 goto disconnect;
3588
3589 if (!pi->sdu)
3590 goto disconnect;
3591
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003592 pi->partial_sdu_len += skb->len;
3593 if (pi->partial_sdu_len > pi->sdu_len)
3594 goto drop;
3595
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03003596 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3597
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003598 break;
3599
3600 case L2CAP_SDU_END:
3601 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3602 goto disconnect;
3603
3604 if (!pi->sdu)
3605 goto disconnect;
3606
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003607 if (!(pi->conn_state & L2CAP_CONN_SAR_RETRY)) {
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003608 pi->partial_sdu_len += skb->len;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003609
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003610 if (pi->partial_sdu_len > pi->imtu)
3611 goto drop;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003612
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003613 if (pi->partial_sdu_len != pi->sdu_len)
3614 goto drop;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03003615
3616 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003617 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003618
3619 _skb = skb_clone(pi->sdu, GFP_ATOMIC);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003620 if (!_skb) {
3621 pi->conn_state |= L2CAP_CONN_SAR_RETRY;
3622 return -ENOMEM;
3623 }
3624
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003625 err = sock_queue_rcv_skb(sk, _skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003626 if (err < 0) {
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003627 kfree_skb(_skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003628 pi->conn_state |= L2CAP_CONN_SAR_RETRY;
3629 return err;
3630 }
3631
3632 pi->conn_state &= ~L2CAP_CONN_SAR_RETRY;
3633 pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003634
3635 kfree_skb(pi->sdu);
3636 break;
3637 }
3638
3639 kfree_skb(skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003640 return 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003641
3642drop:
3643 kfree_skb(pi->sdu);
3644 pi->sdu = NULL;
3645
3646disconnect:
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03003647 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003648 kfree_skb(skb);
3649 return 0;
3650}
3651
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03003652static int l2cap_try_push_rx_skb(struct sock *sk)
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003653{
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03003654 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003655 struct sk_buff *skb;
3656 u16 control;
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03003657 int err;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003658
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03003659 while ((skb = skb_dequeue(BUSY_QUEUE(sk)))) {
3660 control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
3661 err = l2cap_ertm_reassembly_sdu(sk, skb, control);
3662 if (err < 0) {
3663 skb_queue_head(BUSY_QUEUE(sk), skb);
3664 return -EBUSY;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003665 }
3666
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03003667 pi->buffer_seq = (pi->buffer_seq + 1) % 64;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003668 }
3669
3670 if (!(pi->conn_state & L2CAP_CONN_RNR_SENT))
3671 goto done;
3672
3673 control = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3674 control |= L2CAP_SUPER_RCV_READY | L2CAP_CTRL_POLL;
3675 l2cap_send_sframe(pi, control);
3676 l2cap_pi(sk)->retry_count = 1;
3677
3678 del_timer(&pi->retrans_timer);
3679 __mod_monitor_timer();
3680
3681 l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
3682
3683done:
3684 pi->conn_state &= ~L2CAP_CONN_LOCAL_BUSY;
3685 pi->conn_state &= ~L2CAP_CONN_RNR_SENT;
3686
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003687 BT_DBG("sk %p, Exit local busy", sk);
3688
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03003689 return 0;
3690}
3691
3692static void l2cap_busy_work(struct work_struct *work)
3693{
3694 DECLARE_WAITQUEUE(wait, current);
3695 struct l2cap_pinfo *pi =
3696 container_of(work, struct l2cap_pinfo, busy_work);
3697 struct sock *sk = (struct sock *)pi;
3698 int n_tries = 0, timeo = HZ/5, err;
3699 struct sk_buff *skb;
3700
3701 lock_sock(sk);
3702
3703 add_wait_queue(sk_sleep(sk), &wait);
3704 while ((skb = skb_peek(BUSY_QUEUE(sk)))) {
3705 set_current_state(TASK_INTERRUPTIBLE);
3706
3707 if (n_tries++ > L2CAP_LOCAL_BUSY_TRIES) {
3708 err = -EBUSY;
3709 l2cap_send_disconn_req(pi->conn, sk, EBUSY);
3710 break;
3711 }
3712
3713 if (!timeo)
3714 timeo = HZ/5;
3715
3716 if (signal_pending(current)) {
3717 err = sock_intr_errno(timeo);
3718 break;
3719 }
3720
3721 release_sock(sk);
3722 timeo = schedule_timeout(timeo);
3723 lock_sock(sk);
3724
3725 err = sock_error(sk);
3726 if (err)
3727 break;
3728
3729 if (l2cap_try_push_rx_skb(sk) == 0)
3730 break;
3731 }
3732
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003733 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02003734 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003735
3736 release_sock(sk);
3737}
3738
3739static int l2cap_push_rx_skb(struct sock *sk, struct sk_buff *skb, u16 control)
3740{
3741 struct l2cap_pinfo *pi = l2cap_pi(sk);
3742 int sctrl, err;
3743
3744 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
3745 bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT;
3746 __skb_queue_tail(BUSY_QUEUE(sk), skb);
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03003747 return l2cap_try_push_rx_skb(sk);
3748
3749
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003750 }
3751
3752 err = l2cap_ertm_reassembly_sdu(sk, skb, control);
3753 if (err >= 0) {
3754 pi->buffer_seq = (pi->buffer_seq + 1) % 64;
3755 return err;
3756 }
3757
3758 /* Busy Condition */
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003759 BT_DBG("sk %p, Enter local busy", sk);
3760
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003761 pi->conn_state |= L2CAP_CONN_LOCAL_BUSY;
3762 bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT;
3763 __skb_queue_tail(BUSY_QUEUE(sk), skb);
3764
3765 sctrl = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3766 sctrl |= L2CAP_SUPER_RCV_NOT_READY;
3767 l2cap_send_sframe(pi, sctrl);
3768
3769 pi->conn_state |= L2CAP_CONN_RNR_SENT;
3770
Gustavo F. Padovan7fe9b292010-05-12 18:32:04 -03003771 del_timer(&pi->ack_timer);
3772
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003773 queue_work(_busy_wq, &pi->busy_work);
3774
3775 return err;
3776}
3777
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003778static int l2cap_streaming_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003779{
3780 struct l2cap_pinfo *pi = l2cap_pi(sk);
3781 struct sk_buff *_skb;
3782 int err = -EINVAL;
3783
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003784 /*
3785 * TODO: We have to notify the userland if some data is lost with the
3786 * Streaming Mode.
3787 */
3788
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003789 switch (control & L2CAP_CTRL_SAR) {
3790 case L2CAP_SDU_UNSEGMENTED:
3791 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3792 kfree_skb(pi->sdu);
3793 break;
3794 }
3795
3796 err = sock_queue_rcv_skb(sk, skb);
3797 if (!err)
3798 return 0;
3799
3800 break;
3801
3802 case L2CAP_SDU_START:
3803 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3804 kfree_skb(pi->sdu);
3805 break;
3806 }
3807
3808 pi->sdu_len = get_unaligned_le16(skb->data);
3809 skb_pull(skb, 2);
3810
Gustavo F. Padovan052897c2010-05-01 16:15:40 -03003811 if (pi->sdu_len > pi->imtu) {
3812 err = -EMSGSIZE;
3813 break;
3814 }
3815
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003816 pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
3817 if (!pi->sdu) {
3818 err = -ENOMEM;
3819 break;
3820 }
3821
3822 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3823
3824 pi->conn_state |= L2CAP_CONN_SAR_SDU;
3825 pi->partial_sdu_len = skb->len;
3826 err = 0;
3827 break;
3828
3829 case L2CAP_SDU_CONTINUE:
3830 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3831 break;
3832
3833 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3834
3835 pi->partial_sdu_len += skb->len;
3836 if (pi->partial_sdu_len > pi->sdu_len)
3837 kfree_skb(pi->sdu);
3838 else
3839 err = 0;
3840
3841 break;
3842
3843 case L2CAP_SDU_END:
3844 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3845 break;
3846
3847 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3848
3849 pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
3850 pi->partial_sdu_len += skb->len;
3851
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003852 if (pi->partial_sdu_len > pi->imtu)
3853 goto drop;
3854
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003855 if (pi->partial_sdu_len == pi->sdu_len) {
3856 _skb = skb_clone(pi->sdu, GFP_ATOMIC);
3857 err = sock_queue_rcv_skb(sk, _skb);
3858 if (err < 0)
3859 kfree_skb(_skb);
3860 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003861 err = 0;
3862
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003863drop:
3864 kfree_skb(pi->sdu);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003865 break;
3866 }
3867
3868 kfree_skb(skb);
3869 return err;
3870}
3871
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003872static void l2cap_check_srej_gap(struct sock *sk, u8 tx_seq)
3873{
3874 struct sk_buff *skb;
Gustavo F. Padovanafefdbc2010-05-01 16:15:43 -03003875 u16 control;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003876
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003877 while ((skb = skb_peek(SREJ_QUEUE(sk)))) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003878 if (bt_cb(skb)->tx_seq != tx_seq)
3879 break;
3880
3881 skb = skb_dequeue(SREJ_QUEUE(sk));
Gustavo F. Padovanafefdbc2010-05-01 16:15:43 -03003882 control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003883 l2cap_ertm_reassembly_sdu(sk, skb, control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003884 l2cap_pi(sk)->buffer_seq_srej =
3885 (l2cap_pi(sk)->buffer_seq_srej + 1) % 64;
Gustavo F. Padovan8ff50ec2010-05-10 19:34:11 -03003886 tx_seq = (tx_seq + 1) % 64;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003887 }
3888}
3889
3890static void l2cap_resend_srejframe(struct sock *sk, u8 tx_seq)
3891{
3892 struct l2cap_pinfo *pi = l2cap_pi(sk);
3893 struct srej_list *l, *tmp;
3894 u16 control;
3895
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003896 list_for_each_entry_safe(l, tmp, SREJ_LIST(sk), list) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003897 if (l->tx_seq == tx_seq) {
3898 list_del(&l->list);
3899 kfree(l);
3900 return;
3901 }
3902 control = L2CAP_SUPER_SELECT_REJECT;
3903 control |= l->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3904 l2cap_send_sframe(pi, control);
3905 list_del(&l->list);
3906 list_add_tail(&l->list, SREJ_LIST(sk));
3907 }
3908}
3909
3910static void l2cap_send_srejframe(struct sock *sk, u8 tx_seq)
3911{
3912 struct l2cap_pinfo *pi = l2cap_pi(sk);
3913 struct srej_list *new;
3914 u16 control;
3915
3916 while (tx_seq != pi->expected_tx_seq) {
3917 control = L2CAP_SUPER_SELECT_REJECT;
3918 control |= pi->expected_tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3919 l2cap_send_sframe(pi, control);
3920
3921 new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC);
Gustavo F. Padovan8ff50ec2010-05-10 19:34:11 -03003922 new->tx_seq = pi->expected_tx_seq;
3923 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003924 list_add_tail(&new->list, SREJ_LIST(sk));
3925 }
Gustavo F. Padovan8ff50ec2010-05-10 19:34:11 -03003926 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003927}
3928
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003929static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
3930{
3931 struct l2cap_pinfo *pi = l2cap_pi(sk);
3932 u8 tx_seq = __get_txseq(rx_control);
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003933 u8 req_seq = __get_reqseq(rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003934 u8 sar = rx_control >> L2CAP_CTRL_SAR_SHIFT;
Gustavo F. Padovanf6337c72010-05-10 18:32:04 -03003935 int tx_seq_offset, expected_tx_seq_offset;
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03003936 int num_to_ack = (pi->tx_win/6) + 1;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003937 int err = 0;
3938
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003939 BT_DBG("sk %p len %d tx_seq %d rx_control 0x%4.4x", sk, skb->len, tx_seq,
3940 rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003941
Gustavo F. Padovan9b16dc62010-05-05 20:05:57 -03003942 if (L2CAP_CTRL_FINAL & rx_control &&
3943 l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) {
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003944 del_timer(&pi->monitor_timer);
3945 if (pi->unacked_frames > 0)
3946 __mod_retrans_timer();
3947 pi->conn_state &= ~L2CAP_CONN_WAIT_F;
3948 }
3949
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003950 pi->expected_ack_seq = req_seq;
3951 l2cap_drop_acked_frames(sk);
3952
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003953 if (tx_seq == pi->expected_tx_seq)
3954 goto expected;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003955
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003956 tx_seq_offset = (tx_seq - pi->buffer_seq) % 64;
3957 if (tx_seq_offset < 0)
3958 tx_seq_offset += 64;
3959
3960 /* invalid tx_seq */
3961 if (tx_seq_offset >= pi->tx_win) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03003962 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003963 goto drop;
3964 }
3965
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003966 if (pi->conn_state == L2CAP_CONN_LOCAL_BUSY)
3967 goto drop;
3968
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003969 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3970 struct srej_list *first;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003971
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003972 first = list_first_entry(SREJ_LIST(sk),
3973 struct srej_list, list);
3974 if (tx_seq == first->tx_seq) {
3975 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3976 l2cap_check_srej_gap(sk, tx_seq);
3977
3978 list_del(&first->list);
3979 kfree(first);
3980
3981 if (list_empty(SREJ_LIST(sk))) {
3982 pi->buffer_seq = pi->buffer_seq_srej;
3983 pi->conn_state &= ~L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan855666c2010-05-01 16:15:40 -03003984 l2cap_send_ack(pi);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003985 BT_DBG("sk %p, Exit SREJ_SENT", sk);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003986 }
3987 } else {
3988 struct srej_list *l;
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003989
3990 /* duplicated tx_seq */
3991 if (l2cap_add_to_srej_queue(sk, skb, tx_seq, sar) < 0)
3992 goto drop;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003993
3994 list_for_each_entry(l, SREJ_LIST(sk), list) {
3995 if (l->tx_seq == tx_seq) {
3996 l2cap_resend_srejframe(sk, tx_seq);
3997 return 0;
3998 }
3999 }
4000 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03004001 }
4002 } else {
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03004003 expected_tx_seq_offset =
4004 (pi->expected_tx_seq - pi->buffer_seq) % 64;
4005 if (expected_tx_seq_offset < 0)
4006 expected_tx_seq_offset += 64;
4007
4008 /* duplicated tx_seq */
4009 if (tx_seq_offset < expected_tx_seq_offset)
4010 goto drop;
4011
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004012 pi->conn_state |= L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03004013
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03004014 BT_DBG("sk %p, Enter SREJ", sk);
4015
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004016 INIT_LIST_HEAD(SREJ_LIST(sk));
4017 pi->buffer_seq_srej = pi->buffer_seq;
4018
4019 __skb_queue_head_init(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004020 __skb_queue_head_init(BUSY_QUEUE(sk));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004021 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
4022
Gustavo F. Padovanef54fd92009-08-20 22:26:04 -03004023 pi->conn_state |= L2CAP_CONN_SEND_PBIT;
4024
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004025 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan7fe9b292010-05-12 18:32:04 -03004026
4027 del_timer(&pi->ack_timer);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004028 }
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03004029 return 0;
4030
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004031expected:
4032 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
4033
4034 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
Gustavo F. Padovan3b1a9f32010-05-01 16:15:42 -03004035 bt_cb(skb)->tx_seq = tx_seq;
4036 bt_cb(skb)->sar = sar;
4037 __skb_queue_tail(SREJ_QUEUE(sk), skb);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004038 return 0;
4039 }
4040
Gustavo F. Padovan2ece3682010-06-16 17:21:44 -03004041 err = l2cap_push_rx_skb(sk, skb, rx_control);
4042 if (err < 0)
4043 return 0;
4044
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03004045 if (rx_control & L2CAP_CTRL_FINAL) {
4046 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
4047 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004048 else
4049 l2cap_retransmit_frames(sk);
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03004050 }
4051
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03004052 __mod_ack_timer();
4053
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03004054 pi->num_acked = (pi->num_acked + 1) % num_to_ack;
4055 if (pi->num_acked == num_to_ack - 1)
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03004056 l2cap_send_ack(pi);
4057
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004058 return 0;
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03004059
4060drop:
4061 kfree_skb(skb);
4062 return 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004063}
4064
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004065static inline void l2cap_data_channel_rrframe(struct sock *sk, u16 rx_control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004066{
4067 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan6e3a5982010-05-01 16:15:38 -03004068
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03004069 BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, __get_reqseq(rx_control),
4070 rx_control);
4071
Gustavo F. Padovan6e3a5982010-05-01 16:15:38 -03004072 pi->expected_ack_seq = __get_reqseq(rx_control);
4073 l2cap_drop_acked_frames(sk);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004074
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004075 if (rx_control & L2CAP_CTRL_POLL) {
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03004076 pi->conn_state |= L2CAP_CONN_SEND_FBIT;
Gustavo F. Padovan05fbd892010-05-01 16:15:39 -03004077 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
4078 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
4079 (pi->unacked_frames > 0))
4080 __mod_retrans_timer();
4081
4082 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
4083 l2cap_send_srejtail(sk);
4084 } else {
4085 l2cap_send_i_or_rr_or_rnr(sk);
Gustavo F. Padovan05fbd892010-05-01 16:15:39 -03004086 }
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004087
4088 } else if (rx_control & L2CAP_CTRL_FINAL) {
4089 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004090
4091 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
4092 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004093 else
4094 l2cap_retransmit_frames(sk);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004095
4096 } else {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004097 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
4098 (pi->unacked_frames > 0))
4099 __mod_retrans_timer();
4100
4101 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004102 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004103 l2cap_send_ack(pi);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004104 } else {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004105 l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004106 }
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004107 }
4108}
4109
4110static inline void l2cap_data_channel_rejframe(struct sock *sk, u16 rx_control)
4111{
4112 struct l2cap_pinfo *pi = l2cap_pi(sk);
4113 u8 tx_seq = __get_reqseq(rx_control);
4114
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03004115 BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, tx_seq, rx_control);
4116
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004117 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
4118
Gustavo F. Padovan8abb52e2010-05-01 16:15:38 -03004119 pi->expected_ack_seq = tx_seq;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004120 l2cap_drop_acked_frames(sk);
4121
4122 if (rx_control & L2CAP_CTRL_FINAL) {
4123 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
4124 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004125 else
4126 l2cap_retransmit_frames(sk);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004127 } else {
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004128 l2cap_retransmit_frames(sk);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004129
Gustavo F. Padovan0301ef02010-05-05 20:56:43 -03004130 if (pi->conn_state & L2CAP_CONN_WAIT_F)
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004131 pi->conn_state |= L2CAP_CONN_REJ_ACT;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004132 }
4133}
4134static inline void l2cap_data_channel_srejframe(struct sock *sk, u16 rx_control)
4135{
4136 struct l2cap_pinfo *pi = l2cap_pi(sk);
4137 u8 tx_seq = __get_reqseq(rx_control);
4138
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03004139 BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, tx_seq, rx_control);
4140
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004141 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
4142
4143 if (rx_control & L2CAP_CTRL_POLL) {
4144 pi->expected_ack_seq = tx_seq;
4145 l2cap_drop_acked_frames(sk);
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03004146
4147 pi->conn_state |= L2CAP_CONN_SEND_FBIT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004148 l2cap_retransmit_one_frame(sk, tx_seq);
4149
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004150 l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004151
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004152 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
4153 pi->srej_save_reqseq = tx_seq;
4154 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
4155 }
4156 } else if (rx_control & L2CAP_CTRL_FINAL) {
4157 if ((pi->conn_state & L2CAP_CONN_SREJ_ACT) &&
4158 pi->srej_save_reqseq == tx_seq)
4159 pi->conn_state &= ~L2CAP_CONN_SREJ_ACT;
4160 else
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004161 l2cap_retransmit_one_frame(sk, tx_seq);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004162 } else {
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004163 l2cap_retransmit_one_frame(sk, tx_seq);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004164 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
4165 pi->srej_save_reqseq = tx_seq;
4166 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
4167 }
4168 }
4169}
4170
4171static inline void l2cap_data_channel_rnrframe(struct sock *sk, u16 rx_control)
4172{
4173 struct l2cap_pinfo *pi = l2cap_pi(sk);
4174 u8 tx_seq = __get_reqseq(rx_control);
4175
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03004176 BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, tx_seq, rx_control);
4177
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004178 pi->conn_state |= L2CAP_CONN_REMOTE_BUSY;
4179 pi->expected_ack_seq = tx_seq;
4180 l2cap_drop_acked_frames(sk);
4181
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03004182 if (rx_control & L2CAP_CTRL_POLL)
4183 pi->conn_state |= L2CAP_CONN_SEND_FBIT;
4184
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03004185 if (!(pi->conn_state & L2CAP_CONN_SREJ_SENT)) {
4186 del_timer(&pi->retrans_timer);
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -03004187 if (rx_control & L2CAP_CTRL_POLL)
4188 l2cap_send_rr_or_rnr(pi, L2CAP_CTRL_FINAL);
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03004189 return;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004190 }
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03004191
4192 if (rx_control & L2CAP_CTRL_POLL)
4193 l2cap_send_srejtail(sk);
4194 else
4195 l2cap_send_sframe(pi, L2CAP_SUPER_RCV_READY);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004196}
4197
4198static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
4199{
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004200 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
4201
Gustavo F. Padovan9b16dc62010-05-05 20:05:57 -03004202 if (L2CAP_CTRL_FINAL & rx_control &&
4203 l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004204 del_timer(&l2cap_pi(sk)->monitor_timer);
4205 if (l2cap_pi(sk)->unacked_frames > 0)
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03004206 __mod_retrans_timer();
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004207 l2cap_pi(sk)->conn_state &= ~L2CAP_CONN_WAIT_F;
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03004208 }
4209
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004210 switch (rx_control & L2CAP_CTRL_SUPERVISE) {
4211 case L2CAP_SUPER_RCV_READY:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004212 l2cap_data_channel_rrframe(sk, rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004213 break;
4214
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004215 case L2CAP_SUPER_REJECT:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004216 l2cap_data_channel_rejframe(sk, rx_control);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03004217 break;
4218
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004219 case L2CAP_SUPER_SELECT_REJECT:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004220 l2cap_data_channel_srejframe(sk, rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004221 break;
4222
4223 case L2CAP_SUPER_RCV_NOT_READY:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004224 l2cap_data_channel_rnrframe(sk, rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004225 break;
4226 }
4227
Gustavo F. Padovanfaaebd12010-05-01 16:15:35 -03004228 kfree_skb(skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004229 return 0;
4230}
4231
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03004232static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb)
4233{
4234 struct l2cap_pinfo *pi = l2cap_pi(sk);
4235 u16 control;
4236 u8 req_seq;
4237 int len, next_tx_seq_offset, req_seq_offset;
4238
4239 control = get_unaligned_le16(skb->data);
4240 skb_pull(skb, 2);
4241 len = skb->len;
4242
4243 /*
4244 * We can just drop the corrupted I-frame here.
4245 * Receiver will miss it and start proper recovery
4246 * procedures and ask retransmission.
4247 */
4248 if (l2cap_check_fcs(pi, skb))
4249 goto drop;
4250
4251 if (__is_sar_start(control) && __is_iframe(control))
4252 len -= 2;
4253
4254 if (pi->fcs == L2CAP_FCS_CRC16)
4255 len -= 2;
4256
4257 if (len > pi->mps) {
4258 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
4259 goto drop;
4260 }
4261
4262 req_seq = __get_reqseq(control);
4263 req_seq_offset = (req_seq - pi->expected_ack_seq) % 64;
4264 if (req_seq_offset < 0)
4265 req_seq_offset += 64;
4266
4267 next_tx_seq_offset =
4268 (pi->next_tx_seq - pi->expected_ack_seq) % 64;
4269 if (next_tx_seq_offset < 0)
4270 next_tx_seq_offset += 64;
4271
4272 /* check for invalid req-seq */
4273 if (req_seq_offset > next_tx_seq_offset) {
4274 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
4275 goto drop;
4276 }
4277
4278 if (__is_iframe(control)) {
4279 if (len < 0) {
4280 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
4281 goto drop;
4282 }
4283
4284 l2cap_data_channel_iframe(sk, control, skb);
4285 } else {
4286 if (len != 0) {
4287 BT_ERR("%d", len);
4288 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
4289 goto drop;
4290 }
4291
4292 l2cap_data_channel_sframe(sk, control, skb);
4293 }
4294
4295 return 0;
4296
4297drop:
4298 kfree_skb(skb);
4299 return 0;
4300}
4301
Linus Torvalds1da177e2005-04-16 15:20:36 -07004302static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk_buff *skb)
4303{
4304 struct sock *sk;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004305 struct l2cap_pinfo *pi;
Nathan Holstein51893f82010-06-09 15:46:25 -04004306 u16 control;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03004307 u8 tx_seq;
4308 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004309
4310 sk = l2cap_get_chan_by_scid(&conn->chan_list, cid);
4311 if (!sk) {
4312 BT_DBG("unknown cid 0x%4.4x", cid);
4313 goto drop;
4314 }
4315
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004316 pi = l2cap_pi(sk);
4317
Linus Torvalds1da177e2005-04-16 15:20:36 -07004318 BT_DBG("sk %p, len %d", sk, skb->len);
4319
4320 if (sk->sk_state != BT_CONNECTED)
4321 goto drop;
4322
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004323 switch (pi->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004324 case L2CAP_MODE_BASIC:
4325 /* If socket recv buffers overflows we drop data here
4326 * which is *bad* because L2CAP has to be reliable.
4327 * But we don't have any other choice. L2CAP doesn't
4328 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07004329
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004330 if (pi->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004331 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004332
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004333 if (!sock_queue_rcv_skb(sk, skb))
4334 goto done;
4335 break;
4336
4337 case L2CAP_MODE_ERTM:
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03004338 if (!sock_owned_by_user(sk)) {
4339 l2cap_ertm_data_rcv(sk, skb);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004340 } else {
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03004341 if (sk_add_backlog(sk, skb))
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004342 goto drop;
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004343 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004344
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02004345 goto done;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004346
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004347 case L2CAP_MODE_STREAMING:
4348 control = get_unaligned_le16(skb->data);
4349 skb_pull(skb, 2);
4350 len = skb->len;
4351
Gustavo F. Padovan26000082010-05-11 22:02:00 -03004352 if (l2cap_check_fcs(pi, skb))
4353 goto drop;
4354
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004355 if (__is_sar_start(control))
4356 len -= 2;
4357
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004358 if (pi->fcs == L2CAP_FCS_CRC16)
4359 len -= 2;
4360
Nathan Holstein51893f82010-06-09 15:46:25 -04004361 if (len > pi->mps || len < 0 || __is_sframe(control))
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004362 goto drop;
4363
4364 tx_seq = __get_txseq(control);
4365
4366 if (pi->expected_tx_seq == tx_seq)
4367 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
4368 else
Gustavo F. Padovan7dffe422010-05-01 16:15:36 -03004369 pi->expected_tx_seq = (tx_seq + 1) % 64;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004370
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004371 l2cap_streaming_reassembly_sdu(sk, skb, control);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004372
4373 goto done;
4374
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004375 default:
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03004376 BT_DBG("sk %p: bad mode 0x%2.2x", sk, pi->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004377 break;
4378 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004379
4380drop:
4381 kfree_skb(skb);
4382
4383done:
Marcel Holtmann01394182006-07-03 10:02:46 +02004384 if (sk)
4385 bh_unlock_sock(sk);
4386
Linus Torvalds1da177e2005-04-16 15:20:36 -07004387 return 0;
4388}
4389
Al Viro8e036fc2007-07-29 00:16:36 -07004390static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004391{
4392 struct sock *sk;
4393
4394 sk = l2cap_get_sock_by_psm(0, psm, conn->src);
4395 if (!sk)
4396 goto drop;
4397
4398 BT_DBG("sk %p, len %d", sk, skb->len);
4399
4400 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_CONNECTED)
4401 goto drop;
4402
4403 if (l2cap_pi(sk)->imtu < skb->len)
4404 goto drop;
4405
4406 if (!sock_queue_rcv_skb(sk, skb))
4407 goto done;
4408
4409drop:
4410 kfree_skb(skb);
4411
4412done:
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03004413 if (sk)
4414 bh_unlock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004415 return 0;
4416}
4417
4418static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
4419{
4420 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07004421 u16 cid, len;
4422 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004423
4424 skb_pull(skb, L2CAP_HDR_SIZE);
4425 cid = __le16_to_cpu(lh->cid);
4426 len = __le16_to_cpu(lh->len);
4427
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004428 if (len != skb->len) {
4429 kfree_skb(skb);
4430 return;
4431 }
4432
Linus Torvalds1da177e2005-04-16 15:20:36 -07004433 BT_DBG("len %d, cid 0x%4.4x", len, cid);
4434
4435 switch (cid) {
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03004436 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07004437 l2cap_sig_channel(conn, skb);
4438 break;
4439
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03004440 case L2CAP_CID_CONN_LESS:
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03004441 psm = get_unaligned_le16(skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004442 skb_pull(skb, 2);
4443 l2cap_conless_channel(conn, psm, skb);
4444 break;
4445
4446 default:
4447 l2cap_data_channel(conn, cid, skb);
4448 break;
4449 }
4450}
4451
4452/* ---- L2CAP interface with lower layer (HCI) ---- */
4453
4454static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
4455{
4456 int exact = 0, lm1 = 0, lm2 = 0;
4457 register struct sock *sk;
4458 struct hlist_node *node;
4459
4460 if (type != ACL_LINK)
João Paulo Rechi Vita963cf682010-06-22 13:56:28 -03004461 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004462
4463 BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
4464
4465 /* Find listening sockets and check their link_mode */
4466 read_lock(&l2cap_sk_list.lock);
4467 sk_for_each(sk, node, &l2cap_sk_list.head) {
4468 if (sk->sk_state != BT_LISTEN)
4469 continue;
4470
4471 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01004472 lm1 |= HCI_LM_ACCEPT;
4473 if (l2cap_pi(sk)->role_switch)
4474 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004475 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01004476 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
4477 lm2 |= HCI_LM_ACCEPT;
4478 if (l2cap_pi(sk)->role_switch)
4479 lm2 |= HCI_LM_MASTER;
4480 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004481 }
4482 read_unlock(&l2cap_sk_list.lock);
4483
4484 return exact ? lm1 : lm2;
4485}
4486
4487static int l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
4488{
Marcel Holtmann01394182006-07-03 10:02:46 +02004489 struct l2cap_conn *conn;
4490
Linus Torvalds1da177e2005-04-16 15:20:36 -07004491 BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
4492
4493 if (hcon->type != ACL_LINK)
João Paulo Rechi Vita963cf682010-06-22 13:56:28 -03004494 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004495
4496 if (!status) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004497 conn = l2cap_conn_add(hcon, status);
4498 if (conn)
4499 l2cap_conn_ready(conn);
Marcel Holtmann01394182006-07-03 10:02:46 +02004500 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -07004501 l2cap_conn_del(hcon, bt_err(status));
4502
4503 return 0;
4504}
4505
Marcel Holtmann2950f212009-02-12 14:02:50 +01004506static int l2cap_disconn_ind(struct hci_conn *hcon)
4507{
4508 struct l2cap_conn *conn = hcon->l2cap_data;
4509
4510 BT_DBG("hcon %p", hcon);
4511
4512 if (hcon->type != ACL_LINK || !conn)
4513 return 0x13;
4514
4515 return conn->disc_reason;
4516}
4517
4518static int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004519{
4520 BT_DBG("hcon %p reason %d", hcon, reason);
4521
4522 if (hcon->type != ACL_LINK)
João Paulo Rechi Vita963cf682010-06-22 13:56:28 -03004523 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004524
4525 l2cap_conn_del(hcon, bt_err(reason));
Marcel Holtmann01394182006-07-03 10:02:46 +02004526
Linus Torvalds1da177e2005-04-16 15:20:36 -07004527 return 0;
4528}
4529
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004530static inline void l2cap_check_encryption(struct sock *sk, u8 encrypt)
4531{
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03004532 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM)
Marcel Holtmann255c7602009-02-04 21:07:19 +01004533 return;
4534
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004535 if (encrypt == 0x00) {
4536 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM) {
4537 l2cap_sock_clear_timer(sk);
4538 l2cap_sock_set_timer(sk, HZ * 5);
4539 } else if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
4540 __l2cap_sock_close(sk, ECONNREFUSED);
4541 } else {
4542 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM)
4543 l2cap_sock_clear_timer(sk);
4544 }
4545}
4546
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004547static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004548{
4549 struct l2cap_chan_list *l;
Marcel Holtmann40be4922008-07-14 20:13:50 +02004550 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004551 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004552
Marcel Holtmann01394182006-07-03 10:02:46 +02004553 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004554 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02004555
Linus Torvalds1da177e2005-04-16 15:20:36 -07004556 l = &conn->chan_list;
4557
4558 BT_DBG("conn %p", conn);
4559
4560 read_lock(&l->lock);
4561
4562 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
4563 bh_lock_sock(sk);
4564
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01004565 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND) {
4566 bh_unlock_sock(sk);
4567 continue;
4568 }
4569
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004570 if (!status && (sk->sk_state == BT_CONNECTED ||
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004571 sk->sk_state == BT_CONFIG)) {
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004572 l2cap_check_encryption(sk, encrypt);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02004573 bh_unlock_sock(sk);
4574 continue;
4575 }
4576
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004577 if (sk->sk_state == BT_CONNECT) {
4578 if (!status) {
4579 struct l2cap_conn_req req;
4580 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
4581 req.psm = l2cap_pi(sk)->psm;
4582
4583 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03004584 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004585
4586 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
4587 L2CAP_CONN_REQ, sizeof(req), &req);
4588 } else {
4589 l2cap_sock_clear_timer(sk);
4590 l2cap_sock_set_timer(sk, HZ / 10);
4591 }
4592 } else if (sk->sk_state == BT_CONNECT2) {
4593 struct l2cap_conn_rsp rsp;
4594 __u16 result;
4595
4596 if (!status) {
4597 sk->sk_state = BT_CONFIG;
4598 result = L2CAP_CR_SUCCESS;
4599 } else {
4600 sk->sk_state = BT_DISCONN;
4601 l2cap_sock_set_timer(sk, HZ / 10);
4602 result = L2CAP_CR_SEC_BLOCK;
4603 }
4604
4605 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
4606 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
4607 rsp.result = cpu_to_le16(result);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02004608 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004609 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
4610 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004611 }
4612
Linus Torvalds1da177e2005-04-16 15:20:36 -07004613 bh_unlock_sock(sk);
4614 }
4615
4616 read_unlock(&l->lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004617
Linus Torvalds1da177e2005-04-16 15:20:36 -07004618 return 0;
4619}
4620
4621static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
4622{
4623 struct l2cap_conn *conn = hcon->l2cap_data;
4624
4625 if (!conn && !(conn = l2cap_conn_add(hcon, 0)))
4626 goto drop;
4627
4628 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
4629
4630 if (flags & ACL_START) {
4631 struct l2cap_hdr *hdr;
4632 int len;
4633
4634 if (conn->rx_len) {
4635 BT_ERR("Unexpected start frame (len %d)", skb->len);
4636 kfree_skb(conn->rx_skb);
4637 conn->rx_skb = NULL;
4638 conn->rx_len = 0;
4639 l2cap_conn_unreliable(conn, ECOMM);
4640 }
4641
4642 if (skb->len < 2) {
4643 BT_ERR("Frame is too short (len %d)", skb->len);
4644 l2cap_conn_unreliable(conn, ECOMM);
4645 goto drop;
4646 }
4647
4648 hdr = (struct l2cap_hdr *) skb->data;
4649 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
4650
4651 if (len == skb->len) {
4652 /* Complete frame received */
4653 l2cap_recv_frame(conn, skb);
4654 return 0;
4655 }
4656
4657 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
4658
4659 if (skb->len > len) {
4660 BT_ERR("Frame is too long (len %d, expected len %d)",
4661 skb->len, len);
4662 l2cap_conn_unreliable(conn, ECOMM);
4663 goto drop;
4664 }
4665
4666 /* Allocate skb for the complete frame (with header) */
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03004667 conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC);
4668 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004669 goto drop;
4670
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03004671 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004672 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004673 conn->rx_len = len - skb->len;
4674 } else {
4675 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
4676
4677 if (!conn->rx_len) {
4678 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
4679 l2cap_conn_unreliable(conn, ECOMM);
4680 goto drop;
4681 }
4682
4683 if (skb->len > conn->rx_len) {
4684 BT_ERR("Fragment is too long (len %d, expected %d)",
4685 skb->len, conn->rx_len);
4686 kfree_skb(conn->rx_skb);
4687 conn->rx_skb = NULL;
4688 conn->rx_len = 0;
4689 l2cap_conn_unreliable(conn, ECOMM);
4690 goto drop;
4691 }
4692
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03004693 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004694 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004695 conn->rx_len -= skb->len;
4696
4697 if (!conn->rx_len) {
4698 /* Complete frame received */
4699 l2cap_recv_frame(conn, conn->rx_skb);
4700 conn->rx_skb = NULL;
4701 }
4702 }
4703
4704drop:
4705 kfree_skb(skb);
4706 return 0;
4707}
4708
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004709static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004710{
4711 struct sock *sk;
4712 struct hlist_node *node;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004713
4714 read_lock_bh(&l2cap_sk_list.lock);
4715
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004716 sk_for_each(sk, node, &l2cap_sk_list.head) {
4717 struct l2cap_pinfo *pi = l2cap_pi(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004718
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004719 seq_printf(f, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d\n",
4720 batostr(&bt_sk(sk)->src),
4721 batostr(&bt_sk(sk)->dst),
4722 sk->sk_state, __le16_to_cpu(pi->psm),
4723 pi->scid, pi->dcid,
4724 pi->imtu, pi->omtu, pi->sec_level);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004725 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004726
Linus Torvalds1da177e2005-04-16 15:20:36 -07004727 read_unlock_bh(&l2cap_sk_list.lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004728
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004729 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004730}
4731
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004732static int l2cap_debugfs_open(struct inode *inode, struct file *file)
4733{
4734 return single_open(file, l2cap_debugfs_show, inode->i_private);
4735}
4736
4737static const struct file_operations l2cap_debugfs_fops = {
4738 .open = l2cap_debugfs_open,
4739 .read = seq_read,
4740 .llseek = seq_lseek,
4741 .release = single_release,
4742};
4743
4744static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004745
Eric Dumazet90ddc4f2005-12-22 12:49:22 -08004746static const struct proto_ops l2cap_sock_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004747 .family = PF_BLUETOOTH,
4748 .owner = THIS_MODULE,
4749 .release = l2cap_sock_release,
4750 .bind = l2cap_sock_bind,
4751 .connect = l2cap_sock_connect,
4752 .listen = l2cap_sock_listen,
4753 .accept = l2cap_sock_accept,
4754 .getname = l2cap_sock_getname,
4755 .sendmsg = l2cap_sock_sendmsg,
Marcel Holtmannf66dc812009-01-15 21:57:00 +01004756 .recvmsg = l2cap_sock_recvmsg,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004757 .poll = bt_sock_poll,
Marcel Holtmann3241ad82008-07-14 20:13:50 +02004758 .ioctl = bt_sock_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004759 .mmap = sock_no_mmap,
4760 .socketpair = sock_no_socketpair,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004761 .shutdown = l2cap_sock_shutdown,
4762 .setsockopt = l2cap_sock_setsockopt,
4763 .getsockopt = l2cap_sock_getsockopt
4764};
4765
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +00004766static const struct net_proto_family l2cap_sock_family_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004767 .family = PF_BLUETOOTH,
4768 .owner = THIS_MODULE,
4769 .create = l2cap_sock_create,
4770};
4771
4772static struct hci_proto l2cap_hci_proto = {
4773 .name = "L2CAP",
4774 .id = HCI_PROTO_L2CAP,
4775 .connect_ind = l2cap_connect_ind,
4776 .connect_cfm = l2cap_connect_cfm,
4777 .disconn_ind = l2cap_disconn_ind,
Marcel Holtmann2950f212009-02-12 14:02:50 +01004778 .disconn_cfm = l2cap_disconn_cfm,
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004779 .security_cfm = l2cap_security_cfm,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004780 .recv_acldata = l2cap_recv_acldata
4781};
4782
4783static int __init l2cap_init(void)
4784{
4785 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004786
Linus Torvalds1da177e2005-04-16 15:20:36 -07004787 err = proto_register(&l2cap_proto, 0);
4788 if (err < 0)
4789 return err;
4790
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004791 _busy_wq = create_singlethread_workqueue("l2cap");
4792 if (!_busy_wq)
4793 goto error;
4794
Linus Torvalds1da177e2005-04-16 15:20:36 -07004795 err = bt_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops);
4796 if (err < 0) {
4797 BT_ERR("L2CAP socket registration failed");
4798 goto error;
4799 }
4800
4801 err = hci_register_proto(&l2cap_hci_proto);
4802 if (err < 0) {
4803 BT_ERR("L2CAP protocol registration failed");
4804 bt_sock_unregister(BTPROTO_L2CAP);
4805 goto error;
4806 }
4807
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004808 if (bt_debugfs) {
4809 l2cap_debugfs = debugfs_create_file("l2cap", 0444,
4810 bt_debugfs, NULL, &l2cap_debugfs_fops);
4811 if (!l2cap_debugfs)
4812 BT_ERR("Failed to create L2CAP debug file");
4813 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004814
4815 BT_INFO("L2CAP ver %s", VERSION);
4816 BT_INFO("L2CAP socket layer initialized");
4817
4818 return 0;
4819
4820error:
4821 proto_unregister(&l2cap_proto);
4822 return err;
4823}
4824
4825static void __exit l2cap_exit(void)
4826{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004827 debugfs_remove(l2cap_debugfs);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004828
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004829 flush_workqueue(_busy_wq);
4830 destroy_workqueue(_busy_wq);
4831
Linus Torvalds1da177e2005-04-16 15:20:36 -07004832 if (bt_sock_unregister(BTPROTO_L2CAP) < 0)
4833 BT_ERR("L2CAP socket unregistration failed");
4834
4835 if (hci_unregister_proto(&l2cap_hci_proto) < 0)
4836 BT_ERR("L2CAP protocol unregistration failed");
4837
4838 proto_unregister(&l2cap_proto);
4839}
4840
4841void l2cap_load(void)
4842{
4843 /* Dummy function to trigger automatic L2CAP module loading by
4844 * other modules that use L2CAP sockets but don't use any other
4845 * symbols from it. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07004846}
4847EXPORT_SYMBOL(l2cap_load);
4848
4849module_init(l2cap_init);
4850module_exit(l2cap_exit);
4851
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07004852module_param(enable_ertm, bool, 0644);
4853MODULE_PARM_DESC(enable_ertm, "Enable enhanced retransmission mode");
4854
Marcel Holtmann63fbd242008-08-18 13:23:53 +02004855MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004856MODULE_DESCRIPTION("Bluetooth L2CAP ver " VERSION);
4857MODULE_VERSION(VERSION);
4858MODULE_LICENSE("GPL");
4859MODULE_ALIAS("bt-proto-0");