blob: b89762134e4ef97f947ba7cf381a22af2b6d646d [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
58static int enable_ertm = 0;
Marcel Holtmannf0709e02007-10-20 13:38:51 +020059
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -070060static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN;
Marcel Holtmanne1027a72009-02-09 09:18:02 +010061static u8 l2cap_fixed_chan[8] = { 0x02, };
Linus Torvalds1da177e2005-04-16 15:20:36 -070062
Eric Dumazet90ddc4f2005-12-22 12:49:22 -080063static const struct proto_ops l2cap_sock_ops;
Linus Torvalds1da177e2005-04-16 15:20:36 -070064
Gustavo F. Padovan1890d362010-05-01 16:15:44 -030065static struct workqueue_struct *_busy_wq;
66
Linus Torvalds1da177e2005-04-16 15:20:36 -070067static struct bt_sock_list l2cap_sk_list = {
Robert P. J. Dayd5fb2962008-03-28 16:17:38 -070068 .lock = __RW_LOCK_UNLOCKED(l2cap_sk_list.lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -070069};
70
Gustavo F. Padovan1890d362010-05-01 16:15:44 -030071static void l2cap_busy_work(struct work_struct *work);
72
Linus Torvalds1da177e2005-04-16 15:20:36 -070073static void __l2cap_sock_close(struct sock *sk, int reason);
74static void l2cap_sock_close(struct sock *sk);
75static void l2cap_sock_kill(struct sock *sk);
76
77static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
78 u8 code, u8 ident, u16 dlen, void *data);
79
80/* ---- L2CAP timers ---- */
81static void l2cap_sock_timeout(unsigned long arg)
82{
83 struct sock *sk = (struct sock *) arg;
Marcel Holtmannb1235d72008-07-14 20:13:54 +020084 int reason;
Linus Torvalds1da177e2005-04-16 15:20:36 -070085
86 BT_DBG("sock %p state %d", sk, sk->sk_state);
87
88 bh_lock_sock(sk);
Marcel Holtmannb1235d72008-07-14 20:13:54 +020089
Marcel Holtmannf62e4322009-01-15 21:58:44 +010090 if (sk->sk_state == BT_CONNECTED || sk->sk_state == BT_CONFIG)
91 reason = ECONNREFUSED;
92 else if (sk->sk_state == BT_CONNECT &&
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +010093 l2cap_pi(sk)->sec_level != BT_SECURITY_SDP)
Marcel Holtmannb1235d72008-07-14 20:13:54 +020094 reason = ECONNREFUSED;
95 else
96 reason = ETIMEDOUT;
97
98 __l2cap_sock_close(sk, reason);
99
Linus Torvalds1da177e2005-04-16 15:20:36 -0700100 bh_unlock_sock(sk);
101
102 l2cap_sock_kill(sk);
103 sock_put(sk);
104}
105
106static void l2cap_sock_set_timer(struct sock *sk, long timeout)
107{
108 BT_DBG("sk %p state %d timeout %ld", sk, sk->sk_state, timeout);
109 sk_reset_timer(sk, &sk->sk_timer, jiffies + timeout);
110}
111
112static void l2cap_sock_clear_timer(struct sock *sk)
113{
114 BT_DBG("sock %p state %d", sk, sk->sk_state);
115 sk_stop_timer(sk, &sk->sk_timer);
116}
117
Marcel Holtmann01394182006-07-03 10:02:46 +0200118/* ---- L2CAP channels ---- */
119static struct sock *__l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, u16 cid)
120{
121 struct sock *s;
122 for (s = l->head; s; s = l2cap_pi(s)->next_c) {
123 if (l2cap_pi(s)->dcid == cid)
124 break;
125 }
126 return s;
127}
128
129static struct sock *__l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid)
130{
131 struct sock *s;
132 for (s = l->head; s; s = l2cap_pi(s)->next_c) {
133 if (l2cap_pi(s)->scid == cid)
134 break;
135 }
136 return s;
137}
138
139/* Find channel with given SCID.
140 * Returns locked socket */
141static inline struct sock *l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid)
142{
143 struct sock *s;
144 read_lock(&l->lock);
145 s = __l2cap_get_chan_by_scid(l, cid);
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -0300146 if (s)
147 bh_lock_sock(s);
Marcel Holtmann01394182006-07-03 10:02:46 +0200148 read_unlock(&l->lock);
149 return s;
150}
151
152static struct sock *__l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 ident)
153{
154 struct sock *s;
155 for (s = l->head; s; s = l2cap_pi(s)->next_c) {
156 if (l2cap_pi(s)->ident == ident)
157 break;
158 }
159 return s;
160}
161
162static inline struct sock *l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 ident)
163{
164 struct sock *s;
165 read_lock(&l->lock);
166 s = __l2cap_get_chan_by_ident(l, ident);
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -0300167 if (s)
168 bh_lock_sock(s);
Marcel Holtmann01394182006-07-03 10:02:46 +0200169 read_unlock(&l->lock);
170 return s;
171}
172
173static u16 l2cap_alloc_cid(struct l2cap_chan_list *l)
174{
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300175 u16 cid = L2CAP_CID_DYN_START;
Marcel Holtmann01394182006-07-03 10:02:46 +0200176
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300177 for (; cid < L2CAP_CID_DYN_END; cid++) {
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -0300178 if (!__l2cap_get_chan_by_scid(l, cid))
Marcel Holtmann01394182006-07-03 10:02:46 +0200179 return cid;
180 }
181
182 return 0;
183}
184
185static inline void __l2cap_chan_link(struct l2cap_chan_list *l, struct sock *sk)
186{
187 sock_hold(sk);
188
189 if (l->head)
190 l2cap_pi(l->head)->prev_c = sk;
191
192 l2cap_pi(sk)->next_c = l->head;
193 l2cap_pi(sk)->prev_c = NULL;
194 l->head = sk;
195}
196
197static inline void l2cap_chan_unlink(struct l2cap_chan_list *l, struct sock *sk)
198{
199 struct sock *next = l2cap_pi(sk)->next_c, *prev = l2cap_pi(sk)->prev_c;
200
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200201 write_lock_bh(&l->lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200202 if (sk == l->head)
203 l->head = next;
204
205 if (next)
206 l2cap_pi(next)->prev_c = prev;
207 if (prev)
208 l2cap_pi(prev)->next_c = next;
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200209 write_unlock_bh(&l->lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200210
211 __sock_put(sk);
212}
213
214static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
215{
216 struct l2cap_chan_list *l = &conn->chan_list;
217
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -0300218 BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
219 l2cap_pi(sk)->psm, l2cap_pi(sk)->dcid);
Marcel Holtmann01394182006-07-03 10:02:46 +0200220
Marcel Holtmann2950f212009-02-12 14:02:50 +0100221 conn->disc_reason = 0x13;
222
Marcel Holtmann01394182006-07-03 10:02:46 +0200223 l2cap_pi(sk)->conn = conn;
224
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300225 if (sk->sk_type == SOCK_SEQPACKET || sk->sk_type == SOCK_STREAM) {
Marcel Holtmann01394182006-07-03 10:02:46 +0200226 /* Alloc CID for connection-oriented socket */
227 l2cap_pi(sk)->scid = l2cap_alloc_cid(l);
228 } else if (sk->sk_type == SOCK_DGRAM) {
229 /* Connectionless socket */
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300230 l2cap_pi(sk)->scid = L2CAP_CID_CONN_LESS;
231 l2cap_pi(sk)->dcid = L2CAP_CID_CONN_LESS;
Marcel Holtmann01394182006-07-03 10:02:46 +0200232 l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
233 } else {
234 /* Raw socket can send/recv signalling messages only */
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300235 l2cap_pi(sk)->scid = L2CAP_CID_SIGNALING;
236 l2cap_pi(sk)->dcid = L2CAP_CID_SIGNALING;
Marcel Holtmann01394182006-07-03 10:02:46 +0200237 l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
238 }
239
240 __l2cap_chan_link(l, sk);
241
242 if (parent)
243 bt_accept_enqueue(parent, sk);
244}
245
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900246/* Delete channel.
Marcel Holtmann01394182006-07-03 10:02:46 +0200247 * Must be called on the locked socket. */
248static void l2cap_chan_del(struct sock *sk, int err)
249{
250 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
251 struct sock *parent = bt_sk(sk)->parent;
252
253 l2cap_sock_clear_timer(sk);
254
255 BT_DBG("sk %p, conn %p, err %d", sk, conn, err);
256
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900257 if (conn) {
Marcel Holtmann01394182006-07-03 10:02:46 +0200258 /* Unlink from channel list */
259 l2cap_chan_unlink(&conn->chan_list, sk);
260 l2cap_pi(sk)->conn = NULL;
261 hci_conn_put(conn->hcon);
262 }
263
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200264 sk->sk_state = BT_CLOSED;
Marcel Holtmann01394182006-07-03 10:02:46 +0200265 sock_set_flag(sk, SOCK_ZAPPED);
266
267 if (err)
268 sk->sk_err = err;
269
270 if (parent) {
271 bt_accept_unlink(sk);
272 parent->sk_data_ready(parent, 0);
273 } else
274 sk->sk_state_change(sk);
275}
276
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200277/* Service level security */
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100278static inline int l2cap_check_security(struct sock *sk)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200279{
280 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100281 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200282
Marcel Holtmann00ae4af2009-02-12 16:19:45 +0100283 if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) {
284 if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
285 auth_type = HCI_AT_NO_BONDING_MITM;
286 else
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -0300287 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann00ae4af2009-02-12 16:19:45 +0100288
289 if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW)
290 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
291 } else {
292 switch (l2cap_pi(sk)->sec_level) {
293 case BT_SECURITY_HIGH:
294 auth_type = HCI_AT_GENERAL_BONDING_MITM;
295 break;
296 case BT_SECURITY_MEDIUM:
297 auth_type = HCI_AT_GENERAL_BONDING;
298 break;
299 default:
300 auth_type = HCI_AT_NO_BONDING;
301 break;
302 }
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100303 }
304
305 return hci_conn_security(conn->hcon, l2cap_pi(sk)->sec_level,
306 auth_type);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200307}
308
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200309static inline u8 l2cap_get_ident(struct l2cap_conn *conn)
310{
311 u8 id;
312
313 /* Get next available identificator.
314 * 1 - 128 are used by kernel.
315 * 129 - 199 are reserved.
316 * 200 - 254 are used by utilities like l2ping, etc.
317 */
318
319 spin_lock_bh(&conn->lock);
320
321 if (++conn->tx_ident > 128)
322 conn->tx_ident = 1;
323
324 id = conn->tx_ident;
325
326 spin_unlock_bh(&conn->lock);
327
328 return id;
329}
330
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300331static inline void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200332{
333 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
334
335 BT_DBG("code 0x%2.2x", code);
336
337 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300338 return;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200339
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300340 hci_send_acl(conn->hcon, skb, 0);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200341}
342
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300343static inline void l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300344{
345 struct sk_buff *skb;
346 struct l2cap_hdr *lh;
347 struct l2cap_conn *conn = pi->conn;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300348 int count, hlen = L2CAP_HDR_SIZE + 2;
349
350 if (pi->fcs == L2CAP_FCS_CRC16)
351 hlen += 2;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300352
353 BT_DBG("pi %p, control 0x%2.2x", pi, control);
354
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300355 count = min_t(unsigned int, conn->mtu, hlen);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300356 control |= L2CAP_CTRL_FRAME_TYPE;
357
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -0300358 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
359 control |= L2CAP_CTRL_FINAL;
360 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
361 }
362
Gustavo F. Padovanf0946cc2010-05-01 16:15:37 -0300363 if (pi->conn_state & L2CAP_CONN_SEND_PBIT) {
364 control |= L2CAP_CTRL_POLL;
365 pi->conn_state &= ~L2CAP_CONN_SEND_PBIT;
366 }
367
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300368 skb = bt_skb_alloc(count, GFP_ATOMIC);
369 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300370 return;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300371
372 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300373 lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300374 lh->cid = cpu_to_le16(pi->dcid);
375 put_unaligned_le16(control, skb_put(skb, 2));
376
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300377 if (pi->fcs == L2CAP_FCS_CRC16) {
378 u16 fcs = crc16(0, (u8 *)lh, count - 2);
379 put_unaligned_le16(fcs, skb_put(skb, 2));
380 }
381
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300382 hci_send_acl(pi->conn->hcon, skb, 0);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300383}
384
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300385static inline void l2cap_send_rr_or_rnr(struct l2cap_pinfo *pi, u16 control)
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300386{
Gustavo F. Padovan1890d362010-05-01 16:15:44 -0300387 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300388 control |= L2CAP_SUPER_RCV_NOT_READY;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -0300389 pi->conn_state |= L2CAP_CONN_RNR_SENT;
390 } else
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300391 control |= L2CAP_SUPER_RCV_READY;
392
Gustavo F. Padovan2ab25cd2009-10-03 02:34:40 -0300393 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
394
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300395 l2cap_send_sframe(pi, control);
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300396}
397
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300398static inline int __l2cap_no_conn_pending(struct sock *sk)
399{
400 return !(l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND);
401}
402
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200403static void l2cap_do_start(struct sock *sk)
404{
405 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
406
407 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +0100408 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
409 return;
410
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300411 if (l2cap_check_security(sk) && __l2cap_no_conn_pending(sk)) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200412 struct l2cap_conn_req req;
413 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
414 req.psm = l2cap_pi(sk)->psm;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200415
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200416 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300417 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200418
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200419 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200420 L2CAP_CONN_REQ, sizeof(req), &req);
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200421 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200422 } else {
423 struct l2cap_info_req req;
424 req.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
425
426 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
427 conn->info_ident = l2cap_get_ident(conn);
428
429 mod_timer(&conn->info_timer, jiffies +
430 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
431
432 l2cap_send_cmd(conn, conn->info_ident,
433 L2CAP_INFO_REQ, sizeof(req), &req);
434 }
435}
436
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300437static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct sock *sk)
438{
439 struct l2cap_disconn_req req;
440
441 req.dcid = cpu_to_le16(l2cap_pi(sk)->dcid);
442 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
443 l2cap_send_cmd(conn, l2cap_get_ident(conn),
444 L2CAP_DISCONN_REQ, sizeof(req), &req);
445}
446
Linus Torvalds1da177e2005-04-16 15:20:36 -0700447/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200448static void l2cap_conn_start(struct l2cap_conn *conn)
449{
450 struct l2cap_chan_list *l = &conn->chan_list;
451 struct sock *sk;
452
453 BT_DBG("conn %p", conn);
454
455 read_lock(&l->lock);
456
457 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
458 bh_lock_sock(sk);
459
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300460 if (sk->sk_type != SOCK_SEQPACKET &&
461 sk->sk_type != SOCK_STREAM) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200462 bh_unlock_sock(sk);
463 continue;
464 }
465
466 if (sk->sk_state == BT_CONNECT) {
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300467 if (l2cap_check_security(sk) &&
468 __l2cap_no_conn_pending(sk)) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200469 struct l2cap_conn_req req;
470 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
471 req.psm = l2cap_pi(sk)->psm;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200472
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200473 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300474 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200475
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200476 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200477 L2CAP_CONN_REQ, sizeof(req), &req);
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200478 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200479 } else if (sk->sk_state == BT_CONNECT2) {
480 struct l2cap_conn_rsp rsp;
481 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
482 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
483
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100484 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100485 if (bt_sk(sk)->defer_setup) {
486 struct sock *parent = bt_sk(sk)->parent;
487 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
488 rsp.status = cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
489 parent->sk_data_ready(parent, 0);
490
491 } else {
492 sk->sk_state = BT_CONFIG;
493 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
494 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
495 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200496 } else {
497 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
498 rsp.status = cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
499 }
500
501 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
502 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
503 }
504
505 bh_unlock_sock(sk);
506 }
507
508 read_unlock(&l->lock);
509}
510
511static void l2cap_conn_ready(struct l2cap_conn *conn)
512{
513 struct l2cap_chan_list *l = &conn->chan_list;
514 struct sock *sk;
515
516 BT_DBG("conn %p", conn);
517
518 read_lock(&l->lock);
519
520 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
521 bh_lock_sock(sk);
522
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300523 if (sk->sk_type != SOCK_SEQPACKET &&
524 sk->sk_type != SOCK_STREAM) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200525 l2cap_sock_clear_timer(sk);
526 sk->sk_state = BT_CONNECTED;
527 sk->sk_state_change(sk);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200528 } else if (sk->sk_state == BT_CONNECT)
529 l2cap_do_start(sk);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200530
531 bh_unlock_sock(sk);
532 }
533
534 read_unlock(&l->lock);
535}
536
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200537/* Notify sockets that we cannot guaranty reliability anymore */
538static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
539{
540 struct l2cap_chan_list *l = &conn->chan_list;
541 struct sock *sk;
542
543 BT_DBG("conn %p", conn);
544
545 read_lock(&l->lock);
546
547 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100548 if (l2cap_pi(sk)->force_reliable)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200549 sk->sk_err = err;
550 }
551
552 read_unlock(&l->lock);
553}
554
555static void l2cap_info_timeout(unsigned long arg)
556{
557 struct l2cap_conn *conn = (void *) arg;
558
Marcel Holtmann984947d2009-02-06 23:35:19 +0100559 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +0100560 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +0100561
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200562 l2cap_conn_start(conn);
563}
564
Linus Torvalds1da177e2005-04-16 15:20:36 -0700565static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
566{
Marcel Holtmann01394182006-07-03 10:02:46 +0200567 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700568
Marcel Holtmann01394182006-07-03 10:02:46 +0200569 if (conn || status)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700570 return conn;
571
Marcel Holtmann01394182006-07-03 10:02:46 +0200572 conn = kzalloc(sizeof(struct l2cap_conn), GFP_ATOMIC);
573 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700574 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700575
576 hcon->l2cap_data = conn;
577 conn->hcon = hcon;
578
Marcel Holtmann01394182006-07-03 10:02:46 +0200579 BT_DBG("hcon %p conn %p", hcon, conn);
580
Linus Torvalds1da177e2005-04-16 15:20:36 -0700581 conn->mtu = hcon->hdev->acl_mtu;
582 conn->src = &hcon->hdev->bdaddr;
583 conn->dst = &hcon->dst;
584
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200585 conn->feat_mask = 0;
586
Linus Torvalds1da177e2005-04-16 15:20:36 -0700587 spin_lock_init(&conn->lock);
588 rwlock_init(&conn->chan_list.lock);
589
Dave Young45054dc2009-10-18 20:28:30 +0000590 setup_timer(&conn->info_timer, l2cap_info_timeout,
591 (unsigned long) conn);
592
Marcel Holtmann2950f212009-02-12 14:02:50 +0100593 conn->disc_reason = 0x13;
594
Linus Torvalds1da177e2005-04-16 15:20:36 -0700595 return conn;
596}
597
Marcel Holtmann01394182006-07-03 10:02:46 +0200598static void l2cap_conn_del(struct hci_conn *hcon, int err)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700599{
Marcel Holtmann01394182006-07-03 10:02:46 +0200600 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700601 struct sock *sk;
602
Marcel Holtmann01394182006-07-03 10:02:46 +0200603 if (!conn)
604 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700605
606 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
607
Wei Yongjun7585b972009-02-25 18:29:52 +0800608 kfree_skb(conn->rx_skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700609
610 /* Kill channels */
611 while ((sk = conn->chan_list.head)) {
612 bh_lock_sock(sk);
613 l2cap_chan_del(sk, err);
614 bh_unlock_sock(sk);
615 l2cap_sock_kill(sk);
616 }
617
Dave Young8e8440f2008-03-03 12:18:55 -0800618 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
619 del_timer_sync(&conn->info_timer);
Thomas Gleixner3ab22732008-02-26 17:42:56 -0800620
Linus Torvalds1da177e2005-04-16 15:20:36 -0700621 hcon->l2cap_data = NULL;
622 kfree(conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700623}
624
625static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
626{
627 struct l2cap_chan_list *l = &conn->chan_list;
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200628 write_lock_bh(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700629 __l2cap_chan_add(conn, sk, parent);
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200630 write_unlock_bh(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700631}
632
Linus Torvalds1da177e2005-04-16 15:20:36 -0700633/* ---- Socket interface ---- */
Al Viro8e036fc2007-07-29 00:16:36 -0700634static struct sock *__l2cap_get_sock_by_addr(__le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700635{
636 struct sock *sk;
637 struct hlist_node *node;
638 sk_for_each(sk, node, &l2cap_sk_list.head)
639 if (l2cap_pi(sk)->sport == psm && !bacmp(&bt_sk(sk)->src, src))
640 goto found;
641 sk = NULL;
642found:
643 return sk;
644}
645
646/* Find socket with psm and source bdaddr.
647 * Returns closest match.
648 */
Al Viro8e036fc2007-07-29 00:16:36 -0700649static struct sock *__l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700650{
651 struct sock *sk = NULL, *sk1 = NULL;
652 struct hlist_node *node;
653
654 sk_for_each(sk, node, &l2cap_sk_list.head) {
655 if (state && sk->sk_state != state)
656 continue;
657
658 if (l2cap_pi(sk)->psm == psm) {
659 /* Exact match. */
660 if (!bacmp(&bt_sk(sk)->src, src))
661 break;
662
663 /* Closest match */
664 if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY))
665 sk1 = sk;
666 }
667 }
668 return node ? sk : sk1;
669}
670
671/* Find socket with given address (psm, src).
672 * Returns locked socket */
Al Viro8e036fc2007-07-29 00:16:36 -0700673static inline struct sock *l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700674{
675 struct sock *s;
676 read_lock(&l2cap_sk_list.lock);
677 s = __l2cap_get_sock_by_psm(state, psm, src);
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -0300678 if (s)
679 bh_lock_sock(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700680 read_unlock(&l2cap_sk_list.lock);
681 return s;
682}
683
684static void l2cap_sock_destruct(struct sock *sk)
685{
686 BT_DBG("sk %p", sk);
687
688 skb_queue_purge(&sk->sk_receive_queue);
689 skb_queue_purge(&sk->sk_write_queue);
690}
691
692static void l2cap_sock_cleanup_listen(struct sock *parent)
693{
694 struct sock *sk;
695
696 BT_DBG("parent %p", parent);
697
698 /* Close not yet accepted channels */
699 while ((sk = bt_accept_dequeue(parent, NULL)))
700 l2cap_sock_close(sk);
701
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200702 parent->sk_state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700703 sock_set_flag(parent, SOCK_ZAPPED);
704}
705
706/* Kill socket (only if zapped and orphan)
707 * Must be called on unlocked socket.
708 */
709static void l2cap_sock_kill(struct sock *sk)
710{
711 if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket)
712 return;
713
714 BT_DBG("sk %p state %d", sk, sk->sk_state);
715
716 /* Kill poor orphan */
717 bt_sock_unlink(&l2cap_sk_list, sk);
718 sock_set_flag(sk, SOCK_DEAD);
719 sock_put(sk);
720}
721
722static void __l2cap_sock_close(struct sock *sk, int reason)
723{
724 BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket);
725
726 switch (sk->sk_state) {
727 case BT_LISTEN:
728 l2cap_sock_cleanup_listen(sk);
729 break;
730
731 case BT_CONNECTED:
732 case BT_CONFIG:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300733 if (sk->sk_type == SOCK_SEQPACKET ||
734 sk->sk_type == SOCK_STREAM) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700735 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700736
737 sk->sk_state = BT_DISCONN;
738 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300739 l2cap_send_disconn_req(conn, sk);
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200740 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -0700741 l2cap_chan_del(sk, reason);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700742 break;
743
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100744 case BT_CONNECT2:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300745 if (sk->sk_type == SOCK_SEQPACKET ||
746 sk->sk_type == SOCK_STREAM) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100747 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
748 struct l2cap_conn_rsp rsp;
749 __u16 result;
750
751 if (bt_sk(sk)->defer_setup)
752 result = L2CAP_CR_SEC_BLOCK;
753 else
754 result = L2CAP_CR_BAD_PSM;
755
756 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
757 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
758 rsp.result = cpu_to_le16(result);
759 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
760 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
761 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
762 } else
763 l2cap_chan_del(sk, reason);
764 break;
765
Linus Torvalds1da177e2005-04-16 15:20:36 -0700766 case BT_CONNECT:
767 case BT_DISCONN:
768 l2cap_chan_del(sk, reason);
769 break;
770
771 default:
772 sock_set_flag(sk, SOCK_ZAPPED);
773 break;
774 }
775}
776
777/* Must be called on unlocked socket. */
778static void l2cap_sock_close(struct sock *sk)
779{
780 l2cap_sock_clear_timer(sk);
781 lock_sock(sk);
782 __l2cap_sock_close(sk, ECONNRESET);
783 release_sock(sk);
784 l2cap_sock_kill(sk);
785}
786
787static void l2cap_sock_init(struct sock *sk, struct sock *parent)
788{
789 struct l2cap_pinfo *pi = l2cap_pi(sk);
790
791 BT_DBG("sk %p", sk);
792
793 if (parent) {
794 sk->sk_type = parent->sk_type;
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100795 bt_sk(sk)->defer_setup = bt_sk(parent)->defer_setup;
796
Linus Torvalds1da177e2005-04-16 15:20:36 -0700797 pi->imtu = l2cap_pi(parent)->imtu;
798 pi->omtu = l2cap_pi(parent)->omtu;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -0700799 pi->mode = l2cap_pi(parent)->mode;
800 pi->fcs = l2cap_pi(parent)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -0300801 pi->max_tx = l2cap_pi(parent)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -0300802 pi->tx_win = l2cap_pi(parent)->tx_win;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100803 pi->sec_level = l2cap_pi(parent)->sec_level;
804 pi->role_switch = l2cap_pi(parent)->role_switch;
805 pi->force_reliable = l2cap_pi(parent)->force_reliable;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700806 } else {
807 pi->imtu = L2CAP_DEFAULT_MTU;
808 pi->omtu = 0;
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300809 if (enable_ertm && sk->sk_type == SOCK_STREAM)
810 pi->mode = L2CAP_MODE_ERTM;
811 else
812 pi->mode = L2CAP_MODE_BASIC;
Gustavo F. Padovanfd059b92010-05-10 14:22:56 -0300813 pi->max_tx = L2CAP_DEFAULT_MAX_TX;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -0700814 pi->fcs = L2CAP_FCS_CRC16;
Gustavo F. Padovanfd059b92010-05-10 14:22:56 -0300815 pi->tx_win = L2CAP_DEFAULT_TX_WINDOW;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100816 pi->sec_level = BT_SECURITY_LOW;
817 pi->role_switch = 0;
818 pi->force_reliable = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700819 }
820
821 /* Default config options */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +0200822 pi->conf_len = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700823 pi->flush_to = L2CAP_DEFAULT_FLUSH_TO;
Dave Young45054dc2009-10-18 20:28:30 +0000824 skb_queue_head_init(TX_QUEUE(sk));
825 skb_queue_head_init(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -0300826 skb_queue_head_init(BUSY_QUEUE(sk));
Dave Young45054dc2009-10-18 20:28:30 +0000827 INIT_LIST_HEAD(SREJ_LIST(sk));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700828}
829
830static struct proto l2cap_proto = {
831 .name = "L2CAP",
832 .owner = THIS_MODULE,
833 .obj_size = sizeof(struct l2cap_pinfo)
834};
835
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700836static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700837{
838 struct sock *sk;
839
Pavel Emelyanov6257ff22007-11-01 00:39:31 -0700840 sk = sk_alloc(net, PF_BLUETOOTH, prio, &l2cap_proto);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700841 if (!sk)
842 return NULL;
843
844 sock_init_data(sock, sk);
845 INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
846
847 sk->sk_destruct = l2cap_sock_destruct;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200848 sk->sk_sndtimeo = msecs_to_jiffies(L2CAP_CONN_TIMEOUT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700849
850 sock_reset_flag(sk, SOCK_ZAPPED);
851
852 sk->sk_protocol = proto;
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200853 sk->sk_state = BT_OPEN;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700854
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200855 setup_timer(&sk->sk_timer, l2cap_sock_timeout, (unsigned long) sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700856
857 bt_sock_link(&l2cap_sk_list, sk);
858 return sk;
859}
860
Eric Paris3f378b62009-11-05 22:18:14 -0800861static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol,
862 int kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700863{
864 struct sock *sk;
865
866 BT_DBG("sock %p", sock);
867
868 sock->state = SS_UNCONNECTED;
869
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300870 if (sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM &&
Linus Torvalds1da177e2005-04-16 15:20:36 -0700871 sock->type != SOCK_DGRAM && sock->type != SOCK_RAW)
872 return -ESOCKTNOSUPPORT;
873
Eric Parisc84b3262009-11-05 20:45:52 -0800874 if (sock->type == SOCK_RAW && !kern && !capable(CAP_NET_RAW))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700875 return -EPERM;
876
877 sock->ops = &l2cap_sock_ops;
878
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700879 sk = l2cap_sock_alloc(net, sock, protocol, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700880 if (!sk)
881 return -ENOMEM;
882
883 l2cap_sock_init(sk, NULL);
884 return 0;
885}
886
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100887static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700888{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700889 struct sock *sk = sock->sk;
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100890 struct sockaddr_l2 la;
891 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700892
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100893 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700894
895 if (!addr || addr->sa_family != AF_BLUETOOTH)
896 return -EINVAL;
897
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100898 memset(&la, 0, sizeof(la));
899 len = min_t(unsigned int, sizeof(la), alen);
900 memcpy(&la, addr, len);
901
Marcel Holtmann2a517ca2009-02-16 03:20:31 +0100902 if (la.l2_cid)
903 return -EINVAL;
904
Linus Torvalds1da177e2005-04-16 15:20:36 -0700905 lock_sock(sk);
906
907 if (sk->sk_state != BT_OPEN) {
908 err = -EBADFD;
909 goto done;
910 }
911
Marcel Holtmannb4324b52009-06-07 18:06:51 +0200912 if (la.l2_psm && __le16_to_cpu(la.l2_psm) < 0x1001 &&
Marcel Holtmann847641d2007-01-22 22:00:45 +0100913 !capable(CAP_NET_BIND_SERVICE)) {
914 err = -EACCES;
915 goto done;
916 }
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900917
Linus Torvalds1da177e2005-04-16 15:20:36 -0700918 write_lock_bh(&l2cap_sk_list.lock);
919
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100920 if (la.l2_psm && __l2cap_get_sock_by_addr(la.l2_psm, &la.l2_bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700921 err = -EADDRINUSE;
922 } else {
923 /* Save source address */
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100924 bacpy(&bt_sk(sk)->src, &la.l2_bdaddr);
925 l2cap_pi(sk)->psm = la.l2_psm;
926 l2cap_pi(sk)->sport = la.l2_psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700927 sk->sk_state = BT_BOUND;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100928
Marcel Holtmannb4324b52009-06-07 18:06:51 +0200929 if (__le16_to_cpu(la.l2_psm) == 0x0001 ||
930 __le16_to_cpu(la.l2_psm) == 0x0003)
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100931 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700932 }
933
934 write_unlock_bh(&l2cap_sk_list.lock);
935
936done:
937 release_sock(sk);
938 return err;
939}
940
941static int l2cap_do_connect(struct sock *sk)
942{
943 bdaddr_t *src = &bt_sk(sk)->src;
944 bdaddr_t *dst = &bt_sk(sk)->dst;
945 struct l2cap_conn *conn;
946 struct hci_conn *hcon;
947 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200948 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +0200949 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700950
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100951 BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst),
952 l2cap_pi(sk)->psm);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700953
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -0300954 hdev = hci_get_route(dst, src);
955 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700956 return -EHOSTUNREACH;
957
958 hci_dev_lock_bh(hdev);
959
960 err = -ENOMEM;
961
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100962 if (sk->sk_type == SOCK_RAW) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100963 switch (l2cap_pi(sk)->sec_level) {
964 case BT_SECURITY_HIGH:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100965 auth_type = HCI_AT_DEDICATED_BONDING_MITM;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100966 break;
967 case BT_SECURITY_MEDIUM:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100968 auth_type = HCI_AT_DEDICATED_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100969 break;
970 default:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100971 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100972 break;
973 }
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100974 } else if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100975 if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200976 auth_type = HCI_AT_NO_BONDING_MITM;
977 else
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200978 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann435fef22009-02-09 03:55:28 +0100979
980 if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW)
981 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100982 } else {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100983 switch (l2cap_pi(sk)->sec_level) {
984 case BT_SECURITY_HIGH:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100985 auth_type = HCI_AT_GENERAL_BONDING_MITM;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100986 break;
987 case BT_SECURITY_MEDIUM:
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200988 auth_type = HCI_AT_GENERAL_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100989 break;
990 default:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100991 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100992 break;
993 }
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200994 }
995
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100996 hcon = hci_connect(hdev, ACL_LINK, dst,
997 l2cap_pi(sk)->sec_level, auth_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700998 if (!hcon)
999 goto done;
1000
1001 conn = l2cap_conn_add(hcon, 0);
1002 if (!conn) {
1003 hci_conn_put(hcon);
1004 goto done;
1005 }
1006
1007 err = 0;
1008
1009 /* Update source addr of the socket */
1010 bacpy(src, conn->src);
1011
1012 l2cap_chan_add(conn, sk, NULL);
1013
1014 sk->sk_state = BT_CONNECT;
1015 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
1016
1017 if (hcon->state == BT_CONNECTED) {
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001018 if (sk->sk_type != SOCK_SEQPACKET &&
1019 sk->sk_type != SOCK_STREAM) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001020 l2cap_sock_clear_timer(sk);
1021 sk->sk_state = BT_CONNECTED;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001022 } else
1023 l2cap_do_start(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001024 }
1025
1026done:
1027 hci_dev_unlock_bh(hdev);
1028 hci_dev_put(hdev);
1029 return err;
1030}
1031
1032static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
1033{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001034 struct sock *sk = sock->sk;
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001035 struct sockaddr_l2 la;
1036 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001037
Linus Torvalds1da177e2005-04-16 15:20:36 -07001038 BT_DBG("sk %p", sk);
1039
Changli Gao6503d962010-03-31 22:58:26 +00001040 if (!addr || alen < sizeof(addr->sa_family) ||
1041 addr->sa_family != AF_BLUETOOTH)
Marcel Holtmann2a517ca2009-02-16 03:20:31 +01001042 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001043
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001044 memset(&la, 0, sizeof(la));
1045 len = min_t(unsigned int, sizeof(la), alen);
1046 memcpy(&la, addr, len);
1047
Marcel Holtmann2a517ca2009-02-16 03:20:31 +01001048 if (la.l2_cid)
1049 return -EINVAL;
1050
1051 lock_sock(sk);
1052
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001053 if ((sk->sk_type == SOCK_SEQPACKET || sk->sk_type == SOCK_STREAM)
1054 && !la.l2_psm) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001055 err = -EINVAL;
1056 goto done;
1057 }
1058
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001059 switch (l2cap_pi(sk)->mode) {
1060 case L2CAP_MODE_BASIC:
1061 break;
1062 case L2CAP_MODE_ERTM:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001063 case L2CAP_MODE_STREAMING:
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001064 if (enable_ertm)
1065 break;
1066 /* fall through */
1067 default:
1068 err = -ENOTSUPP;
1069 goto done;
1070 }
1071
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03001072 switch (sk->sk_state) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001073 case BT_CONNECT:
1074 case BT_CONNECT2:
1075 case BT_CONFIG:
1076 /* Already connecting */
1077 goto wait;
1078
1079 case BT_CONNECTED:
1080 /* Already connected */
1081 goto done;
1082
1083 case BT_OPEN:
1084 case BT_BOUND:
1085 /* Can connect */
1086 break;
1087
1088 default:
1089 err = -EBADFD;
1090 goto done;
1091 }
1092
1093 /* Set destination address and psm */
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001094 bacpy(&bt_sk(sk)->dst, &la.l2_bdaddr);
1095 l2cap_pi(sk)->psm = la.l2_psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001096
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03001097 err = l2cap_do_connect(sk);
1098 if (err)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001099 goto done;
1100
1101wait:
1102 err = bt_sock_wait_state(sk, BT_CONNECTED,
1103 sock_sndtimeo(sk, flags & O_NONBLOCK));
1104done:
1105 release_sock(sk);
1106 return err;
1107}
1108
1109static int l2cap_sock_listen(struct socket *sock, int backlog)
1110{
1111 struct sock *sk = sock->sk;
1112 int err = 0;
1113
1114 BT_DBG("sk %p backlog %d", sk, backlog);
1115
1116 lock_sock(sk);
1117
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001118 if ((sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM)
1119 || sk->sk_state != BT_BOUND) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001120 err = -EBADFD;
1121 goto done;
1122 }
1123
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001124 switch (l2cap_pi(sk)->mode) {
1125 case L2CAP_MODE_BASIC:
1126 break;
1127 case L2CAP_MODE_ERTM:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001128 case L2CAP_MODE_STREAMING:
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001129 if (enable_ertm)
1130 break;
1131 /* fall through */
1132 default:
1133 err = -ENOTSUPP;
1134 goto done;
1135 }
1136
Linus Torvalds1da177e2005-04-16 15:20:36 -07001137 if (!l2cap_pi(sk)->psm) {
1138 bdaddr_t *src = &bt_sk(sk)->src;
1139 u16 psm;
1140
1141 err = -EINVAL;
1142
1143 write_lock_bh(&l2cap_sk_list.lock);
1144
1145 for (psm = 0x1001; psm < 0x1100; psm += 2)
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001146 if (!__l2cap_get_sock_by_addr(cpu_to_le16(psm), src)) {
1147 l2cap_pi(sk)->psm = cpu_to_le16(psm);
1148 l2cap_pi(sk)->sport = cpu_to_le16(psm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001149 err = 0;
1150 break;
1151 }
1152
1153 write_unlock_bh(&l2cap_sk_list.lock);
1154
1155 if (err < 0)
1156 goto done;
1157 }
1158
1159 sk->sk_max_ack_backlog = backlog;
1160 sk->sk_ack_backlog = 0;
1161 sk->sk_state = BT_LISTEN;
1162
1163done:
1164 release_sock(sk);
1165 return err;
1166}
1167
1168static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int flags)
1169{
1170 DECLARE_WAITQUEUE(wait, current);
1171 struct sock *sk = sock->sk, *nsk;
1172 long timeo;
1173 int err = 0;
1174
Peter Zijlstrafcc70d52006-11-08 22:44:35 -08001175 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001176
1177 if (sk->sk_state != BT_LISTEN) {
1178 err = -EBADFD;
1179 goto done;
1180 }
1181
1182 timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
1183
1184 BT_DBG("sk %p timeo %ld", sk, timeo);
1185
1186 /* Wait for an incoming connection. (wake-one). */
Eric Dumazetaa395142010-04-20 13:03:51 +00001187 add_wait_queue_exclusive(sk_sleep(sk), &wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001188 while (!(nsk = bt_accept_dequeue(sk, newsock))) {
1189 set_current_state(TASK_INTERRUPTIBLE);
1190 if (!timeo) {
1191 err = -EAGAIN;
1192 break;
1193 }
1194
1195 release_sock(sk);
1196 timeo = schedule_timeout(timeo);
Peter Zijlstrafcc70d52006-11-08 22:44:35 -08001197 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001198
1199 if (sk->sk_state != BT_LISTEN) {
1200 err = -EBADFD;
1201 break;
1202 }
1203
1204 if (signal_pending(current)) {
1205 err = sock_intr_errno(timeo);
1206 break;
1207 }
1208 }
1209 set_current_state(TASK_RUNNING);
Eric Dumazetaa395142010-04-20 13:03:51 +00001210 remove_wait_queue(sk_sleep(sk), &wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001211
1212 if (err)
1213 goto done;
1214
1215 newsock->state = SS_CONNECTED;
1216
1217 BT_DBG("new socket %p", nsk);
1218
1219done:
1220 release_sock(sk);
1221 return err;
1222}
1223
1224static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
1225{
1226 struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
1227 struct sock *sk = sock->sk;
1228
1229 BT_DBG("sock %p, sk %p", sock, sk);
1230
1231 addr->sa_family = AF_BLUETOOTH;
1232 *len = sizeof(struct sockaddr_l2);
1233
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001234 if (peer) {
1235 la->l2_psm = l2cap_pi(sk)->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001236 bacpy(&la->l2_bdaddr, &bt_sk(sk)->dst);
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001237 la->l2_cid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001238 } else {
1239 la->l2_psm = l2cap_pi(sk)->sport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001240 bacpy(&la->l2_bdaddr, &bt_sk(sk)->src);
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001241 la->l2_cid = cpu_to_le16(l2cap_pi(sk)->scid);
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001242 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001243
Linus Torvalds1da177e2005-04-16 15:20:36 -07001244 return 0;
1245}
1246
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001247static int __l2cap_wait_ack(struct sock *sk)
1248{
1249 DECLARE_WAITQUEUE(wait, current);
1250 int err = 0;
1251 int timeo = HZ/5;
1252
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001253 add_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001254 while ((l2cap_pi(sk)->unacked_frames > 0 && l2cap_pi(sk)->conn)) {
1255 set_current_state(TASK_INTERRUPTIBLE);
1256
1257 if (!timeo)
1258 timeo = HZ/5;
1259
1260 if (signal_pending(current)) {
1261 err = sock_intr_errno(timeo);
1262 break;
1263 }
1264
1265 release_sock(sk);
1266 timeo = schedule_timeout(timeo);
1267 lock_sock(sk);
1268
1269 err = sock_error(sk);
1270 if (err)
1271 break;
1272 }
1273 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001274 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001275 return err;
1276}
1277
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001278static void l2cap_monitor_timeout(unsigned long arg)
1279{
1280 struct sock *sk = (void *) arg;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001281
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001282 bh_lock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001283 if (l2cap_pi(sk)->retry_count >= l2cap_pi(sk)->remote_max_tx) {
1284 l2cap_send_disconn_req(l2cap_pi(sk)->conn, sk);
Andrei Emeltchenkob13f5862009-12-15 11:38:04 +02001285 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001286 return;
1287 }
1288
1289 l2cap_pi(sk)->retry_count++;
1290 __mod_monitor_timer();
1291
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -03001292 l2cap_send_rr_or_rnr(l2cap_pi(sk), L2CAP_CTRL_POLL);
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001293 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001294}
1295
1296static void l2cap_retrans_timeout(unsigned long arg)
1297{
1298 struct sock *sk = (void *) arg;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001299
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001300 bh_lock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001301 l2cap_pi(sk)->retry_count = 1;
1302 __mod_monitor_timer();
1303
1304 l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
1305
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -03001306 l2cap_send_rr_or_rnr(l2cap_pi(sk), L2CAP_CTRL_POLL);
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001307 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001308}
1309
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001310static void l2cap_drop_acked_frames(struct sock *sk)
1311{
1312 struct sk_buff *skb;
1313
Gustavo F. Padovan812e7372010-05-01 16:15:42 -03001314 while ((skb = skb_peek(TX_QUEUE(sk))) &&
1315 l2cap_pi(sk)->unacked_frames) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001316 if (bt_cb(skb)->tx_seq == l2cap_pi(sk)->expected_ack_seq)
1317 break;
1318
1319 skb = skb_dequeue(TX_QUEUE(sk));
1320 kfree_skb(skb);
1321
1322 l2cap_pi(sk)->unacked_frames--;
1323 }
1324
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001325 if (!l2cap_pi(sk)->unacked_frames)
1326 del_timer(&l2cap_pi(sk)->retrans_timer);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001327}
1328
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001329static inline void l2cap_do_send(struct sock *sk, struct sk_buff *skb)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001330{
1331 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001332
1333 BT_DBG("sk %p, skb %p len %d", sk, skb, skb->len);
1334
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001335 hci_send_acl(pi->conn->hcon, skb, 0);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001336}
1337
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001338static int l2cap_streaming_send(struct sock *sk)
1339{
1340 struct sk_buff *skb, *tx_skb;
1341 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001342 u16 control, fcs;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001343
1344 while ((skb = sk->sk_send_head)) {
1345 tx_skb = skb_clone(skb, GFP_ATOMIC);
1346
1347 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
1348 control |= pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT;
1349 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1350
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001351 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001352 fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
1353 put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
1354 }
1355
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001356 l2cap_do_send(sk, tx_skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001357
1358 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
1359
1360 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1361 sk->sk_send_head = NULL;
1362 else
1363 sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
1364
1365 skb = skb_dequeue(TX_QUEUE(sk));
1366 kfree_skb(skb);
1367 }
1368 return 0;
1369}
1370
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001371static void l2cap_retransmit_one_frame(struct sock *sk, u8 tx_seq)
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001372{
1373 struct l2cap_pinfo *pi = l2cap_pi(sk);
1374 struct sk_buff *skb, *tx_skb;
1375 u16 control, fcs;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001376
1377 skb = skb_peek(TX_QUEUE(sk));
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001378 if (!skb)
1379 return;
1380
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001381 do {
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001382 if (bt_cb(skb)->tx_seq == tx_seq)
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001383 break;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001384
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001385 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1386 return;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001387
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001388 } while ((skb = skb_queue_next(TX_QUEUE(sk), skb)));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001389
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001390 if (pi->remote_max_tx &&
1391 bt_cb(skb)->retries == pi->remote_max_tx) {
1392 l2cap_send_disconn_req(pi->conn, sk);
1393 return;
1394 }
1395
1396 tx_skb = skb_clone(skb, GFP_ATOMIC);
1397 bt_cb(skb)->retries++;
1398 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
1399 control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
1400 | (tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
1401 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1402
1403 if (pi->fcs == L2CAP_FCS_CRC16) {
1404 fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
1405 put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
1406 }
1407
1408 l2cap_do_send(sk, tx_skb);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001409}
1410
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001411static int l2cap_ertm_send(struct sock *sk)
1412{
1413 struct sk_buff *skb, *tx_skb;
1414 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001415 u16 control, fcs;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001416 int nsent = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001417
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001418
Gustavo F. Padovan6e2b6722010-06-01 18:52:58 -03001419 while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(sk))) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001420
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001421 if (pi->remote_max_tx &&
1422 bt_cb(skb)->retries == pi->remote_max_tx) {
1423 l2cap_send_disconn_req(pi->conn, sk);
1424 break;
1425 }
1426
Andrei Emeltchenkoe420aba2009-12-23 13:07:14 +02001427 tx_skb = skb_clone(skb, GFP_ATOMIC);
1428
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001429 bt_cb(skb)->retries++;
1430
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001431 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001432 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
1433 control |= L2CAP_CTRL_FINAL;
1434 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
1435 }
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03001436 control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001437 | (pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
1438 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1439
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001440
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001441 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001442 fcs = crc16(0, (u8 *)skb->data, tx_skb->len - 2);
1443 put_unaligned_le16(fcs, skb->data + tx_skb->len - 2);
1444 }
1445
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001446 l2cap_do_send(sk, tx_skb);
1447
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001448 __mod_retrans_timer();
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001449
1450 bt_cb(skb)->tx_seq = pi->next_tx_seq;
1451 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
1452
1453 pi->unacked_frames++;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001454 pi->frames_sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001455
1456 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1457 sk->sk_send_head = NULL;
1458 else
1459 sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001460
1461 nsent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001462 }
1463
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001464 return nsent;
1465}
1466
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001467static int l2cap_retransmit_frames(struct sock *sk)
1468{
1469 struct l2cap_pinfo *pi = l2cap_pi(sk);
1470 int ret;
1471
1472 spin_lock_bh(&pi->send_lock);
1473
1474 if (!skb_queue_empty(TX_QUEUE(sk)))
1475 sk->sk_send_head = TX_QUEUE(sk)->next;
1476
1477 pi->next_tx_seq = pi->expected_ack_seq;
1478 ret = l2cap_ertm_send(sk);
1479
1480 spin_unlock_bh(&pi->send_lock);
1481
1482 return ret;
1483}
1484
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001485static void l2cap_send_ack(struct l2cap_pinfo *pi)
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001486{
1487 struct sock *sk = (struct sock *)pi;
1488 u16 control = 0;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001489 int nframes;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001490
1491 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1492
1493 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
1494 control |= L2CAP_SUPER_RCV_NOT_READY;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03001495 pi->conn_state |= L2CAP_CONN_RNR_SENT;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001496 l2cap_send_sframe(pi, control);
1497 return;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001498 }
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001499
1500 spin_lock_bh(&pi->send_lock);
1501 nframes = l2cap_ertm_send(sk);
1502 spin_unlock_bh(&pi->send_lock);
1503
1504 if (nframes > 0)
1505 return;
1506
1507 control |= L2CAP_SUPER_RCV_READY;
1508 l2cap_send_sframe(pi, control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001509}
1510
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001511static void l2cap_send_srejtail(struct sock *sk)
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03001512{
1513 struct srej_list *tail;
1514 u16 control;
1515
1516 control = L2CAP_SUPER_SELECT_REJECT;
1517 control |= L2CAP_CTRL_FINAL;
1518
1519 tail = list_entry(SREJ_LIST(sk)->prev, struct srej_list, list);
1520 control |= tail->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1521
1522 l2cap_send_sframe(l2cap_pi(sk), control);
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03001523}
1524
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001525static 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 -07001526{
1527 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001528 struct sk_buff **frag;
1529 int err, sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001530
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03001531 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001532 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001533
1534 sent += count;
1535 len -= count;
1536
1537 /* Continuation fragments (no L2CAP header) */
1538 frag = &skb_shinfo(skb)->frag_list;
1539 while (len) {
1540 count = min_t(unsigned int, conn->mtu, len);
1541
1542 *frag = bt_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err);
1543 if (!*frag)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001544 return -EFAULT;
1545 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
1546 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001547
1548 sent += count;
1549 len -= count;
1550
1551 frag = &(*frag)->next;
1552 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001553
1554 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001555}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001556
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001557static struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, size_t len)
1558{
1559 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1560 struct sk_buff *skb;
1561 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1562 struct l2cap_hdr *lh;
1563
1564 BT_DBG("sk %p len %d", sk, (int)len);
1565
1566 count = min_t(unsigned int, (conn->mtu - hlen), len);
1567 skb = bt_skb_send_alloc(sk, count + hlen,
1568 msg->msg_flags & MSG_DONTWAIT, &err);
1569 if (!skb)
1570 return ERR_PTR(-ENOMEM);
1571
1572 /* Create L2CAP header */
1573 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1574 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1575 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1576 put_unaligned_le16(l2cap_pi(sk)->psm, skb_put(skb, 2));
1577
1578 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1579 if (unlikely(err < 0)) {
1580 kfree_skb(skb);
1581 return ERR_PTR(err);
1582 }
1583 return skb;
1584}
1585
1586static struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *msg, size_t len)
1587{
1588 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1589 struct sk_buff *skb;
1590 int err, count, hlen = L2CAP_HDR_SIZE;
1591 struct l2cap_hdr *lh;
1592
1593 BT_DBG("sk %p len %d", sk, (int)len);
1594
1595 count = min_t(unsigned int, (conn->mtu - hlen), len);
1596 skb = bt_skb_send_alloc(sk, count + hlen,
1597 msg->msg_flags & MSG_DONTWAIT, &err);
1598 if (!skb)
1599 return ERR_PTR(-ENOMEM);
1600
1601 /* Create L2CAP header */
1602 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1603 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1604 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1605
1606 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1607 if (unlikely(err < 0)) {
1608 kfree_skb(skb);
1609 return ERR_PTR(err);
1610 }
1611 return skb;
1612}
1613
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001614static 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 -03001615{
1616 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1617 struct sk_buff *skb;
1618 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1619 struct l2cap_hdr *lh;
1620
1621 BT_DBG("sk %p len %d", sk, (int)len);
1622
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03001623 if (!conn)
1624 return ERR_PTR(-ENOTCONN);
1625
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001626 if (sdulen)
1627 hlen += 2;
1628
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001629 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1630 hlen += 2;
1631
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001632 count = min_t(unsigned int, (conn->mtu - hlen), len);
1633 skb = bt_skb_send_alloc(sk, count + hlen,
1634 msg->msg_flags & MSG_DONTWAIT, &err);
1635 if (!skb)
1636 return ERR_PTR(-ENOMEM);
1637
1638 /* Create L2CAP header */
1639 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1640 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1641 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1642 put_unaligned_le16(control, skb_put(skb, 2));
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001643 if (sdulen)
1644 put_unaligned_le16(sdulen, skb_put(skb, 2));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001645
1646 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1647 if (unlikely(err < 0)) {
1648 kfree_skb(skb);
1649 return ERR_PTR(err);
1650 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001651
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001652 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1653 put_unaligned_le16(0, skb_put(skb, 2));
1654
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001655 bt_cb(skb)->retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001656 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001657}
1658
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001659static inline int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len)
1660{
1661 struct l2cap_pinfo *pi = l2cap_pi(sk);
1662 struct sk_buff *skb;
1663 struct sk_buff_head sar_queue;
1664 u16 control;
1665 size_t size = 0;
1666
Gustavo F. Padovanff12fd62010-05-05 22:09:15 -03001667 skb_queue_head_init(&sar_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001668 control = L2CAP_SDU_START;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001669 skb = l2cap_create_iframe_pdu(sk, msg, pi->remote_mps, control, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001670 if (IS_ERR(skb))
1671 return PTR_ERR(skb);
1672
1673 __skb_queue_tail(&sar_queue, skb);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001674 len -= pi->remote_mps;
1675 size += pi->remote_mps;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001676
1677 while (len > 0) {
1678 size_t buflen;
1679
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001680 if (len > pi->remote_mps) {
Gustavo F. Padovan44651b82010-05-01 16:15:43 -03001681 control = L2CAP_SDU_CONTINUE;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001682 buflen = pi->remote_mps;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001683 } else {
Gustavo F. Padovan44651b82010-05-01 16:15:43 -03001684 control = L2CAP_SDU_END;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001685 buflen = len;
1686 }
1687
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001688 skb = l2cap_create_iframe_pdu(sk, msg, buflen, control, 0);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001689 if (IS_ERR(skb)) {
1690 skb_queue_purge(&sar_queue);
1691 return PTR_ERR(skb);
1692 }
1693
1694 __skb_queue_tail(&sar_queue, skb);
1695 len -= buflen;
1696 size += buflen;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001697 }
1698 skb_queue_splice_tail(&sar_queue, TX_QUEUE(sk));
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001699 spin_lock_bh(&pi->send_lock);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001700 if (sk->sk_send_head == NULL)
1701 sk->sk_send_head = sar_queue.next;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001702 spin_unlock_bh(&pi->send_lock);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001703
1704 return size;
1705}
1706
Linus Torvalds1da177e2005-04-16 15:20:36 -07001707static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len)
1708{
1709 struct sock *sk = sock->sk;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001710 struct l2cap_pinfo *pi = l2cap_pi(sk);
1711 struct sk_buff *skb;
1712 u16 control;
1713 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001714
1715 BT_DBG("sock %p, sk %p", sock, sk);
1716
Benjamin LaHaisec1cbe4b2005-12-13 23:22:19 -08001717 err = sock_error(sk);
1718 if (err)
1719 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001720
1721 if (msg->msg_flags & MSG_OOB)
1722 return -EOPNOTSUPP;
1723
Linus Torvalds1da177e2005-04-16 15:20:36 -07001724 lock_sock(sk);
1725
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001726 if (sk->sk_state != BT_CONNECTED) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001727 err = -ENOTCONN;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001728 goto done;
1729 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001730
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001731 /* Connectionless channel */
1732 if (sk->sk_type == SOCK_DGRAM) {
1733 skb = l2cap_create_connless_pdu(sk, msg, len);
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001734 if (IS_ERR(skb)) {
Dan Carpenter477fffb2010-04-21 23:52:01 +00001735 err = PTR_ERR(skb);
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001736 } else {
1737 l2cap_do_send(sk, skb);
1738 err = len;
1739 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001740 goto done;
1741 }
1742
1743 switch (pi->mode) {
1744 case L2CAP_MODE_BASIC:
Gustavo F. Padovanc69163e2010-05-01 16:15:35 -03001745 /* Check outgoing MTU */
1746 if (len > pi->omtu) {
1747 err = -EINVAL;
1748 goto done;
1749 }
1750
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001751 /* Create a basic PDU */
1752 skb = l2cap_create_basic_pdu(sk, msg, len);
1753 if (IS_ERR(skb)) {
1754 err = PTR_ERR(skb);
1755 goto done;
1756 }
1757
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001758 l2cap_do_send(sk, skb);
1759 err = len;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001760 break;
1761
1762 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001763 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001764 /* Entire SDU fits into one PDU */
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001765 if (len <= pi->remote_mps) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001766 control = L2CAP_SDU_UNSEGMENTED;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001767 skb = l2cap_create_iframe_pdu(sk, msg, len, control, 0);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001768 if (IS_ERR(skb)) {
1769 err = PTR_ERR(skb);
1770 goto done;
1771 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001772 __skb_queue_tail(TX_QUEUE(sk), skb);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001773
1774 if (pi->mode == L2CAP_MODE_ERTM)
1775 spin_lock_bh(&pi->send_lock);
1776
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001777 if (sk->sk_send_head == NULL)
1778 sk->sk_send_head = skb;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001779
1780 if (pi->mode == L2CAP_MODE_ERTM)
1781 spin_unlock_bh(&pi->send_lock);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001782 } else {
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001783 /* Segment SDU into multiples PDUs */
1784 err = l2cap_sar_segment_sdu(sk, msg, len);
1785 if (err < 0)
1786 goto done;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001787 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001788
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001789 if (pi->mode == L2CAP_MODE_STREAMING) {
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001790 err = l2cap_streaming_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001791 } else {
Gustavo F. Padovan6e2b6722010-06-01 18:52:58 -03001792 if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY &&
1793 pi->conn_state && L2CAP_CONN_WAIT_F) {
1794 err = len;
1795 break;
1796 }
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001797 spin_lock_bh(&pi->send_lock);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001798 err = l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001799 spin_unlock_bh(&pi->send_lock);
1800 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001801
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001802 if (err >= 0)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001803 err = len;
1804 break;
1805
1806 default:
1807 BT_DBG("bad state %1.1x", pi->mode);
1808 err = -EINVAL;
1809 }
1810
1811done:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001812 release_sock(sk);
1813 return err;
1814}
1815
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001816static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags)
1817{
1818 struct sock *sk = sock->sk;
1819
1820 lock_sock(sk);
1821
1822 if (sk->sk_state == BT_CONNECT2 && bt_sk(sk)->defer_setup) {
1823 struct l2cap_conn_rsp rsp;
1824
1825 sk->sk_state = BT_CONFIG;
1826
1827 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
1828 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
1829 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
1830 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
1831 l2cap_send_cmd(l2cap_pi(sk)->conn, l2cap_pi(sk)->ident,
1832 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
1833
1834 release_sock(sk);
1835 return 0;
1836 }
1837
1838 release_sock(sk);
1839
1840 return bt_sock_recvmsg(iocb, sock, msg, len, flags);
1841}
1842
David S. Millerb7058842009-09-30 16:12:20 -07001843static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001844{
1845 struct sock *sk = sock->sk;
1846 struct l2cap_options opts;
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001847 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001848 u32 opt;
1849
1850 BT_DBG("sk %p", sk);
1851
1852 lock_sock(sk);
1853
1854 switch (optname) {
1855 case L2CAP_OPTIONS:
Marcel Holtmann0878b662007-05-05 00:35:59 +02001856 opts.imtu = l2cap_pi(sk)->imtu;
1857 opts.omtu = l2cap_pi(sk)->omtu;
1858 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001859 opts.mode = l2cap_pi(sk)->mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001860 opts.fcs = l2cap_pi(sk)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03001861 opts.max_tx = l2cap_pi(sk)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03001862 opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
Marcel Holtmann0878b662007-05-05 00:35:59 +02001863
Linus Torvalds1da177e2005-04-16 15:20:36 -07001864 len = min_t(unsigned int, sizeof(opts), optlen);
1865 if (copy_from_user((char *) &opts, optval, len)) {
1866 err = -EFAULT;
1867 break;
1868 }
Marcel Holtmann0878b662007-05-05 00:35:59 +02001869
João Paulo Rechi Vita0041ecf2010-05-01 16:15:42 -03001870 l2cap_pi(sk)->mode = opts.mode;
1871 switch (l2cap_pi(sk)->mode) {
1872 case L2CAP_MODE_BASIC:
1873 break;
1874 case L2CAP_MODE_ERTM:
1875 case L2CAP_MODE_STREAMING:
1876 if (enable_ertm)
1877 break;
1878 /* fall through */
1879 default:
1880 err = -EINVAL;
1881 break;
1882 }
1883
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001884 l2cap_pi(sk)->imtu = opts.imtu;
1885 l2cap_pi(sk)->omtu = opts.omtu;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001886 l2cap_pi(sk)->fcs = opts.fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03001887 l2cap_pi(sk)->max_tx = opts.max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03001888 l2cap_pi(sk)->tx_win = (__u8)opts.txwin_size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001889 break;
1890
1891 case L2CAP_LM:
1892 if (get_user(opt, (u32 __user *) optval)) {
1893 err = -EFAULT;
1894 break;
1895 }
1896
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001897 if (opt & L2CAP_LM_AUTH)
1898 l2cap_pi(sk)->sec_level = BT_SECURITY_LOW;
1899 if (opt & L2CAP_LM_ENCRYPT)
1900 l2cap_pi(sk)->sec_level = BT_SECURITY_MEDIUM;
1901 if (opt & L2CAP_LM_SECURE)
1902 l2cap_pi(sk)->sec_level = BT_SECURITY_HIGH;
1903
1904 l2cap_pi(sk)->role_switch = (opt & L2CAP_LM_MASTER);
1905 l2cap_pi(sk)->force_reliable = (opt & L2CAP_LM_RELIABLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001906 break;
1907
1908 default:
1909 err = -ENOPROTOOPT;
1910 break;
1911 }
1912
1913 release_sock(sk);
1914 return err;
1915}
1916
David S. Millerb7058842009-09-30 16:12:20 -07001917static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001918{
1919 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001920 struct bt_security sec;
1921 int len, err = 0;
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001922 u32 opt;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001923
1924 BT_DBG("sk %p", sk);
1925
1926 if (level == SOL_L2CAP)
1927 return l2cap_sock_setsockopt_old(sock, optname, optval, optlen);
1928
Marcel Holtmann0588d942009-01-16 10:06:13 +01001929 if (level != SOL_BLUETOOTH)
1930 return -ENOPROTOOPT;
1931
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001932 lock_sock(sk);
1933
1934 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001935 case BT_SECURITY:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001936 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
1937 && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01001938 err = -EINVAL;
1939 break;
1940 }
1941
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001942 sec.level = BT_SECURITY_LOW;
1943
1944 len = min_t(unsigned int, sizeof(sec), optlen);
1945 if (copy_from_user((char *) &sec, optval, len)) {
1946 err = -EFAULT;
1947 break;
1948 }
1949
1950 if (sec.level < BT_SECURITY_LOW ||
1951 sec.level > BT_SECURITY_HIGH) {
1952 err = -EINVAL;
1953 break;
1954 }
1955
1956 l2cap_pi(sk)->sec_level = sec.level;
1957 break;
1958
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001959 case BT_DEFER_SETUP:
1960 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
1961 err = -EINVAL;
1962 break;
1963 }
1964
1965 if (get_user(opt, (u32 __user *) optval)) {
1966 err = -EFAULT;
1967 break;
1968 }
1969
1970 bt_sk(sk)->defer_setup = opt;
1971 break;
1972
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001973 default:
1974 err = -ENOPROTOOPT;
1975 break;
1976 }
1977
1978 release_sock(sk);
1979 return err;
1980}
1981
1982static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001983{
1984 struct sock *sk = sock->sk;
1985 struct l2cap_options opts;
1986 struct l2cap_conninfo cinfo;
1987 int len, err = 0;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001988 u32 opt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001989
1990 BT_DBG("sk %p", sk);
1991
1992 if (get_user(len, optlen))
1993 return -EFAULT;
1994
1995 lock_sock(sk);
1996
1997 switch (optname) {
1998 case L2CAP_OPTIONS:
1999 opts.imtu = l2cap_pi(sk)->imtu;
2000 opts.omtu = l2cap_pi(sk)->omtu;
2001 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07002002 opts.mode = l2cap_pi(sk)->mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002003 opts.fcs = l2cap_pi(sk)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03002004 opts.max_tx = l2cap_pi(sk)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03002005 opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002006
2007 len = min_t(unsigned int, len, sizeof(opts));
2008 if (copy_to_user(optval, (char *) &opts, len))
2009 err = -EFAULT;
2010
2011 break;
2012
2013 case L2CAP_LM:
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002014 switch (l2cap_pi(sk)->sec_level) {
2015 case BT_SECURITY_LOW:
2016 opt = L2CAP_LM_AUTH;
2017 break;
2018 case BT_SECURITY_MEDIUM:
2019 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT;
2020 break;
2021 case BT_SECURITY_HIGH:
2022 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT |
2023 L2CAP_LM_SECURE;
2024 break;
2025 default:
2026 opt = 0;
2027 break;
2028 }
2029
2030 if (l2cap_pi(sk)->role_switch)
2031 opt |= L2CAP_LM_MASTER;
2032
2033 if (l2cap_pi(sk)->force_reliable)
2034 opt |= L2CAP_LM_RELIABLE;
2035
2036 if (put_user(opt, (u32 __user *) optval))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002037 err = -EFAULT;
2038 break;
2039
2040 case L2CAP_CONNINFO:
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002041 if (sk->sk_state != BT_CONNECTED &&
2042 !(sk->sk_state == BT_CONNECT2 &&
2043 bt_sk(sk)->defer_setup)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002044 err = -ENOTCONN;
2045 break;
2046 }
2047
2048 cinfo.hci_handle = l2cap_pi(sk)->conn->hcon->handle;
2049 memcpy(cinfo.dev_class, l2cap_pi(sk)->conn->hcon->dev_class, 3);
2050
2051 len = min_t(unsigned int, len, sizeof(cinfo));
2052 if (copy_to_user(optval, (char *) &cinfo, len))
2053 err = -EFAULT;
2054
2055 break;
2056
2057 default:
2058 err = -ENOPROTOOPT;
2059 break;
2060 }
2061
2062 release_sock(sk);
2063 return err;
2064}
2065
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002066static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
2067{
2068 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002069 struct bt_security sec;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002070 int len, err = 0;
2071
2072 BT_DBG("sk %p", sk);
2073
2074 if (level == SOL_L2CAP)
2075 return l2cap_sock_getsockopt_old(sock, optname, optval, optlen);
2076
Marcel Holtmann0588d942009-01-16 10:06:13 +01002077 if (level != SOL_BLUETOOTH)
2078 return -ENOPROTOOPT;
2079
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002080 if (get_user(len, optlen))
2081 return -EFAULT;
2082
2083 lock_sock(sk);
2084
2085 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002086 case BT_SECURITY:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03002087 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
2088 && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01002089 err = -EINVAL;
2090 break;
2091 }
2092
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002093 sec.level = l2cap_pi(sk)->sec_level;
2094
2095 len = min_t(unsigned int, len, sizeof(sec));
2096 if (copy_to_user(optval, (char *) &sec, len))
2097 err = -EFAULT;
2098
2099 break;
2100
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002101 case BT_DEFER_SETUP:
2102 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
2103 err = -EINVAL;
2104 break;
2105 }
2106
2107 if (put_user(bt_sk(sk)->defer_setup, (u32 __user *) optval))
2108 err = -EFAULT;
2109
2110 break;
2111
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002112 default:
2113 err = -ENOPROTOOPT;
2114 break;
2115 }
2116
2117 release_sock(sk);
2118 return err;
2119}
2120
Linus Torvalds1da177e2005-04-16 15:20:36 -07002121static int l2cap_sock_shutdown(struct socket *sock, int how)
2122{
2123 struct sock *sk = sock->sk;
2124 int err = 0;
2125
2126 BT_DBG("sock %p, sk %p", sock, sk);
2127
2128 if (!sk)
2129 return 0;
2130
2131 lock_sock(sk);
2132 if (!sk->sk_shutdown) {
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03002133 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
2134 err = __l2cap_wait_ack(sk);
2135
Linus Torvalds1da177e2005-04-16 15:20:36 -07002136 sk->sk_shutdown = SHUTDOWN_MASK;
2137 l2cap_sock_clear_timer(sk);
2138 __l2cap_sock_close(sk, 0);
2139
2140 if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
Marcel Holtmannb1235d72008-07-14 20:13:54 +02002141 err = bt_sock_wait_state(sk, BT_CLOSED,
2142 sk->sk_lingertime);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002143 }
2144 release_sock(sk);
2145 return err;
2146}
2147
2148static int l2cap_sock_release(struct socket *sock)
2149{
2150 struct sock *sk = sock->sk;
2151 int err;
2152
2153 BT_DBG("sock %p, sk %p", sock, sk);
2154
2155 if (!sk)
2156 return 0;
2157
2158 err = l2cap_sock_shutdown(sock, 2);
2159
2160 sock_orphan(sk);
2161 l2cap_sock_kill(sk);
2162 return err;
2163}
2164
Linus Torvalds1da177e2005-04-16 15:20:36 -07002165static void l2cap_chan_ready(struct sock *sk)
2166{
2167 struct sock *parent = bt_sk(sk)->parent;
2168
2169 BT_DBG("sk %p, parent %p", sk, parent);
2170
2171 l2cap_pi(sk)->conf_state = 0;
2172 l2cap_sock_clear_timer(sk);
2173
2174 if (!parent) {
2175 /* Outgoing channel.
2176 * Wake up socket sleeping on connect.
2177 */
2178 sk->sk_state = BT_CONNECTED;
2179 sk->sk_state_change(sk);
2180 } else {
2181 /* Incoming channel.
2182 * Wake up socket sleeping on accept.
2183 */
2184 parent->sk_data_ready(parent, 0);
2185 }
2186}
2187
2188/* Copy frame to all raw sockets on that connection */
2189static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2190{
2191 struct l2cap_chan_list *l = &conn->chan_list;
2192 struct sk_buff *nskb;
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002193 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002194
2195 BT_DBG("conn %p", conn);
2196
2197 read_lock(&l->lock);
2198 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
2199 if (sk->sk_type != SOCK_RAW)
2200 continue;
2201
2202 /* Don't send frame to the socket it came from */
2203 if (skb->sk == sk)
2204 continue;
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002205 nskb = skb_clone(skb, GFP_ATOMIC);
2206 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002207 continue;
2208
2209 if (sock_queue_rcv_skb(sk, nskb))
2210 kfree_skb(nskb);
2211 }
2212 read_unlock(&l->lock);
2213}
2214
2215/* ---- L2CAP signalling commands ---- */
2216static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
2217 u8 code, u8 ident, u16 dlen, void *data)
2218{
2219 struct sk_buff *skb, **frag;
2220 struct l2cap_cmd_hdr *cmd;
2221 struct l2cap_hdr *lh;
2222 int len, count;
2223
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002224 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d",
2225 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002226
2227 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2228 count = min_t(unsigned int, conn->mtu, len);
2229
2230 skb = bt_skb_alloc(count, GFP_ATOMIC);
2231 if (!skb)
2232 return NULL;
2233
2234 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002235 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03002236 lh->cid = cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002237
2238 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2239 cmd->code = code;
2240 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002241 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002242
2243 if (dlen) {
2244 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2245 memcpy(skb_put(skb, count), data, count);
2246 data += count;
2247 }
2248
2249 len -= skb->len;
2250
2251 /* Continuation fragments (no L2CAP header) */
2252 frag = &skb_shinfo(skb)->frag_list;
2253 while (len) {
2254 count = min_t(unsigned int, conn->mtu, len);
2255
2256 *frag = bt_skb_alloc(count, GFP_ATOMIC);
2257 if (!*frag)
2258 goto fail;
2259
2260 memcpy(skb_put(*frag, count), data, count);
2261
2262 len -= count;
2263 data += count;
2264
2265 frag = &(*frag)->next;
2266 }
2267
2268 return skb;
2269
2270fail:
2271 kfree_skb(skb);
2272 return NULL;
2273}
2274
2275static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned long *val)
2276{
2277 struct l2cap_conf_opt *opt = *ptr;
2278 int len;
2279
2280 len = L2CAP_CONF_OPT_SIZE + opt->len;
2281 *ptr += len;
2282
2283 *type = opt->type;
2284 *olen = opt->len;
2285
2286 switch (opt->len) {
2287 case 1:
2288 *val = *((u8 *) opt->val);
2289 break;
2290
2291 case 2:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002292 *val = __le16_to_cpu(*((__le16 *) opt->val));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002293 break;
2294
2295 case 4:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002296 *val = __le32_to_cpu(*((__le32 *) opt->val));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002297 break;
2298
2299 default:
2300 *val = (unsigned long) opt->val;
2301 break;
2302 }
2303
2304 BT_DBG("type 0x%2.2x len %d val 0x%lx", *type, opt->len, *val);
2305 return len;
2306}
2307
Linus Torvalds1da177e2005-04-16 15:20:36 -07002308static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2309{
2310 struct l2cap_conf_opt *opt = *ptr;
2311
2312 BT_DBG("type 0x%2.2x len %d val 0x%lx", type, len, val);
2313
2314 opt->type = type;
2315 opt->len = len;
2316
2317 switch (len) {
2318 case 1:
2319 *((u8 *) opt->val) = val;
2320 break;
2321
2322 case 2:
Al Viro8e036fc2007-07-29 00:16:36 -07002323 *((__le16 *) opt->val) = cpu_to_le16(val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002324 break;
2325
2326 case 4:
Al Viro8e036fc2007-07-29 00:16:36 -07002327 *((__le32 *) opt->val) = cpu_to_le32(val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002328 break;
2329
2330 default:
2331 memcpy(opt->val, (void *) val, len);
2332 break;
2333 }
2334
2335 *ptr += L2CAP_CONF_OPT_SIZE + len;
2336}
2337
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002338static void l2cap_ack_timeout(unsigned long arg)
2339{
2340 struct sock *sk = (void *) arg;
2341
2342 bh_lock_sock(sk);
2343 l2cap_send_ack(l2cap_pi(sk));
2344 bh_unlock_sock(sk);
2345}
2346
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002347static inline void l2cap_ertm_init(struct sock *sk)
2348{
2349 l2cap_pi(sk)->expected_ack_seq = 0;
2350 l2cap_pi(sk)->unacked_frames = 0;
2351 l2cap_pi(sk)->buffer_seq = 0;
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03002352 l2cap_pi(sk)->num_acked = 0;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03002353 l2cap_pi(sk)->frames_sent = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002354
2355 setup_timer(&l2cap_pi(sk)->retrans_timer,
2356 l2cap_retrans_timeout, (unsigned long) sk);
2357 setup_timer(&l2cap_pi(sk)->monitor_timer,
2358 l2cap_monitor_timeout, (unsigned long) sk);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002359 setup_timer(&l2cap_pi(sk)->ack_timer,
2360 l2cap_ack_timeout, (unsigned long) sk);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002361
2362 __skb_queue_head_init(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002363 __skb_queue_head_init(BUSY_QUEUE(sk));
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03002364 spin_lock_init(&l2cap_pi(sk)->send_lock);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002365
2366 INIT_WORK(&l2cap_pi(sk)->busy_work, l2cap_busy_work);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002367}
2368
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002369static int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
2370{
2371 u32 local_feat_mask = l2cap_feat_mask;
2372 if (enable_ertm)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002373 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002374
2375 switch (mode) {
2376 case L2CAP_MODE_ERTM:
2377 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
2378 case L2CAP_MODE_STREAMING:
2379 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
2380 default:
2381 return 0x00;
2382 }
2383}
2384
2385static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
2386{
2387 switch (mode) {
2388 case L2CAP_MODE_STREAMING:
2389 case L2CAP_MODE_ERTM:
2390 if (l2cap_mode_supported(mode, remote_feat_mask))
2391 return mode;
2392 /* fall through */
2393 default:
2394 return L2CAP_MODE_BASIC;
2395 }
2396}
2397
Linus Torvalds1da177e2005-04-16 15:20:36 -07002398static int l2cap_build_conf_req(struct sock *sk, void *data)
2399{
2400 struct l2cap_pinfo *pi = l2cap_pi(sk);
2401 struct l2cap_conf_req *req = data;
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03002402 struct l2cap_conf_rfc rfc = { .mode = pi->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07002403 void *ptr = req->data;
2404
2405 BT_DBG("sk %p", sk);
2406
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002407 if (pi->num_conf_req || pi->num_conf_rsp)
2408 goto done;
2409
2410 switch (pi->mode) {
2411 case L2CAP_MODE_STREAMING:
2412 case L2CAP_MODE_ERTM:
2413 pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002414 if (!l2cap_mode_supported(pi->mode, pi->conn->feat_mask))
2415 l2cap_send_disconn_req(pi->conn, sk);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002416 break;
2417 default:
2418 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
2419 break;
2420 }
2421
2422done:
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002423 switch (pi->mode) {
2424 case L2CAP_MODE_BASIC:
2425 if (pi->imtu != L2CAP_DEFAULT_MTU)
2426 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
2427 break;
2428
2429 case L2CAP_MODE_ERTM:
2430 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03002431 rfc.txwin_size = pi->tx_win;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03002432 rfc.max_transmit = pi->max_tx;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002433 rfc.retrans_timeout = 0;
2434 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002435 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03002436 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002437 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002438
2439 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2440 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002441
2442 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2443 break;
2444
2445 if (pi->fcs == L2CAP_FCS_NONE ||
2446 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
2447 pi->fcs = L2CAP_FCS_NONE;
2448 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
2449 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002450 break;
2451
2452 case L2CAP_MODE_STREAMING:
2453 rfc.mode = L2CAP_MODE_STREAMING;
2454 rfc.txwin_size = 0;
2455 rfc.max_transmit = 0;
2456 rfc.retrans_timeout = 0;
2457 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002458 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03002459 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002460 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002461
2462 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2463 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002464
2465 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2466 break;
2467
2468 if (pi->fcs == L2CAP_FCS_NONE ||
2469 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
2470 pi->fcs = L2CAP_FCS_NONE;
2471 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
2472 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002473 break;
2474 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002475
2476 /* FIXME: Need actual value of the flush timeout */
2477 //if (flush_to != L2CAP_DEFAULT_FLUSH_TO)
2478 // l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2, pi->flush_to);
2479
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002480 req->dcid = cpu_to_le16(pi->dcid);
2481 req->flags = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002482
2483 return ptr - data;
2484}
2485
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002486static int l2cap_parse_conf_req(struct sock *sk, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002487{
2488 struct l2cap_pinfo *pi = l2cap_pi(sk);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002489 struct l2cap_conf_rsp *rsp = data;
2490 void *ptr = rsp->data;
2491 void *req = pi->conf_req;
2492 int len = pi->conf_len;
2493 int type, hint, olen;
2494 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002495 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Marcel Holtmann861d6882007-10-20 13:37:06 +02002496 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002497 u16 result = L2CAP_CONF_SUCCESS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002498
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002499 BT_DBG("sk %p", sk);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01002500
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002501 while (len >= L2CAP_CONF_OPT_SIZE) {
2502 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002503
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03002504 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07002505 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002506
2507 switch (type) {
2508 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002509 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002510 break;
2511
2512 case L2CAP_CONF_FLUSH_TO:
2513 pi->flush_to = val;
2514 break;
2515
2516 case L2CAP_CONF_QOS:
2517 break;
2518
Marcel Holtmann6464f352007-10-20 13:39:51 +02002519 case L2CAP_CONF_RFC:
2520 if (olen == sizeof(rfc))
2521 memcpy(&rfc, (void *) val, olen);
2522 break;
2523
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002524 case L2CAP_CONF_FCS:
2525 if (val == L2CAP_FCS_NONE)
2526 pi->conf_state |= L2CAP_CONF_NO_FCS_RECV;
2527
2528 break;
2529
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002530 default:
2531 if (hint)
2532 break;
2533
2534 result = L2CAP_CONF_UNKNOWN;
2535 *((u8 *) ptr++) = type;
2536 break;
2537 }
2538 }
2539
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002540 if (pi->num_conf_rsp || pi->num_conf_req)
2541 goto done;
2542
2543 switch (pi->mode) {
2544 case L2CAP_MODE_STREAMING:
2545 case L2CAP_MODE_ERTM:
2546 pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
2547 if (!l2cap_mode_supported(pi->mode, pi->conn->feat_mask))
2548 return -ECONNREFUSED;
2549 break;
2550 default:
2551 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
2552 break;
2553 }
2554
2555done:
2556 if (pi->mode != rfc.mode) {
2557 result = L2CAP_CONF_UNACCEPT;
2558 rfc.mode = pi->mode;
2559
2560 if (pi->num_conf_rsp == 1)
2561 return -ECONNREFUSED;
2562
2563 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2564 sizeof(rfc), (unsigned long) &rfc);
2565 }
2566
2567
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002568 if (result == L2CAP_CONF_SUCCESS) {
2569 /* Configure output options and let the other side know
2570 * which ones we don't like. */
2571
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002572 if (mtu < L2CAP_DEFAULT_MIN_MTU)
2573 result = L2CAP_CONF_UNACCEPT;
2574 else {
2575 pi->omtu = mtu;
2576 pi->conf_state |= L2CAP_CONF_MTU_DONE;
2577 }
2578 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002579
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002580 switch (rfc.mode) {
2581 case L2CAP_MODE_BASIC:
2582 pi->fcs = L2CAP_FCS_NONE;
2583 pi->conf_state |= L2CAP_CONF_MODE_DONE;
2584 break;
2585
2586 case L2CAP_MODE_ERTM:
2587 pi->remote_tx_win = rfc.txwin_size;
2588 pi->remote_max_tx = rfc.max_transmit;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002589 if (rfc.max_pdu_size > pi->conn->mtu - 10)
2590 rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10);
2591
2592 pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002593
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002594 rfc.retrans_timeout =
2595 le16_to_cpu(L2CAP_DEFAULT_RETRANS_TO);
2596 rfc.monitor_timeout =
2597 le16_to_cpu(L2CAP_DEFAULT_MONITOR_TO);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002598
2599 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03002600
2601 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2602 sizeof(rfc), (unsigned long) &rfc);
2603
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002604 break;
2605
2606 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002607 if (rfc.max_pdu_size > pi->conn->mtu - 10)
2608 rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10);
2609
2610 pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002611
2612 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03002613
2614 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2615 sizeof(rfc), (unsigned long) &rfc);
2616
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002617 break;
2618
2619 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02002620 result = L2CAP_CONF_UNACCEPT;
2621
2622 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002623 rfc.mode = pi->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002624 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002625
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002626 if (result == L2CAP_CONF_SUCCESS)
2627 pi->conf_state |= L2CAP_CONF_OUTPUT_DONE;
2628 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002629 rsp->scid = cpu_to_le16(pi->dcid);
2630 rsp->result = cpu_to_le16(result);
2631 rsp->flags = cpu_to_le16(0x0000);
2632
2633 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002634}
2635
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002636static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data, u16 *result)
2637{
2638 struct l2cap_pinfo *pi = l2cap_pi(sk);
2639 struct l2cap_conf_req *req = data;
2640 void *ptr = req->data;
2641 int type, olen;
2642 unsigned long val;
2643 struct l2cap_conf_rfc rfc;
2644
2645 BT_DBG("sk %p, rsp %p, len %d, req %p", sk, rsp, len, data);
2646
2647 while (len >= L2CAP_CONF_OPT_SIZE) {
2648 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
2649
2650 switch (type) {
2651 case L2CAP_CONF_MTU:
2652 if (val < L2CAP_DEFAULT_MIN_MTU) {
2653 *result = L2CAP_CONF_UNACCEPT;
2654 pi->omtu = L2CAP_DEFAULT_MIN_MTU;
2655 } else
2656 pi->omtu = val;
2657 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
2658 break;
2659
2660 case L2CAP_CONF_FLUSH_TO:
2661 pi->flush_to = val;
2662 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
2663 2, pi->flush_to);
2664 break;
2665
2666 case L2CAP_CONF_RFC:
2667 if (olen == sizeof(rfc))
2668 memcpy(&rfc, (void *)val, olen);
2669
2670 if ((pi->conf_state & L2CAP_CONF_STATE2_DEVICE) &&
2671 rfc.mode != pi->mode)
2672 return -ECONNREFUSED;
2673
2674 pi->mode = rfc.mode;
2675 pi->fcs = 0;
2676
2677 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2678 sizeof(rfc), (unsigned long) &rfc);
2679 break;
2680 }
2681 }
2682
2683 if (*result == L2CAP_CONF_SUCCESS) {
2684 switch (rfc.mode) {
2685 case L2CAP_MODE_ERTM:
2686 pi->remote_tx_win = rfc.txwin_size;
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002687 pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
2688 pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002689 pi->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002690 break;
2691 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002692 pi->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002693 }
2694 }
2695
2696 req->dcid = cpu_to_le16(pi->dcid);
2697 req->flags = cpu_to_le16(0x0000);
2698
2699 return ptr - data;
2700}
2701
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002702static int l2cap_build_conf_rsp(struct sock *sk, void *data, u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002703{
2704 struct l2cap_conf_rsp *rsp = data;
2705 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002706
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002707 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002708
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002709 rsp->scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002710 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002711 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002712
2713 return ptr - data;
2714}
2715
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002716static void l2cap_conf_rfc_get(struct sock *sk, void *rsp, int len)
2717{
2718 struct l2cap_pinfo *pi = l2cap_pi(sk);
2719 int type, olen;
2720 unsigned long val;
2721 struct l2cap_conf_rfc rfc;
2722
2723 BT_DBG("sk %p, rsp %p, len %d", sk, rsp, len);
2724
2725 if ((pi->mode != L2CAP_MODE_ERTM) && (pi->mode != L2CAP_MODE_STREAMING))
2726 return;
2727
2728 while (len >= L2CAP_CONF_OPT_SIZE) {
2729 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
2730
2731 switch (type) {
2732 case L2CAP_CONF_RFC:
2733 if (olen == sizeof(rfc))
2734 memcpy(&rfc, (void *)val, olen);
2735 goto done;
2736 }
2737 }
2738
2739done:
2740 switch (rfc.mode) {
2741 case L2CAP_MODE_ERTM:
2742 pi->remote_tx_win = rfc.txwin_size;
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002743 pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
2744 pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002745 pi->mps = le16_to_cpu(rfc.max_pdu_size);
2746 break;
2747 case L2CAP_MODE_STREAMING:
2748 pi->mps = le16_to_cpu(rfc.max_pdu_size);
2749 }
2750}
2751
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002752static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2753{
2754 struct l2cap_cmd_rej *rej = (struct l2cap_cmd_rej *) data;
2755
2756 if (rej->reason != 0x0000)
2757 return 0;
2758
2759 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
2760 cmd->ident == conn->info_ident) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002761 del_timer(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01002762
2763 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002764 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01002765
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002766 l2cap_conn_start(conn);
2767 }
2768
2769 return 0;
2770}
2771
Linus Torvalds1da177e2005-04-16 15:20:36 -07002772static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2773{
2774 struct l2cap_chan_list *list = &conn->chan_list;
2775 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
2776 struct l2cap_conn_rsp rsp;
2777 struct sock *sk, *parent;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002778 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002779
2780 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002781 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002782
2783 BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
2784
2785 /* Check if we have socket listening on psm */
2786 parent = l2cap_get_sock_by_psm(BT_LISTEN, psm, conn->src);
2787 if (!parent) {
2788 result = L2CAP_CR_BAD_PSM;
2789 goto sendresp;
2790 }
2791
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002792 /* Check if the ACL is secure enough (if not SDP) */
2793 if (psm != cpu_to_le16(0x0001) &&
2794 !hci_conn_check_link_mode(conn->hcon)) {
Marcel Holtmann2950f212009-02-12 14:02:50 +01002795 conn->disc_reason = 0x05;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002796 result = L2CAP_CR_SEC_BLOCK;
2797 goto response;
2798 }
2799
Linus Torvalds1da177e2005-04-16 15:20:36 -07002800 result = L2CAP_CR_NO_MEM;
2801
2802 /* Check for backlog size */
2803 if (sk_acceptq_is_full(parent)) {
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09002804 BT_DBG("backlog full %d", parent->sk_ack_backlog);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002805 goto response;
2806 }
2807
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09002808 sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002809 if (!sk)
2810 goto response;
2811
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002812 write_lock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002813
2814 /* Check if we already have channel with that dcid */
2815 if (__l2cap_get_chan_by_dcid(list, scid)) {
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002816 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002817 sock_set_flag(sk, SOCK_ZAPPED);
2818 l2cap_sock_kill(sk);
2819 goto response;
2820 }
2821
2822 hci_conn_hold(conn->hcon);
2823
2824 l2cap_sock_init(sk, parent);
2825 bacpy(&bt_sk(sk)->src, conn->src);
2826 bacpy(&bt_sk(sk)->dst, conn->dst);
2827 l2cap_pi(sk)->psm = psm;
2828 l2cap_pi(sk)->dcid = scid;
2829
2830 __l2cap_chan_add(conn, sk, parent);
2831 dcid = l2cap_pi(sk)->scid;
2832
2833 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
2834
Linus Torvalds1da177e2005-04-16 15:20:36 -07002835 l2cap_pi(sk)->ident = cmd->ident;
2836
Marcel Holtmann984947d2009-02-06 23:35:19 +01002837 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002838 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002839 if (bt_sk(sk)->defer_setup) {
2840 sk->sk_state = BT_CONNECT2;
2841 result = L2CAP_CR_PEND;
2842 status = L2CAP_CS_AUTHOR_PEND;
2843 parent->sk_data_ready(parent, 0);
2844 } else {
2845 sk->sk_state = BT_CONFIG;
2846 result = L2CAP_CR_SUCCESS;
2847 status = L2CAP_CS_NO_INFO;
2848 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002849 } else {
2850 sk->sk_state = BT_CONNECT2;
2851 result = L2CAP_CR_PEND;
2852 status = L2CAP_CS_AUTHEN_PEND;
2853 }
2854 } else {
2855 sk->sk_state = BT_CONNECT2;
2856 result = L2CAP_CR_PEND;
2857 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002858 }
2859
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002860 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002861
2862response:
2863 bh_unlock_sock(parent);
2864
2865sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002866 rsp.scid = cpu_to_le16(scid);
2867 rsp.dcid = cpu_to_le16(dcid);
2868 rsp.result = cpu_to_le16(result);
2869 rsp.status = cpu_to_le16(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002870 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002871
2872 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
2873 struct l2cap_info_req info;
2874 info.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
2875
2876 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
2877 conn->info_ident = l2cap_get_ident(conn);
2878
2879 mod_timer(&conn->info_timer, jiffies +
2880 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
2881
2882 l2cap_send_cmd(conn, conn->info_ident,
2883 L2CAP_INFO_REQ, sizeof(info), &info);
2884 }
2885
Linus Torvalds1da177e2005-04-16 15:20:36 -07002886 return 0;
2887}
2888
2889static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2890{
2891 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
2892 u16 scid, dcid, result, status;
2893 struct sock *sk;
2894 u8 req[128];
2895
2896 scid = __le16_to_cpu(rsp->scid);
2897 dcid = __le16_to_cpu(rsp->dcid);
2898 result = __le16_to_cpu(rsp->result);
2899 status = __le16_to_cpu(rsp->status);
2900
2901 BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
2902
2903 if (scid) {
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002904 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2905 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002906 return 0;
2907 } else {
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002908 sk = l2cap_get_chan_by_ident(&conn->chan_list, cmd->ident);
2909 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002910 return 0;
2911 }
2912
2913 switch (result) {
2914 case L2CAP_CR_SUCCESS:
2915 sk->sk_state = BT_CONFIG;
2916 l2cap_pi(sk)->ident = 0;
2917 l2cap_pi(sk)->dcid = dcid;
2918 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002919 l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_CONNECT_PEND;
2920
Linus Torvalds1da177e2005-04-16 15:20:36 -07002921 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
2922 l2cap_build_conf_req(sk, req), req);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002923 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002924 break;
2925
2926 case L2CAP_CR_PEND:
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002927 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002928 break;
2929
2930 default:
2931 l2cap_chan_del(sk, ECONNREFUSED);
2932 break;
2933 }
2934
2935 bh_unlock_sock(sk);
2936 return 0;
2937}
2938
Al Viro88219a02007-07-29 00:17:25 -07002939static 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 -07002940{
2941 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
2942 u16 dcid, flags;
2943 u8 rsp[64];
2944 struct sock *sk;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002945 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002946
2947 dcid = __le16_to_cpu(req->dcid);
2948 flags = __le16_to_cpu(req->flags);
2949
2950 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
2951
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002952 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
2953 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002954 return -ENOENT;
2955
Marcel Holtmann354f60a2006-11-18 22:15:20 +01002956 if (sk->sk_state == BT_DISCONN)
2957 goto unlock;
2958
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002959 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07002960 len = cmd_len - sizeof(*req);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002961 if (l2cap_pi(sk)->conf_len + len > sizeof(l2cap_pi(sk)->conf_req)) {
2962 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
2963 l2cap_build_conf_rsp(sk, rsp,
2964 L2CAP_CONF_REJECT, flags), rsp);
2965 goto unlock;
2966 }
2967
2968 /* Store config. */
2969 memcpy(l2cap_pi(sk)->conf_req + l2cap_pi(sk)->conf_len, req->data, len);
2970 l2cap_pi(sk)->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002971
2972 if (flags & 0x0001) {
2973 /* Incomplete config. Send empty response. */
2974 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002975 l2cap_build_conf_rsp(sk, rsp,
2976 L2CAP_CONF_SUCCESS, 0x0001), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002977 goto unlock;
2978 }
2979
2980 /* Complete config. */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002981 len = l2cap_parse_conf_req(sk, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002982 if (len < 0) {
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002983 l2cap_send_disconn_req(conn, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002984 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002985 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002986
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002987 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002988 l2cap_pi(sk)->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002989
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002990 /* Reset config buffer. */
2991 l2cap_pi(sk)->conf_len = 0;
2992
Marcel Holtmann876d9482007-10-20 13:35:42 +02002993 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE))
2994 goto unlock;
2995
Linus Torvalds1da177e2005-04-16 15:20:36 -07002996 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) {
Joe Perchesf64f9e72009-11-29 16:55:45 -08002997 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) ||
2998 l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002999 l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
3000
Linus Torvalds1da177e2005-04-16 15:20:36 -07003001 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003002
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003003 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003004 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003005 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003006 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
3007 l2cap_ertm_init(sk);
3008
Linus Torvalds1da177e2005-04-16 15:20:36 -07003009 l2cap_chan_ready(sk);
Marcel Holtmann876d9482007-10-20 13:35:42 +02003010 goto unlock;
3011 }
3012
3013 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003014 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003015 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003016 l2cap_build_conf_req(sk, buf), buf);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003017 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003018 }
3019
3020unlock:
3021 bh_unlock_sock(sk);
3022 return 0;
3023}
3024
3025static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3026{
3027 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
3028 u16 scid, flags, result;
3029 struct sock *sk;
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003030 int len = cmd->len - sizeof(*rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003031
3032 scid = __le16_to_cpu(rsp->scid);
3033 flags = __le16_to_cpu(rsp->flags);
3034 result = __le16_to_cpu(rsp->result);
3035
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03003036 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x",
3037 scid, flags, result);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003038
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03003039 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
3040 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003041 return 0;
3042
3043 switch (result) {
3044 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003045 l2cap_conf_rfc_get(sk, rsp->data, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003046 break;
3047
3048 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003049 if (l2cap_pi(sk)->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003050 char req[64];
3051
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02003052 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
3053 l2cap_send_disconn_req(conn, sk);
3054 goto done;
3055 }
3056
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003057 /* throw out any old stored conf requests */
3058 result = L2CAP_CONF_SUCCESS;
3059 len = l2cap_parse_conf_rsp(sk, rsp->data,
3060 len, req, &result);
3061 if (len < 0) {
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03003062 l2cap_send_disconn_req(conn, sk);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003063 goto done;
3064 }
3065
3066 l2cap_send_cmd(conn, l2cap_get_ident(conn),
3067 L2CAP_CONF_REQ, len, req);
3068 l2cap_pi(sk)->num_conf_req++;
3069 if (result != L2CAP_CONF_SUCCESS)
3070 goto done;
3071 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003072 }
3073
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09003074 default:
Linus Torvalds1da177e2005-04-16 15:20:36 -07003075 sk->sk_state = BT_DISCONN;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02003076 sk->sk_err = ECONNRESET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003077 l2cap_sock_set_timer(sk, HZ * 5);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03003078 l2cap_send_disconn_req(conn, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003079 goto done;
3080 }
3081
3082 if (flags & 0x01)
3083 goto done;
3084
Linus Torvalds1da177e2005-04-16 15:20:36 -07003085 l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE;
3086
3087 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) {
Joe Perchesf64f9e72009-11-29 16:55:45 -08003088 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) ||
3089 l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003090 l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
3091
Linus Torvalds1da177e2005-04-16 15:20:36 -07003092 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003093 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003094 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003095 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003096 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
3097 l2cap_ertm_init(sk);
3098
Linus Torvalds1da177e2005-04-16 15:20:36 -07003099 l2cap_chan_ready(sk);
3100 }
3101
3102done:
3103 bh_unlock_sock(sk);
3104 return 0;
3105}
3106
3107static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3108{
3109 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
3110 struct l2cap_disconn_rsp rsp;
3111 u16 dcid, scid;
3112 struct sock *sk;
3113
3114 scid = __le16_to_cpu(req->scid);
3115 dcid = __le16_to_cpu(req->dcid);
3116
3117 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
3118
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03003119 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
3120 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003121 return 0;
3122
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003123 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
3124 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003125 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
3126
3127 sk->sk_shutdown = SHUTDOWN_MASK;
3128
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003129 skb_queue_purge(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003130
3131 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
3132 skb_queue_purge(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003133 skb_queue_purge(BUSY_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003134 del_timer(&l2cap_pi(sk)->retrans_timer);
3135 del_timer(&l2cap_pi(sk)->monitor_timer);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003136 del_timer(&l2cap_pi(sk)->ack_timer);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003137 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003138
Linus Torvalds1da177e2005-04-16 15:20:36 -07003139 l2cap_chan_del(sk, ECONNRESET);
3140 bh_unlock_sock(sk);
3141
3142 l2cap_sock_kill(sk);
3143 return 0;
3144}
3145
3146static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3147{
3148 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
3149 u16 dcid, scid;
3150 struct sock *sk;
3151
3152 scid = __le16_to_cpu(rsp->scid);
3153 dcid = __le16_to_cpu(rsp->dcid);
3154
3155 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
3156
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03003157 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
3158 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003159 return 0;
3160
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003161 skb_queue_purge(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003162
3163 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
3164 skb_queue_purge(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003165 skb_queue_purge(BUSY_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003166 del_timer(&l2cap_pi(sk)->retrans_timer);
3167 del_timer(&l2cap_pi(sk)->monitor_timer);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003168 del_timer(&l2cap_pi(sk)->ack_timer);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003169 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003170
Linus Torvalds1da177e2005-04-16 15:20:36 -07003171 l2cap_chan_del(sk, 0);
3172 bh_unlock_sock(sk);
3173
3174 l2cap_sock_kill(sk);
3175 return 0;
3176}
3177
3178static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3179{
3180 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003181 u16 type;
3182
3183 type = __le16_to_cpu(req->type);
3184
3185 BT_DBG("type 0x%4.4x", type);
3186
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003187 if (type == L2CAP_IT_FEAT_MASK) {
3188 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003189 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003190 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
3191 rsp->type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
3192 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003193 if (enable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003194 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
3195 | L2CAP_FEAT_FCS;
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03003196 put_unaligned_le32(feat_mask, rsp->data);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003197 l2cap_send_cmd(conn, cmd->ident,
3198 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003199 } else if (type == L2CAP_IT_FIXED_CHAN) {
3200 u8 buf[12];
3201 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
3202 rsp->type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3203 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
3204 memcpy(buf + 4, l2cap_fixed_chan, 8);
3205 l2cap_send_cmd(conn, cmd->ident,
3206 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003207 } else {
3208 struct l2cap_info_rsp rsp;
3209 rsp.type = cpu_to_le16(type);
3210 rsp.result = cpu_to_le16(L2CAP_IR_NOTSUPP);
3211 l2cap_send_cmd(conn, cmd->ident,
3212 L2CAP_INFO_RSP, sizeof(rsp), &rsp);
3213 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003214
3215 return 0;
3216}
3217
3218static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3219{
3220 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
3221 u16 type, result;
3222
3223 type = __le16_to_cpu(rsp->type);
3224 result = __le16_to_cpu(rsp->result);
3225
3226 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
3227
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003228 del_timer(&conn->info_timer);
3229
Marcel Holtmann984947d2009-02-06 23:35:19 +01003230 if (type == L2CAP_IT_FEAT_MASK) {
Harvey Harrison83985312008-05-02 16:25:46 -07003231 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003232
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003233 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003234 struct l2cap_info_req req;
3235 req.type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3236
3237 conn->info_ident = l2cap_get_ident(conn);
3238
3239 l2cap_send_cmd(conn, conn->info_ident,
3240 L2CAP_INFO_REQ, sizeof(req), &req);
3241 } else {
3242 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
3243 conn->info_ident = 0;
3244
3245 l2cap_conn_start(conn);
3246 }
3247 } else if (type == L2CAP_IT_FIXED_CHAN) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01003248 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003249 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003250
3251 l2cap_conn_start(conn);
3252 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003253
Linus Torvalds1da177e2005-04-16 15:20:36 -07003254 return 0;
3255}
3256
3257static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
3258{
3259 u8 *data = skb->data;
3260 int len = skb->len;
3261 struct l2cap_cmd_hdr cmd;
3262 int err = 0;
3263
3264 l2cap_raw_recv(conn, skb);
3265
3266 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07003267 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003268 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
3269 data += L2CAP_CMD_HDR_SIZE;
3270 len -= L2CAP_CMD_HDR_SIZE;
3271
Al Viro88219a02007-07-29 00:17:25 -07003272 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003273
Al Viro88219a02007-07-29 00:17:25 -07003274 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 -07003275
Al Viro88219a02007-07-29 00:17:25 -07003276 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003277 BT_DBG("corrupted command");
3278 break;
3279 }
3280
3281 switch (cmd.code) {
3282 case L2CAP_COMMAND_REJ:
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003283 l2cap_command_rej(conn, &cmd, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003284 break;
3285
3286 case L2CAP_CONN_REQ:
3287 err = l2cap_connect_req(conn, &cmd, data);
3288 break;
3289
3290 case L2CAP_CONN_RSP:
3291 err = l2cap_connect_rsp(conn, &cmd, data);
3292 break;
3293
3294 case L2CAP_CONF_REQ:
Al Viro88219a02007-07-29 00:17:25 -07003295 err = l2cap_config_req(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003296 break;
3297
3298 case L2CAP_CONF_RSP:
3299 err = l2cap_config_rsp(conn, &cmd, data);
3300 break;
3301
3302 case L2CAP_DISCONN_REQ:
3303 err = l2cap_disconnect_req(conn, &cmd, data);
3304 break;
3305
3306 case L2CAP_DISCONN_RSP:
3307 err = l2cap_disconnect_rsp(conn, &cmd, data);
3308 break;
3309
3310 case L2CAP_ECHO_REQ:
Al Viro88219a02007-07-29 00:17:25 -07003311 l2cap_send_cmd(conn, cmd.ident, L2CAP_ECHO_RSP, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003312 break;
3313
3314 case L2CAP_ECHO_RSP:
3315 break;
3316
3317 case L2CAP_INFO_REQ:
3318 err = l2cap_information_req(conn, &cmd, data);
3319 break;
3320
3321 case L2CAP_INFO_RSP:
3322 err = l2cap_information_rsp(conn, &cmd, data);
3323 break;
3324
3325 default:
3326 BT_ERR("Unknown signaling command 0x%2.2x", cmd.code);
3327 err = -EINVAL;
3328 break;
3329 }
3330
3331 if (err) {
3332 struct l2cap_cmd_rej rej;
3333 BT_DBG("error %d", err);
3334
3335 /* FIXME: Map err to a valid reason */
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003336 rej.reason = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003337 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
3338 }
3339
Al Viro88219a02007-07-29 00:17:25 -07003340 data += cmd_len;
3341 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003342 }
3343
3344 kfree_skb(skb);
3345}
3346
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003347static int l2cap_check_fcs(struct l2cap_pinfo *pi, struct sk_buff *skb)
3348{
3349 u16 our_fcs, rcv_fcs;
3350 int hdr_size = L2CAP_HDR_SIZE + 2;
3351
3352 if (pi->fcs == L2CAP_FCS_CRC16) {
3353 skb_trim(skb, skb->len - 2);
3354 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
3355 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
3356
3357 if (our_fcs != rcv_fcs)
3358 return -EINVAL;
3359 }
3360 return 0;
3361}
3362
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003363static inline void l2cap_send_i_or_rr_or_rnr(struct sock *sk)
3364{
3365 struct l2cap_pinfo *pi = l2cap_pi(sk);
3366 u16 control = 0;
3367
3368 pi->frames_sent = 0;
3369 pi->conn_state |= L2CAP_CONN_SEND_FBIT;
3370
3371 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3372
3373 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
3374 control |= L2CAP_SUPER_RCV_NOT_READY | L2CAP_CTRL_FINAL;
3375 l2cap_send_sframe(pi, control);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003376 pi->conn_state |= L2CAP_CONN_RNR_SENT;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003377 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
3378 }
3379
3380 if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY && pi->unacked_frames > 0)
3381 __mod_retrans_timer();
3382
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003383 spin_lock_bh(&pi->send_lock);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003384 l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003385 spin_unlock_bh(&pi->send_lock);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003386
3387 if (!(pi->conn_state & L2CAP_CONN_LOCAL_BUSY) &&
3388 pi->frames_sent == 0) {
3389 control |= L2CAP_SUPER_RCV_READY;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003390 l2cap_send_sframe(pi, control);
3391 }
3392}
3393
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003394static 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 -03003395{
3396 struct sk_buff *next_skb;
João Paulo Rechi Vitabfbacc12010-05-31 18:35:44 -03003397 struct l2cap_pinfo *pi = l2cap_pi(sk);
3398 int tx_seq_offset, next_tx_seq_offset;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003399
3400 bt_cb(skb)->tx_seq = tx_seq;
3401 bt_cb(skb)->sar = sar;
3402
3403 next_skb = skb_peek(SREJ_QUEUE(sk));
3404 if (!next_skb) {
3405 __skb_queue_tail(SREJ_QUEUE(sk), skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003406 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003407 }
3408
João Paulo Rechi Vitabfbacc12010-05-31 18:35:44 -03003409 tx_seq_offset = (tx_seq - pi->buffer_seq) % 64;
3410 if (tx_seq_offset < 0)
3411 tx_seq_offset += 64;
3412
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003413 do {
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003414 if (bt_cb(next_skb)->tx_seq == tx_seq)
3415 return -EINVAL;
3416
João Paulo Rechi Vitabfbacc12010-05-31 18:35:44 -03003417 next_tx_seq_offset = (bt_cb(next_skb)->tx_seq -
3418 pi->buffer_seq) % 64;
3419 if (next_tx_seq_offset < 0)
3420 next_tx_seq_offset += 64;
3421
3422 if (next_tx_seq_offset > tx_seq_offset) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003423 __skb_queue_before(SREJ_QUEUE(sk), next_skb, skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003424 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003425 }
3426
3427 if (skb_queue_is_last(SREJ_QUEUE(sk), next_skb))
3428 break;
3429
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003430 } while ((next_skb = skb_queue_next(SREJ_QUEUE(sk), next_skb)));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003431
3432 __skb_queue_tail(SREJ_QUEUE(sk), skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003433
3434 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003435}
3436
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003437static int l2cap_ertm_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
3438{
3439 struct l2cap_pinfo *pi = l2cap_pi(sk);
3440 struct sk_buff *_skb;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003441 int err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003442
3443 switch (control & L2CAP_CTRL_SAR) {
3444 case L2CAP_SDU_UNSEGMENTED:
3445 if (pi->conn_state & L2CAP_CONN_SAR_SDU)
3446 goto drop;
3447
3448 err = sock_queue_rcv_skb(sk, skb);
3449 if (!err)
3450 return err;
3451
3452 break;
3453
3454 case L2CAP_SDU_START:
3455 if (pi->conn_state & L2CAP_CONN_SAR_SDU)
3456 goto drop;
3457
3458 pi->sdu_len = get_unaligned_le16(skb->data);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003459
3460 if (pi->sdu_len > pi->imtu)
3461 goto disconnect;
3462
3463 pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003464 if (!pi->sdu)
3465 return -ENOMEM;
3466
3467 /* pull sdu_len bytes only after alloc, because of Local Busy
3468 * condition we have to be sure that this will be executed
3469 * only once, i.e., when alloc does not fail */
3470 skb_pull(skb, 2);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003471
3472 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3473
3474 pi->conn_state |= L2CAP_CONN_SAR_SDU;
3475 pi->partial_sdu_len = skb->len;
3476 break;
3477
3478 case L2CAP_SDU_CONTINUE:
3479 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3480 goto disconnect;
3481
3482 if (!pi->sdu)
3483 goto disconnect;
3484
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003485 pi->partial_sdu_len += skb->len;
3486 if (pi->partial_sdu_len > pi->sdu_len)
3487 goto drop;
3488
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03003489 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3490
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003491 break;
3492
3493 case L2CAP_SDU_END:
3494 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3495 goto disconnect;
3496
3497 if (!pi->sdu)
3498 goto disconnect;
3499
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003500 if (!(pi->conn_state & L2CAP_CONN_SAR_RETRY)) {
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003501 pi->partial_sdu_len += skb->len;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003502
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003503 if (pi->partial_sdu_len > pi->imtu)
3504 goto drop;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003505
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003506 if (pi->partial_sdu_len != pi->sdu_len)
3507 goto drop;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03003508
3509 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003510 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003511
3512 _skb = skb_clone(pi->sdu, GFP_ATOMIC);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003513 if (!_skb) {
3514 pi->conn_state |= L2CAP_CONN_SAR_RETRY;
3515 return -ENOMEM;
3516 }
3517
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003518 err = sock_queue_rcv_skb(sk, _skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003519 if (err < 0) {
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003520 kfree_skb(_skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003521 pi->conn_state |= L2CAP_CONN_SAR_RETRY;
3522 return err;
3523 }
3524
3525 pi->conn_state &= ~L2CAP_CONN_SAR_RETRY;
3526 pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003527
3528 kfree_skb(pi->sdu);
3529 break;
3530 }
3531
3532 kfree_skb(skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003533 return 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003534
3535drop:
3536 kfree_skb(pi->sdu);
3537 pi->sdu = NULL;
3538
3539disconnect:
3540 l2cap_send_disconn_req(pi->conn, sk);
3541 kfree_skb(skb);
3542 return 0;
3543}
3544
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003545static void l2cap_busy_work(struct work_struct *work)
3546{
3547 DECLARE_WAITQUEUE(wait, current);
3548 struct l2cap_pinfo *pi =
3549 container_of(work, struct l2cap_pinfo, busy_work);
3550 struct sock *sk = (struct sock *)pi;
3551 int n_tries = 0, timeo = HZ/5, err;
3552 struct sk_buff *skb;
3553 u16 control;
3554
3555 lock_sock(sk);
3556
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02003557 add_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003558 while ((skb = skb_peek(BUSY_QUEUE(sk)))) {
3559 set_current_state(TASK_INTERRUPTIBLE);
3560
3561 if (n_tries++ > L2CAP_LOCAL_BUSY_TRIES) {
3562 err = -EBUSY;
3563 l2cap_send_disconn_req(pi->conn, sk);
3564 goto done;
3565 }
3566
3567 if (!timeo)
3568 timeo = HZ/5;
3569
3570 if (signal_pending(current)) {
3571 err = sock_intr_errno(timeo);
3572 goto done;
3573 }
3574
3575 release_sock(sk);
3576 timeo = schedule_timeout(timeo);
3577 lock_sock(sk);
3578
3579 err = sock_error(sk);
3580 if (err)
3581 goto done;
3582
3583 while ((skb = skb_dequeue(BUSY_QUEUE(sk)))) {
3584 control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
3585 err = l2cap_ertm_reassembly_sdu(sk, skb, control);
3586 if (err < 0) {
3587 skb_queue_head(BUSY_QUEUE(sk), skb);
3588 break;
3589 }
3590
3591 pi->buffer_seq = (pi->buffer_seq + 1) % 64;
3592 }
3593
3594 if (!skb)
3595 break;
3596 }
3597
3598 if (!(pi->conn_state & L2CAP_CONN_RNR_SENT))
3599 goto done;
3600
3601 control = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3602 control |= L2CAP_SUPER_RCV_READY | L2CAP_CTRL_POLL;
3603 l2cap_send_sframe(pi, control);
3604 l2cap_pi(sk)->retry_count = 1;
3605
3606 del_timer(&pi->retrans_timer);
3607 __mod_monitor_timer();
3608
3609 l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
3610
3611done:
3612 pi->conn_state &= ~L2CAP_CONN_LOCAL_BUSY;
3613 pi->conn_state &= ~L2CAP_CONN_RNR_SENT;
3614
3615 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02003616 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003617
3618 release_sock(sk);
3619}
3620
3621static int l2cap_push_rx_skb(struct sock *sk, struct sk_buff *skb, u16 control)
3622{
3623 struct l2cap_pinfo *pi = l2cap_pi(sk);
3624 int sctrl, err;
3625
3626 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
3627 bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT;
3628 __skb_queue_tail(BUSY_QUEUE(sk), skb);
3629 return -EBUSY;
3630 }
3631
3632 err = l2cap_ertm_reassembly_sdu(sk, skb, control);
3633 if (err >= 0) {
3634 pi->buffer_seq = (pi->buffer_seq + 1) % 64;
3635 return err;
3636 }
3637
3638 /* Busy Condition */
3639 pi->conn_state |= L2CAP_CONN_LOCAL_BUSY;
3640 bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT;
3641 __skb_queue_tail(BUSY_QUEUE(sk), skb);
3642
3643 sctrl = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3644 sctrl |= L2CAP_SUPER_RCV_NOT_READY;
3645 l2cap_send_sframe(pi, sctrl);
3646
3647 pi->conn_state |= L2CAP_CONN_RNR_SENT;
3648
3649 queue_work(_busy_wq, &pi->busy_work);
3650
3651 return err;
3652}
3653
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003654static int l2cap_streaming_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003655{
3656 struct l2cap_pinfo *pi = l2cap_pi(sk);
3657 struct sk_buff *_skb;
3658 int err = -EINVAL;
3659
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003660 /*
3661 * TODO: We have to notify the userland if some data is lost with the
3662 * Streaming Mode.
3663 */
3664
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003665 switch (control & L2CAP_CTRL_SAR) {
3666 case L2CAP_SDU_UNSEGMENTED:
3667 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3668 kfree_skb(pi->sdu);
3669 break;
3670 }
3671
3672 err = sock_queue_rcv_skb(sk, skb);
3673 if (!err)
3674 return 0;
3675
3676 break;
3677
3678 case L2CAP_SDU_START:
3679 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3680 kfree_skb(pi->sdu);
3681 break;
3682 }
3683
3684 pi->sdu_len = get_unaligned_le16(skb->data);
3685 skb_pull(skb, 2);
3686
Gustavo F. Padovan052897c2010-05-01 16:15:40 -03003687 if (pi->sdu_len > pi->imtu) {
3688 err = -EMSGSIZE;
3689 break;
3690 }
3691
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003692 pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
3693 if (!pi->sdu) {
3694 err = -ENOMEM;
3695 break;
3696 }
3697
3698 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3699
3700 pi->conn_state |= L2CAP_CONN_SAR_SDU;
3701 pi->partial_sdu_len = skb->len;
3702 err = 0;
3703 break;
3704
3705 case L2CAP_SDU_CONTINUE:
3706 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3707 break;
3708
3709 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3710
3711 pi->partial_sdu_len += skb->len;
3712 if (pi->partial_sdu_len > pi->sdu_len)
3713 kfree_skb(pi->sdu);
3714 else
3715 err = 0;
3716
3717 break;
3718
3719 case L2CAP_SDU_END:
3720 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3721 break;
3722
3723 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3724
3725 pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
3726 pi->partial_sdu_len += skb->len;
3727
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003728 if (pi->partial_sdu_len > pi->imtu)
3729 goto drop;
3730
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003731 if (pi->partial_sdu_len == pi->sdu_len) {
3732 _skb = skb_clone(pi->sdu, GFP_ATOMIC);
3733 err = sock_queue_rcv_skb(sk, _skb);
3734 if (err < 0)
3735 kfree_skb(_skb);
3736 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003737 err = 0;
3738
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003739drop:
3740 kfree_skb(pi->sdu);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003741 break;
3742 }
3743
3744 kfree_skb(skb);
3745 return err;
3746}
3747
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003748static void l2cap_check_srej_gap(struct sock *sk, u8 tx_seq)
3749{
3750 struct sk_buff *skb;
Gustavo F. Padovanafefdbc2010-05-01 16:15:43 -03003751 u16 control;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003752
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003753 while ((skb = skb_peek(SREJ_QUEUE(sk)))) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003754 if (bt_cb(skb)->tx_seq != tx_seq)
3755 break;
3756
3757 skb = skb_dequeue(SREJ_QUEUE(sk));
Gustavo F. Padovanafefdbc2010-05-01 16:15:43 -03003758 control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003759 l2cap_ertm_reassembly_sdu(sk, skb, control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003760 l2cap_pi(sk)->buffer_seq_srej =
3761 (l2cap_pi(sk)->buffer_seq_srej + 1) % 64;
Gustavo F. Padovan8ff50ec2010-05-10 19:34:11 -03003762 tx_seq = (tx_seq + 1) % 64;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003763 }
3764}
3765
3766static void l2cap_resend_srejframe(struct sock *sk, u8 tx_seq)
3767{
3768 struct l2cap_pinfo *pi = l2cap_pi(sk);
3769 struct srej_list *l, *tmp;
3770 u16 control;
3771
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003772 list_for_each_entry_safe(l, tmp, SREJ_LIST(sk), list) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003773 if (l->tx_seq == tx_seq) {
3774 list_del(&l->list);
3775 kfree(l);
3776 return;
3777 }
3778 control = L2CAP_SUPER_SELECT_REJECT;
3779 control |= l->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3780 l2cap_send_sframe(pi, control);
3781 list_del(&l->list);
3782 list_add_tail(&l->list, SREJ_LIST(sk));
3783 }
3784}
3785
3786static void l2cap_send_srejframe(struct sock *sk, u8 tx_seq)
3787{
3788 struct l2cap_pinfo *pi = l2cap_pi(sk);
3789 struct srej_list *new;
3790 u16 control;
3791
3792 while (tx_seq != pi->expected_tx_seq) {
3793 control = L2CAP_SUPER_SELECT_REJECT;
3794 control |= pi->expected_tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3795 l2cap_send_sframe(pi, control);
3796
3797 new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC);
Gustavo F. Padovan8ff50ec2010-05-10 19:34:11 -03003798 new->tx_seq = pi->expected_tx_seq;
3799 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003800 list_add_tail(&new->list, SREJ_LIST(sk));
3801 }
Gustavo F. Padovan8ff50ec2010-05-10 19:34:11 -03003802 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003803}
3804
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003805static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
3806{
3807 struct l2cap_pinfo *pi = l2cap_pi(sk);
3808 u8 tx_seq = __get_txseq(rx_control);
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003809 u8 req_seq = __get_reqseq(rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003810 u8 sar = rx_control >> L2CAP_CTRL_SAR_SHIFT;
Gustavo F. Padovanf6337c72010-05-10 18:32:04 -03003811 int tx_seq_offset, expected_tx_seq_offset;
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03003812 int num_to_ack = (pi->tx_win/6) + 1;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003813 int err = 0;
3814
3815 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
3816
Gustavo F. Padovan9b16dc62010-05-05 20:05:57 -03003817 if (L2CAP_CTRL_FINAL & rx_control &&
3818 l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) {
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003819 del_timer(&pi->monitor_timer);
3820 if (pi->unacked_frames > 0)
3821 __mod_retrans_timer();
3822 pi->conn_state &= ~L2CAP_CONN_WAIT_F;
3823 }
3824
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003825 pi->expected_ack_seq = req_seq;
3826 l2cap_drop_acked_frames(sk);
3827
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003828 if (tx_seq == pi->expected_tx_seq)
3829 goto expected;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003830
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003831 tx_seq_offset = (tx_seq - pi->buffer_seq) % 64;
3832 if (tx_seq_offset < 0)
3833 tx_seq_offset += 64;
3834
3835 /* invalid tx_seq */
3836 if (tx_seq_offset >= pi->tx_win) {
3837 l2cap_send_disconn_req(pi->conn, sk);
3838 goto drop;
3839 }
3840
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003841 if (pi->conn_state == L2CAP_CONN_LOCAL_BUSY)
3842 goto drop;
3843
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003844 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3845 struct srej_list *first;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003846
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003847 first = list_first_entry(SREJ_LIST(sk),
3848 struct srej_list, list);
3849 if (tx_seq == first->tx_seq) {
3850 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3851 l2cap_check_srej_gap(sk, tx_seq);
3852
3853 list_del(&first->list);
3854 kfree(first);
3855
3856 if (list_empty(SREJ_LIST(sk))) {
3857 pi->buffer_seq = pi->buffer_seq_srej;
3858 pi->conn_state &= ~L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan855666c2010-05-01 16:15:40 -03003859 l2cap_send_ack(pi);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003860 }
3861 } else {
3862 struct srej_list *l;
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003863
3864 /* duplicated tx_seq */
3865 if (l2cap_add_to_srej_queue(sk, skb, tx_seq, sar) < 0)
3866 goto drop;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003867
3868 list_for_each_entry(l, SREJ_LIST(sk), list) {
3869 if (l->tx_seq == tx_seq) {
3870 l2cap_resend_srejframe(sk, tx_seq);
3871 return 0;
3872 }
3873 }
3874 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003875 }
3876 } else {
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003877 expected_tx_seq_offset =
3878 (pi->expected_tx_seq - pi->buffer_seq) % 64;
3879 if (expected_tx_seq_offset < 0)
3880 expected_tx_seq_offset += 64;
3881
3882 /* duplicated tx_seq */
3883 if (tx_seq_offset < expected_tx_seq_offset)
3884 goto drop;
3885
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003886 pi->conn_state |= L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003887
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003888 INIT_LIST_HEAD(SREJ_LIST(sk));
3889 pi->buffer_seq_srej = pi->buffer_seq;
3890
3891 __skb_queue_head_init(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003892 __skb_queue_head_init(BUSY_QUEUE(sk));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003893 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3894
Gustavo F. Padovanef54fd92009-08-20 22:26:04 -03003895 pi->conn_state |= L2CAP_CONN_SEND_PBIT;
3896
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003897 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003898 }
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003899 return 0;
3900
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003901expected:
3902 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
3903
3904 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
Gustavo F. Padovan3b1a9f32010-05-01 16:15:42 -03003905 bt_cb(skb)->tx_seq = tx_seq;
3906 bt_cb(skb)->sar = sar;
3907 __skb_queue_tail(SREJ_QUEUE(sk), skb);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003908 return 0;
3909 }
3910
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03003911 if (rx_control & L2CAP_CTRL_FINAL) {
3912 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3913 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003914 else
3915 l2cap_retransmit_frames(sk);
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03003916 }
3917
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003918 err = l2cap_push_rx_skb(sk, skb, rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003919 if (err < 0)
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003920 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003921
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003922 __mod_ack_timer();
3923
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03003924 pi->num_acked = (pi->num_acked + 1) % num_to_ack;
3925 if (pi->num_acked == num_to_ack - 1)
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03003926 l2cap_send_ack(pi);
3927
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003928 return 0;
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003929
3930drop:
3931 kfree_skb(skb);
3932 return 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003933}
3934
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003935static inline void l2cap_data_channel_rrframe(struct sock *sk, u16 rx_control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003936{
3937 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan6e3a5982010-05-01 16:15:38 -03003938
3939 pi->expected_ack_seq = __get_reqseq(rx_control);
3940 l2cap_drop_acked_frames(sk);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003941
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003942 if (rx_control & L2CAP_CTRL_POLL) {
Gustavo F. Padovan05fbd892010-05-01 16:15:39 -03003943 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3944 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
3945 (pi->unacked_frames > 0))
3946 __mod_retrans_timer();
3947
3948 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3949 l2cap_send_srejtail(sk);
3950 } else {
3951 l2cap_send_i_or_rr_or_rnr(sk);
Gustavo F. Padovan05fbd892010-05-01 16:15:39 -03003952 }
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003953
3954 } else if (rx_control & L2CAP_CTRL_FINAL) {
3955 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003956
3957 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3958 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003959 else
3960 l2cap_retransmit_frames(sk);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003961
3962 } else {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003963 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
3964 (pi->unacked_frames > 0))
3965 __mod_retrans_timer();
3966
3967 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003968 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003969 l2cap_send_ack(pi);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003970 } else {
3971 spin_lock_bh(&pi->send_lock);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003972 l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003973 spin_unlock_bh(&pi->send_lock);
3974 }
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003975 }
3976}
3977
3978static inline void l2cap_data_channel_rejframe(struct sock *sk, u16 rx_control)
3979{
3980 struct l2cap_pinfo *pi = l2cap_pi(sk);
3981 u8 tx_seq = __get_reqseq(rx_control);
3982
3983 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3984
Gustavo F. Padovan8abb52e2010-05-01 16:15:38 -03003985 pi->expected_ack_seq = tx_seq;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003986 l2cap_drop_acked_frames(sk);
3987
3988 if (rx_control & L2CAP_CTRL_FINAL) {
3989 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3990 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003991 else
3992 l2cap_retransmit_frames(sk);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003993 } else {
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003994 l2cap_retransmit_frames(sk);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003995
Gustavo F. Padovan0301ef02010-05-05 20:56:43 -03003996 if (pi->conn_state & L2CAP_CONN_WAIT_F)
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003997 pi->conn_state |= L2CAP_CONN_REJ_ACT;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003998 }
3999}
4000static inline void l2cap_data_channel_srejframe(struct sock *sk, u16 rx_control)
4001{
4002 struct l2cap_pinfo *pi = l2cap_pi(sk);
4003 u8 tx_seq = __get_reqseq(rx_control);
4004
4005 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
4006
4007 if (rx_control & L2CAP_CTRL_POLL) {
4008 pi->expected_ack_seq = tx_seq;
4009 l2cap_drop_acked_frames(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004010 l2cap_retransmit_one_frame(sk, tx_seq);
4011
4012 spin_lock_bh(&pi->send_lock);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004013 l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004014 spin_unlock_bh(&pi->send_lock);
4015
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004016 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
4017 pi->srej_save_reqseq = tx_seq;
4018 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
4019 }
4020 } else if (rx_control & L2CAP_CTRL_FINAL) {
4021 if ((pi->conn_state & L2CAP_CONN_SREJ_ACT) &&
4022 pi->srej_save_reqseq == tx_seq)
4023 pi->conn_state &= ~L2CAP_CONN_SREJ_ACT;
4024 else
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004025 l2cap_retransmit_one_frame(sk, tx_seq);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004026 } else {
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004027 l2cap_retransmit_one_frame(sk, tx_seq);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004028 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
4029 pi->srej_save_reqseq = tx_seq;
4030 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
4031 }
4032 }
4033}
4034
4035static inline void l2cap_data_channel_rnrframe(struct sock *sk, u16 rx_control)
4036{
4037 struct l2cap_pinfo *pi = l2cap_pi(sk);
4038 u8 tx_seq = __get_reqseq(rx_control);
4039
4040 pi->conn_state |= L2CAP_CONN_REMOTE_BUSY;
4041 pi->expected_ack_seq = tx_seq;
4042 l2cap_drop_acked_frames(sk);
4043
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03004044 if (!(pi->conn_state & L2CAP_CONN_SREJ_SENT)) {
4045 del_timer(&pi->retrans_timer);
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -03004046 if (rx_control & L2CAP_CTRL_POLL)
4047 l2cap_send_rr_or_rnr(pi, L2CAP_CTRL_FINAL);
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03004048 return;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004049 }
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03004050
4051 if (rx_control & L2CAP_CTRL_POLL)
4052 l2cap_send_srejtail(sk);
4053 else
4054 l2cap_send_sframe(pi, L2CAP_SUPER_RCV_READY);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004055}
4056
4057static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
4058{
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004059 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
4060
Gustavo F. Padovan9b16dc62010-05-05 20:05:57 -03004061 if (L2CAP_CTRL_FINAL & rx_control &&
4062 l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004063 del_timer(&l2cap_pi(sk)->monitor_timer);
4064 if (l2cap_pi(sk)->unacked_frames > 0)
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03004065 __mod_retrans_timer();
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004066 l2cap_pi(sk)->conn_state &= ~L2CAP_CONN_WAIT_F;
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03004067 }
4068
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004069 switch (rx_control & L2CAP_CTRL_SUPERVISE) {
4070 case L2CAP_SUPER_RCV_READY:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004071 l2cap_data_channel_rrframe(sk, rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004072 break;
4073
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004074 case L2CAP_SUPER_REJECT:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004075 l2cap_data_channel_rejframe(sk, rx_control);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03004076 break;
4077
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004078 case L2CAP_SUPER_SELECT_REJECT:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004079 l2cap_data_channel_srejframe(sk, rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004080 break;
4081
4082 case L2CAP_SUPER_RCV_NOT_READY:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004083 l2cap_data_channel_rnrframe(sk, rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004084 break;
4085 }
4086
Gustavo F. Padovanfaaebd12010-05-01 16:15:35 -03004087 kfree_skb(skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004088 return 0;
4089}
4090
Linus Torvalds1da177e2005-04-16 15:20:36 -07004091static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk_buff *skb)
4092{
4093 struct sock *sk;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004094 struct l2cap_pinfo *pi;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03004095 u16 control, len;
Gustavo F. Padovanf6337c72010-05-10 18:32:04 -03004096 u8 tx_seq, req_seq;
4097 int next_tx_seq_offset, req_seq_offset;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004098
4099 sk = l2cap_get_chan_by_scid(&conn->chan_list, cid);
4100 if (!sk) {
4101 BT_DBG("unknown cid 0x%4.4x", cid);
4102 goto drop;
4103 }
4104
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004105 pi = l2cap_pi(sk);
4106
Linus Torvalds1da177e2005-04-16 15:20:36 -07004107 BT_DBG("sk %p, len %d", sk, skb->len);
4108
4109 if (sk->sk_state != BT_CONNECTED)
4110 goto drop;
4111
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004112 switch (pi->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004113 case L2CAP_MODE_BASIC:
4114 /* If socket recv buffers overflows we drop data here
4115 * which is *bad* because L2CAP has to be reliable.
4116 * But we don't have any other choice. L2CAP doesn't
4117 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07004118
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004119 if (pi->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004120 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004121
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004122 if (!sock_queue_rcv_skb(sk, skb))
4123 goto done;
4124 break;
4125
4126 case L2CAP_MODE_ERTM:
4127 control = get_unaligned_le16(skb->data);
4128 skb_pull(skb, 2);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03004129 len = skb->len;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004130
Gustavo F. Padovanbc1b1f82010-05-11 22:14:00 -03004131 if (__is_sar_start(control) && __is_iframe(control))
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03004132 len -= 2;
4133
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004134 if (pi->fcs == L2CAP_FCS_CRC16)
4135 len -= 2;
4136
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03004137 /*
4138 * We can just drop the corrupted I-frame here.
4139 * Receiver will miss it and start proper recovery
4140 * procedures and ask retransmission.
4141 */
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004142 if (len > pi->mps) {
4143 l2cap_send_disconn_req(pi->conn, sk);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004144 goto drop;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004145 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004146
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004147 if (l2cap_check_fcs(pi, skb))
4148 goto drop;
4149
João Paulo Rechi Vita01760bd2010-05-01 16:15:43 -03004150 req_seq = __get_reqseq(control);
4151 req_seq_offset = (req_seq - pi->expected_ack_seq) % 64;
4152 if (req_seq_offset < 0)
4153 req_seq_offset += 64;
4154
4155 next_tx_seq_offset =
4156 (pi->next_tx_seq - pi->expected_ack_seq) % 64;
4157 if (next_tx_seq_offset < 0)
4158 next_tx_seq_offset += 64;
4159
4160 /* check for invalid req-seq */
4161 if (req_seq_offset > next_tx_seq_offset) {
4162 l2cap_send_disconn_req(pi->conn, sk);
4163 goto drop;
4164 }
4165
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004166 if (__is_iframe(control)) {
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004167 if (len < 4) {
4168 l2cap_send_disconn_req(pi->conn, sk);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004169 goto drop;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004170 }
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004171
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02004172 l2cap_data_channel_iframe(sk, control, skb);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004173 } else {
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004174 if (len != 0) {
4175 l2cap_send_disconn_req(pi->conn, sk);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004176 goto drop;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004177 }
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004178
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02004179 l2cap_data_channel_sframe(sk, control, skb);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004180 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004181
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02004182 goto done;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004183
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004184 case L2CAP_MODE_STREAMING:
4185 control = get_unaligned_le16(skb->data);
4186 skb_pull(skb, 2);
4187 len = skb->len;
4188
4189 if (__is_sar_start(control))
4190 len -= 2;
4191
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004192 if (pi->fcs == L2CAP_FCS_CRC16)
4193 len -= 2;
4194
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03004195 if (len > pi->mps || len < 4 || __is_sframe(control))
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004196 goto drop;
4197
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004198 if (l2cap_check_fcs(pi, skb))
4199 goto drop;
4200
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004201 tx_seq = __get_txseq(control);
4202
4203 if (pi->expected_tx_seq == tx_seq)
4204 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
4205 else
Gustavo F. Padovan7dffe422010-05-01 16:15:36 -03004206 pi->expected_tx_seq = (tx_seq + 1) % 64;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004207
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004208 l2cap_streaming_reassembly_sdu(sk, skb, control);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004209
4210 goto done;
4211
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004212 default:
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03004213 BT_DBG("sk %p: bad mode 0x%2.2x", sk, pi->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004214 break;
4215 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004216
4217drop:
4218 kfree_skb(skb);
4219
4220done:
Marcel Holtmann01394182006-07-03 10:02:46 +02004221 if (sk)
4222 bh_unlock_sock(sk);
4223
Linus Torvalds1da177e2005-04-16 15:20:36 -07004224 return 0;
4225}
4226
Al Viro8e036fc2007-07-29 00:16:36 -07004227static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004228{
4229 struct sock *sk;
4230
4231 sk = l2cap_get_sock_by_psm(0, psm, conn->src);
4232 if (!sk)
4233 goto drop;
4234
4235 BT_DBG("sk %p, len %d", sk, skb->len);
4236
4237 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_CONNECTED)
4238 goto drop;
4239
4240 if (l2cap_pi(sk)->imtu < skb->len)
4241 goto drop;
4242
4243 if (!sock_queue_rcv_skb(sk, skb))
4244 goto done;
4245
4246drop:
4247 kfree_skb(skb);
4248
4249done:
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03004250 if (sk)
4251 bh_unlock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004252 return 0;
4253}
4254
4255static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
4256{
4257 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07004258 u16 cid, len;
4259 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004260
4261 skb_pull(skb, L2CAP_HDR_SIZE);
4262 cid = __le16_to_cpu(lh->cid);
4263 len = __le16_to_cpu(lh->len);
4264
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004265 if (len != skb->len) {
4266 kfree_skb(skb);
4267 return;
4268 }
4269
Linus Torvalds1da177e2005-04-16 15:20:36 -07004270 BT_DBG("len %d, cid 0x%4.4x", len, cid);
4271
4272 switch (cid) {
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03004273 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07004274 l2cap_sig_channel(conn, skb);
4275 break;
4276
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03004277 case L2CAP_CID_CONN_LESS:
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03004278 psm = get_unaligned_le16(skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004279 skb_pull(skb, 2);
4280 l2cap_conless_channel(conn, psm, skb);
4281 break;
4282
4283 default:
4284 l2cap_data_channel(conn, cid, skb);
4285 break;
4286 }
4287}
4288
4289/* ---- L2CAP interface with lower layer (HCI) ---- */
4290
4291static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
4292{
4293 int exact = 0, lm1 = 0, lm2 = 0;
4294 register struct sock *sk;
4295 struct hlist_node *node;
4296
4297 if (type != ACL_LINK)
4298 return 0;
4299
4300 BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
4301
4302 /* Find listening sockets and check their link_mode */
4303 read_lock(&l2cap_sk_list.lock);
4304 sk_for_each(sk, node, &l2cap_sk_list.head) {
4305 if (sk->sk_state != BT_LISTEN)
4306 continue;
4307
4308 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01004309 lm1 |= HCI_LM_ACCEPT;
4310 if (l2cap_pi(sk)->role_switch)
4311 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004312 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01004313 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
4314 lm2 |= HCI_LM_ACCEPT;
4315 if (l2cap_pi(sk)->role_switch)
4316 lm2 |= HCI_LM_MASTER;
4317 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004318 }
4319 read_unlock(&l2cap_sk_list.lock);
4320
4321 return exact ? lm1 : lm2;
4322}
4323
4324static int l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
4325{
Marcel Holtmann01394182006-07-03 10:02:46 +02004326 struct l2cap_conn *conn;
4327
Linus Torvalds1da177e2005-04-16 15:20:36 -07004328 BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
4329
4330 if (hcon->type != ACL_LINK)
4331 return 0;
4332
4333 if (!status) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004334 conn = l2cap_conn_add(hcon, status);
4335 if (conn)
4336 l2cap_conn_ready(conn);
Marcel Holtmann01394182006-07-03 10:02:46 +02004337 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -07004338 l2cap_conn_del(hcon, bt_err(status));
4339
4340 return 0;
4341}
4342
Marcel Holtmann2950f212009-02-12 14:02:50 +01004343static int l2cap_disconn_ind(struct hci_conn *hcon)
4344{
4345 struct l2cap_conn *conn = hcon->l2cap_data;
4346
4347 BT_DBG("hcon %p", hcon);
4348
4349 if (hcon->type != ACL_LINK || !conn)
4350 return 0x13;
4351
4352 return conn->disc_reason;
4353}
4354
4355static int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004356{
4357 BT_DBG("hcon %p reason %d", hcon, reason);
4358
4359 if (hcon->type != ACL_LINK)
4360 return 0;
4361
4362 l2cap_conn_del(hcon, bt_err(reason));
Marcel Holtmann01394182006-07-03 10:02:46 +02004363
Linus Torvalds1da177e2005-04-16 15:20:36 -07004364 return 0;
4365}
4366
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004367static inline void l2cap_check_encryption(struct sock *sk, u8 encrypt)
4368{
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03004369 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM)
Marcel Holtmann255c7602009-02-04 21:07:19 +01004370 return;
4371
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004372 if (encrypt == 0x00) {
4373 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM) {
4374 l2cap_sock_clear_timer(sk);
4375 l2cap_sock_set_timer(sk, HZ * 5);
4376 } else if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
4377 __l2cap_sock_close(sk, ECONNREFUSED);
4378 } else {
4379 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM)
4380 l2cap_sock_clear_timer(sk);
4381 }
4382}
4383
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004384static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004385{
4386 struct l2cap_chan_list *l;
Marcel Holtmann40be4922008-07-14 20:13:50 +02004387 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004388 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004389
Marcel Holtmann01394182006-07-03 10:02:46 +02004390 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004391 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02004392
Linus Torvalds1da177e2005-04-16 15:20:36 -07004393 l = &conn->chan_list;
4394
4395 BT_DBG("conn %p", conn);
4396
4397 read_lock(&l->lock);
4398
4399 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
4400 bh_lock_sock(sk);
4401
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01004402 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND) {
4403 bh_unlock_sock(sk);
4404 continue;
4405 }
4406
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004407 if (!status && (sk->sk_state == BT_CONNECTED ||
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004408 sk->sk_state == BT_CONFIG)) {
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004409 l2cap_check_encryption(sk, encrypt);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02004410 bh_unlock_sock(sk);
4411 continue;
4412 }
4413
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004414 if (sk->sk_state == BT_CONNECT) {
4415 if (!status) {
4416 struct l2cap_conn_req req;
4417 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
4418 req.psm = l2cap_pi(sk)->psm;
4419
4420 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03004421 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004422
4423 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
4424 L2CAP_CONN_REQ, sizeof(req), &req);
4425 } else {
4426 l2cap_sock_clear_timer(sk);
4427 l2cap_sock_set_timer(sk, HZ / 10);
4428 }
4429 } else if (sk->sk_state == BT_CONNECT2) {
4430 struct l2cap_conn_rsp rsp;
4431 __u16 result;
4432
4433 if (!status) {
4434 sk->sk_state = BT_CONFIG;
4435 result = L2CAP_CR_SUCCESS;
4436 } else {
4437 sk->sk_state = BT_DISCONN;
4438 l2cap_sock_set_timer(sk, HZ / 10);
4439 result = L2CAP_CR_SEC_BLOCK;
4440 }
4441
4442 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
4443 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
4444 rsp.result = cpu_to_le16(result);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02004445 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004446 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
4447 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004448 }
4449
Linus Torvalds1da177e2005-04-16 15:20:36 -07004450 bh_unlock_sock(sk);
4451 }
4452
4453 read_unlock(&l->lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004454
Linus Torvalds1da177e2005-04-16 15:20:36 -07004455 return 0;
4456}
4457
4458static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
4459{
4460 struct l2cap_conn *conn = hcon->l2cap_data;
4461
4462 if (!conn && !(conn = l2cap_conn_add(hcon, 0)))
4463 goto drop;
4464
4465 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
4466
4467 if (flags & ACL_START) {
4468 struct l2cap_hdr *hdr;
4469 int len;
4470
4471 if (conn->rx_len) {
4472 BT_ERR("Unexpected start frame (len %d)", skb->len);
4473 kfree_skb(conn->rx_skb);
4474 conn->rx_skb = NULL;
4475 conn->rx_len = 0;
4476 l2cap_conn_unreliable(conn, ECOMM);
4477 }
4478
4479 if (skb->len < 2) {
4480 BT_ERR("Frame is too short (len %d)", skb->len);
4481 l2cap_conn_unreliable(conn, ECOMM);
4482 goto drop;
4483 }
4484
4485 hdr = (struct l2cap_hdr *) skb->data;
4486 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
4487
4488 if (len == skb->len) {
4489 /* Complete frame received */
4490 l2cap_recv_frame(conn, skb);
4491 return 0;
4492 }
4493
4494 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
4495
4496 if (skb->len > len) {
4497 BT_ERR("Frame is too long (len %d, expected len %d)",
4498 skb->len, len);
4499 l2cap_conn_unreliable(conn, ECOMM);
4500 goto drop;
4501 }
4502
4503 /* Allocate skb for the complete frame (with header) */
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03004504 conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC);
4505 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004506 goto drop;
4507
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03004508 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004509 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004510 conn->rx_len = len - skb->len;
4511 } else {
4512 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
4513
4514 if (!conn->rx_len) {
4515 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
4516 l2cap_conn_unreliable(conn, ECOMM);
4517 goto drop;
4518 }
4519
4520 if (skb->len > conn->rx_len) {
4521 BT_ERR("Fragment is too long (len %d, expected %d)",
4522 skb->len, conn->rx_len);
4523 kfree_skb(conn->rx_skb);
4524 conn->rx_skb = NULL;
4525 conn->rx_len = 0;
4526 l2cap_conn_unreliable(conn, ECOMM);
4527 goto drop;
4528 }
4529
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03004530 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004531 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004532 conn->rx_len -= skb->len;
4533
4534 if (!conn->rx_len) {
4535 /* Complete frame received */
4536 l2cap_recv_frame(conn, conn->rx_skb);
4537 conn->rx_skb = NULL;
4538 }
4539 }
4540
4541drop:
4542 kfree_skb(skb);
4543 return 0;
4544}
4545
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004546static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004547{
4548 struct sock *sk;
4549 struct hlist_node *node;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004550
4551 read_lock_bh(&l2cap_sk_list.lock);
4552
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004553 sk_for_each(sk, node, &l2cap_sk_list.head) {
4554 struct l2cap_pinfo *pi = l2cap_pi(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004555
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004556 seq_printf(f, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d\n",
4557 batostr(&bt_sk(sk)->src),
4558 batostr(&bt_sk(sk)->dst),
4559 sk->sk_state, __le16_to_cpu(pi->psm),
4560 pi->scid, pi->dcid,
4561 pi->imtu, pi->omtu, pi->sec_level);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004562 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004563
Linus Torvalds1da177e2005-04-16 15:20:36 -07004564 read_unlock_bh(&l2cap_sk_list.lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004565
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004566 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004567}
4568
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004569static int l2cap_debugfs_open(struct inode *inode, struct file *file)
4570{
4571 return single_open(file, l2cap_debugfs_show, inode->i_private);
4572}
4573
4574static const struct file_operations l2cap_debugfs_fops = {
4575 .open = l2cap_debugfs_open,
4576 .read = seq_read,
4577 .llseek = seq_lseek,
4578 .release = single_release,
4579};
4580
4581static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004582
Eric Dumazet90ddc4f2005-12-22 12:49:22 -08004583static const struct proto_ops l2cap_sock_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004584 .family = PF_BLUETOOTH,
4585 .owner = THIS_MODULE,
4586 .release = l2cap_sock_release,
4587 .bind = l2cap_sock_bind,
4588 .connect = l2cap_sock_connect,
4589 .listen = l2cap_sock_listen,
4590 .accept = l2cap_sock_accept,
4591 .getname = l2cap_sock_getname,
4592 .sendmsg = l2cap_sock_sendmsg,
Marcel Holtmannf66dc812009-01-15 21:57:00 +01004593 .recvmsg = l2cap_sock_recvmsg,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004594 .poll = bt_sock_poll,
Marcel Holtmann3241ad82008-07-14 20:13:50 +02004595 .ioctl = bt_sock_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004596 .mmap = sock_no_mmap,
4597 .socketpair = sock_no_socketpair,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004598 .shutdown = l2cap_sock_shutdown,
4599 .setsockopt = l2cap_sock_setsockopt,
4600 .getsockopt = l2cap_sock_getsockopt
4601};
4602
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +00004603static const struct net_proto_family l2cap_sock_family_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004604 .family = PF_BLUETOOTH,
4605 .owner = THIS_MODULE,
4606 .create = l2cap_sock_create,
4607};
4608
4609static struct hci_proto l2cap_hci_proto = {
4610 .name = "L2CAP",
4611 .id = HCI_PROTO_L2CAP,
4612 .connect_ind = l2cap_connect_ind,
4613 .connect_cfm = l2cap_connect_cfm,
4614 .disconn_ind = l2cap_disconn_ind,
Marcel Holtmann2950f212009-02-12 14:02:50 +01004615 .disconn_cfm = l2cap_disconn_cfm,
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004616 .security_cfm = l2cap_security_cfm,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004617 .recv_acldata = l2cap_recv_acldata
4618};
4619
4620static int __init l2cap_init(void)
4621{
4622 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004623
Linus Torvalds1da177e2005-04-16 15:20:36 -07004624 err = proto_register(&l2cap_proto, 0);
4625 if (err < 0)
4626 return err;
4627
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004628 _busy_wq = create_singlethread_workqueue("l2cap");
4629 if (!_busy_wq)
4630 goto error;
4631
Linus Torvalds1da177e2005-04-16 15:20:36 -07004632 err = bt_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops);
4633 if (err < 0) {
4634 BT_ERR("L2CAP socket registration failed");
4635 goto error;
4636 }
4637
4638 err = hci_register_proto(&l2cap_hci_proto);
4639 if (err < 0) {
4640 BT_ERR("L2CAP protocol registration failed");
4641 bt_sock_unregister(BTPROTO_L2CAP);
4642 goto error;
4643 }
4644
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004645 if (bt_debugfs) {
4646 l2cap_debugfs = debugfs_create_file("l2cap", 0444,
4647 bt_debugfs, NULL, &l2cap_debugfs_fops);
4648 if (!l2cap_debugfs)
4649 BT_ERR("Failed to create L2CAP debug file");
4650 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004651
4652 BT_INFO("L2CAP ver %s", VERSION);
4653 BT_INFO("L2CAP socket layer initialized");
4654
4655 return 0;
4656
4657error:
4658 proto_unregister(&l2cap_proto);
4659 return err;
4660}
4661
4662static void __exit l2cap_exit(void)
4663{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004664 debugfs_remove(l2cap_debugfs);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004665
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004666 flush_workqueue(_busy_wq);
4667 destroy_workqueue(_busy_wq);
4668
Linus Torvalds1da177e2005-04-16 15:20:36 -07004669 if (bt_sock_unregister(BTPROTO_L2CAP) < 0)
4670 BT_ERR("L2CAP socket unregistration failed");
4671
4672 if (hci_unregister_proto(&l2cap_hci_proto) < 0)
4673 BT_ERR("L2CAP protocol unregistration failed");
4674
4675 proto_unregister(&l2cap_proto);
4676}
4677
4678void l2cap_load(void)
4679{
4680 /* Dummy function to trigger automatic L2CAP module loading by
4681 * other modules that use L2CAP sockets but don't use any other
4682 * symbols from it. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07004683}
4684EXPORT_SYMBOL(l2cap_load);
4685
4686module_init(l2cap_init);
4687module_exit(l2cap_exit);
4688
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07004689module_param(enable_ertm, bool, 0644);
4690MODULE_PARM_DESC(enable_ertm, "Enable enhanced retransmission mode");
4691
Marcel Holtmann63fbd242008-08-18 13:23:53 +02004692MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004693MODULE_DESCRIPTION("Bluetooth L2CAP ver " VERSION);
4694MODULE_VERSION(VERSION);
4695MODULE_LICENSE("GPL");
4696MODULE_ALIAS("bt-proto-0");