blob: fd507cbc79323ef76df9c77d3e8aa3914e40da91 [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
4
5 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License version 2 as
9 published by the Free Software Foundation;
10
11 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
12 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
14 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090015 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
16 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Linus Torvalds1da177e2005-04-16 15:20:36 -070018 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090020 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
21 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
Linus Torvalds1da177e2005-04-16 15:20:36 -070022 SOFTWARE IS DISCLAIMED.
23*/
24
25/* Bluetooth L2CAP core and sockets. */
26
Linus Torvalds1da177e2005-04-16 15:20:36 -070027#include <linux/module.h>
28
29#include <linux/types.h>
Randy Dunlap4fc268d2006-01-11 12:17:47 -080030#include <linux/capability.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070031#include <linux/errno.h>
32#include <linux/kernel.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070033#include <linux/sched.h>
34#include <linux/slab.h>
35#include <linux/poll.h>
36#include <linux/fcntl.h>
37#include <linux/init.h>
38#include <linux/interrupt.h>
39#include <linux/socket.h>
40#include <linux/skbuff.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070041#include <linux/list.h>
Marcel Holtmannbe9d1222005-11-08 09:57:38 -080042#include <linux/device.h>
Marcel Holtmannaef7d972010-03-21 05:27:45 +010043#include <linux/debugfs.h>
44#include <linux/seq_file.h>
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -030045#include <linux/uaccess.h>
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -030046#include <linux/crc16.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070047#include <net/sock.h>
48
49#include <asm/system.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070050#include <asm/unaligned.h>
51
52#include <net/bluetooth/bluetooth.h>
53#include <net/bluetooth/hci_core.h>
54#include <net/bluetooth/l2cap.h>
55
Marcel Holtmann44dd46d2009-05-02 19:09:01 -070056#define VERSION "2.14"
57
Gustavo F. Padovan84fb0a62010-05-01 16:15:42 -030058#ifdef CONFIG_BT_L2CAP_EXT_FEATURES
59static int enable_ertm = 1;
60#else
Marcel Holtmann44dd46d2009-05-02 19:09:01 -070061static int enable_ertm = 0;
Gustavo F. Padovan84fb0a62010-05-01 16:15:42 -030062#endif
Marcel Holtmannf0709e02007-10-20 13:38:51 +020063
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -070064static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN;
Marcel Holtmanne1027a72009-02-09 09:18:02 +010065static u8 l2cap_fixed_chan[8] = { 0x02, };
Linus Torvalds1da177e2005-04-16 15:20:36 -070066
Eric Dumazet90ddc4f2005-12-22 12:49:22 -080067static const struct proto_ops l2cap_sock_ops;
Linus Torvalds1da177e2005-04-16 15:20:36 -070068
Gustavo F. Padovan1890d362010-05-01 16:15:44 -030069static struct workqueue_struct *_busy_wq;
70
Linus Torvalds1da177e2005-04-16 15:20:36 -070071static struct bt_sock_list l2cap_sk_list = {
Robert P. J. Dayd5fb2962008-03-28 16:17:38 -070072 .lock = __RW_LOCK_UNLOCKED(l2cap_sk_list.lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -070073};
74
Gustavo F. Padovan1890d362010-05-01 16:15:44 -030075static void l2cap_busy_work(struct work_struct *work);
76
Linus Torvalds1da177e2005-04-16 15:20:36 -070077static void __l2cap_sock_close(struct sock *sk, int reason);
78static void l2cap_sock_close(struct sock *sk);
79static void l2cap_sock_kill(struct sock *sk);
80
81static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
82 u8 code, u8 ident, u16 dlen, void *data);
83
84/* ---- 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);
279}
280
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200281/* Service level security */
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100282static inline int l2cap_check_security(struct sock *sk)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200283{
284 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100285 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200286
Marcel Holtmann00ae4af2009-02-12 16:19:45 +0100287 if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) {
288 if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
289 auth_type = HCI_AT_NO_BONDING_MITM;
290 else
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -0300291 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann00ae4af2009-02-12 16:19:45 +0100292
293 if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW)
294 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
295 } else {
296 switch (l2cap_pi(sk)->sec_level) {
297 case BT_SECURITY_HIGH:
298 auth_type = HCI_AT_GENERAL_BONDING_MITM;
299 break;
300 case BT_SECURITY_MEDIUM:
301 auth_type = HCI_AT_GENERAL_BONDING;
302 break;
303 default:
304 auth_type = HCI_AT_NO_BONDING;
305 break;
306 }
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100307 }
308
309 return hci_conn_security(conn->hcon, l2cap_pi(sk)->sec_level,
310 auth_type);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200311}
312
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200313static inline u8 l2cap_get_ident(struct l2cap_conn *conn)
314{
315 u8 id;
316
317 /* Get next available identificator.
318 * 1 - 128 are used by kernel.
319 * 129 - 199 are reserved.
320 * 200 - 254 are used by utilities like l2ping, etc.
321 */
322
323 spin_lock_bh(&conn->lock);
324
325 if (++conn->tx_ident > 128)
326 conn->tx_ident = 1;
327
328 id = conn->tx_ident;
329
330 spin_unlock_bh(&conn->lock);
331
332 return id;
333}
334
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300335static inline void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200336{
337 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
338
339 BT_DBG("code 0x%2.2x", code);
340
341 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300342 return;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200343
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300344 hci_send_acl(conn->hcon, skb, 0);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200345}
346
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300347static inline void l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300348{
349 struct sk_buff *skb;
350 struct l2cap_hdr *lh;
351 struct l2cap_conn *conn = pi->conn;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300352 int count, hlen = L2CAP_HDR_SIZE + 2;
353
354 if (pi->fcs == L2CAP_FCS_CRC16)
355 hlen += 2;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300356
357 BT_DBG("pi %p, control 0x%2.2x", pi, control);
358
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300359 count = min_t(unsigned int, conn->mtu, hlen);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300360 control |= L2CAP_CTRL_FRAME_TYPE;
361
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -0300362 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
363 control |= L2CAP_CTRL_FINAL;
364 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
365 }
366
Gustavo F. Padovanf0946cc2010-05-01 16:15:37 -0300367 if (pi->conn_state & L2CAP_CONN_SEND_PBIT) {
368 control |= L2CAP_CTRL_POLL;
369 pi->conn_state &= ~L2CAP_CONN_SEND_PBIT;
370 }
371
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300372 skb = bt_skb_alloc(count, GFP_ATOMIC);
373 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300374 return;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300375
376 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300377 lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300378 lh->cid = cpu_to_le16(pi->dcid);
379 put_unaligned_le16(control, skb_put(skb, 2));
380
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300381 if (pi->fcs == L2CAP_FCS_CRC16) {
382 u16 fcs = crc16(0, (u8 *)lh, count - 2);
383 put_unaligned_le16(fcs, skb_put(skb, 2));
384 }
385
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300386 hci_send_acl(pi->conn->hcon, skb, 0);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300387}
388
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300389static inline void l2cap_send_rr_or_rnr(struct l2cap_pinfo *pi, u16 control)
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300390{
Gustavo F. Padovan1890d362010-05-01 16:15:44 -0300391 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300392 control |= L2CAP_SUPER_RCV_NOT_READY;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -0300393 pi->conn_state |= L2CAP_CONN_RNR_SENT;
394 } else
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300395 control |= L2CAP_SUPER_RCV_READY;
396
Gustavo F. Padovan2ab25cd2009-10-03 02:34:40 -0300397 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
398
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300399 l2cap_send_sframe(pi, control);
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300400}
401
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300402static inline int __l2cap_no_conn_pending(struct sock *sk)
403{
404 return !(l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND);
405}
406
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200407static void l2cap_do_start(struct sock *sk)
408{
409 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
410
411 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +0100412 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
413 return;
414
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300415 if (l2cap_check_security(sk) && __l2cap_no_conn_pending(sk)) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200416 struct l2cap_conn_req req;
417 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
418 req.psm = l2cap_pi(sk)->psm;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200419
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200420 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300421 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200422
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200423 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200424 L2CAP_CONN_REQ, sizeof(req), &req);
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200425 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200426 } else {
427 struct l2cap_info_req req;
428 req.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
429
430 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
431 conn->info_ident = l2cap_get_ident(conn);
432
433 mod_timer(&conn->info_timer, jiffies +
434 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
435
436 l2cap_send_cmd(conn, conn->info_ident,
437 L2CAP_INFO_REQ, sizeof(req), &req);
438 }
439}
440
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300441static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct sock *sk)
442{
443 struct l2cap_disconn_req req;
444
445 req.dcid = cpu_to_le16(l2cap_pi(sk)->dcid);
446 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
447 l2cap_send_cmd(conn, l2cap_get_ident(conn),
448 L2CAP_DISCONN_REQ, sizeof(req), &req);
449}
450
Linus Torvalds1da177e2005-04-16 15:20:36 -0700451/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200452static void l2cap_conn_start(struct l2cap_conn *conn)
453{
454 struct l2cap_chan_list *l = &conn->chan_list;
455 struct sock *sk;
456
457 BT_DBG("conn %p", conn);
458
459 read_lock(&l->lock);
460
461 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
462 bh_lock_sock(sk);
463
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300464 if (sk->sk_type != SOCK_SEQPACKET &&
465 sk->sk_type != SOCK_STREAM) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200466 bh_unlock_sock(sk);
467 continue;
468 }
469
470 if (sk->sk_state == BT_CONNECT) {
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300471 if (l2cap_check_security(sk) &&
472 __l2cap_no_conn_pending(sk)) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200473 struct l2cap_conn_req req;
474 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
475 req.psm = l2cap_pi(sk)->psm;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200476
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200477 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300478 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200479
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200480 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200481 L2CAP_CONN_REQ, sizeof(req), &req);
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200482 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200483 } else if (sk->sk_state == BT_CONNECT2) {
484 struct l2cap_conn_rsp rsp;
485 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
486 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
487
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100488 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100489 if (bt_sk(sk)->defer_setup) {
490 struct sock *parent = bt_sk(sk)->parent;
491 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
492 rsp.status = cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
493 parent->sk_data_ready(parent, 0);
494
495 } else {
496 sk->sk_state = BT_CONFIG;
497 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
498 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
499 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200500 } else {
501 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
502 rsp.status = cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
503 }
504
505 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
506 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
507 }
508
509 bh_unlock_sock(sk);
510 }
511
512 read_unlock(&l->lock);
513}
514
515static void l2cap_conn_ready(struct l2cap_conn *conn)
516{
517 struct l2cap_chan_list *l = &conn->chan_list;
518 struct sock *sk;
519
520 BT_DBG("conn %p", conn);
521
522 read_lock(&l->lock);
523
524 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
525 bh_lock_sock(sk);
526
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300527 if (sk->sk_type != SOCK_SEQPACKET &&
528 sk->sk_type != SOCK_STREAM) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200529 l2cap_sock_clear_timer(sk);
530 sk->sk_state = BT_CONNECTED;
531 sk->sk_state_change(sk);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200532 } else if (sk->sk_state == BT_CONNECT)
533 l2cap_do_start(sk);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200534
535 bh_unlock_sock(sk);
536 }
537
538 read_unlock(&l->lock);
539}
540
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200541/* Notify sockets that we cannot guaranty reliability anymore */
542static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
543{
544 struct l2cap_chan_list *l = &conn->chan_list;
545 struct sock *sk;
546
547 BT_DBG("conn %p", conn);
548
549 read_lock(&l->lock);
550
551 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100552 if (l2cap_pi(sk)->force_reliable)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200553 sk->sk_err = err;
554 }
555
556 read_unlock(&l->lock);
557}
558
559static void l2cap_info_timeout(unsigned long arg)
560{
561 struct l2cap_conn *conn = (void *) arg;
562
Marcel Holtmann984947d2009-02-06 23:35:19 +0100563 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +0100564 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +0100565
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200566 l2cap_conn_start(conn);
567}
568
Linus Torvalds1da177e2005-04-16 15:20:36 -0700569static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
570{
Marcel Holtmann01394182006-07-03 10:02:46 +0200571 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700572
Marcel Holtmann01394182006-07-03 10:02:46 +0200573 if (conn || status)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700574 return conn;
575
Marcel Holtmann01394182006-07-03 10:02:46 +0200576 conn = kzalloc(sizeof(struct l2cap_conn), GFP_ATOMIC);
577 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700578 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700579
580 hcon->l2cap_data = conn;
581 conn->hcon = hcon;
582
Marcel Holtmann01394182006-07-03 10:02:46 +0200583 BT_DBG("hcon %p conn %p", hcon, conn);
584
Linus Torvalds1da177e2005-04-16 15:20:36 -0700585 conn->mtu = hcon->hdev->acl_mtu;
586 conn->src = &hcon->hdev->bdaddr;
587 conn->dst = &hcon->dst;
588
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200589 conn->feat_mask = 0;
590
Linus Torvalds1da177e2005-04-16 15:20:36 -0700591 spin_lock_init(&conn->lock);
592 rwlock_init(&conn->chan_list.lock);
593
Dave Young45054dc2009-10-18 20:28:30 +0000594 setup_timer(&conn->info_timer, l2cap_info_timeout,
595 (unsigned long) conn);
596
Marcel Holtmann2950f212009-02-12 14:02:50 +0100597 conn->disc_reason = 0x13;
598
Linus Torvalds1da177e2005-04-16 15:20:36 -0700599 return conn;
600}
601
Marcel Holtmann01394182006-07-03 10:02:46 +0200602static void l2cap_conn_del(struct hci_conn *hcon, int err)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700603{
Marcel Holtmann01394182006-07-03 10:02:46 +0200604 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700605 struct sock *sk;
606
Marcel Holtmann01394182006-07-03 10:02:46 +0200607 if (!conn)
608 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700609
610 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
611
Wei Yongjun7585b972009-02-25 18:29:52 +0800612 kfree_skb(conn->rx_skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700613
614 /* Kill channels */
615 while ((sk = conn->chan_list.head)) {
616 bh_lock_sock(sk);
617 l2cap_chan_del(sk, err);
618 bh_unlock_sock(sk);
619 l2cap_sock_kill(sk);
620 }
621
Dave Young8e8440f2008-03-03 12:18:55 -0800622 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
623 del_timer_sync(&conn->info_timer);
Thomas Gleixner3ab22732008-02-26 17:42:56 -0800624
Linus Torvalds1da177e2005-04-16 15:20:36 -0700625 hcon->l2cap_data = NULL;
626 kfree(conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700627}
628
629static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
630{
631 struct l2cap_chan_list *l = &conn->chan_list;
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200632 write_lock_bh(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700633 __l2cap_chan_add(conn, sk, parent);
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200634 write_unlock_bh(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700635}
636
Linus Torvalds1da177e2005-04-16 15:20:36 -0700637/* ---- Socket interface ---- */
Al Viro8e036fc2007-07-29 00:16:36 -0700638static struct sock *__l2cap_get_sock_by_addr(__le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700639{
640 struct sock *sk;
641 struct hlist_node *node;
642 sk_for_each(sk, node, &l2cap_sk_list.head)
643 if (l2cap_pi(sk)->sport == psm && !bacmp(&bt_sk(sk)->src, src))
644 goto found;
645 sk = NULL;
646found:
647 return sk;
648}
649
650/* Find socket with psm and source bdaddr.
651 * Returns closest match.
652 */
Al Viro8e036fc2007-07-29 00:16:36 -0700653static struct sock *__l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700654{
655 struct sock *sk = NULL, *sk1 = NULL;
656 struct hlist_node *node;
657
658 sk_for_each(sk, node, &l2cap_sk_list.head) {
659 if (state && sk->sk_state != state)
660 continue;
661
662 if (l2cap_pi(sk)->psm == psm) {
663 /* Exact match. */
664 if (!bacmp(&bt_sk(sk)->src, src))
665 break;
666
667 /* Closest match */
668 if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY))
669 sk1 = sk;
670 }
671 }
672 return node ? sk : sk1;
673}
674
675/* Find socket with given address (psm, src).
676 * Returns locked socket */
Al Viro8e036fc2007-07-29 00:16:36 -0700677static inline struct sock *l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700678{
679 struct sock *s;
680 read_lock(&l2cap_sk_list.lock);
681 s = __l2cap_get_sock_by_psm(state, psm, src);
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -0300682 if (s)
683 bh_lock_sock(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700684 read_unlock(&l2cap_sk_list.lock);
685 return s;
686}
687
688static void l2cap_sock_destruct(struct sock *sk)
689{
690 BT_DBG("sk %p", sk);
691
692 skb_queue_purge(&sk->sk_receive_queue);
693 skb_queue_purge(&sk->sk_write_queue);
694}
695
696static void l2cap_sock_cleanup_listen(struct sock *parent)
697{
698 struct sock *sk;
699
700 BT_DBG("parent %p", parent);
701
702 /* Close not yet accepted channels */
703 while ((sk = bt_accept_dequeue(parent, NULL)))
704 l2cap_sock_close(sk);
705
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200706 parent->sk_state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700707 sock_set_flag(parent, SOCK_ZAPPED);
708}
709
710/* Kill socket (only if zapped and orphan)
711 * Must be called on unlocked socket.
712 */
713static void l2cap_sock_kill(struct sock *sk)
714{
715 if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket)
716 return;
717
718 BT_DBG("sk %p state %d", sk, sk->sk_state);
719
720 /* Kill poor orphan */
721 bt_sock_unlink(&l2cap_sk_list, sk);
722 sock_set_flag(sk, SOCK_DEAD);
723 sock_put(sk);
724}
725
726static void __l2cap_sock_close(struct sock *sk, int reason)
727{
728 BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket);
729
730 switch (sk->sk_state) {
731 case BT_LISTEN:
732 l2cap_sock_cleanup_listen(sk);
733 break;
734
735 case BT_CONNECTED:
736 case BT_CONFIG:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300737 if (sk->sk_type == SOCK_SEQPACKET ||
738 sk->sk_type == SOCK_STREAM) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700739 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700740
741 sk->sk_state = BT_DISCONN;
742 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300743 l2cap_send_disconn_req(conn, sk);
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200744 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -0700745 l2cap_chan_del(sk, reason);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700746 break;
747
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100748 case BT_CONNECT2:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300749 if (sk->sk_type == SOCK_SEQPACKET ||
750 sk->sk_type == SOCK_STREAM) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100751 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
752 struct l2cap_conn_rsp rsp;
753 __u16 result;
754
755 if (bt_sk(sk)->defer_setup)
756 result = L2CAP_CR_SEC_BLOCK;
757 else
758 result = L2CAP_CR_BAD_PSM;
759
760 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
761 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
762 rsp.result = cpu_to_le16(result);
763 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
764 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
765 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
766 } else
767 l2cap_chan_del(sk, reason);
768 break;
769
Linus Torvalds1da177e2005-04-16 15:20:36 -0700770 case BT_CONNECT:
771 case BT_DISCONN:
772 l2cap_chan_del(sk, reason);
773 break;
774
775 default:
776 sock_set_flag(sk, SOCK_ZAPPED);
777 break;
778 }
779}
780
781/* Must be called on unlocked socket. */
782static void l2cap_sock_close(struct sock *sk)
783{
784 l2cap_sock_clear_timer(sk);
785 lock_sock(sk);
786 __l2cap_sock_close(sk, ECONNRESET);
787 release_sock(sk);
788 l2cap_sock_kill(sk);
789}
790
791static void l2cap_sock_init(struct sock *sk, struct sock *parent)
792{
793 struct l2cap_pinfo *pi = l2cap_pi(sk);
794
795 BT_DBG("sk %p", sk);
796
797 if (parent) {
798 sk->sk_type = parent->sk_type;
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100799 bt_sk(sk)->defer_setup = bt_sk(parent)->defer_setup;
800
Linus Torvalds1da177e2005-04-16 15:20:36 -0700801 pi->imtu = l2cap_pi(parent)->imtu;
802 pi->omtu = l2cap_pi(parent)->omtu;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -0700803 pi->mode = l2cap_pi(parent)->mode;
804 pi->fcs = l2cap_pi(parent)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -0300805 pi->max_tx = l2cap_pi(parent)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -0300806 pi->tx_win = l2cap_pi(parent)->tx_win;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100807 pi->sec_level = l2cap_pi(parent)->sec_level;
808 pi->role_switch = l2cap_pi(parent)->role_switch;
809 pi->force_reliable = l2cap_pi(parent)->force_reliable;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700810 } else {
811 pi->imtu = L2CAP_DEFAULT_MTU;
812 pi->omtu = 0;
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300813 if (enable_ertm && sk->sk_type == SOCK_STREAM)
814 pi->mode = L2CAP_MODE_ERTM;
815 else
816 pi->mode = L2CAP_MODE_BASIC;
Gustavo F. Padovanfd059b92010-05-10 14:22:56 -0300817 pi->max_tx = L2CAP_DEFAULT_MAX_TX;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -0700818 pi->fcs = L2CAP_FCS_CRC16;
Gustavo F. Padovanfd059b92010-05-10 14:22:56 -0300819 pi->tx_win = L2CAP_DEFAULT_TX_WINDOW;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100820 pi->sec_level = BT_SECURITY_LOW;
821 pi->role_switch = 0;
822 pi->force_reliable = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700823 }
824
825 /* Default config options */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +0200826 pi->conf_len = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700827 pi->flush_to = L2CAP_DEFAULT_FLUSH_TO;
Dave Young45054dc2009-10-18 20:28:30 +0000828 skb_queue_head_init(TX_QUEUE(sk));
829 skb_queue_head_init(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -0300830 skb_queue_head_init(BUSY_QUEUE(sk));
Dave Young45054dc2009-10-18 20:28:30 +0000831 INIT_LIST_HEAD(SREJ_LIST(sk));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700832}
833
834static struct proto l2cap_proto = {
835 .name = "L2CAP",
836 .owner = THIS_MODULE,
837 .obj_size = sizeof(struct l2cap_pinfo)
838};
839
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700840static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700841{
842 struct sock *sk;
843
Pavel Emelyanov6257ff22007-11-01 00:39:31 -0700844 sk = sk_alloc(net, PF_BLUETOOTH, prio, &l2cap_proto);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700845 if (!sk)
846 return NULL;
847
848 sock_init_data(sock, sk);
849 INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
850
851 sk->sk_destruct = l2cap_sock_destruct;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200852 sk->sk_sndtimeo = msecs_to_jiffies(L2CAP_CONN_TIMEOUT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700853
854 sock_reset_flag(sk, SOCK_ZAPPED);
855
856 sk->sk_protocol = proto;
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200857 sk->sk_state = BT_OPEN;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700858
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200859 setup_timer(&sk->sk_timer, l2cap_sock_timeout, (unsigned long) sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700860
861 bt_sock_link(&l2cap_sk_list, sk);
862 return sk;
863}
864
Eric Paris3f378b62009-11-05 22:18:14 -0800865static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol,
866 int kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700867{
868 struct sock *sk;
869
870 BT_DBG("sock %p", sock);
871
872 sock->state = SS_UNCONNECTED;
873
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300874 if (sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM &&
Linus Torvalds1da177e2005-04-16 15:20:36 -0700875 sock->type != SOCK_DGRAM && sock->type != SOCK_RAW)
876 return -ESOCKTNOSUPPORT;
877
Eric Parisc84b3262009-11-05 20:45:52 -0800878 if (sock->type == SOCK_RAW && !kern && !capable(CAP_NET_RAW))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700879 return -EPERM;
880
881 sock->ops = &l2cap_sock_ops;
882
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700883 sk = l2cap_sock_alloc(net, sock, protocol, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700884 if (!sk)
885 return -ENOMEM;
886
887 l2cap_sock_init(sk, NULL);
888 return 0;
889}
890
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100891static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700892{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700893 struct sock *sk = sock->sk;
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100894 struct sockaddr_l2 la;
895 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700896
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100897 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700898
899 if (!addr || addr->sa_family != AF_BLUETOOTH)
900 return -EINVAL;
901
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100902 memset(&la, 0, sizeof(la));
903 len = min_t(unsigned int, sizeof(la), alen);
904 memcpy(&la, addr, len);
905
Marcel Holtmann2a517ca2009-02-16 03:20:31 +0100906 if (la.l2_cid)
907 return -EINVAL;
908
Linus Torvalds1da177e2005-04-16 15:20:36 -0700909 lock_sock(sk);
910
911 if (sk->sk_state != BT_OPEN) {
912 err = -EBADFD;
913 goto done;
914 }
915
Marcel Holtmannb4324b52009-06-07 18:06:51 +0200916 if (la.l2_psm && __le16_to_cpu(la.l2_psm) < 0x1001 &&
Marcel Holtmann847641d2007-01-22 22:00:45 +0100917 !capable(CAP_NET_BIND_SERVICE)) {
918 err = -EACCES;
919 goto done;
920 }
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900921
Linus Torvalds1da177e2005-04-16 15:20:36 -0700922 write_lock_bh(&l2cap_sk_list.lock);
923
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100924 if (la.l2_psm && __l2cap_get_sock_by_addr(la.l2_psm, &la.l2_bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700925 err = -EADDRINUSE;
926 } else {
927 /* Save source address */
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100928 bacpy(&bt_sk(sk)->src, &la.l2_bdaddr);
929 l2cap_pi(sk)->psm = la.l2_psm;
930 l2cap_pi(sk)->sport = la.l2_psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700931 sk->sk_state = BT_BOUND;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100932
Marcel Holtmannb4324b52009-06-07 18:06:51 +0200933 if (__le16_to_cpu(la.l2_psm) == 0x0001 ||
934 __le16_to_cpu(la.l2_psm) == 0x0003)
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100935 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700936 }
937
938 write_unlock_bh(&l2cap_sk_list.lock);
939
940done:
941 release_sock(sk);
942 return err;
943}
944
945static int l2cap_do_connect(struct sock *sk)
946{
947 bdaddr_t *src = &bt_sk(sk)->src;
948 bdaddr_t *dst = &bt_sk(sk)->dst;
949 struct l2cap_conn *conn;
950 struct hci_conn *hcon;
951 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200952 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +0200953 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700954
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100955 BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst),
956 l2cap_pi(sk)->psm);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700957
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -0300958 hdev = hci_get_route(dst, src);
959 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700960 return -EHOSTUNREACH;
961
962 hci_dev_lock_bh(hdev);
963
964 err = -ENOMEM;
965
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100966 if (sk->sk_type == SOCK_RAW) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100967 switch (l2cap_pi(sk)->sec_level) {
968 case BT_SECURITY_HIGH:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100969 auth_type = HCI_AT_DEDICATED_BONDING_MITM;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100970 break;
971 case BT_SECURITY_MEDIUM:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100972 auth_type = HCI_AT_DEDICATED_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100973 break;
974 default:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100975 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100976 break;
977 }
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100978 } else if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100979 if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200980 auth_type = HCI_AT_NO_BONDING_MITM;
981 else
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200982 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann435fef22009-02-09 03:55:28 +0100983
984 if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW)
985 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100986 } else {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100987 switch (l2cap_pi(sk)->sec_level) {
988 case BT_SECURITY_HIGH:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100989 auth_type = HCI_AT_GENERAL_BONDING_MITM;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100990 break;
991 case BT_SECURITY_MEDIUM:
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200992 auth_type = HCI_AT_GENERAL_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100993 break;
994 default:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100995 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100996 break;
997 }
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200998 }
999
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001000 hcon = hci_connect(hdev, ACL_LINK, dst,
1001 l2cap_pi(sk)->sec_level, auth_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001002 if (!hcon)
1003 goto done;
1004
1005 conn = l2cap_conn_add(hcon, 0);
1006 if (!conn) {
1007 hci_conn_put(hcon);
1008 goto done;
1009 }
1010
1011 err = 0;
1012
1013 /* Update source addr of the socket */
1014 bacpy(src, conn->src);
1015
1016 l2cap_chan_add(conn, sk, NULL);
1017
1018 sk->sk_state = BT_CONNECT;
1019 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
1020
1021 if (hcon->state == BT_CONNECTED) {
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001022 if (sk->sk_type != SOCK_SEQPACKET &&
1023 sk->sk_type != SOCK_STREAM) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001024 l2cap_sock_clear_timer(sk);
1025 sk->sk_state = BT_CONNECTED;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001026 } else
1027 l2cap_do_start(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001028 }
1029
1030done:
1031 hci_dev_unlock_bh(hdev);
1032 hci_dev_put(hdev);
1033 return err;
1034}
1035
1036static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
1037{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001038 struct sock *sk = sock->sk;
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001039 struct sockaddr_l2 la;
1040 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001041
Linus Torvalds1da177e2005-04-16 15:20:36 -07001042 BT_DBG("sk %p", sk);
1043
Changli Gao6503d962010-03-31 22:58:26 +00001044 if (!addr || alen < sizeof(addr->sa_family) ||
1045 addr->sa_family != AF_BLUETOOTH)
Marcel Holtmann2a517ca2009-02-16 03:20:31 +01001046 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001047
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001048 memset(&la, 0, sizeof(la));
1049 len = min_t(unsigned int, sizeof(la), alen);
1050 memcpy(&la, addr, len);
1051
Marcel Holtmann2a517ca2009-02-16 03:20:31 +01001052 if (la.l2_cid)
1053 return -EINVAL;
1054
1055 lock_sock(sk);
1056
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001057 if ((sk->sk_type == SOCK_SEQPACKET || sk->sk_type == SOCK_STREAM)
1058 && !la.l2_psm) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001059 err = -EINVAL;
1060 goto done;
1061 }
1062
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001063 switch (l2cap_pi(sk)->mode) {
1064 case L2CAP_MODE_BASIC:
1065 break;
1066 case L2CAP_MODE_ERTM:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001067 case L2CAP_MODE_STREAMING:
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001068 if (enable_ertm)
1069 break;
1070 /* fall through */
1071 default:
1072 err = -ENOTSUPP;
1073 goto done;
1074 }
1075
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03001076 switch (sk->sk_state) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001077 case BT_CONNECT:
1078 case BT_CONNECT2:
1079 case BT_CONFIG:
1080 /* Already connecting */
1081 goto wait;
1082
1083 case BT_CONNECTED:
1084 /* Already connected */
1085 goto done;
1086
1087 case BT_OPEN:
1088 case BT_BOUND:
1089 /* Can connect */
1090 break;
1091
1092 default:
1093 err = -EBADFD;
1094 goto done;
1095 }
1096
1097 /* Set destination address and psm */
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001098 bacpy(&bt_sk(sk)->dst, &la.l2_bdaddr);
1099 l2cap_pi(sk)->psm = la.l2_psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001100
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03001101 err = l2cap_do_connect(sk);
1102 if (err)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001103 goto done;
1104
1105wait:
1106 err = bt_sock_wait_state(sk, BT_CONNECTED,
1107 sock_sndtimeo(sk, flags & O_NONBLOCK));
1108done:
1109 release_sock(sk);
1110 return err;
1111}
1112
1113static int l2cap_sock_listen(struct socket *sock, int backlog)
1114{
1115 struct sock *sk = sock->sk;
1116 int err = 0;
1117
1118 BT_DBG("sk %p backlog %d", sk, backlog);
1119
1120 lock_sock(sk);
1121
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001122 if ((sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM)
1123 || sk->sk_state != BT_BOUND) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001124 err = -EBADFD;
1125 goto done;
1126 }
1127
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001128 switch (l2cap_pi(sk)->mode) {
1129 case L2CAP_MODE_BASIC:
1130 break;
1131 case L2CAP_MODE_ERTM:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001132 case L2CAP_MODE_STREAMING:
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001133 if (enable_ertm)
1134 break;
1135 /* fall through */
1136 default:
1137 err = -ENOTSUPP;
1138 goto done;
1139 }
1140
Linus Torvalds1da177e2005-04-16 15:20:36 -07001141 if (!l2cap_pi(sk)->psm) {
1142 bdaddr_t *src = &bt_sk(sk)->src;
1143 u16 psm;
1144
1145 err = -EINVAL;
1146
1147 write_lock_bh(&l2cap_sk_list.lock);
1148
1149 for (psm = 0x1001; psm < 0x1100; psm += 2)
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001150 if (!__l2cap_get_sock_by_addr(cpu_to_le16(psm), src)) {
1151 l2cap_pi(sk)->psm = cpu_to_le16(psm);
1152 l2cap_pi(sk)->sport = cpu_to_le16(psm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001153 err = 0;
1154 break;
1155 }
1156
1157 write_unlock_bh(&l2cap_sk_list.lock);
1158
1159 if (err < 0)
1160 goto done;
1161 }
1162
1163 sk->sk_max_ack_backlog = backlog;
1164 sk->sk_ack_backlog = 0;
1165 sk->sk_state = BT_LISTEN;
1166
1167done:
1168 release_sock(sk);
1169 return err;
1170}
1171
1172static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int flags)
1173{
1174 DECLARE_WAITQUEUE(wait, current);
1175 struct sock *sk = sock->sk, *nsk;
1176 long timeo;
1177 int err = 0;
1178
Peter Zijlstrafcc70d52006-11-08 22:44:35 -08001179 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001180
1181 if (sk->sk_state != BT_LISTEN) {
1182 err = -EBADFD;
1183 goto done;
1184 }
1185
1186 timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
1187
1188 BT_DBG("sk %p timeo %ld", sk, timeo);
1189
1190 /* Wait for an incoming connection. (wake-one). */
Eric Dumazetaa395142010-04-20 13:03:51 +00001191 add_wait_queue_exclusive(sk_sleep(sk), &wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001192 while (!(nsk = bt_accept_dequeue(sk, newsock))) {
1193 set_current_state(TASK_INTERRUPTIBLE);
1194 if (!timeo) {
1195 err = -EAGAIN;
1196 break;
1197 }
1198
1199 release_sock(sk);
1200 timeo = schedule_timeout(timeo);
Peter Zijlstrafcc70d52006-11-08 22:44:35 -08001201 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001202
1203 if (sk->sk_state != BT_LISTEN) {
1204 err = -EBADFD;
1205 break;
1206 }
1207
1208 if (signal_pending(current)) {
1209 err = sock_intr_errno(timeo);
1210 break;
1211 }
1212 }
1213 set_current_state(TASK_RUNNING);
Eric Dumazetaa395142010-04-20 13:03:51 +00001214 remove_wait_queue(sk_sleep(sk), &wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001215
1216 if (err)
1217 goto done;
1218
1219 newsock->state = SS_CONNECTED;
1220
1221 BT_DBG("new socket %p", nsk);
1222
1223done:
1224 release_sock(sk);
1225 return err;
1226}
1227
1228static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
1229{
1230 struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
1231 struct sock *sk = sock->sk;
1232
1233 BT_DBG("sock %p, sk %p", sock, sk);
1234
1235 addr->sa_family = AF_BLUETOOTH;
1236 *len = sizeof(struct sockaddr_l2);
1237
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001238 if (peer) {
1239 la->l2_psm = l2cap_pi(sk)->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001240 bacpy(&la->l2_bdaddr, &bt_sk(sk)->dst);
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001241 la->l2_cid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001242 } else {
1243 la->l2_psm = l2cap_pi(sk)->sport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001244 bacpy(&la->l2_bdaddr, &bt_sk(sk)->src);
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001245 la->l2_cid = cpu_to_le16(l2cap_pi(sk)->scid);
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001246 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001247
Linus Torvalds1da177e2005-04-16 15:20:36 -07001248 return 0;
1249}
1250
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001251static int __l2cap_wait_ack(struct sock *sk)
1252{
1253 DECLARE_WAITQUEUE(wait, current);
1254 int err = 0;
1255 int timeo = HZ/5;
1256
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001257 add_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001258 while ((l2cap_pi(sk)->unacked_frames > 0 && l2cap_pi(sk)->conn)) {
1259 set_current_state(TASK_INTERRUPTIBLE);
1260
1261 if (!timeo)
1262 timeo = HZ/5;
1263
1264 if (signal_pending(current)) {
1265 err = sock_intr_errno(timeo);
1266 break;
1267 }
1268
1269 release_sock(sk);
1270 timeo = schedule_timeout(timeo);
1271 lock_sock(sk);
1272
1273 err = sock_error(sk);
1274 if (err)
1275 break;
1276 }
1277 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001278 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001279 return err;
1280}
1281
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001282static void l2cap_monitor_timeout(unsigned long arg)
1283{
1284 struct sock *sk = (void *) arg;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001285
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001286 bh_lock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001287 if (l2cap_pi(sk)->retry_count >= l2cap_pi(sk)->remote_max_tx) {
1288 l2cap_send_disconn_req(l2cap_pi(sk)->conn, sk);
Andrei Emeltchenkob13f5862009-12-15 11:38:04 +02001289 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001290 return;
1291 }
1292
1293 l2cap_pi(sk)->retry_count++;
1294 __mod_monitor_timer();
1295
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -03001296 l2cap_send_rr_or_rnr(l2cap_pi(sk), L2CAP_CTRL_POLL);
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001297 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001298}
1299
1300static void l2cap_retrans_timeout(unsigned long arg)
1301{
1302 struct sock *sk = (void *) arg;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001303
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001304 bh_lock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001305 l2cap_pi(sk)->retry_count = 1;
1306 __mod_monitor_timer();
1307
1308 l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
1309
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -03001310 l2cap_send_rr_or_rnr(l2cap_pi(sk), L2CAP_CTRL_POLL);
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001311 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001312}
1313
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001314static void l2cap_drop_acked_frames(struct sock *sk)
1315{
1316 struct sk_buff *skb;
1317
Gustavo F. Padovan812e7372010-05-01 16:15:42 -03001318 while ((skb = skb_peek(TX_QUEUE(sk))) &&
1319 l2cap_pi(sk)->unacked_frames) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001320 if (bt_cb(skb)->tx_seq == l2cap_pi(sk)->expected_ack_seq)
1321 break;
1322
1323 skb = skb_dequeue(TX_QUEUE(sk));
1324 kfree_skb(skb);
1325
1326 l2cap_pi(sk)->unacked_frames--;
1327 }
1328
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001329 if (!l2cap_pi(sk)->unacked_frames)
1330 del_timer(&l2cap_pi(sk)->retrans_timer);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001331}
1332
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001333static inline void l2cap_do_send(struct sock *sk, struct sk_buff *skb)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001334{
1335 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001336
1337 BT_DBG("sk %p, skb %p len %d", sk, skb, skb->len);
1338
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001339 hci_send_acl(pi->conn->hcon, skb, 0);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001340}
1341
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001342static int l2cap_streaming_send(struct sock *sk)
1343{
1344 struct sk_buff *skb, *tx_skb;
1345 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001346 u16 control, fcs;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001347
1348 while ((skb = sk->sk_send_head)) {
1349 tx_skb = skb_clone(skb, GFP_ATOMIC);
1350
1351 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
1352 control |= pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT;
1353 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1354
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001355 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001356 fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
1357 put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
1358 }
1359
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001360 l2cap_do_send(sk, tx_skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001361
1362 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
1363
1364 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1365 sk->sk_send_head = NULL;
1366 else
1367 sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
1368
1369 skb = skb_dequeue(TX_QUEUE(sk));
1370 kfree_skb(skb);
1371 }
1372 return 0;
1373}
1374
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001375static void l2cap_retransmit_one_frame(struct sock *sk, u8 tx_seq)
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001376{
1377 struct l2cap_pinfo *pi = l2cap_pi(sk);
1378 struct sk_buff *skb, *tx_skb;
1379 u16 control, fcs;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001380
1381 skb = skb_peek(TX_QUEUE(sk));
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001382 if (!skb)
1383 return;
1384
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001385 do {
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001386 if (bt_cb(skb)->tx_seq == tx_seq)
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001387 break;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001388
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001389 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1390 return;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001391
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001392 } while ((skb = skb_queue_next(TX_QUEUE(sk), skb)));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001393
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001394 if (pi->remote_max_tx &&
1395 bt_cb(skb)->retries == pi->remote_max_tx) {
1396 l2cap_send_disconn_req(pi->conn, sk);
1397 return;
1398 }
1399
1400 tx_skb = skb_clone(skb, GFP_ATOMIC);
1401 bt_cb(skb)->retries++;
1402 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
1403 control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
1404 | (tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
1405 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1406
1407 if (pi->fcs == L2CAP_FCS_CRC16) {
1408 fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
1409 put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
1410 }
1411
1412 l2cap_do_send(sk, tx_skb);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001413}
1414
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001415static int l2cap_ertm_send(struct sock *sk)
1416{
1417 struct sk_buff *skb, *tx_skb;
1418 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001419 u16 control, fcs;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001420 int nsent = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001421
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001422 if (pi->conn_state & L2CAP_CONN_WAIT_F)
1423 return 0;
1424
Joe Perchesf64f9e72009-11-29 16:55:45 -08001425 while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(sk)) &&
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03001426 !(pi->conn_state & L2CAP_CONN_REMOTE_BUSY)) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001427
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001428 if (pi->remote_max_tx &&
1429 bt_cb(skb)->retries == pi->remote_max_tx) {
1430 l2cap_send_disconn_req(pi->conn, sk);
1431 break;
1432 }
1433
Andrei Emeltchenkoe420aba2009-12-23 13:07:14 +02001434 tx_skb = skb_clone(skb, GFP_ATOMIC);
1435
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001436 bt_cb(skb)->retries++;
1437
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001438 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001439 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
1440 control |= L2CAP_CTRL_FINAL;
1441 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
1442 }
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03001443 control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001444 | (pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
1445 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1446
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001447
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001448 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001449 fcs = crc16(0, (u8 *)skb->data, tx_skb->len - 2);
1450 put_unaligned_le16(fcs, skb->data + tx_skb->len - 2);
1451 }
1452
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001453 l2cap_do_send(sk, tx_skb);
1454
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001455 __mod_retrans_timer();
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001456
1457 bt_cb(skb)->tx_seq = pi->next_tx_seq;
1458 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
1459
1460 pi->unacked_frames++;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001461 pi->frames_sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001462
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);
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001467
1468 nsent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001469 }
1470
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001471 return nsent;
1472}
1473
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001474static int l2cap_retransmit_frames(struct sock *sk)
1475{
1476 struct l2cap_pinfo *pi = l2cap_pi(sk);
1477 int ret;
1478
1479 spin_lock_bh(&pi->send_lock);
1480
1481 if (!skb_queue_empty(TX_QUEUE(sk)))
1482 sk->sk_send_head = TX_QUEUE(sk)->next;
1483
1484 pi->next_tx_seq = pi->expected_ack_seq;
1485 ret = l2cap_ertm_send(sk);
1486
1487 spin_unlock_bh(&pi->send_lock);
1488
1489 return ret;
1490}
1491
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001492static void l2cap_send_ack(struct l2cap_pinfo *pi)
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001493{
1494 struct sock *sk = (struct sock *)pi;
1495 u16 control = 0;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001496 int nframes;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001497
1498 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1499
1500 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
1501 control |= L2CAP_SUPER_RCV_NOT_READY;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03001502 pi->conn_state |= L2CAP_CONN_RNR_SENT;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001503 l2cap_send_sframe(pi, control);
1504 return;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001505 }
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001506
1507 spin_lock_bh(&pi->send_lock);
1508 nframes = l2cap_ertm_send(sk);
1509 spin_unlock_bh(&pi->send_lock);
1510
1511 if (nframes > 0)
1512 return;
1513
1514 control |= L2CAP_SUPER_RCV_READY;
1515 l2cap_send_sframe(pi, control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001516}
1517
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001518static void l2cap_send_srejtail(struct sock *sk)
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03001519{
1520 struct srej_list *tail;
1521 u16 control;
1522
1523 control = L2CAP_SUPER_SELECT_REJECT;
1524 control |= L2CAP_CTRL_FINAL;
1525
1526 tail = list_entry(SREJ_LIST(sk)->prev, struct srej_list, list);
1527 control |= tail->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1528
1529 l2cap_send_sframe(l2cap_pi(sk), control);
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03001530}
1531
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001532static 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 -07001533{
1534 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001535 struct sk_buff **frag;
1536 int err, sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001537
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03001538 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001539 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001540
1541 sent += count;
1542 len -= count;
1543
1544 /* Continuation fragments (no L2CAP header) */
1545 frag = &skb_shinfo(skb)->frag_list;
1546 while (len) {
1547 count = min_t(unsigned int, conn->mtu, len);
1548
1549 *frag = bt_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err);
1550 if (!*frag)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001551 return -EFAULT;
1552 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
1553 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001554
1555 sent += count;
1556 len -= count;
1557
1558 frag = &(*frag)->next;
1559 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001560
1561 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001562}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001563
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001564static struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, size_t len)
1565{
1566 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1567 struct sk_buff *skb;
1568 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1569 struct l2cap_hdr *lh;
1570
1571 BT_DBG("sk %p len %d", sk, (int)len);
1572
1573 count = min_t(unsigned int, (conn->mtu - hlen), len);
1574 skb = bt_skb_send_alloc(sk, count + hlen,
1575 msg->msg_flags & MSG_DONTWAIT, &err);
1576 if (!skb)
1577 return ERR_PTR(-ENOMEM);
1578
1579 /* Create L2CAP header */
1580 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1581 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1582 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1583 put_unaligned_le16(l2cap_pi(sk)->psm, skb_put(skb, 2));
1584
1585 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1586 if (unlikely(err < 0)) {
1587 kfree_skb(skb);
1588 return ERR_PTR(err);
1589 }
1590 return skb;
1591}
1592
1593static struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *msg, size_t len)
1594{
1595 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1596 struct sk_buff *skb;
1597 int err, count, hlen = L2CAP_HDR_SIZE;
1598 struct l2cap_hdr *lh;
1599
1600 BT_DBG("sk %p len %d", sk, (int)len);
1601
1602 count = min_t(unsigned int, (conn->mtu - hlen), len);
1603 skb = bt_skb_send_alloc(sk, count + hlen,
1604 msg->msg_flags & MSG_DONTWAIT, &err);
1605 if (!skb)
1606 return ERR_PTR(-ENOMEM);
1607
1608 /* Create L2CAP header */
1609 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1610 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1611 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1612
1613 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1614 if (unlikely(err < 0)) {
1615 kfree_skb(skb);
1616 return ERR_PTR(err);
1617 }
1618 return skb;
1619}
1620
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001621static 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 -03001622{
1623 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1624 struct sk_buff *skb;
1625 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1626 struct l2cap_hdr *lh;
1627
1628 BT_DBG("sk %p len %d", sk, (int)len);
1629
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03001630 if (!conn)
1631 return ERR_PTR(-ENOTCONN);
1632
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001633 if (sdulen)
1634 hlen += 2;
1635
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001636 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1637 hlen += 2;
1638
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001639 count = min_t(unsigned int, (conn->mtu - hlen), len);
1640 skb = bt_skb_send_alloc(sk, count + hlen,
1641 msg->msg_flags & MSG_DONTWAIT, &err);
1642 if (!skb)
1643 return ERR_PTR(-ENOMEM);
1644
1645 /* Create L2CAP header */
1646 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1647 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1648 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1649 put_unaligned_le16(control, skb_put(skb, 2));
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001650 if (sdulen)
1651 put_unaligned_le16(sdulen, skb_put(skb, 2));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001652
1653 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1654 if (unlikely(err < 0)) {
1655 kfree_skb(skb);
1656 return ERR_PTR(err);
1657 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001658
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001659 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1660 put_unaligned_le16(0, skb_put(skb, 2));
1661
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001662 bt_cb(skb)->retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001663 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001664}
1665
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001666static inline int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len)
1667{
1668 struct l2cap_pinfo *pi = l2cap_pi(sk);
1669 struct sk_buff *skb;
1670 struct sk_buff_head sar_queue;
1671 u16 control;
1672 size_t size = 0;
1673
Gustavo F. Padovanff12fd62010-05-05 22:09:15 -03001674 skb_queue_head_init(&sar_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001675 control = L2CAP_SDU_START;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001676 skb = l2cap_create_iframe_pdu(sk, msg, pi->remote_mps, control, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001677 if (IS_ERR(skb))
1678 return PTR_ERR(skb);
1679
1680 __skb_queue_tail(&sar_queue, skb);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001681 len -= pi->remote_mps;
1682 size += pi->remote_mps;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001683
1684 while (len > 0) {
1685 size_t buflen;
1686
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001687 if (len > pi->remote_mps) {
Gustavo F. Padovan44651b82010-05-01 16:15:43 -03001688 control = L2CAP_SDU_CONTINUE;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001689 buflen = pi->remote_mps;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001690 } else {
Gustavo F. Padovan44651b82010-05-01 16:15:43 -03001691 control = L2CAP_SDU_END;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001692 buflen = len;
1693 }
1694
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001695 skb = l2cap_create_iframe_pdu(sk, msg, buflen, control, 0);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001696 if (IS_ERR(skb)) {
1697 skb_queue_purge(&sar_queue);
1698 return PTR_ERR(skb);
1699 }
1700
1701 __skb_queue_tail(&sar_queue, skb);
1702 len -= buflen;
1703 size += buflen;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001704 }
1705 skb_queue_splice_tail(&sar_queue, TX_QUEUE(sk));
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001706 spin_lock_bh(&pi->send_lock);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001707 if (sk->sk_send_head == NULL)
1708 sk->sk_send_head = sar_queue.next;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001709 spin_unlock_bh(&pi->send_lock);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001710
1711 return size;
1712}
1713
Linus Torvalds1da177e2005-04-16 15:20:36 -07001714static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len)
1715{
1716 struct sock *sk = sock->sk;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001717 struct l2cap_pinfo *pi = l2cap_pi(sk);
1718 struct sk_buff *skb;
1719 u16 control;
1720 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001721
1722 BT_DBG("sock %p, sk %p", sock, sk);
1723
Benjamin LaHaisec1cbe4b2005-12-13 23:22:19 -08001724 err = sock_error(sk);
1725 if (err)
1726 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001727
1728 if (msg->msg_flags & MSG_OOB)
1729 return -EOPNOTSUPP;
1730
Linus Torvalds1da177e2005-04-16 15:20:36 -07001731 lock_sock(sk);
1732
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001733 if (sk->sk_state != BT_CONNECTED) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001734 err = -ENOTCONN;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001735 goto done;
1736 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001737
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001738 /* Connectionless channel */
1739 if (sk->sk_type == SOCK_DGRAM) {
1740 skb = l2cap_create_connless_pdu(sk, msg, len);
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001741 if (IS_ERR(skb)) {
Dan Carpenter477fffb2010-04-21 23:52:01 +00001742 err = PTR_ERR(skb);
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001743 } else {
1744 l2cap_do_send(sk, skb);
1745 err = len;
1746 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001747 goto done;
1748 }
1749
1750 switch (pi->mode) {
1751 case L2CAP_MODE_BASIC:
Gustavo F. Padovanc69163e2010-05-01 16:15:35 -03001752 /* Check outgoing MTU */
1753 if (len > pi->omtu) {
1754 err = -EINVAL;
1755 goto done;
1756 }
1757
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001758 /* Create a basic PDU */
1759 skb = l2cap_create_basic_pdu(sk, msg, len);
1760 if (IS_ERR(skb)) {
1761 err = PTR_ERR(skb);
1762 goto done;
1763 }
1764
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001765 l2cap_do_send(sk, skb);
1766 err = len;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001767 break;
1768
1769 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001770 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001771 /* Entire SDU fits into one PDU */
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001772 if (len <= pi->remote_mps) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001773 control = L2CAP_SDU_UNSEGMENTED;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001774 skb = l2cap_create_iframe_pdu(sk, msg, len, control, 0);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001775 if (IS_ERR(skb)) {
1776 err = PTR_ERR(skb);
1777 goto done;
1778 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001779 __skb_queue_tail(TX_QUEUE(sk), skb);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001780
1781 if (pi->mode == L2CAP_MODE_ERTM)
1782 spin_lock_bh(&pi->send_lock);
1783
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001784 if (sk->sk_send_head == NULL)
1785 sk->sk_send_head = skb;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001786
1787 if (pi->mode == L2CAP_MODE_ERTM)
1788 spin_unlock_bh(&pi->send_lock);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001789 } else {
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001790 /* Segment SDU into multiples PDUs */
1791 err = l2cap_sar_segment_sdu(sk, msg, len);
1792 if (err < 0)
1793 goto done;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001794 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001795
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001796 if (pi->mode == L2CAP_MODE_STREAMING) {
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001797 err = l2cap_streaming_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001798 } else {
1799 spin_lock_bh(&pi->send_lock);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001800 err = l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001801 spin_unlock_bh(&pi->send_lock);
1802 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001803
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001804 if (err >= 0)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001805 err = len;
1806 break;
1807
1808 default:
1809 BT_DBG("bad state %1.1x", pi->mode);
1810 err = -EINVAL;
1811 }
1812
1813done:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001814 release_sock(sk);
1815 return err;
1816}
1817
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001818static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags)
1819{
1820 struct sock *sk = sock->sk;
1821
1822 lock_sock(sk);
1823
1824 if (sk->sk_state == BT_CONNECT2 && bt_sk(sk)->defer_setup) {
1825 struct l2cap_conn_rsp rsp;
1826
1827 sk->sk_state = BT_CONFIG;
1828
1829 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
1830 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
1831 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
1832 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
1833 l2cap_send_cmd(l2cap_pi(sk)->conn, l2cap_pi(sk)->ident,
1834 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
1835
1836 release_sock(sk);
1837 return 0;
1838 }
1839
1840 release_sock(sk);
1841
1842 return bt_sock_recvmsg(iocb, sock, msg, len, flags);
1843}
1844
David S. Millerb7058842009-09-30 16:12:20 -07001845static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001846{
1847 struct sock *sk = sock->sk;
1848 struct l2cap_options opts;
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001849 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001850 u32 opt;
1851
1852 BT_DBG("sk %p", sk);
1853
1854 lock_sock(sk);
1855
1856 switch (optname) {
1857 case L2CAP_OPTIONS:
Marcel Holtmann0878b662007-05-05 00:35:59 +02001858 opts.imtu = l2cap_pi(sk)->imtu;
1859 opts.omtu = l2cap_pi(sk)->omtu;
1860 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001861 opts.mode = l2cap_pi(sk)->mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001862 opts.fcs = l2cap_pi(sk)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03001863 opts.max_tx = l2cap_pi(sk)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03001864 opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
Marcel Holtmann0878b662007-05-05 00:35:59 +02001865
Linus Torvalds1da177e2005-04-16 15:20:36 -07001866 len = min_t(unsigned int, sizeof(opts), optlen);
1867 if (copy_from_user((char *) &opts, optval, len)) {
1868 err = -EFAULT;
1869 break;
1870 }
Marcel Holtmann0878b662007-05-05 00:35:59 +02001871
João Paulo Rechi Vita0041ecf2010-05-01 16:15:42 -03001872 l2cap_pi(sk)->mode = opts.mode;
1873 switch (l2cap_pi(sk)->mode) {
1874 case L2CAP_MODE_BASIC:
1875 break;
1876 case L2CAP_MODE_ERTM:
1877 case L2CAP_MODE_STREAMING:
1878 if (enable_ertm)
1879 break;
1880 /* fall through */
1881 default:
1882 err = -EINVAL;
1883 break;
1884 }
1885
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001886 l2cap_pi(sk)->imtu = opts.imtu;
1887 l2cap_pi(sk)->omtu = opts.omtu;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001888 l2cap_pi(sk)->fcs = opts.fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03001889 l2cap_pi(sk)->max_tx = opts.max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03001890 l2cap_pi(sk)->tx_win = (__u8)opts.txwin_size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001891 break;
1892
1893 case L2CAP_LM:
1894 if (get_user(opt, (u32 __user *) optval)) {
1895 err = -EFAULT;
1896 break;
1897 }
1898
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001899 if (opt & L2CAP_LM_AUTH)
1900 l2cap_pi(sk)->sec_level = BT_SECURITY_LOW;
1901 if (opt & L2CAP_LM_ENCRYPT)
1902 l2cap_pi(sk)->sec_level = BT_SECURITY_MEDIUM;
1903 if (opt & L2CAP_LM_SECURE)
1904 l2cap_pi(sk)->sec_level = BT_SECURITY_HIGH;
1905
1906 l2cap_pi(sk)->role_switch = (opt & L2CAP_LM_MASTER);
1907 l2cap_pi(sk)->force_reliable = (opt & L2CAP_LM_RELIABLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001908 break;
1909
1910 default:
1911 err = -ENOPROTOOPT;
1912 break;
1913 }
1914
1915 release_sock(sk);
1916 return err;
1917}
1918
David S. Millerb7058842009-09-30 16:12:20 -07001919static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001920{
1921 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001922 struct bt_security sec;
1923 int len, err = 0;
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001924 u32 opt;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001925
1926 BT_DBG("sk %p", sk);
1927
1928 if (level == SOL_L2CAP)
1929 return l2cap_sock_setsockopt_old(sock, optname, optval, optlen);
1930
Marcel Holtmann0588d942009-01-16 10:06:13 +01001931 if (level != SOL_BLUETOOTH)
1932 return -ENOPROTOOPT;
1933
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001934 lock_sock(sk);
1935
1936 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001937 case BT_SECURITY:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001938 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
1939 && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01001940 err = -EINVAL;
1941 break;
1942 }
1943
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001944 sec.level = BT_SECURITY_LOW;
1945
1946 len = min_t(unsigned int, sizeof(sec), optlen);
1947 if (copy_from_user((char *) &sec, optval, len)) {
1948 err = -EFAULT;
1949 break;
1950 }
1951
1952 if (sec.level < BT_SECURITY_LOW ||
1953 sec.level > BT_SECURITY_HIGH) {
1954 err = -EINVAL;
1955 break;
1956 }
1957
1958 l2cap_pi(sk)->sec_level = sec.level;
1959 break;
1960
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001961 case BT_DEFER_SETUP:
1962 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
1963 err = -EINVAL;
1964 break;
1965 }
1966
1967 if (get_user(opt, (u32 __user *) optval)) {
1968 err = -EFAULT;
1969 break;
1970 }
1971
1972 bt_sk(sk)->defer_setup = opt;
1973 break;
1974
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001975 default:
1976 err = -ENOPROTOOPT;
1977 break;
1978 }
1979
1980 release_sock(sk);
1981 return err;
1982}
1983
1984static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001985{
1986 struct sock *sk = sock->sk;
1987 struct l2cap_options opts;
1988 struct l2cap_conninfo cinfo;
1989 int len, err = 0;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001990 u32 opt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001991
1992 BT_DBG("sk %p", sk);
1993
1994 if (get_user(len, optlen))
1995 return -EFAULT;
1996
1997 lock_sock(sk);
1998
1999 switch (optname) {
2000 case L2CAP_OPTIONS:
2001 opts.imtu = l2cap_pi(sk)->imtu;
2002 opts.omtu = l2cap_pi(sk)->omtu;
2003 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07002004 opts.mode = l2cap_pi(sk)->mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002005 opts.fcs = l2cap_pi(sk)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03002006 opts.max_tx = l2cap_pi(sk)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03002007 opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002008
2009 len = min_t(unsigned int, len, sizeof(opts));
2010 if (copy_to_user(optval, (char *) &opts, len))
2011 err = -EFAULT;
2012
2013 break;
2014
2015 case L2CAP_LM:
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002016 switch (l2cap_pi(sk)->sec_level) {
2017 case BT_SECURITY_LOW:
2018 opt = L2CAP_LM_AUTH;
2019 break;
2020 case BT_SECURITY_MEDIUM:
2021 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT;
2022 break;
2023 case BT_SECURITY_HIGH:
2024 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT |
2025 L2CAP_LM_SECURE;
2026 break;
2027 default:
2028 opt = 0;
2029 break;
2030 }
2031
2032 if (l2cap_pi(sk)->role_switch)
2033 opt |= L2CAP_LM_MASTER;
2034
2035 if (l2cap_pi(sk)->force_reliable)
2036 opt |= L2CAP_LM_RELIABLE;
2037
2038 if (put_user(opt, (u32 __user *) optval))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002039 err = -EFAULT;
2040 break;
2041
2042 case L2CAP_CONNINFO:
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002043 if (sk->sk_state != BT_CONNECTED &&
2044 !(sk->sk_state == BT_CONNECT2 &&
2045 bt_sk(sk)->defer_setup)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002046 err = -ENOTCONN;
2047 break;
2048 }
2049
2050 cinfo.hci_handle = l2cap_pi(sk)->conn->hcon->handle;
2051 memcpy(cinfo.dev_class, l2cap_pi(sk)->conn->hcon->dev_class, 3);
2052
2053 len = min_t(unsigned int, len, sizeof(cinfo));
2054 if (copy_to_user(optval, (char *) &cinfo, len))
2055 err = -EFAULT;
2056
2057 break;
2058
2059 default:
2060 err = -ENOPROTOOPT;
2061 break;
2062 }
2063
2064 release_sock(sk);
2065 return err;
2066}
2067
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002068static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
2069{
2070 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002071 struct bt_security sec;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002072 int len, err = 0;
2073
2074 BT_DBG("sk %p", sk);
2075
2076 if (level == SOL_L2CAP)
2077 return l2cap_sock_getsockopt_old(sock, optname, optval, optlen);
2078
Marcel Holtmann0588d942009-01-16 10:06:13 +01002079 if (level != SOL_BLUETOOTH)
2080 return -ENOPROTOOPT;
2081
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002082 if (get_user(len, optlen))
2083 return -EFAULT;
2084
2085 lock_sock(sk);
2086
2087 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002088 case BT_SECURITY:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03002089 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
2090 && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01002091 err = -EINVAL;
2092 break;
2093 }
2094
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002095 sec.level = l2cap_pi(sk)->sec_level;
2096
2097 len = min_t(unsigned int, len, sizeof(sec));
2098 if (copy_to_user(optval, (char *) &sec, len))
2099 err = -EFAULT;
2100
2101 break;
2102
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002103 case BT_DEFER_SETUP:
2104 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
2105 err = -EINVAL;
2106 break;
2107 }
2108
2109 if (put_user(bt_sk(sk)->defer_setup, (u32 __user *) optval))
2110 err = -EFAULT;
2111
2112 break;
2113
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002114 default:
2115 err = -ENOPROTOOPT;
2116 break;
2117 }
2118
2119 release_sock(sk);
2120 return err;
2121}
2122
Linus Torvalds1da177e2005-04-16 15:20:36 -07002123static int l2cap_sock_shutdown(struct socket *sock, int how)
2124{
2125 struct sock *sk = sock->sk;
2126 int err = 0;
2127
2128 BT_DBG("sock %p, sk %p", sock, sk);
2129
2130 if (!sk)
2131 return 0;
2132
2133 lock_sock(sk);
2134 if (!sk->sk_shutdown) {
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03002135 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
2136 err = __l2cap_wait_ack(sk);
2137
Linus Torvalds1da177e2005-04-16 15:20:36 -07002138 sk->sk_shutdown = SHUTDOWN_MASK;
2139 l2cap_sock_clear_timer(sk);
2140 __l2cap_sock_close(sk, 0);
2141
2142 if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
Marcel Holtmannb1235d72008-07-14 20:13:54 +02002143 err = bt_sock_wait_state(sk, BT_CLOSED,
2144 sk->sk_lingertime);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002145 }
2146 release_sock(sk);
2147 return err;
2148}
2149
2150static int l2cap_sock_release(struct socket *sock)
2151{
2152 struct sock *sk = sock->sk;
2153 int err;
2154
2155 BT_DBG("sock %p, sk %p", sock, sk);
2156
2157 if (!sk)
2158 return 0;
2159
2160 err = l2cap_sock_shutdown(sock, 2);
2161
2162 sock_orphan(sk);
2163 l2cap_sock_kill(sk);
2164 return err;
2165}
2166
Linus Torvalds1da177e2005-04-16 15:20:36 -07002167static void l2cap_chan_ready(struct sock *sk)
2168{
2169 struct sock *parent = bt_sk(sk)->parent;
2170
2171 BT_DBG("sk %p, parent %p", sk, parent);
2172
2173 l2cap_pi(sk)->conf_state = 0;
2174 l2cap_sock_clear_timer(sk);
2175
2176 if (!parent) {
2177 /* Outgoing channel.
2178 * Wake up socket sleeping on connect.
2179 */
2180 sk->sk_state = BT_CONNECTED;
2181 sk->sk_state_change(sk);
2182 } else {
2183 /* Incoming channel.
2184 * Wake up socket sleeping on accept.
2185 */
2186 parent->sk_data_ready(parent, 0);
2187 }
2188}
2189
2190/* Copy frame to all raw sockets on that connection */
2191static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2192{
2193 struct l2cap_chan_list *l = &conn->chan_list;
2194 struct sk_buff *nskb;
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002195 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002196
2197 BT_DBG("conn %p", conn);
2198
2199 read_lock(&l->lock);
2200 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
2201 if (sk->sk_type != SOCK_RAW)
2202 continue;
2203
2204 /* Don't send frame to the socket it came from */
2205 if (skb->sk == sk)
2206 continue;
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002207 nskb = skb_clone(skb, GFP_ATOMIC);
2208 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002209 continue;
2210
2211 if (sock_queue_rcv_skb(sk, nskb))
2212 kfree_skb(nskb);
2213 }
2214 read_unlock(&l->lock);
2215}
2216
2217/* ---- L2CAP signalling commands ---- */
2218static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
2219 u8 code, u8 ident, u16 dlen, void *data)
2220{
2221 struct sk_buff *skb, **frag;
2222 struct l2cap_cmd_hdr *cmd;
2223 struct l2cap_hdr *lh;
2224 int len, count;
2225
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002226 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d",
2227 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002228
2229 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2230 count = min_t(unsigned int, conn->mtu, len);
2231
2232 skb = bt_skb_alloc(count, GFP_ATOMIC);
2233 if (!skb)
2234 return NULL;
2235
2236 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002237 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03002238 lh->cid = cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002239
2240 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2241 cmd->code = code;
2242 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002243 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002244
2245 if (dlen) {
2246 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2247 memcpy(skb_put(skb, count), data, count);
2248 data += count;
2249 }
2250
2251 len -= skb->len;
2252
2253 /* Continuation fragments (no L2CAP header) */
2254 frag = &skb_shinfo(skb)->frag_list;
2255 while (len) {
2256 count = min_t(unsigned int, conn->mtu, len);
2257
2258 *frag = bt_skb_alloc(count, GFP_ATOMIC);
2259 if (!*frag)
2260 goto fail;
2261
2262 memcpy(skb_put(*frag, count), data, count);
2263
2264 len -= count;
2265 data += count;
2266
2267 frag = &(*frag)->next;
2268 }
2269
2270 return skb;
2271
2272fail:
2273 kfree_skb(skb);
2274 return NULL;
2275}
2276
2277static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned long *val)
2278{
2279 struct l2cap_conf_opt *opt = *ptr;
2280 int len;
2281
2282 len = L2CAP_CONF_OPT_SIZE + opt->len;
2283 *ptr += len;
2284
2285 *type = opt->type;
2286 *olen = opt->len;
2287
2288 switch (opt->len) {
2289 case 1:
2290 *val = *((u8 *) opt->val);
2291 break;
2292
2293 case 2:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002294 *val = __le16_to_cpu(*((__le16 *) opt->val));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002295 break;
2296
2297 case 4:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002298 *val = __le32_to_cpu(*((__le32 *) opt->val));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002299 break;
2300
2301 default:
2302 *val = (unsigned long) opt->val;
2303 break;
2304 }
2305
2306 BT_DBG("type 0x%2.2x len %d val 0x%lx", *type, opt->len, *val);
2307 return len;
2308}
2309
Linus Torvalds1da177e2005-04-16 15:20:36 -07002310static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2311{
2312 struct l2cap_conf_opt *opt = *ptr;
2313
2314 BT_DBG("type 0x%2.2x len %d val 0x%lx", type, len, val);
2315
2316 opt->type = type;
2317 opt->len = len;
2318
2319 switch (len) {
2320 case 1:
2321 *((u8 *) opt->val) = val;
2322 break;
2323
2324 case 2:
Al Viro8e036fc2007-07-29 00:16:36 -07002325 *((__le16 *) opt->val) = cpu_to_le16(val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002326 break;
2327
2328 case 4:
Al Viro8e036fc2007-07-29 00:16:36 -07002329 *((__le32 *) opt->val) = cpu_to_le32(val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002330 break;
2331
2332 default:
2333 memcpy(opt->val, (void *) val, len);
2334 break;
2335 }
2336
2337 *ptr += L2CAP_CONF_OPT_SIZE + len;
2338}
2339
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002340static void l2cap_ack_timeout(unsigned long arg)
2341{
2342 struct sock *sk = (void *) arg;
2343
2344 bh_lock_sock(sk);
2345 l2cap_send_ack(l2cap_pi(sk));
2346 bh_unlock_sock(sk);
2347}
2348
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002349static inline void l2cap_ertm_init(struct sock *sk)
2350{
2351 l2cap_pi(sk)->expected_ack_seq = 0;
2352 l2cap_pi(sk)->unacked_frames = 0;
2353 l2cap_pi(sk)->buffer_seq = 0;
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03002354 l2cap_pi(sk)->num_acked = 0;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03002355 l2cap_pi(sk)->frames_sent = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002356
2357 setup_timer(&l2cap_pi(sk)->retrans_timer,
2358 l2cap_retrans_timeout, (unsigned long) sk);
2359 setup_timer(&l2cap_pi(sk)->monitor_timer,
2360 l2cap_monitor_timeout, (unsigned long) sk);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002361 setup_timer(&l2cap_pi(sk)->ack_timer,
2362 l2cap_ack_timeout, (unsigned long) sk);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002363
2364 __skb_queue_head_init(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002365 __skb_queue_head_init(BUSY_QUEUE(sk));
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03002366 spin_lock_init(&l2cap_pi(sk)->send_lock);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002367
2368 INIT_WORK(&l2cap_pi(sk)->busy_work, l2cap_busy_work);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002369}
2370
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002371static int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
2372{
2373 u32 local_feat_mask = l2cap_feat_mask;
2374 if (enable_ertm)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002375 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002376
2377 switch (mode) {
2378 case L2CAP_MODE_ERTM:
2379 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
2380 case L2CAP_MODE_STREAMING:
2381 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
2382 default:
2383 return 0x00;
2384 }
2385}
2386
2387static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
2388{
2389 switch (mode) {
2390 case L2CAP_MODE_STREAMING:
2391 case L2CAP_MODE_ERTM:
2392 if (l2cap_mode_supported(mode, remote_feat_mask))
2393 return mode;
2394 /* fall through */
2395 default:
2396 return L2CAP_MODE_BASIC;
2397 }
2398}
2399
Linus Torvalds1da177e2005-04-16 15:20:36 -07002400static int l2cap_build_conf_req(struct sock *sk, void *data)
2401{
2402 struct l2cap_pinfo *pi = l2cap_pi(sk);
2403 struct l2cap_conf_req *req = data;
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03002404 struct l2cap_conf_rfc rfc = { .mode = pi->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07002405 void *ptr = req->data;
2406
2407 BT_DBG("sk %p", sk);
2408
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002409 if (pi->num_conf_req || pi->num_conf_rsp)
2410 goto done;
2411
2412 switch (pi->mode) {
2413 case L2CAP_MODE_STREAMING:
2414 case L2CAP_MODE_ERTM:
2415 pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002416 if (!l2cap_mode_supported(pi->mode, pi->conn->feat_mask))
2417 l2cap_send_disconn_req(pi->conn, sk);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002418 break;
2419 default:
2420 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
2421 break;
2422 }
2423
2424done:
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002425 switch (pi->mode) {
2426 case L2CAP_MODE_BASIC:
2427 if (pi->imtu != L2CAP_DEFAULT_MTU)
2428 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
2429 break;
2430
2431 case L2CAP_MODE_ERTM:
2432 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03002433 rfc.txwin_size = pi->tx_win;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03002434 rfc.max_transmit = pi->max_tx;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002435 rfc.retrans_timeout = 0;
2436 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002437 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03002438 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002439 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002440
2441 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2442 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002443
2444 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2445 break;
2446
2447 if (pi->fcs == L2CAP_FCS_NONE ||
2448 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
2449 pi->fcs = L2CAP_FCS_NONE;
2450 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
2451 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002452 break;
2453
2454 case L2CAP_MODE_STREAMING:
2455 rfc.mode = L2CAP_MODE_STREAMING;
2456 rfc.txwin_size = 0;
2457 rfc.max_transmit = 0;
2458 rfc.retrans_timeout = 0;
2459 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002460 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03002461 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002462 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002463
2464 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2465 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002466
2467 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2468 break;
2469
2470 if (pi->fcs == L2CAP_FCS_NONE ||
2471 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
2472 pi->fcs = L2CAP_FCS_NONE;
2473 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
2474 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002475 break;
2476 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002477
2478 /* FIXME: Need actual value of the flush timeout */
2479 //if (flush_to != L2CAP_DEFAULT_FLUSH_TO)
2480 // l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2, pi->flush_to);
2481
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002482 req->dcid = cpu_to_le16(pi->dcid);
2483 req->flags = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002484
2485 return ptr - data;
2486}
2487
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002488static int l2cap_parse_conf_req(struct sock *sk, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002489{
2490 struct l2cap_pinfo *pi = l2cap_pi(sk);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002491 struct l2cap_conf_rsp *rsp = data;
2492 void *ptr = rsp->data;
2493 void *req = pi->conf_req;
2494 int len = pi->conf_len;
2495 int type, hint, olen;
2496 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002497 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Marcel Holtmann861d6882007-10-20 13:37:06 +02002498 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002499 u16 result = L2CAP_CONF_SUCCESS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002500
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002501 BT_DBG("sk %p", sk);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01002502
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002503 while (len >= L2CAP_CONF_OPT_SIZE) {
2504 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002505
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03002506 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07002507 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002508
2509 switch (type) {
2510 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002511 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002512 break;
2513
2514 case L2CAP_CONF_FLUSH_TO:
2515 pi->flush_to = val;
2516 break;
2517
2518 case L2CAP_CONF_QOS:
2519 break;
2520
Marcel Holtmann6464f352007-10-20 13:39:51 +02002521 case L2CAP_CONF_RFC:
2522 if (olen == sizeof(rfc))
2523 memcpy(&rfc, (void *) val, olen);
2524 break;
2525
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002526 case L2CAP_CONF_FCS:
2527 if (val == L2CAP_FCS_NONE)
2528 pi->conf_state |= L2CAP_CONF_NO_FCS_RECV;
2529
2530 break;
2531
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002532 default:
2533 if (hint)
2534 break;
2535
2536 result = L2CAP_CONF_UNKNOWN;
2537 *((u8 *) ptr++) = type;
2538 break;
2539 }
2540 }
2541
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002542 if (pi->num_conf_rsp || pi->num_conf_req)
2543 goto done;
2544
2545 switch (pi->mode) {
2546 case L2CAP_MODE_STREAMING:
2547 case L2CAP_MODE_ERTM:
2548 pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
2549 if (!l2cap_mode_supported(pi->mode, pi->conn->feat_mask))
2550 return -ECONNREFUSED;
2551 break;
2552 default:
2553 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
2554 break;
2555 }
2556
2557done:
2558 if (pi->mode != rfc.mode) {
2559 result = L2CAP_CONF_UNACCEPT;
2560 rfc.mode = pi->mode;
2561
2562 if (pi->num_conf_rsp == 1)
2563 return -ECONNREFUSED;
2564
2565 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2566 sizeof(rfc), (unsigned long) &rfc);
2567 }
2568
2569
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002570 if (result == L2CAP_CONF_SUCCESS) {
2571 /* Configure output options and let the other side know
2572 * which ones we don't like. */
2573
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002574 if (mtu < L2CAP_DEFAULT_MIN_MTU)
2575 result = L2CAP_CONF_UNACCEPT;
2576 else {
2577 pi->omtu = mtu;
2578 pi->conf_state |= L2CAP_CONF_MTU_DONE;
2579 }
2580 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002581
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002582 switch (rfc.mode) {
2583 case L2CAP_MODE_BASIC:
2584 pi->fcs = L2CAP_FCS_NONE;
2585 pi->conf_state |= L2CAP_CONF_MODE_DONE;
2586 break;
2587
2588 case L2CAP_MODE_ERTM:
2589 pi->remote_tx_win = rfc.txwin_size;
2590 pi->remote_max_tx = rfc.max_transmit;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002591 if (rfc.max_pdu_size > pi->conn->mtu - 10)
2592 rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10);
2593
2594 pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002595
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002596 rfc.retrans_timeout =
2597 le16_to_cpu(L2CAP_DEFAULT_RETRANS_TO);
2598 rfc.monitor_timeout =
2599 le16_to_cpu(L2CAP_DEFAULT_MONITOR_TO);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002600
2601 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03002602
2603 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2604 sizeof(rfc), (unsigned long) &rfc);
2605
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002606 break;
2607
2608 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002609 if (rfc.max_pdu_size > pi->conn->mtu - 10)
2610 rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10);
2611
2612 pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002613
2614 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03002615
2616 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2617 sizeof(rfc), (unsigned long) &rfc);
2618
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002619 break;
2620
2621 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02002622 result = L2CAP_CONF_UNACCEPT;
2623
2624 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002625 rfc.mode = pi->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002626 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002627
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002628 if (result == L2CAP_CONF_SUCCESS)
2629 pi->conf_state |= L2CAP_CONF_OUTPUT_DONE;
2630 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002631 rsp->scid = cpu_to_le16(pi->dcid);
2632 rsp->result = cpu_to_le16(result);
2633 rsp->flags = cpu_to_le16(0x0000);
2634
2635 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002636}
2637
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002638static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data, u16 *result)
2639{
2640 struct l2cap_pinfo *pi = l2cap_pi(sk);
2641 struct l2cap_conf_req *req = data;
2642 void *ptr = req->data;
2643 int type, olen;
2644 unsigned long val;
2645 struct l2cap_conf_rfc rfc;
2646
2647 BT_DBG("sk %p, rsp %p, len %d, req %p", sk, rsp, len, data);
2648
2649 while (len >= L2CAP_CONF_OPT_SIZE) {
2650 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
2651
2652 switch (type) {
2653 case L2CAP_CONF_MTU:
2654 if (val < L2CAP_DEFAULT_MIN_MTU) {
2655 *result = L2CAP_CONF_UNACCEPT;
2656 pi->omtu = L2CAP_DEFAULT_MIN_MTU;
2657 } else
2658 pi->omtu = val;
2659 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
2660 break;
2661
2662 case L2CAP_CONF_FLUSH_TO:
2663 pi->flush_to = val;
2664 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
2665 2, pi->flush_to);
2666 break;
2667
2668 case L2CAP_CONF_RFC:
2669 if (olen == sizeof(rfc))
2670 memcpy(&rfc, (void *)val, olen);
2671
2672 if ((pi->conf_state & L2CAP_CONF_STATE2_DEVICE) &&
2673 rfc.mode != pi->mode)
2674 return -ECONNREFUSED;
2675
2676 pi->mode = rfc.mode;
2677 pi->fcs = 0;
2678
2679 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2680 sizeof(rfc), (unsigned long) &rfc);
2681 break;
2682 }
2683 }
2684
2685 if (*result == L2CAP_CONF_SUCCESS) {
2686 switch (rfc.mode) {
2687 case L2CAP_MODE_ERTM:
2688 pi->remote_tx_win = rfc.txwin_size;
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002689 pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
2690 pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002691 pi->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002692 break;
2693 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002694 pi->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002695 }
2696 }
2697
2698 req->dcid = cpu_to_le16(pi->dcid);
2699 req->flags = cpu_to_le16(0x0000);
2700
2701 return ptr - data;
2702}
2703
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002704static int l2cap_build_conf_rsp(struct sock *sk, void *data, u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002705{
2706 struct l2cap_conf_rsp *rsp = data;
2707 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002708
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002709 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002710
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002711 rsp->scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002712 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002713 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002714
2715 return ptr - data;
2716}
2717
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002718static void l2cap_conf_rfc_get(struct sock *sk, void *rsp, int len)
2719{
2720 struct l2cap_pinfo *pi = l2cap_pi(sk);
2721 int type, olen;
2722 unsigned long val;
2723 struct l2cap_conf_rfc rfc;
2724
2725 BT_DBG("sk %p, rsp %p, len %d", sk, rsp, len);
2726
2727 if ((pi->mode != L2CAP_MODE_ERTM) && (pi->mode != L2CAP_MODE_STREAMING))
2728 return;
2729
2730 while (len >= L2CAP_CONF_OPT_SIZE) {
2731 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
2732
2733 switch (type) {
2734 case L2CAP_CONF_RFC:
2735 if (olen == sizeof(rfc))
2736 memcpy(&rfc, (void *)val, olen);
2737 goto done;
2738 }
2739 }
2740
2741done:
2742 switch (rfc.mode) {
2743 case L2CAP_MODE_ERTM:
2744 pi->remote_tx_win = rfc.txwin_size;
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002745 pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
2746 pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002747 pi->mps = le16_to_cpu(rfc.max_pdu_size);
2748 break;
2749 case L2CAP_MODE_STREAMING:
2750 pi->mps = le16_to_cpu(rfc.max_pdu_size);
2751 }
2752}
2753
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002754static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2755{
2756 struct l2cap_cmd_rej *rej = (struct l2cap_cmd_rej *) data;
2757
2758 if (rej->reason != 0x0000)
2759 return 0;
2760
2761 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
2762 cmd->ident == conn->info_ident) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002763 del_timer(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01002764
2765 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002766 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01002767
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002768 l2cap_conn_start(conn);
2769 }
2770
2771 return 0;
2772}
2773
Linus Torvalds1da177e2005-04-16 15:20:36 -07002774static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2775{
2776 struct l2cap_chan_list *list = &conn->chan_list;
2777 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
2778 struct l2cap_conn_rsp rsp;
2779 struct sock *sk, *parent;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002780 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002781
2782 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002783 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002784
2785 BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
2786
2787 /* Check if we have socket listening on psm */
2788 parent = l2cap_get_sock_by_psm(BT_LISTEN, psm, conn->src);
2789 if (!parent) {
2790 result = L2CAP_CR_BAD_PSM;
2791 goto sendresp;
2792 }
2793
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002794 /* Check if the ACL is secure enough (if not SDP) */
2795 if (psm != cpu_to_le16(0x0001) &&
2796 !hci_conn_check_link_mode(conn->hcon)) {
Marcel Holtmann2950f212009-02-12 14:02:50 +01002797 conn->disc_reason = 0x05;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002798 result = L2CAP_CR_SEC_BLOCK;
2799 goto response;
2800 }
2801
Linus Torvalds1da177e2005-04-16 15:20:36 -07002802 result = L2CAP_CR_NO_MEM;
2803
2804 /* Check for backlog size */
2805 if (sk_acceptq_is_full(parent)) {
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09002806 BT_DBG("backlog full %d", parent->sk_ack_backlog);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002807 goto response;
2808 }
2809
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09002810 sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002811 if (!sk)
2812 goto response;
2813
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002814 write_lock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002815
2816 /* Check if we already have channel with that dcid */
2817 if (__l2cap_get_chan_by_dcid(list, scid)) {
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002818 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002819 sock_set_flag(sk, SOCK_ZAPPED);
2820 l2cap_sock_kill(sk);
2821 goto response;
2822 }
2823
2824 hci_conn_hold(conn->hcon);
2825
2826 l2cap_sock_init(sk, parent);
2827 bacpy(&bt_sk(sk)->src, conn->src);
2828 bacpy(&bt_sk(sk)->dst, conn->dst);
2829 l2cap_pi(sk)->psm = psm;
2830 l2cap_pi(sk)->dcid = scid;
2831
2832 __l2cap_chan_add(conn, sk, parent);
2833 dcid = l2cap_pi(sk)->scid;
2834
2835 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
2836
Linus Torvalds1da177e2005-04-16 15:20:36 -07002837 l2cap_pi(sk)->ident = cmd->ident;
2838
Marcel Holtmann984947d2009-02-06 23:35:19 +01002839 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002840 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002841 if (bt_sk(sk)->defer_setup) {
2842 sk->sk_state = BT_CONNECT2;
2843 result = L2CAP_CR_PEND;
2844 status = L2CAP_CS_AUTHOR_PEND;
2845 parent->sk_data_ready(parent, 0);
2846 } else {
2847 sk->sk_state = BT_CONFIG;
2848 result = L2CAP_CR_SUCCESS;
2849 status = L2CAP_CS_NO_INFO;
2850 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002851 } else {
2852 sk->sk_state = BT_CONNECT2;
2853 result = L2CAP_CR_PEND;
2854 status = L2CAP_CS_AUTHEN_PEND;
2855 }
2856 } else {
2857 sk->sk_state = BT_CONNECT2;
2858 result = L2CAP_CR_PEND;
2859 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002860 }
2861
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002862 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002863
2864response:
2865 bh_unlock_sock(parent);
2866
2867sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002868 rsp.scid = cpu_to_le16(scid);
2869 rsp.dcid = cpu_to_le16(dcid);
2870 rsp.result = cpu_to_le16(result);
2871 rsp.status = cpu_to_le16(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002872 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002873
2874 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
2875 struct l2cap_info_req info;
2876 info.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
2877
2878 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
2879 conn->info_ident = l2cap_get_ident(conn);
2880
2881 mod_timer(&conn->info_timer, jiffies +
2882 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
2883
2884 l2cap_send_cmd(conn, conn->info_ident,
2885 L2CAP_INFO_REQ, sizeof(info), &info);
2886 }
2887
Linus Torvalds1da177e2005-04-16 15:20:36 -07002888 return 0;
2889}
2890
2891static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2892{
2893 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
2894 u16 scid, dcid, result, status;
2895 struct sock *sk;
2896 u8 req[128];
2897
2898 scid = __le16_to_cpu(rsp->scid);
2899 dcid = __le16_to_cpu(rsp->dcid);
2900 result = __le16_to_cpu(rsp->result);
2901 status = __le16_to_cpu(rsp->status);
2902
2903 BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
2904
2905 if (scid) {
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002906 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2907 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002908 return 0;
2909 } else {
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002910 sk = l2cap_get_chan_by_ident(&conn->chan_list, cmd->ident);
2911 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002912 return 0;
2913 }
2914
2915 switch (result) {
2916 case L2CAP_CR_SUCCESS:
2917 sk->sk_state = BT_CONFIG;
2918 l2cap_pi(sk)->ident = 0;
2919 l2cap_pi(sk)->dcid = dcid;
2920 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002921 l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_CONNECT_PEND;
2922
Linus Torvalds1da177e2005-04-16 15:20:36 -07002923 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
2924 l2cap_build_conf_req(sk, req), req);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002925 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002926 break;
2927
2928 case L2CAP_CR_PEND:
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002929 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002930 break;
2931
2932 default:
2933 l2cap_chan_del(sk, ECONNREFUSED);
2934 break;
2935 }
2936
2937 bh_unlock_sock(sk);
2938 return 0;
2939}
2940
Al Viro88219a02007-07-29 00:17:25 -07002941static 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 -07002942{
2943 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
2944 u16 dcid, flags;
2945 u8 rsp[64];
2946 struct sock *sk;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002947 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002948
2949 dcid = __le16_to_cpu(req->dcid);
2950 flags = __le16_to_cpu(req->flags);
2951
2952 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
2953
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002954 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
2955 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002956 return -ENOENT;
2957
Marcel Holtmann354f60a2006-11-18 22:15:20 +01002958 if (sk->sk_state == BT_DISCONN)
2959 goto unlock;
2960
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002961 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07002962 len = cmd_len - sizeof(*req);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002963 if (l2cap_pi(sk)->conf_len + len > sizeof(l2cap_pi(sk)->conf_req)) {
2964 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
2965 l2cap_build_conf_rsp(sk, rsp,
2966 L2CAP_CONF_REJECT, flags), rsp);
2967 goto unlock;
2968 }
2969
2970 /* Store config. */
2971 memcpy(l2cap_pi(sk)->conf_req + l2cap_pi(sk)->conf_len, req->data, len);
2972 l2cap_pi(sk)->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002973
2974 if (flags & 0x0001) {
2975 /* Incomplete config. Send empty response. */
2976 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002977 l2cap_build_conf_rsp(sk, rsp,
2978 L2CAP_CONF_SUCCESS, 0x0001), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002979 goto unlock;
2980 }
2981
2982 /* Complete config. */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002983 len = l2cap_parse_conf_req(sk, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002984 if (len < 0) {
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002985 l2cap_send_disconn_req(conn, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002986 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002987 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002988
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002989 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002990 l2cap_pi(sk)->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002991
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002992 /* Reset config buffer. */
2993 l2cap_pi(sk)->conf_len = 0;
2994
Marcel Holtmann876d9482007-10-20 13:35:42 +02002995 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE))
2996 goto unlock;
2997
Linus Torvalds1da177e2005-04-16 15:20:36 -07002998 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) {
Joe Perchesf64f9e72009-11-29 16:55:45 -08002999 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) ||
3000 l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003001 l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
3002
Linus Torvalds1da177e2005-04-16 15:20:36 -07003003 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003004
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003005 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003006 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003007 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003008 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
3009 l2cap_ertm_init(sk);
3010
Linus Torvalds1da177e2005-04-16 15:20:36 -07003011 l2cap_chan_ready(sk);
Marcel Holtmann876d9482007-10-20 13:35:42 +02003012 goto unlock;
3013 }
3014
3015 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003016 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003017 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003018 l2cap_build_conf_req(sk, buf), buf);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003019 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003020 }
3021
3022unlock:
3023 bh_unlock_sock(sk);
3024 return 0;
3025}
3026
3027static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3028{
3029 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
3030 u16 scid, flags, result;
3031 struct sock *sk;
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003032 int len = cmd->len - sizeof(*rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003033
3034 scid = __le16_to_cpu(rsp->scid);
3035 flags = __le16_to_cpu(rsp->flags);
3036 result = __le16_to_cpu(rsp->result);
3037
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03003038 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x",
3039 scid, flags, result);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003040
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03003041 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
3042 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003043 return 0;
3044
3045 switch (result) {
3046 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003047 l2cap_conf_rfc_get(sk, rsp->data, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003048 break;
3049
3050 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003051 if (l2cap_pi(sk)->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003052 char req[64];
3053
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02003054 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
3055 l2cap_send_disconn_req(conn, sk);
3056 goto done;
3057 }
3058
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003059 /* throw out any old stored conf requests */
3060 result = L2CAP_CONF_SUCCESS;
3061 len = l2cap_parse_conf_rsp(sk, rsp->data,
3062 len, req, &result);
3063 if (len < 0) {
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03003064 l2cap_send_disconn_req(conn, sk);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003065 goto done;
3066 }
3067
3068 l2cap_send_cmd(conn, l2cap_get_ident(conn),
3069 L2CAP_CONF_REQ, len, req);
3070 l2cap_pi(sk)->num_conf_req++;
3071 if (result != L2CAP_CONF_SUCCESS)
3072 goto done;
3073 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003074 }
3075
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09003076 default:
Linus Torvalds1da177e2005-04-16 15:20:36 -07003077 sk->sk_state = BT_DISCONN;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02003078 sk->sk_err = ECONNRESET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003079 l2cap_sock_set_timer(sk, HZ * 5);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03003080 l2cap_send_disconn_req(conn, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003081 goto done;
3082 }
3083
3084 if (flags & 0x01)
3085 goto done;
3086
Linus Torvalds1da177e2005-04-16 15:20:36 -07003087 l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE;
3088
3089 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) {
Joe Perchesf64f9e72009-11-29 16:55:45 -08003090 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) ||
3091 l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003092 l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
3093
Linus Torvalds1da177e2005-04-16 15:20:36 -07003094 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003095 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003096 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003097 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003098 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
3099 l2cap_ertm_init(sk);
3100
Linus Torvalds1da177e2005-04-16 15:20:36 -07003101 l2cap_chan_ready(sk);
3102 }
3103
3104done:
3105 bh_unlock_sock(sk);
3106 return 0;
3107}
3108
3109static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3110{
3111 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
3112 struct l2cap_disconn_rsp rsp;
3113 u16 dcid, scid;
3114 struct sock *sk;
3115
3116 scid = __le16_to_cpu(req->scid);
3117 dcid = __le16_to_cpu(req->dcid);
3118
3119 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
3120
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03003121 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
3122 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003123 return 0;
3124
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003125 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
3126 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003127 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
3128
3129 sk->sk_shutdown = SHUTDOWN_MASK;
3130
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003131 skb_queue_purge(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003132
3133 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
3134 skb_queue_purge(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003135 skb_queue_purge(BUSY_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003136 del_timer(&l2cap_pi(sk)->retrans_timer);
3137 del_timer(&l2cap_pi(sk)->monitor_timer);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003138 del_timer(&l2cap_pi(sk)->ack_timer);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003139 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003140
Linus Torvalds1da177e2005-04-16 15:20:36 -07003141 l2cap_chan_del(sk, ECONNRESET);
3142 bh_unlock_sock(sk);
3143
3144 l2cap_sock_kill(sk);
3145 return 0;
3146}
3147
3148static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3149{
3150 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
3151 u16 dcid, scid;
3152 struct sock *sk;
3153
3154 scid = __le16_to_cpu(rsp->scid);
3155 dcid = __le16_to_cpu(rsp->dcid);
3156
3157 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
3158
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03003159 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
3160 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003161 return 0;
3162
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003163 skb_queue_purge(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003164
3165 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
3166 skb_queue_purge(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003167 skb_queue_purge(BUSY_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003168 del_timer(&l2cap_pi(sk)->retrans_timer);
3169 del_timer(&l2cap_pi(sk)->monitor_timer);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003170 del_timer(&l2cap_pi(sk)->ack_timer);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003171 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003172
Linus Torvalds1da177e2005-04-16 15:20:36 -07003173 l2cap_chan_del(sk, 0);
3174 bh_unlock_sock(sk);
3175
3176 l2cap_sock_kill(sk);
3177 return 0;
3178}
3179
3180static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3181{
3182 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003183 u16 type;
3184
3185 type = __le16_to_cpu(req->type);
3186
3187 BT_DBG("type 0x%4.4x", type);
3188
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003189 if (type == L2CAP_IT_FEAT_MASK) {
3190 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003191 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003192 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
3193 rsp->type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
3194 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003195 if (enable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003196 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
3197 | L2CAP_FEAT_FCS;
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03003198 put_unaligned_le32(feat_mask, rsp->data);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003199 l2cap_send_cmd(conn, cmd->ident,
3200 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003201 } else if (type == L2CAP_IT_FIXED_CHAN) {
3202 u8 buf[12];
3203 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
3204 rsp->type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3205 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
3206 memcpy(buf + 4, l2cap_fixed_chan, 8);
3207 l2cap_send_cmd(conn, cmd->ident,
3208 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003209 } else {
3210 struct l2cap_info_rsp rsp;
3211 rsp.type = cpu_to_le16(type);
3212 rsp.result = cpu_to_le16(L2CAP_IR_NOTSUPP);
3213 l2cap_send_cmd(conn, cmd->ident,
3214 L2CAP_INFO_RSP, sizeof(rsp), &rsp);
3215 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003216
3217 return 0;
3218}
3219
3220static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3221{
3222 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
3223 u16 type, result;
3224
3225 type = __le16_to_cpu(rsp->type);
3226 result = __le16_to_cpu(rsp->result);
3227
3228 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
3229
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003230 del_timer(&conn->info_timer);
3231
Marcel Holtmann984947d2009-02-06 23:35:19 +01003232 if (type == L2CAP_IT_FEAT_MASK) {
Harvey Harrison83985312008-05-02 16:25:46 -07003233 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003234
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003235 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003236 struct l2cap_info_req req;
3237 req.type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3238
3239 conn->info_ident = l2cap_get_ident(conn);
3240
3241 l2cap_send_cmd(conn, conn->info_ident,
3242 L2CAP_INFO_REQ, sizeof(req), &req);
3243 } else {
3244 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
3245 conn->info_ident = 0;
3246
3247 l2cap_conn_start(conn);
3248 }
3249 } else if (type == L2CAP_IT_FIXED_CHAN) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01003250 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003251 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003252
3253 l2cap_conn_start(conn);
3254 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003255
Linus Torvalds1da177e2005-04-16 15:20:36 -07003256 return 0;
3257}
3258
3259static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
3260{
3261 u8 *data = skb->data;
3262 int len = skb->len;
3263 struct l2cap_cmd_hdr cmd;
3264 int err = 0;
3265
3266 l2cap_raw_recv(conn, skb);
3267
3268 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07003269 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003270 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
3271 data += L2CAP_CMD_HDR_SIZE;
3272 len -= L2CAP_CMD_HDR_SIZE;
3273
Al Viro88219a02007-07-29 00:17:25 -07003274 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003275
Al Viro88219a02007-07-29 00:17:25 -07003276 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 -07003277
Al Viro88219a02007-07-29 00:17:25 -07003278 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003279 BT_DBG("corrupted command");
3280 break;
3281 }
3282
3283 switch (cmd.code) {
3284 case L2CAP_COMMAND_REJ:
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003285 l2cap_command_rej(conn, &cmd, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003286 break;
3287
3288 case L2CAP_CONN_REQ:
3289 err = l2cap_connect_req(conn, &cmd, data);
3290 break;
3291
3292 case L2CAP_CONN_RSP:
3293 err = l2cap_connect_rsp(conn, &cmd, data);
3294 break;
3295
3296 case L2CAP_CONF_REQ:
Al Viro88219a02007-07-29 00:17:25 -07003297 err = l2cap_config_req(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003298 break;
3299
3300 case L2CAP_CONF_RSP:
3301 err = l2cap_config_rsp(conn, &cmd, data);
3302 break;
3303
3304 case L2CAP_DISCONN_REQ:
3305 err = l2cap_disconnect_req(conn, &cmd, data);
3306 break;
3307
3308 case L2CAP_DISCONN_RSP:
3309 err = l2cap_disconnect_rsp(conn, &cmd, data);
3310 break;
3311
3312 case L2CAP_ECHO_REQ:
Al Viro88219a02007-07-29 00:17:25 -07003313 l2cap_send_cmd(conn, cmd.ident, L2CAP_ECHO_RSP, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003314 break;
3315
3316 case L2CAP_ECHO_RSP:
3317 break;
3318
3319 case L2CAP_INFO_REQ:
3320 err = l2cap_information_req(conn, &cmd, data);
3321 break;
3322
3323 case L2CAP_INFO_RSP:
3324 err = l2cap_information_rsp(conn, &cmd, data);
3325 break;
3326
3327 default:
3328 BT_ERR("Unknown signaling command 0x%2.2x", cmd.code);
3329 err = -EINVAL;
3330 break;
3331 }
3332
3333 if (err) {
3334 struct l2cap_cmd_rej rej;
3335 BT_DBG("error %d", err);
3336
3337 /* FIXME: Map err to a valid reason */
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003338 rej.reason = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003339 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
3340 }
3341
Al Viro88219a02007-07-29 00:17:25 -07003342 data += cmd_len;
3343 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003344 }
3345
3346 kfree_skb(skb);
3347}
3348
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003349static int l2cap_check_fcs(struct l2cap_pinfo *pi, struct sk_buff *skb)
3350{
3351 u16 our_fcs, rcv_fcs;
3352 int hdr_size = L2CAP_HDR_SIZE + 2;
3353
3354 if (pi->fcs == L2CAP_FCS_CRC16) {
3355 skb_trim(skb, skb->len - 2);
3356 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
3357 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
3358
3359 if (our_fcs != rcv_fcs)
3360 return -EINVAL;
3361 }
3362 return 0;
3363}
3364
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003365static inline void l2cap_send_i_or_rr_or_rnr(struct sock *sk)
3366{
3367 struct l2cap_pinfo *pi = l2cap_pi(sk);
3368 u16 control = 0;
3369
3370 pi->frames_sent = 0;
3371 pi->conn_state |= L2CAP_CONN_SEND_FBIT;
3372
3373 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3374
3375 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
3376 control |= L2CAP_SUPER_RCV_NOT_READY | L2CAP_CTRL_FINAL;
3377 l2cap_send_sframe(pi, control);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003378 pi->conn_state |= L2CAP_CONN_RNR_SENT;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003379 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
3380 }
3381
3382 if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY && pi->unacked_frames > 0)
3383 __mod_retrans_timer();
3384
Gustavo F. Padovan844c0972010-05-04 23:16:01 -03003385 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3386
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003387 spin_lock_bh(&pi->send_lock);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003388 l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003389 spin_unlock_bh(&pi->send_lock);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003390
3391 if (!(pi->conn_state & L2CAP_CONN_LOCAL_BUSY) &&
3392 pi->frames_sent == 0) {
3393 control |= L2CAP_SUPER_RCV_READY;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003394 l2cap_send_sframe(pi, control);
3395 }
3396}
3397
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003398static 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 -03003399{
3400 struct sk_buff *next_skb;
3401
3402 bt_cb(skb)->tx_seq = tx_seq;
3403 bt_cb(skb)->sar = sar;
3404
3405 next_skb = skb_peek(SREJ_QUEUE(sk));
3406 if (!next_skb) {
3407 __skb_queue_tail(SREJ_QUEUE(sk), skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003408 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003409 }
3410
3411 do {
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003412 if (bt_cb(next_skb)->tx_seq == tx_seq)
3413 return -EINVAL;
3414
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003415 if (bt_cb(next_skb)->tx_seq > tx_seq) {
3416 __skb_queue_before(SREJ_QUEUE(sk), next_skb, skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003417 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003418 }
3419
3420 if (skb_queue_is_last(SREJ_QUEUE(sk), next_skb))
3421 break;
3422
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003423 } while ((next_skb = skb_queue_next(SREJ_QUEUE(sk), next_skb)));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003424
3425 __skb_queue_tail(SREJ_QUEUE(sk), skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003426
3427 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003428}
3429
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003430static int l2cap_ertm_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
3431{
3432 struct l2cap_pinfo *pi = l2cap_pi(sk);
3433 struct sk_buff *_skb;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003434 int err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003435
3436 switch (control & L2CAP_CTRL_SAR) {
3437 case L2CAP_SDU_UNSEGMENTED:
3438 if (pi->conn_state & L2CAP_CONN_SAR_SDU)
3439 goto drop;
3440
3441 err = sock_queue_rcv_skb(sk, skb);
3442 if (!err)
3443 return err;
3444
3445 break;
3446
3447 case L2CAP_SDU_START:
3448 if (pi->conn_state & L2CAP_CONN_SAR_SDU)
3449 goto drop;
3450
3451 pi->sdu_len = get_unaligned_le16(skb->data);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003452
3453 if (pi->sdu_len > pi->imtu)
3454 goto disconnect;
3455
3456 pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003457 if (!pi->sdu)
3458 return -ENOMEM;
3459
3460 /* pull sdu_len bytes only after alloc, because of Local Busy
3461 * condition we have to be sure that this will be executed
3462 * only once, i.e., when alloc does not fail */
3463 skb_pull(skb, 2);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003464
3465 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3466
3467 pi->conn_state |= L2CAP_CONN_SAR_SDU;
3468 pi->partial_sdu_len = skb->len;
3469 break;
3470
3471 case L2CAP_SDU_CONTINUE:
3472 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3473 goto disconnect;
3474
3475 if (!pi->sdu)
3476 goto disconnect;
3477
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003478 pi->partial_sdu_len += skb->len;
3479 if (pi->partial_sdu_len > pi->sdu_len)
3480 goto drop;
3481
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03003482 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3483
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003484 break;
3485
3486 case L2CAP_SDU_END:
3487 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3488 goto disconnect;
3489
3490 if (!pi->sdu)
3491 goto disconnect;
3492
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003493 if (!(pi->conn_state & L2CAP_CONN_SAR_RETRY)) {
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003494 pi->partial_sdu_len += skb->len;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003495
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003496 if (pi->partial_sdu_len > pi->imtu)
3497 goto drop;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003498
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003499 if (pi->partial_sdu_len != pi->sdu_len)
3500 goto drop;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03003501
3502 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003503 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003504
3505 _skb = skb_clone(pi->sdu, GFP_ATOMIC);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003506 if (!_skb) {
3507 pi->conn_state |= L2CAP_CONN_SAR_RETRY;
3508 return -ENOMEM;
3509 }
3510
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003511 err = sock_queue_rcv_skb(sk, _skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003512 if (err < 0) {
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003513 kfree_skb(_skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003514 pi->conn_state |= L2CAP_CONN_SAR_RETRY;
3515 return err;
3516 }
3517
3518 pi->conn_state &= ~L2CAP_CONN_SAR_RETRY;
3519 pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003520
3521 kfree_skb(pi->sdu);
3522 break;
3523 }
3524
3525 kfree_skb(skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003526 return 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003527
3528drop:
3529 kfree_skb(pi->sdu);
3530 pi->sdu = NULL;
3531
3532disconnect:
3533 l2cap_send_disconn_req(pi->conn, sk);
3534 kfree_skb(skb);
3535 return 0;
3536}
3537
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003538static void l2cap_busy_work(struct work_struct *work)
3539{
3540 DECLARE_WAITQUEUE(wait, current);
3541 struct l2cap_pinfo *pi =
3542 container_of(work, struct l2cap_pinfo, busy_work);
3543 struct sock *sk = (struct sock *)pi;
3544 int n_tries = 0, timeo = HZ/5, err;
3545 struct sk_buff *skb;
3546 u16 control;
3547
3548 lock_sock(sk);
3549
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02003550 add_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003551 while ((skb = skb_peek(BUSY_QUEUE(sk)))) {
3552 set_current_state(TASK_INTERRUPTIBLE);
3553
3554 if (n_tries++ > L2CAP_LOCAL_BUSY_TRIES) {
3555 err = -EBUSY;
3556 l2cap_send_disconn_req(pi->conn, sk);
3557 goto done;
3558 }
3559
3560 if (!timeo)
3561 timeo = HZ/5;
3562
3563 if (signal_pending(current)) {
3564 err = sock_intr_errno(timeo);
3565 goto done;
3566 }
3567
3568 release_sock(sk);
3569 timeo = schedule_timeout(timeo);
3570 lock_sock(sk);
3571
3572 err = sock_error(sk);
3573 if (err)
3574 goto done;
3575
3576 while ((skb = skb_dequeue(BUSY_QUEUE(sk)))) {
3577 control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
3578 err = l2cap_ertm_reassembly_sdu(sk, skb, control);
3579 if (err < 0) {
3580 skb_queue_head(BUSY_QUEUE(sk), skb);
3581 break;
3582 }
3583
3584 pi->buffer_seq = (pi->buffer_seq + 1) % 64;
3585 }
3586
3587 if (!skb)
3588 break;
3589 }
3590
3591 if (!(pi->conn_state & L2CAP_CONN_RNR_SENT))
3592 goto done;
3593
3594 control = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3595 control |= L2CAP_SUPER_RCV_READY | L2CAP_CTRL_POLL;
3596 l2cap_send_sframe(pi, control);
3597 l2cap_pi(sk)->retry_count = 1;
3598
3599 del_timer(&pi->retrans_timer);
3600 __mod_monitor_timer();
3601
3602 l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
3603
3604done:
3605 pi->conn_state &= ~L2CAP_CONN_LOCAL_BUSY;
3606 pi->conn_state &= ~L2CAP_CONN_RNR_SENT;
3607
3608 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02003609 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003610
3611 release_sock(sk);
3612}
3613
3614static int l2cap_push_rx_skb(struct sock *sk, struct sk_buff *skb, u16 control)
3615{
3616 struct l2cap_pinfo *pi = l2cap_pi(sk);
3617 int sctrl, err;
3618
3619 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
3620 bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT;
3621 __skb_queue_tail(BUSY_QUEUE(sk), skb);
3622 return -EBUSY;
3623 }
3624
3625 err = l2cap_ertm_reassembly_sdu(sk, skb, control);
3626 if (err >= 0) {
3627 pi->buffer_seq = (pi->buffer_seq + 1) % 64;
3628 return err;
3629 }
3630
3631 /* Busy Condition */
3632 pi->conn_state |= L2CAP_CONN_LOCAL_BUSY;
3633 bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT;
3634 __skb_queue_tail(BUSY_QUEUE(sk), skb);
3635
3636 sctrl = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3637 sctrl |= L2CAP_SUPER_RCV_NOT_READY;
3638 l2cap_send_sframe(pi, sctrl);
3639
3640 pi->conn_state |= L2CAP_CONN_RNR_SENT;
3641
3642 queue_work(_busy_wq, &pi->busy_work);
3643
3644 return err;
3645}
3646
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003647static int l2cap_streaming_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003648{
3649 struct l2cap_pinfo *pi = l2cap_pi(sk);
3650 struct sk_buff *_skb;
3651 int err = -EINVAL;
3652
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003653 /*
3654 * TODO: We have to notify the userland if some data is lost with the
3655 * Streaming Mode.
3656 */
3657
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003658 switch (control & L2CAP_CTRL_SAR) {
3659 case L2CAP_SDU_UNSEGMENTED:
3660 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3661 kfree_skb(pi->sdu);
3662 break;
3663 }
3664
3665 err = sock_queue_rcv_skb(sk, skb);
3666 if (!err)
3667 return 0;
3668
3669 break;
3670
3671 case L2CAP_SDU_START:
3672 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3673 kfree_skb(pi->sdu);
3674 break;
3675 }
3676
3677 pi->sdu_len = get_unaligned_le16(skb->data);
3678 skb_pull(skb, 2);
3679
Gustavo F. Padovan052897c2010-05-01 16:15:40 -03003680 if (pi->sdu_len > pi->imtu) {
3681 err = -EMSGSIZE;
3682 break;
3683 }
3684
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003685 pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
3686 if (!pi->sdu) {
3687 err = -ENOMEM;
3688 break;
3689 }
3690
3691 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3692
3693 pi->conn_state |= L2CAP_CONN_SAR_SDU;
3694 pi->partial_sdu_len = skb->len;
3695 err = 0;
3696 break;
3697
3698 case L2CAP_SDU_CONTINUE:
3699 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3700 break;
3701
3702 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3703
3704 pi->partial_sdu_len += skb->len;
3705 if (pi->partial_sdu_len > pi->sdu_len)
3706 kfree_skb(pi->sdu);
3707 else
3708 err = 0;
3709
3710 break;
3711
3712 case L2CAP_SDU_END:
3713 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3714 break;
3715
3716 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3717
3718 pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
3719 pi->partial_sdu_len += skb->len;
3720
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003721 if (pi->partial_sdu_len > pi->imtu)
3722 goto drop;
3723
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003724 if (pi->partial_sdu_len == pi->sdu_len) {
3725 _skb = skb_clone(pi->sdu, GFP_ATOMIC);
3726 err = sock_queue_rcv_skb(sk, _skb);
3727 if (err < 0)
3728 kfree_skb(_skb);
3729 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003730 err = 0;
3731
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003732drop:
3733 kfree_skb(pi->sdu);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003734 break;
3735 }
3736
3737 kfree_skb(skb);
3738 return err;
3739}
3740
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003741static void l2cap_check_srej_gap(struct sock *sk, u8 tx_seq)
3742{
3743 struct sk_buff *skb;
Gustavo F. Padovanafefdbc2010-05-01 16:15:43 -03003744 u16 control;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003745
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003746 while ((skb = skb_peek(SREJ_QUEUE(sk)))) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003747 if (bt_cb(skb)->tx_seq != tx_seq)
3748 break;
3749
3750 skb = skb_dequeue(SREJ_QUEUE(sk));
Gustavo F. Padovanafefdbc2010-05-01 16:15:43 -03003751 control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003752 l2cap_ertm_reassembly_sdu(sk, skb, control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003753 l2cap_pi(sk)->buffer_seq_srej =
3754 (l2cap_pi(sk)->buffer_seq_srej + 1) % 64;
3755 tx_seq++;
3756 }
3757}
3758
3759static void l2cap_resend_srejframe(struct sock *sk, u8 tx_seq)
3760{
3761 struct l2cap_pinfo *pi = l2cap_pi(sk);
3762 struct srej_list *l, *tmp;
3763 u16 control;
3764
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003765 list_for_each_entry_safe(l, tmp, SREJ_LIST(sk), list) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003766 if (l->tx_seq == tx_seq) {
3767 list_del(&l->list);
3768 kfree(l);
3769 return;
3770 }
3771 control = L2CAP_SUPER_SELECT_REJECT;
3772 control |= l->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3773 l2cap_send_sframe(pi, control);
3774 list_del(&l->list);
3775 list_add_tail(&l->list, SREJ_LIST(sk));
3776 }
3777}
3778
3779static void l2cap_send_srejframe(struct sock *sk, u8 tx_seq)
3780{
3781 struct l2cap_pinfo *pi = l2cap_pi(sk);
3782 struct srej_list *new;
3783 u16 control;
3784
3785 while (tx_seq != pi->expected_tx_seq) {
3786 control = L2CAP_SUPER_SELECT_REJECT;
3787 control |= pi->expected_tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3788 l2cap_send_sframe(pi, control);
3789
3790 new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC);
3791 new->tx_seq = pi->expected_tx_seq++;
3792 list_add_tail(&new->list, SREJ_LIST(sk));
3793 }
3794 pi->expected_tx_seq++;
3795}
3796
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003797static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
3798{
3799 struct l2cap_pinfo *pi = l2cap_pi(sk);
3800 u8 tx_seq = __get_txseq(rx_control);
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003801 u8 req_seq = __get_reqseq(rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003802 u8 sar = rx_control >> L2CAP_CTRL_SAR_SHIFT;
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003803 u8 tx_seq_offset, expected_tx_seq_offset;
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03003804 int num_to_ack = (pi->tx_win/6) + 1;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003805 int err = 0;
3806
3807 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
3808
Gustavo F. Padovan9b16dc62010-05-05 20:05:57 -03003809 if (L2CAP_CTRL_FINAL & rx_control &&
3810 l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) {
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003811 del_timer(&pi->monitor_timer);
3812 if (pi->unacked_frames > 0)
3813 __mod_retrans_timer();
3814 pi->conn_state &= ~L2CAP_CONN_WAIT_F;
3815 }
3816
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003817 pi->expected_ack_seq = req_seq;
3818 l2cap_drop_acked_frames(sk);
3819
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003820 if (tx_seq == pi->expected_tx_seq)
3821 goto expected;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003822
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003823 tx_seq_offset = (tx_seq - pi->buffer_seq) % 64;
3824 if (tx_seq_offset < 0)
3825 tx_seq_offset += 64;
3826
3827 /* invalid tx_seq */
3828 if (tx_seq_offset >= pi->tx_win) {
3829 l2cap_send_disconn_req(pi->conn, sk);
3830 goto drop;
3831 }
3832
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003833 if (pi->conn_state == L2CAP_CONN_LOCAL_BUSY)
3834 goto drop;
3835
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003836 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3837 struct srej_list *first;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003838
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003839 first = list_first_entry(SREJ_LIST(sk),
3840 struct srej_list, list);
3841 if (tx_seq == first->tx_seq) {
3842 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3843 l2cap_check_srej_gap(sk, tx_seq);
3844
3845 list_del(&first->list);
3846 kfree(first);
3847
3848 if (list_empty(SREJ_LIST(sk))) {
3849 pi->buffer_seq = pi->buffer_seq_srej;
3850 pi->conn_state &= ~L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan855666c2010-05-01 16:15:40 -03003851 l2cap_send_ack(pi);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003852 }
3853 } else {
3854 struct srej_list *l;
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003855
3856 /* duplicated tx_seq */
3857 if (l2cap_add_to_srej_queue(sk, skb, tx_seq, sar) < 0)
3858 goto drop;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003859
3860 list_for_each_entry(l, SREJ_LIST(sk), list) {
3861 if (l->tx_seq == tx_seq) {
3862 l2cap_resend_srejframe(sk, tx_seq);
3863 return 0;
3864 }
3865 }
3866 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003867 }
3868 } else {
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003869 expected_tx_seq_offset =
3870 (pi->expected_tx_seq - pi->buffer_seq) % 64;
3871 if (expected_tx_seq_offset < 0)
3872 expected_tx_seq_offset += 64;
3873
3874 /* duplicated tx_seq */
3875 if (tx_seq_offset < expected_tx_seq_offset)
3876 goto drop;
3877
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003878 pi->conn_state |= L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003879
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003880 INIT_LIST_HEAD(SREJ_LIST(sk));
3881 pi->buffer_seq_srej = pi->buffer_seq;
3882
3883 __skb_queue_head_init(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003884 __skb_queue_head_init(BUSY_QUEUE(sk));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003885 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3886
Gustavo F. Padovanef54fd92009-08-20 22:26:04 -03003887 pi->conn_state |= L2CAP_CONN_SEND_PBIT;
3888
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003889 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003890 }
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003891 return 0;
3892
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003893expected:
3894 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
3895
3896 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
Gustavo F. Padovan3b1a9f32010-05-01 16:15:42 -03003897 bt_cb(skb)->tx_seq = tx_seq;
3898 bt_cb(skb)->sar = sar;
3899 __skb_queue_tail(SREJ_QUEUE(sk), skb);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003900 return 0;
3901 }
3902
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03003903 if (rx_control & L2CAP_CTRL_FINAL) {
3904 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3905 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003906 else
3907 l2cap_retransmit_frames(sk);
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03003908 }
3909
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003910 err = l2cap_push_rx_skb(sk, skb, rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003911 if (err < 0)
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003912 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003913
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003914 __mod_ack_timer();
3915
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03003916 pi->num_acked = (pi->num_acked + 1) % num_to_ack;
3917 if (pi->num_acked == num_to_ack - 1)
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03003918 l2cap_send_ack(pi);
3919
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003920 return 0;
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003921
3922drop:
3923 kfree_skb(skb);
3924 return 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003925}
3926
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003927static inline void l2cap_data_channel_rrframe(struct sock *sk, u16 rx_control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003928{
3929 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan6e3a5982010-05-01 16:15:38 -03003930
3931 pi->expected_ack_seq = __get_reqseq(rx_control);
3932 l2cap_drop_acked_frames(sk);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003933
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003934 if (rx_control & L2CAP_CTRL_POLL) {
Gustavo F. Padovan05fbd892010-05-01 16:15:39 -03003935 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3936 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
3937 (pi->unacked_frames > 0))
3938 __mod_retrans_timer();
3939
3940 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3941 l2cap_send_srejtail(sk);
3942 } else {
3943 l2cap_send_i_or_rr_or_rnr(sk);
Gustavo F. Padovan05fbd892010-05-01 16:15:39 -03003944 }
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003945
3946 } else if (rx_control & L2CAP_CTRL_FINAL) {
3947 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003948
3949 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3950 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003951 else
3952 l2cap_retransmit_frames(sk);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003953
3954 } else {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003955 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
3956 (pi->unacked_frames > 0))
3957 __mod_retrans_timer();
3958
3959 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003960 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003961 l2cap_send_ack(pi);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003962 } else {
3963 spin_lock_bh(&pi->send_lock);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003964 l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003965 spin_unlock_bh(&pi->send_lock);
3966 }
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003967 }
3968}
3969
3970static inline void l2cap_data_channel_rejframe(struct sock *sk, u16 rx_control)
3971{
3972 struct l2cap_pinfo *pi = l2cap_pi(sk);
3973 u8 tx_seq = __get_reqseq(rx_control);
3974
3975 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3976
Gustavo F. Padovan8abb52e2010-05-01 16:15:38 -03003977 pi->expected_ack_seq = tx_seq;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003978 l2cap_drop_acked_frames(sk);
3979
3980 if (rx_control & L2CAP_CTRL_FINAL) {
3981 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3982 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003983 else
3984 l2cap_retransmit_frames(sk);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003985 } else {
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003986 l2cap_retransmit_frames(sk);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003987
Gustavo F. Padovan0301ef02010-05-05 20:56:43 -03003988 if (pi->conn_state & L2CAP_CONN_WAIT_F)
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003989 pi->conn_state |= L2CAP_CONN_REJ_ACT;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003990 }
3991}
3992static inline void l2cap_data_channel_srejframe(struct sock *sk, u16 rx_control)
3993{
3994 struct l2cap_pinfo *pi = l2cap_pi(sk);
3995 u8 tx_seq = __get_reqseq(rx_control);
3996
3997 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3998
3999 if (rx_control & L2CAP_CTRL_POLL) {
4000 pi->expected_ack_seq = tx_seq;
4001 l2cap_drop_acked_frames(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004002 l2cap_retransmit_one_frame(sk, tx_seq);
4003
4004 spin_lock_bh(&pi->send_lock);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004005 l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004006 spin_unlock_bh(&pi->send_lock);
4007
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004008 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
4009 pi->srej_save_reqseq = tx_seq;
4010 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
4011 }
4012 } else if (rx_control & L2CAP_CTRL_FINAL) {
4013 if ((pi->conn_state & L2CAP_CONN_SREJ_ACT) &&
4014 pi->srej_save_reqseq == tx_seq)
4015 pi->conn_state &= ~L2CAP_CONN_SREJ_ACT;
4016 else
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004017 l2cap_retransmit_one_frame(sk, tx_seq);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004018 } else {
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004019 l2cap_retransmit_one_frame(sk, tx_seq);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004020 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
4021 pi->srej_save_reqseq = tx_seq;
4022 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
4023 }
4024 }
4025}
4026
4027static inline void l2cap_data_channel_rnrframe(struct sock *sk, u16 rx_control)
4028{
4029 struct l2cap_pinfo *pi = l2cap_pi(sk);
4030 u8 tx_seq = __get_reqseq(rx_control);
4031
4032 pi->conn_state |= L2CAP_CONN_REMOTE_BUSY;
4033 pi->expected_ack_seq = tx_seq;
4034 l2cap_drop_acked_frames(sk);
4035
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03004036 if (!(pi->conn_state & L2CAP_CONN_SREJ_SENT)) {
4037 del_timer(&pi->retrans_timer);
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -03004038 if (rx_control & L2CAP_CTRL_POLL)
4039 l2cap_send_rr_or_rnr(pi, L2CAP_CTRL_FINAL);
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03004040 return;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004041 }
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03004042
4043 if (rx_control & L2CAP_CTRL_POLL)
4044 l2cap_send_srejtail(sk);
4045 else
4046 l2cap_send_sframe(pi, L2CAP_SUPER_RCV_READY);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004047}
4048
4049static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
4050{
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004051 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
4052
Gustavo F. Padovan9b16dc62010-05-05 20:05:57 -03004053 if (L2CAP_CTRL_FINAL & rx_control &&
4054 l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004055 del_timer(&l2cap_pi(sk)->monitor_timer);
4056 if (l2cap_pi(sk)->unacked_frames > 0)
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03004057 __mod_retrans_timer();
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004058 l2cap_pi(sk)->conn_state &= ~L2CAP_CONN_WAIT_F;
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03004059 }
4060
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004061 switch (rx_control & L2CAP_CTRL_SUPERVISE) {
4062 case L2CAP_SUPER_RCV_READY:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004063 l2cap_data_channel_rrframe(sk, rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004064 break;
4065
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004066 case L2CAP_SUPER_REJECT:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004067 l2cap_data_channel_rejframe(sk, rx_control);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03004068 break;
4069
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004070 case L2CAP_SUPER_SELECT_REJECT:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004071 l2cap_data_channel_srejframe(sk, rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004072 break;
4073
4074 case L2CAP_SUPER_RCV_NOT_READY:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004075 l2cap_data_channel_rnrframe(sk, rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004076 break;
4077 }
4078
Gustavo F. Padovanfaaebd12010-05-01 16:15:35 -03004079 kfree_skb(skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004080 return 0;
4081}
4082
Linus Torvalds1da177e2005-04-16 15:20:36 -07004083static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk_buff *skb)
4084{
4085 struct sock *sk;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004086 struct l2cap_pinfo *pi;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03004087 u16 control, len;
João Paulo Rechi Vita01760bd2010-05-01 16:15:43 -03004088 u8 tx_seq, req_seq, next_tx_seq_offset, req_seq_offset;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004089
4090 sk = l2cap_get_chan_by_scid(&conn->chan_list, cid);
4091 if (!sk) {
4092 BT_DBG("unknown cid 0x%4.4x", cid);
4093 goto drop;
4094 }
4095
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004096 pi = l2cap_pi(sk);
4097
Linus Torvalds1da177e2005-04-16 15:20:36 -07004098 BT_DBG("sk %p, len %d", sk, skb->len);
4099
4100 if (sk->sk_state != BT_CONNECTED)
4101 goto drop;
4102
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004103 switch (pi->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004104 case L2CAP_MODE_BASIC:
4105 /* If socket recv buffers overflows we drop data here
4106 * which is *bad* because L2CAP has to be reliable.
4107 * But we don't have any other choice. L2CAP doesn't
4108 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07004109
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004110 if (pi->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004111 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004112
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004113 if (!sock_queue_rcv_skb(sk, skb))
4114 goto done;
4115 break;
4116
4117 case L2CAP_MODE_ERTM:
4118 control = get_unaligned_le16(skb->data);
4119 skb_pull(skb, 2);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03004120 len = skb->len;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004121
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03004122 if (__is_sar_start(control))
4123 len -= 2;
4124
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004125 if (pi->fcs == L2CAP_FCS_CRC16)
4126 len -= 2;
4127
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03004128 /*
4129 * We can just drop the corrupted I-frame here.
4130 * Receiver will miss it and start proper recovery
4131 * procedures and ask retransmission.
4132 */
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004133 if (len > pi->mps) {
4134 l2cap_send_disconn_req(pi->conn, sk);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004135 goto drop;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004136 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004137
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004138 if (l2cap_check_fcs(pi, skb))
4139 goto drop;
4140
João Paulo Rechi Vita01760bd2010-05-01 16:15:43 -03004141 req_seq = __get_reqseq(control);
4142 req_seq_offset = (req_seq - pi->expected_ack_seq) % 64;
4143 if (req_seq_offset < 0)
4144 req_seq_offset += 64;
4145
4146 next_tx_seq_offset =
4147 (pi->next_tx_seq - pi->expected_ack_seq) % 64;
4148 if (next_tx_seq_offset < 0)
4149 next_tx_seq_offset += 64;
4150
4151 /* check for invalid req-seq */
4152 if (req_seq_offset > next_tx_seq_offset) {
4153 l2cap_send_disconn_req(pi->conn, sk);
4154 goto drop;
4155 }
4156
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004157 if (__is_iframe(control)) {
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004158 if (len < 4) {
4159 l2cap_send_disconn_req(pi->conn, sk);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004160 goto drop;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004161 }
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004162
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02004163 l2cap_data_channel_iframe(sk, control, skb);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004164 } else {
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004165 if (len != 0) {
4166 l2cap_send_disconn_req(pi->conn, sk);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004167 goto drop;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004168 }
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004169
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02004170 l2cap_data_channel_sframe(sk, control, skb);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004171 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004172
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02004173 goto done;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004174
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004175 case L2CAP_MODE_STREAMING:
4176 control = get_unaligned_le16(skb->data);
4177 skb_pull(skb, 2);
4178 len = skb->len;
4179
4180 if (__is_sar_start(control))
4181 len -= 2;
4182
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004183 if (pi->fcs == L2CAP_FCS_CRC16)
4184 len -= 2;
4185
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03004186 if (len > pi->mps || len < 4 || __is_sframe(control))
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004187 goto drop;
4188
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004189 if (l2cap_check_fcs(pi, skb))
4190 goto drop;
4191
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004192 tx_seq = __get_txseq(control);
4193
4194 if (pi->expected_tx_seq == tx_seq)
4195 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
4196 else
Gustavo F. Padovan7dffe422010-05-01 16:15:36 -03004197 pi->expected_tx_seq = (tx_seq + 1) % 64;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004198
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004199 l2cap_streaming_reassembly_sdu(sk, skb, control);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004200
4201 goto done;
4202
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004203 default:
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03004204 BT_DBG("sk %p: bad mode 0x%2.2x", sk, pi->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004205 break;
4206 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004207
4208drop:
4209 kfree_skb(skb);
4210
4211done:
Marcel Holtmann01394182006-07-03 10:02:46 +02004212 if (sk)
4213 bh_unlock_sock(sk);
4214
Linus Torvalds1da177e2005-04-16 15:20:36 -07004215 return 0;
4216}
4217
Al Viro8e036fc2007-07-29 00:16:36 -07004218static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004219{
4220 struct sock *sk;
4221
4222 sk = l2cap_get_sock_by_psm(0, psm, conn->src);
4223 if (!sk)
4224 goto drop;
4225
4226 BT_DBG("sk %p, len %d", sk, skb->len);
4227
4228 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_CONNECTED)
4229 goto drop;
4230
4231 if (l2cap_pi(sk)->imtu < skb->len)
4232 goto drop;
4233
4234 if (!sock_queue_rcv_skb(sk, skb))
4235 goto done;
4236
4237drop:
4238 kfree_skb(skb);
4239
4240done:
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03004241 if (sk)
4242 bh_unlock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004243 return 0;
4244}
4245
4246static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
4247{
4248 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07004249 u16 cid, len;
4250 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004251
4252 skb_pull(skb, L2CAP_HDR_SIZE);
4253 cid = __le16_to_cpu(lh->cid);
4254 len = __le16_to_cpu(lh->len);
4255
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004256 if (len != skb->len) {
4257 kfree_skb(skb);
4258 return;
4259 }
4260
Linus Torvalds1da177e2005-04-16 15:20:36 -07004261 BT_DBG("len %d, cid 0x%4.4x", len, cid);
4262
4263 switch (cid) {
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03004264 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07004265 l2cap_sig_channel(conn, skb);
4266 break;
4267
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03004268 case L2CAP_CID_CONN_LESS:
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03004269 psm = get_unaligned_le16(skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004270 skb_pull(skb, 2);
4271 l2cap_conless_channel(conn, psm, skb);
4272 break;
4273
4274 default:
4275 l2cap_data_channel(conn, cid, skb);
4276 break;
4277 }
4278}
4279
4280/* ---- L2CAP interface with lower layer (HCI) ---- */
4281
4282static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
4283{
4284 int exact = 0, lm1 = 0, lm2 = 0;
4285 register struct sock *sk;
4286 struct hlist_node *node;
4287
4288 if (type != ACL_LINK)
4289 return 0;
4290
4291 BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
4292
4293 /* Find listening sockets and check their link_mode */
4294 read_lock(&l2cap_sk_list.lock);
4295 sk_for_each(sk, node, &l2cap_sk_list.head) {
4296 if (sk->sk_state != BT_LISTEN)
4297 continue;
4298
4299 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01004300 lm1 |= HCI_LM_ACCEPT;
4301 if (l2cap_pi(sk)->role_switch)
4302 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004303 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01004304 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
4305 lm2 |= HCI_LM_ACCEPT;
4306 if (l2cap_pi(sk)->role_switch)
4307 lm2 |= HCI_LM_MASTER;
4308 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004309 }
4310 read_unlock(&l2cap_sk_list.lock);
4311
4312 return exact ? lm1 : lm2;
4313}
4314
4315static int l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
4316{
Marcel Holtmann01394182006-07-03 10:02:46 +02004317 struct l2cap_conn *conn;
4318
Linus Torvalds1da177e2005-04-16 15:20:36 -07004319 BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
4320
4321 if (hcon->type != ACL_LINK)
4322 return 0;
4323
4324 if (!status) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004325 conn = l2cap_conn_add(hcon, status);
4326 if (conn)
4327 l2cap_conn_ready(conn);
Marcel Holtmann01394182006-07-03 10:02:46 +02004328 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -07004329 l2cap_conn_del(hcon, bt_err(status));
4330
4331 return 0;
4332}
4333
Marcel Holtmann2950f212009-02-12 14:02:50 +01004334static int l2cap_disconn_ind(struct hci_conn *hcon)
4335{
4336 struct l2cap_conn *conn = hcon->l2cap_data;
4337
4338 BT_DBG("hcon %p", hcon);
4339
4340 if (hcon->type != ACL_LINK || !conn)
4341 return 0x13;
4342
4343 return conn->disc_reason;
4344}
4345
4346static int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004347{
4348 BT_DBG("hcon %p reason %d", hcon, reason);
4349
4350 if (hcon->type != ACL_LINK)
4351 return 0;
4352
4353 l2cap_conn_del(hcon, bt_err(reason));
Marcel Holtmann01394182006-07-03 10:02:46 +02004354
Linus Torvalds1da177e2005-04-16 15:20:36 -07004355 return 0;
4356}
4357
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004358static inline void l2cap_check_encryption(struct sock *sk, u8 encrypt)
4359{
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03004360 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM)
Marcel Holtmann255c7602009-02-04 21:07:19 +01004361 return;
4362
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004363 if (encrypt == 0x00) {
4364 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM) {
4365 l2cap_sock_clear_timer(sk);
4366 l2cap_sock_set_timer(sk, HZ * 5);
4367 } else if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
4368 __l2cap_sock_close(sk, ECONNREFUSED);
4369 } else {
4370 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM)
4371 l2cap_sock_clear_timer(sk);
4372 }
4373}
4374
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004375static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004376{
4377 struct l2cap_chan_list *l;
Marcel Holtmann40be4922008-07-14 20:13:50 +02004378 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004379 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004380
Marcel Holtmann01394182006-07-03 10:02:46 +02004381 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004382 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02004383
Linus Torvalds1da177e2005-04-16 15:20:36 -07004384 l = &conn->chan_list;
4385
4386 BT_DBG("conn %p", conn);
4387
4388 read_lock(&l->lock);
4389
4390 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
4391 bh_lock_sock(sk);
4392
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01004393 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND) {
4394 bh_unlock_sock(sk);
4395 continue;
4396 }
4397
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004398 if (!status && (sk->sk_state == BT_CONNECTED ||
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004399 sk->sk_state == BT_CONFIG)) {
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004400 l2cap_check_encryption(sk, encrypt);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02004401 bh_unlock_sock(sk);
4402 continue;
4403 }
4404
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004405 if (sk->sk_state == BT_CONNECT) {
4406 if (!status) {
4407 struct l2cap_conn_req req;
4408 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
4409 req.psm = l2cap_pi(sk)->psm;
4410
4411 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03004412 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004413
4414 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
4415 L2CAP_CONN_REQ, sizeof(req), &req);
4416 } else {
4417 l2cap_sock_clear_timer(sk);
4418 l2cap_sock_set_timer(sk, HZ / 10);
4419 }
4420 } else if (sk->sk_state == BT_CONNECT2) {
4421 struct l2cap_conn_rsp rsp;
4422 __u16 result;
4423
4424 if (!status) {
4425 sk->sk_state = BT_CONFIG;
4426 result = L2CAP_CR_SUCCESS;
4427 } else {
4428 sk->sk_state = BT_DISCONN;
4429 l2cap_sock_set_timer(sk, HZ / 10);
4430 result = L2CAP_CR_SEC_BLOCK;
4431 }
4432
4433 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
4434 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
4435 rsp.result = cpu_to_le16(result);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02004436 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004437 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
4438 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004439 }
4440
Linus Torvalds1da177e2005-04-16 15:20:36 -07004441 bh_unlock_sock(sk);
4442 }
4443
4444 read_unlock(&l->lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004445
Linus Torvalds1da177e2005-04-16 15:20:36 -07004446 return 0;
4447}
4448
4449static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
4450{
4451 struct l2cap_conn *conn = hcon->l2cap_data;
4452
4453 if (!conn && !(conn = l2cap_conn_add(hcon, 0)))
4454 goto drop;
4455
4456 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
4457
4458 if (flags & ACL_START) {
4459 struct l2cap_hdr *hdr;
4460 int len;
4461
4462 if (conn->rx_len) {
4463 BT_ERR("Unexpected start frame (len %d)", skb->len);
4464 kfree_skb(conn->rx_skb);
4465 conn->rx_skb = NULL;
4466 conn->rx_len = 0;
4467 l2cap_conn_unreliable(conn, ECOMM);
4468 }
4469
4470 if (skb->len < 2) {
4471 BT_ERR("Frame is too short (len %d)", skb->len);
4472 l2cap_conn_unreliable(conn, ECOMM);
4473 goto drop;
4474 }
4475
4476 hdr = (struct l2cap_hdr *) skb->data;
4477 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
4478
4479 if (len == skb->len) {
4480 /* Complete frame received */
4481 l2cap_recv_frame(conn, skb);
4482 return 0;
4483 }
4484
4485 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
4486
4487 if (skb->len > len) {
4488 BT_ERR("Frame is too long (len %d, expected len %d)",
4489 skb->len, len);
4490 l2cap_conn_unreliable(conn, ECOMM);
4491 goto drop;
4492 }
4493
4494 /* Allocate skb for the complete frame (with header) */
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03004495 conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC);
4496 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004497 goto drop;
4498
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03004499 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004500 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004501 conn->rx_len = len - skb->len;
4502 } else {
4503 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
4504
4505 if (!conn->rx_len) {
4506 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
4507 l2cap_conn_unreliable(conn, ECOMM);
4508 goto drop;
4509 }
4510
4511 if (skb->len > conn->rx_len) {
4512 BT_ERR("Fragment is too long (len %d, expected %d)",
4513 skb->len, conn->rx_len);
4514 kfree_skb(conn->rx_skb);
4515 conn->rx_skb = NULL;
4516 conn->rx_len = 0;
4517 l2cap_conn_unreliable(conn, ECOMM);
4518 goto drop;
4519 }
4520
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03004521 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004522 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004523 conn->rx_len -= skb->len;
4524
4525 if (!conn->rx_len) {
4526 /* Complete frame received */
4527 l2cap_recv_frame(conn, conn->rx_skb);
4528 conn->rx_skb = NULL;
4529 }
4530 }
4531
4532drop:
4533 kfree_skb(skb);
4534 return 0;
4535}
4536
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004537static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004538{
4539 struct sock *sk;
4540 struct hlist_node *node;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004541
4542 read_lock_bh(&l2cap_sk_list.lock);
4543
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004544 sk_for_each(sk, node, &l2cap_sk_list.head) {
4545 struct l2cap_pinfo *pi = l2cap_pi(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004546
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004547 seq_printf(f, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d\n",
4548 batostr(&bt_sk(sk)->src),
4549 batostr(&bt_sk(sk)->dst),
4550 sk->sk_state, __le16_to_cpu(pi->psm),
4551 pi->scid, pi->dcid,
4552 pi->imtu, pi->omtu, pi->sec_level);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004553 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004554
Linus Torvalds1da177e2005-04-16 15:20:36 -07004555 read_unlock_bh(&l2cap_sk_list.lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004556
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004557 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004558}
4559
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004560static int l2cap_debugfs_open(struct inode *inode, struct file *file)
4561{
4562 return single_open(file, l2cap_debugfs_show, inode->i_private);
4563}
4564
4565static const struct file_operations l2cap_debugfs_fops = {
4566 .open = l2cap_debugfs_open,
4567 .read = seq_read,
4568 .llseek = seq_lseek,
4569 .release = single_release,
4570};
4571
4572static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004573
Eric Dumazet90ddc4f2005-12-22 12:49:22 -08004574static const struct proto_ops l2cap_sock_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004575 .family = PF_BLUETOOTH,
4576 .owner = THIS_MODULE,
4577 .release = l2cap_sock_release,
4578 .bind = l2cap_sock_bind,
4579 .connect = l2cap_sock_connect,
4580 .listen = l2cap_sock_listen,
4581 .accept = l2cap_sock_accept,
4582 .getname = l2cap_sock_getname,
4583 .sendmsg = l2cap_sock_sendmsg,
Marcel Holtmannf66dc812009-01-15 21:57:00 +01004584 .recvmsg = l2cap_sock_recvmsg,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004585 .poll = bt_sock_poll,
Marcel Holtmann3241ad82008-07-14 20:13:50 +02004586 .ioctl = bt_sock_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004587 .mmap = sock_no_mmap,
4588 .socketpair = sock_no_socketpair,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004589 .shutdown = l2cap_sock_shutdown,
4590 .setsockopt = l2cap_sock_setsockopt,
4591 .getsockopt = l2cap_sock_getsockopt
4592};
4593
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +00004594static const struct net_proto_family l2cap_sock_family_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004595 .family = PF_BLUETOOTH,
4596 .owner = THIS_MODULE,
4597 .create = l2cap_sock_create,
4598};
4599
4600static struct hci_proto l2cap_hci_proto = {
4601 .name = "L2CAP",
4602 .id = HCI_PROTO_L2CAP,
4603 .connect_ind = l2cap_connect_ind,
4604 .connect_cfm = l2cap_connect_cfm,
4605 .disconn_ind = l2cap_disconn_ind,
Marcel Holtmann2950f212009-02-12 14:02:50 +01004606 .disconn_cfm = l2cap_disconn_cfm,
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004607 .security_cfm = l2cap_security_cfm,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004608 .recv_acldata = l2cap_recv_acldata
4609};
4610
4611static int __init l2cap_init(void)
4612{
4613 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004614
Linus Torvalds1da177e2005-04-16 15:20:36 -07004615 err = proto_register(&l2cap_proto, 0);
4616 if (err < 0)
4617 return err;
4618
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004619 _busy_wq = create_singlethread_workqueue("l2cap");
4620 if (!_busy_wq)
4621 goto error;
4622
Linus Torvalds1da177e2005-04-16 15:20:36 -07004623 err = bt_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops);
4624 if (err < 0) {
4625 BT_ERR("L2CAP socket registration failed");
4626 goto error;
4627 }
4628
4629 err = hci_register_proto(&l2cap_hci_proto);
4630 if (err < 0) {
4631 BT_ERR("L2CAP protocol registration failed");
4632 bt_sock_unregister(BTPROTO_L2CAP);
4633 goto error;
4634 }
4635
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004636 if (bt_debugfs) {
4637 l2cap_debugfs = debugfs_create_file("l2cap", 0444,
4638 bt_debugfs, NULL, &l2cap_debugfs_fops);
4639 if (!l2cap_debugfs)
4640 BT_ERR("Failed to create L2CAP debug file");
4641 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004642
4643 BT_INFO("L2CAP ver %s", VERSION);
4644 BT_INFO("L2CAP socket layer initialized");
4645
4646 return 0;
4647
4648error:
4649 proto_unregister(&l2cap_proto);
4650 return err;
4651}
4652
4653static void __exit l2cap_exit(void)
4654{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004655 debugfs_remove(l2cap_debugfs);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004656
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004657 flush_workqueue(_busy_wq);
4658 destroy_workqueue(_busy_wq);
4659
Linus Torvalds1da177e2005-04-16 15:20:36 -07004660 if (bt_sock_unregister(BTPROTO_L2CAP) < 0)
4661 BT_ERR("L2CAP socket unregistration failed");
4662
4663 if (hci_unregister_proto(&l2cap_hci_proto) < 0)
4664 BT_ERR("L2CAP protocol unregistration failed");
4665
4666 proto_unregister(&l2cap_proto);
4667}
4668
4669void l2cap_load(void)
4670{
4671 /* Dummy function to trigger automatic L2CAP module loading by
4672 * other modules that use L2CAP sockets but don't use any other
4673 * symbols from it. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07004674}
4675EXPORT_SYMBOL(l2cap_load);
4676
4677module_init(l2cap_init);
4678module_exit(l2cap_exit);
4679
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07004680module_param(enable_ertm, bool, 0644);
4681MODULE_PARM_DESC(enable_ertm, "Enable enhanced retransmission mode");
4682
Marcel Holtmann63fbd242008-08-18 13:23:53 +02004683MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004684MODULE_DESCRIPTION("Bluetooth L2CAP ver " VERSION);
4685MODULE_VERSION(VERSION);
4686MODULE_LICENSE("GPL");
4687MODULE_ALIAS("bt-proto-0");