blob: 7e39d9ee0b9ce666099f4457bb353851fc4a4484 [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 if (pi->conn_state & L2CAP_CONN_WAIT_F)
1419 return 0;
1420
Joe Perchesf64f9e72009-11-29 16:55:45 -08001421 while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(sk)) &&
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03001422 !(pi->conn_state & L2CAP_CONN_REMOTE_BUSY)) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001423
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001424 if (pi->remote_max_tx &&
1425 bt_cb(skb)->retries == pi->remote_max_tx) {
1426 l2cap_send_disconn_req(pi->conn, sk);
1427 break;
1428 }
1429
Andrei Emeltchenkoe420aba2009-12-23 13:07:14 +02001430 tx_skb = skb_clone(skb, GFP_ATOMIC);
1431
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001432 bt_cb(skb)->retries++;
1433
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001434 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001435 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
1436 control |= L2CAP_CTRL_FINAL;
1437 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
1438 }
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03001439 control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001440 | (pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
1441 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1442
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001443
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001444 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001445 fcs = crc16(0, (u8 *)skb->data, tx_skb->len - 2);
1446 put_unaligned_le16(fcs, skb->data + tx_skb->len - 2);
1447 }
1448
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001449 l2cap_do_send(sk, tx_skb);
1450
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001451 __mod_retrans_timer();
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001452
1453 bt_cb(skb)->tx_seq = pi->next_tx_seq;
1454 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
1455
1456 pi->unacked_frames++;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001457 pi->frames_sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001458
1459 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1460 sk->sk_send_head = NULL;
1461 else
1462 sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001463
1464 nsent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001465 }
1466
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001467 return nsent;
1468}
1469
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001470static int l2cap_retransmit_frames(struct sock *sk)
1471{
1472 struct l2cap_pinfo *pi = l2cap_pi(sk);
1473 int ret;
1474
1475 spin_lock_bh(&pi->send_lock);
1476
1477 if (!skb_queue_empty(TX_QUEUE(sk)))
1478 sk->sk_send_head = TX_QUEUE(sk)->next;
1479
1480 pi->next_tx_seq = pi->expected_ack_seq;
1481 ret = l2cap_ertm_send(sk);
1482
1483 spin_unlock_bh(&pi->send_lock);
1484
1485 return ret;
1486}
1487
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001488static void l2cap_send_ack(struct l2cap_pinfo *pi)
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001489{
1490 struct sock *sk = (struct sock *)pi;
1491 u16 control = 0;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001492 int nframes;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001493
1494 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1495
1496 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
1497 control |= L2CAP_SUPER_RCV_NOT_READY;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03001498 pi->conn_state |= L2CAP_CONN_RNR_SENT;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001499 l2cap_send_sframe(pi, control);
1500 return;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001501 }
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001502
1503 spin_lock_bh(&pi->send_lock);
1504 nframes = l2cap_ertm_send(sk);
1505 spin_unlock_bh(&pi->send_lock);
1506
1507 if (nframes > 0)
1508 return;
1509
1510 control |= L2CAP_SUPER_RCV_READY;
1511 l2cap_send_sframe(pi, control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001512}
1513
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001514static void l2cap_send_srejtail(struct sock *sk)
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03001515{
1516 struct srej_list *tail;
1517 u16 control;
1518
1519 control = L2CAP_SUPER_SELECT_REJECT;
1520 control |= L2CAP_CTRL_FINAL;
1521
1522 tail = list_entry(SREJ_LIST(sk)->prev, struct srej_list, list);
1523 control |= tail->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1524
1525 l2cap_send_sframe(l2cap_pi(sk), control);
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03001526}
1527
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001528static 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 -07001529{
1530 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001531 struct sk_buff **frag;
1532 int err, sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001533
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03001534 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001535 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001536
1537 sent += count;
1538 len -= count;
1539
1540 /* Continuation fragments (no L2CAP header) */
1541 frag = &skb_shinfo(skb)->frag_list;
1542 while (len) {
1543 count = min_t(unsigned int, conn->mtu, len);
1544
1545 *frag = bt_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err);
1546 if (!*frag)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001547 return -EFAULT;
1548 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
1549 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001550
1551 sent += count;
1552 len -= count;
1553
1554 frag = &(*frag)->next;
1555 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001556
1557 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001558}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001559
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001560static struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, size_t len)
1561{
1562 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1563 struct sk_buff *skb;
1564 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1565 struct l2cap_hdr *lh;
1566
1567 BT_DBG("sk %p len %d", sk, (int)len);
1568
1569 count = min_t(unsigned int, (conn->mtu - hlen), len);
1570 skb = bt_skb_send_alloc(sk, count + hlen,
1571 msg->msg_flags & MSG_DONTWAIT, &err);
1572 if (!skb)
1573 return ERR_PTR(-ENOMEM);
1574
1575 /* Create L2CAP header */
1576 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1577 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1578 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1579 put_unaligned_le16(l2cap_pi(sk)->psm, skb_put(skb, 2));
1580
1581 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1582 if (unlikely(err < 0)) {
1583 kfree_skb(skb);
1584 return ERR_PTR(err);
1585 }
1586 return skb;
1587}
1588
1589static struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *msg, size_t len)
1590{
1591 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1592 struct sk_buff *skb;
1593 int err, count, hlen = L2CAP_HDR_SIZE;
1594 struct l2cap_hdr *lh;
1595
1596 BT_DBG("sk %p len %d", sk, (int)len);
1597
1598 count = min_t(unsigned int, (conn->mtu - hlen), len);
1599 skb = bt_skb_send_alloc(sk, count + hlen,
1600 msg->msg_flags & MSG_DONTWAIT, &err);
1601 if (!skb)
1602 return ERR_PTR(-ENOMEM);
1603
1604 /* Create L2CAP header */
1605 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1606 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1607 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1608
1609 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1610 if (unlikely(err < 0)) {
1611 kfree_skb(skb);
1612 return ERR_PTR(err);
1613 }
1614 return skb;
1615}
1616
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001617static 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 -03001618{
1619 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1620 struct sk_buff *skb;
1621 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1622 struct l2cap_hdr *lh;
1623
1624 BT_DBG("sk %p len %d", sk, (int)len);
1625
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03001626 if (!conn)
1627 return ERR_PTR(-ENOTCONN);
1628
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001629 if (sdulen)
1630 hlen += 2;
1631
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001632 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1633 hlen += 2;
1634
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001635 count = min_t(unsigned int, (conn->mtu - hlen), len);
1636 skb = bt_skb_send_alloc(sk, count + hlen,
1637 msg->msg_flags & MSG_DONTWAIT, &err);
1638 if (!skb)
1639 return ERR_PTR(-ENOMEM);
1640
1641 /* Create L2CAP header */
1642 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1643 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1644 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1645 put_unaligned_le16(control, skb_put(skb, 2));
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001646 if (sdulen)
1647 put_unaligned_le16(sdulen, skb_put(skb, 2));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001648
1649 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1650 if (unlikely(err < 0)) {
1651 kfree_skb(skb);
1652 return ERR_PTR(err);
1653 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001654
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001655 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1656 put_unaligned_le16(0, skb_put(skb, 2));
1657
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001658 bt_cb(skb)->retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001659 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001660}
1661
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001662static inline int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len)
1663{
1664 struct l2cap_pinfo *pi = l2cap_pi(sk);
1665 struct sk_buff *skb;
1666 struct sk_buff_head sar_queue;
1667 u16 control;
1668 size_t size = 0;
1669
Gustavo F. Padovanff12fd62010-05-05 22:09:15 -03001670 skb_queue_head_init(&sar_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001671 control = L2CAP_SDU_START;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001672 skb = l2cap_create_iframe_pdu(sk, msg, pi->remote_mps, control, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001673 if (IS_ERR(skb))
1674 return PTR_ERR(skb);
1675
1676 __skb_queue_tail(&sar_queue, skb);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001677 len -= pi->remote_mps;
1678 size += pi->remote_mps;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001679
1680 while (len > 0) {
1681 size_t buflen;
1682
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001683 if (len > pi->remote_mps) {
Gustavo F. Padovan44651b82010-05-01 16:15:43 -03001684 control = L2CAP_SDU_CONTINUE;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001685 buflen = pi->remote_mps;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001686 } else {
Gustavo F. Padovan44651b82010-05-01 16:15:43 -03001687 control = L2CAP_SDU_END;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001688 buflen = len;
1689 }
1690
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001691 skb = l2cap_create_iframe_pdu(sk, msg, buflen, control, 0);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001692 if (IS_ERR(skb)) {
1693 skb_queue_purge(&sar_queue);
1694 return PTR_ERR(skb);
1695 }
1696
1697 __skb_queue_tail(&sar_queue, skb);
1698 len -= buflen;
1699 size += buflen;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001700 }
1701 skb_queue_splice_tail(&sar_queue, TX_QUEUE(sk));
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001702 spin_lock_bh(&pi->send_lock);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001703 if (sk->sk_send_head == NULL)
1704 sk->sk_send_head = sar_queue.next;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001705 spin_unlock_bh(&pi->send_lock);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001706
1707 return size;
1708}
1709
Linus Torvalds1da177e2005-04-16 15:20:36 -07001710static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len)
1711{
1712 struct sock *sk = sock->sk;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001713 struct l2cap_pinfo *pi = l2cap_pi(sk);
1714 struct sk_buff *skb;
1715 u16 control;
1716 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001717
1718 BT_DBG("sock %p, sk %p", sock, sk);
1719
Benjamin LaHaisec1cbe4b2005-12-13 23:22:19 -08001720 err = sock_error(sk);
1721 if (err)
1722 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001723
1724 if (msg->msg_flags & MSG_OOB)
1725 return -EOPNOTSUPP;
1726
Linus Torvalds1da177e2005-04-16 15:20:36 -07001727 lock_sock(sk);
1728
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001729 if (sk->sk_state != BT_CONNECTED) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001730 err = -ENOTCONN;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001731 goto done;
1732 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001733
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001734 /* Connectionless channel */
1735 if (sk->sk_type == SOCK_DGRAM) {
1736 skb = l2cap_create_connless_pdu(sk, msg, len);
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001737 if (IS_ERR(skb)) {
Dan Carpenter477fffb2010-04-21 23:52:01 +00001738 err = PTR_ERR(skb);
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001739 } else {
1740 l2cap_do_send(sk, skb);
1741 err = len;
1742 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001743 goto done;
1744 }
1745
1746 switch (pi->mode) {
1747 case L2CAP_MODE_BASIC:
Gustavo F. Padovanc69163e2010-05-01 16:15:35 -03001748 /* Check outgoing MTU */
1749 if (len > pi->omtu) {
1750 err = -EINVAL;
1751 goto done;
1752 }
1753
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001754 /* Create a basic PDU */
1755 skb = l2cap_create_basic_pdu(sk, msg, len);
1756 if (IS_ERR(skb)) {
1757 err = PTR_ERR(skb);
1758 goto done;
1759 }
1760
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001761 l2cap_do_send(sk, skb);
1762 err = len;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001763 break;
1764
1765 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001766 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001767 /* Entire SDU fits into one PDU */
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001768 if (len <= pi->remote_mps) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001769 control = L2CAP_SDU_UNSEGMENTED;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001770 skb = l2cap_create_iframe_pdu(sk, msg, len, control, 0);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001771 if (IS_ERR(skb)) {
1772 err = PTR_ERR(skb);
1773 goto done;
1774 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001775 __skb_queue_tail(TX_QUEUE(sk), skb);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001776
1777 if (pi->mode == L2CAP_MODE_ERTM)
1778 spin_lock_bh(&pi->send_lock);
1779
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001780 if (sk->sk_send_head == NULL)
1781 sk->sk_send_head = skb;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001782
1783 if (pi->mode == L2CAP_MODE_ERTM)
1784 spin_unlock_bh(&pi->send_lock);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001785 } else {
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001786 /* Segment SDU into multiples PDUs */
1787 err = l2cap_sar_segment_sdu(sk, msg, len);
1788 if (err < 0)
1789 goto done;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001790 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001791
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001792 if (pi->mode == L2CAP_MODE_STREAMING) {
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001793 err = l2cap_streaming_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001794 } else {
1795 spin_lock_bh(&pi->send_lock);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001796 err = l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001797 spin_unlock_bh(&pi->send_lock);
1798 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001799
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001800 if (err >= 0)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001801 err = len;
1802 break;
1803
1804 default:
1805 BT_DBG("bad state %1.1x", pi->mode);
1806 err = -EINVAL;
1807 }
1808
1809done:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001810 release_sock(sk);
1811 return err;
1812}
1813
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001814static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags)
1815{
1816 struct sock *sk = sock->sk;
1817
1818 lock_sock(sk);
1819
1820 if (sk->sk_state == BT_CONNECT2 && bt_sk(sk)->defer_setup) {
1821 struct l2cap_conn_rsp rsp;
1822
1823 sk->sk_state = BT_CONFIG;
1824
1825 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
1826 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
1827 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
1828 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
1829 l2cap_send_cmd(l2cap_pi(sk)->conn, l2cap_pi(sk)->ident,
1830 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
1831
1832 release_sock(sk);
1833 return 0;
1834 }
1835
1836 release_sock(sk);
1837
1838 return bt_sock_recvmsg(iocb, sock, msg, len, flags);
1839}
1840
David S. Millerb7058842009-09-30 16:12:20 -07001841static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001842{
1843 struct sock *sk = sock->sk;
1844 struct l2cap_options opts;
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001845 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001846 u32 opt;
1847
1848 BT_DBG("sk %p", sk);
1849
1850 lock_sock(sk);
1851
1852 switch (optname) {
1853 case L2CAP_OPTIONS:
Marcel Holtmann0878b662007-05-05 00:35:59 +02001854 opts.imtu = l2cap_pi(sk)->imtu;
1855 opts.omtu = l2cap_pi(sk)->omtu;
1856 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001857 opts.mode = l2cap_pi(sk)->mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001858 opts.fcs = l2cap_pi(sk)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03001859 opts.max_tx = l2cap_pi(sk)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03001860 opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
Marcel Holtmann0878b662007-05-05 00:35:59 +02001861
Linus Torvalds1da177e2005-04-16 15:20:36 -07001862 len = min_t(unsigned int, sizeof(opts), optlen);
1863 if (copy_from_user((char *) &opts, optval, len)) {
1864 err = -EFAULT;
1865 break;
1866 }
Marcel Holtmann0878b662007-05-05 00:35:59 +02001867
João Paulo Rechi Vita0041ecf2010-05-01 16:15:42 -03001868 l2cap_pi(sk)->mode = opts.mode;
1869 switch (l2cap_pi(sk)->mode) {
1870 case L2CAP_MODE_BASIC:
1871 break;
1872 case L2CAP_MODE_ERTM:
1873 case L2CAP_MODE_STREAMING:
1874 if (enable_ertm)
1875 break;
1876 /* fall through */
1877 default:
1878 err = -EINVAL;
1879 break;
1880 }
1881
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001882 l2cap_pi(sk)->imtu = opts.imtu;
1883 l2cap_pi(sk)->omtu = opts.omtu;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001884 l2cap_pi(sk)->fcs = opts.fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03001885 l2cap_pi(sk)->max_tx = opts.max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03001886 l2cap_pi(sk)->tx_win = (__u8)opts.txwin_size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001887 break;
1888
1889 case L2CAP_LM:
1890 if (get_user(opt, (u32 __user *) optval)) {
1891 err = -EFAULT;
1892 break;
1893 }
1894
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001895 if (opt & L2CAP_LM_AUTH)
1896 l2cap_pi(sk)->sec_level = BT_SECURITY_LOW;
1897 if (opt & L2CAP_LM_ENCRYPT)
1898 l2cap_pi(sk)->sec_level = BT_SECURITY_MEDIUM;
1899 if (opt & L2CAP_LM_SECURE)
1900 l2cap_pi(sk)->sec_level = BT_SECURITY_HIGH;
1901
1902 l2cap_pi(sk)->role_switch = (opt & L2CAP_LM_MASTER);
1903 l2cap_pi(sk)->force_reliable = (opt & L2CAP_LM_RELIABLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001904 break;
1905
1906 default:
1907 err = -ENOPROTOOPT;
1908 break;
1909 }
1910
1911 release_sock(sk);
1912 return err;
1913}
1914
David S. Millerb7058842009-09-30 16:12:20 -07001915static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001916{
1917 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001918 struct bt_security sec;
1919 int len, err = 0;
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001920 u32 opt;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001921
1922 BT_DBG("sk %p", sk);
1923
1924 if (level == SOL_L2CAP)
1925 return l2cap_sock_setsockopt_old(sock, optname, optval, optlen);
1926
Marcel Holtmann0588d942009-01-16 10:06:13 +01001927 if (level != SOL_BLUETOOTH)
1928 return -ENOPROTOOPT;
1929
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001930 lock_sock(sk);
1931
1932 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001933 case BT_SECURITY:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001934 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
1935 && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01001936 err = -EINVAL;
1937 break;
1938 }
1939
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001940 sec.level = BT_SECURITY_LOW;
1941
1942 len = min_t(unsigned int, sizeof(sec), optlen);
1943 if (copy_from_user((char *) &sec, optval, len)) {
1944 err = -EFAULT;
1945 break;
1946 }
1947
1948 if (sec.level < BT_SECURITY_LOW ||
1949 sec.level > BT_SECURITY_HIGH) {
1950 err = -EINVAL;
1951 break;
1952 }
1953
1954 l2cap_pi(sk)->sec_level = sec.level;
1955 break;
1956
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001957 case BT_DEFER_SETUP:
1958 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
1959 err = -EINVAL;
1960 break;
1961 }
1962
1963 if (get_user(opt, (u32 __user *) optval)) {
1964 err = -EFAULT;
1965 break;
1966 }
1967
1968 bt_sk(sk)->defer_setup = opt;
1969 break;
1970
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001971 default:
1972 err = -ENOPROTOOPT;
1973 break;
1974 }
1975
1976 release_sock(sk);
1977 return err;
1978}
1979
1980static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001981{
1982 struct sock *sk = sock->sk;
1983 struct l2cap_options opts;
1984 struct l2cap_conninfo cinfo;
1985 int len, err = 0;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001986 u32 opt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001987
1988 BT_DBG("sk %p", sk);
1989
1990 if (get_user(len, optlen))
1991 return -EFAULT;
1992
1993 lock_sock(sk);
1994
1995 switch (optname) {
1996 case L2CAP_OPTIONS:
1997 opts.imtu = l2cap_pi(sk)->imtu;
1998 opts.omtu = l2cap_pi(sk)->omtu;
1999 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07002000 opts.mode = l2cap_pi(sk)->mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002001 opts.fcs = l2cap_pi(sk)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03002002 opts.max_tx = l2cap_pi(sk)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03002003 opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002004
2005 len = min_t(unsigned int, len, sizeof(opts));
2006 if (copy_to_user(optval, (char *) &opts, len))
2007 err = -EFAULT;
2008
2009 break;
2010
2011 case L2CAP_LM:
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002012 switch (l2cap_pi(sk)->sec_level) {
2013 case BT_SECURITY_LOW:
2014 opt = L2CAP_LM_AUTH;
2015 break;
2016 case BT_SECURITY_MEDIUM:
2017 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT;
2018 break;
2019 case BT_SECURITY_HIGH:
2020 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT |
2021 L2CAP_LM_SECURE;
2022 break;
2023 default:
2024 opt = 0;
2025 break;
2026 }
2027
2028 if (l2cap_pi(sk)->role_switch)
2029 opt |= L2CAP_LM_MASTER;
2030
2031 if (l2cap_pi(sk)->force_reliable)
2032 opt |= L2CAP_LM_RELIABLE;
2033
2034 if (put_user(opt, (u32 __user *) optval))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002035 err = -EFAULT;
2036 break;
2037
2038 case L2CAP_CONNINFO:
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002039 if (sk->sk_state != BT_CONNECTED &&
2040 !(sk->sk_state == BT_CONNECT2 &&
2041 bt_sk(sk)->defer_setup)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002042 err = -ENOTCONN;
2043 break;
2044 }
2045
2046 cinfo.hci_handle = l2cap_pi(sk)->conn->hcon->handle;
2047 memcpy(cinfo.dev_class, l2cap_pi(sk)->conn->hcon->dev_class, 3);
2048
2049 len = min_t(unsigned int, len, sizeof(cinfo));
2050 if (copy_to_user(optval, (char *) &cinfo, len))
2051 err = -EFAULT;
2052
2053 break;
2054
2055 default:
2056 err = -ENOPROTOOPT;
2057 break;
2058 }
2059
2060 release_sock(sk);
2061 return err;
2062}
2063
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002064static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
2065{
2066 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002067 struct bt_security sec;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002068 int len, err = 0;
2069
2070 BT_DBG("sk %p", sk);
2071
2072 if (level == SOL_L2CAP)
2073 return l2cap_sock_getsockopt_old(sock, optname, optval, optlen);
2074
Marcel Holtmann0588d942009-01-16 10:06:13 +01002075 if (level != SOL_BLUETOOTH)
2076 return -ENOPROTOOPT;
2077
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002078 if (get_user(len, optlen))
2079 return -EFAULT;
2080
2081 lock_sock(sk);
2082
2083 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002084 case BT_SECURITY:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03002085 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
2086 && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01002087 err = -EINVAL;
2088 break;
2089 }
2090
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002091 sec.level = l2cap_pi(sk)->sec_level;
2092
2093 len = min_t(unsigned int, len, sizeof(sec));
2094 if (copy_to_user(optval, (char *) &sec, len))
2095 err = -EFAULT;
2096
2097 break;
2098
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002099 case BT_DEFER_SETUP:
2100 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
2101 err = -EINVAL;
2102 break;
2103 }
2104
2105 if (put_user(bt_sk(sk)->defer_setup, (u32 __user *) optval))
2106 err = -EFAULT;
2107
2108 break;
2109
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002110 default:
2111 err = -ENOPROTOOPT;
2112 break;
2113 }
2114
2115 release_sock(sk);
2116 return err;
2117}
2118
Linus Torvalds1da177e2005-04-16 15:20:36 -07002119static int l2cap_sock_shutdown(struct socket *sock, int how)
2120{
2121 struct sock *sk = sock->sk;
2122 int err = 0;
2123
2124 BT_DBG("sock %p, sk %p", sock, sk);
2125
2126 if (!sk)
2127 return 0;
2128
2129 lock_sock(sk);
2130 if (!sk->sk_shutdown) {
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03002131 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
2132 err = __l2cap_wait_ack(sk);
2133
Linus Torvalds1da177e2005-04-16 15:20:36 -07002134 sk->sk_shutdown = SHUTDOWN_MASK;
2135 l2cap_sock_clear_timer(sk);
2136 __l2cap_sock_close(sk, 0);
2137
2138 if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
Marcel Holtmannb1235d72008-07-14 20:13:54 +02002139 err = bt_sock_wait_state(sk, BT_CLOSED,
2140 sk->sk_lingertime);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002141 }
2142 release_sock(sk);
2143 return err;
2144}
2145
2146static int l2cap_sock_release(struct socket *sock)
2147{
2148 struct sock *sk = sock->sk;
2149 int err;
2150
2151 BT_DBG("sock %p, sk %p", sock, sk);
2152
2153 if (!sk)
2154 return 0;
2155
2156 err = l2cap_sock_shutdown(sock, 2);
2157
2158 sock_orphan(sk);
2159 l2cap_sock_kill(sk);
2160 return err;
2161}
2162
Linus Torvalds1da177e2005-04-16 15:20:36 -07002163static void l2cap_chan_ready(struct sock *sk)
2164{
2165 struct sock *parent = bt_sk(sk)->parent;
2166
2167 BT_DBG("sk %p, parent %p", sk, parent);
2168
2169 l2cap_pi(sk)->conf_state = 0;
2170 l2cap_sock_clear_timer(sk);
2171
2172 if (!parent) {
2173 /* Outgoing channel.
2174 * Wake up socket sleeping on connect.
2175 */
2176 sk->sk_state = BT_CONNECTED;
2177 sk->sk_state_change(sk);
2178 } else {
2179 /* Incoming channel.
2180 * Wake up socket sleeping on accept.
2181 */
2182 parent->sk_data_ready(parent, 0);
2183 }
2184}
2185
2186/* Copy frame to all raw sockets on that connection */
2187static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2188{
2189 struct l2cap_chan_list *l = &conn->chan_list;
2190 struct sk_buff *nskb;
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002191 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002192
2193 BT_DBG("conn %p", conn);
2194
2195 read_lock(&l->lock);
2196 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
2197 if (sk->sk_type != SOCK_RAW)
2198 continue;
2199
2200 /* Don't send frame to the socket it came from */
2201 if (skb->sk == sk)
2202 continue;
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002203 nskb = skb_clone(skb, GFP_ATOMIC);
2204 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002205 continue;
2206
2207 if (sock_queue_rcv_skb(sk, nskb))
2208 kfree_skb(nskb);
2209 }
2210 read_unlock(&l->lock);
2211}
2212
2213/* ---- L2CAP signalling commands ---- */
2214static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
2215 u8 code, u8 ident, u16 dlen, void *data)
2216{
2217 struct sk_buff *skb, **frag;
2218 struct l2cap_cmd_hdr *cmd;
2219 struct l2cap_hdr *lh;
2220 int len, count;
2221
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002222 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d",
2223 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002224
2225 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2226 count = min_t(unsigned int, conn->mtu, len);
2227
2228 skb = bt_skb_alloc(count, GFP_ATOMIC);
2229 if (!skb)
2230 return NULL;
2231
2232 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002233 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03002234 lh->cid = cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002235
2236 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2237 cmd->code = code;
2238 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002239 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002240
2241 if (dlen) {
2242 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2243 memcpy(skb_put(skb, count), data, count);
2244 data += count;
2245 }
2246
2247 len -= skb->len;
2248
2249 /* Continuation fragments (no L2CAP header) */
2250 frag = &skb_shinfo(skb)->frag_list;
2251 while (len) {
2252 count = min_t(unsigned int, conn->mtu, len);
2253
2254 *frag = bt_skb_alloc(count, GFP_ATOMIC);
2255 if (!*frag)
2256 goto fail;
2257
2258 memcpy(skb_put(*frag, count), data, count);
2259
2260 len -= count;
2261 data += count;
2262
2263 frag = &(*frag)->next;
2264 }
2265
2266 return skb;
2267
2268fail:
2269 kfree_skb(skb);
2270 return NULL;
2271}
2272
2273static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned long *val)
2274{
2275 struct l2cap_conf_opt *opt = *ptr;
2276 int len;
2277
2278 len = L2CAP_CONF_OPT_SIZE + opt->len;
2279 *ptr += len;
2280
2281 *type = opt->type;
2282 *olen = opt->len;
2283
2284 switch (opt->len) {
2285 case 1:
2286 *val = *((u8 *) opt->val);
2287 break;
2288
2289 case 2:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002290 *val = __le16_to_cpu(*((__le16 *) opt->val));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002291 break;
2292
2293 case 4:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002294 *val = __le32_to_cpu(*((__le32 *) opt->val));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002295 break;
2296
2297 default:
2298 *val = (unsigned long) opt->val;
2299 break;
2300 }
2301
2302 BT_DBG("type 0x%2.2x len %d val 0x%lx", *type, opt->len, *val);
2303 return len;
2304}
2305
Linus Torvalds1da177e2005-04-16 15:20:36 -07002306static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2307{
2308 struct l2cap_conf_opt *opt = *ptr;
2309
2310 BT_DBG("type 0x%2.2x len %d val 0x%lx", type, len, val);
2311
2312 opt->type = type;
2313 opt->len = len;
2314
2315 switch (len) {
2316 case 1:
2317 *((u8 *) opt->val) = val;
2318 break;
2319
2320 case 2:
Al Viro8e036fc2007-07-29 00:16:36 -07002321 *((__le16 *) opt->val) = cpu_to_le16(val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002322 break;
2323
2324 case 4:
Al Viro8e036fc2007-07-29 00:16:36 -07002325 *((__le32 *) opt->val) = cpu_to_le32(val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002326 break;
2327
2328 default:
2329 memcpy(opt->val, (void *) val, len);
2330 break;
2331 }
2332
2333 *ptr += L2CAP_CONF_OPT_SIZE + len;
2334}
2335
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002336static void l2cap_ack_timeout(unsigned long arg)
2337{
2338 struct sock *sk = (void *) arg;
2339
2340 bh_lock_sock(sk);
2341 l2cap_send_ack(l2cap_pi(sk));
2342 bh_unlock_sock(sk);
2343}
2344
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002345static inline void l2cap_ertm_init(struct sock *sk)
2346{
2347 l2cap_pi(sk)->expected_ack_seq = 0;
2348 l2cap_pi(sk)->unacked_frames = 0;
2349 l2cap_pi(sk)->buffer_seq = 0;
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03002350 l2cap_pi(sk)->num_acked = 0;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03002351 l2cap_pi(sk)->frames_sent = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002352
2353 setup_timer(&l2cap_pi(sk)->retrans_timer,
2354 l2cap_retrans_timeout, (unsigned long) sk);
2355 setup_timer(&l2cap_pi(sk)->monitor_timer,
2356 l2cap_monitor_timeout, (unsigned long) sk);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002357 setup_timer(&l2cap_pi(sk)->ack_timer,
2358 l2cap_ack_timeout, (unsigned long) sk);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002359
2360 __skb_queue_head_init(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002361 __skb_queue_head_init(BUSY_QUEUE(sk));
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03002362 spin_lock_init(&l2cap_pi(sk)->send_lock);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002363
2364 INIT_WORK(&l2cap_pi(sk)->busy_work, l2cap_busy_work);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002365}
2366
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002367static int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
2368{
2369 u32 local_feat_mask = l2cap_feat_mask;
2370 if (enable_ertm)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002371 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002372
2373 switch (mode) {
2374 case L2CAP_MODE_ERTM:
2375 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
2376 case L2CAP_MODE_STREAMING:
2377 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
2378 default:
2379 return 0x00;
2380 }
2381}
2382
2383static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
2384{
2385 switch (mode) {
2386 case L2CAP_MODE_STREAMING:
2387 case L2CAP_MODE_ERTM:
2388 if (l2cap_mode_supported(mode, remote_feat_mask))
2389 return mode;
2390 /* fall through */
2391 default:
2392 return L2CAP_MODE_BASIC;
2393 }
2394}
2395
Linus Torvalds1da177e2005-04-16 15:20:36 -07002396static int l2cap_build_conf_req(struct sock *sk, void *data)
2397{
2398 struct l2cap_pinfo *pi = l2cap_pi(sk);
2399 struct l2cap_conf_req *req = data;
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03002400 struct l2cap_conf_rfc rfc = { .mode = pi->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07002401 void *ptr = req->data;
2402
2403 BT_DBG("sk %p", sk);
2404
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002405 if (pi->num_conf_req || pi->num_conf_rsp)
2406 goto done;
2407
2408 switch (pi->mode) {
2409 case L2CAP_MODE_STREAMING:
2410 case L2CAP_MODE_ERTM:
2411 pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002412 if (!l2cap_mode_supported(pi->mode, pi->conn->feat_mask))
2413 l2cap_send_disconn_req(pi->conn, sk);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002414 break;
2415 default:
2416 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
2417 break;
2418 }
2419
2420done:
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002421 switch (pi->mode) {
2422 case L2CAP_MODE_BASIC:
2423 if (pi->imtu != L2CAP_DEFAULT_MTU)
2424 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
2425 break;
2426
2427 case L2CAP_MODE_ERTM:
2428 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03002429 rfc.txwin_size = pi->tx_win;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03002430 rfc.max_transmit = pi->max_tx;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002431 rfc.retrans_timeout = 0;
2432 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002433 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03002434 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002435 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002436
2437 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2438 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002439
2440 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2441 break;
2442
2443 if (pi->fcs == L2CAP_FCS_NONE ||
2444 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
2445 pi->fcs = L2CAP_FCS_NONE;
2446 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
2447 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002448 break;
2449
2450 case L2CAP_MODE_STREAMING:
2451 rfc.mode = L2CAP_MODE_STREAMING;
2452 rfc.txwin_size = 0;
2453 rfc.max_transmit = 0;
2454 rfc.retrans_timeout = 0;
2455 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002456 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03002457 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002458 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002459
2460 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2461 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002462
2463 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2464 break;
2465
2466 if (pi->fcs == L2CAP_FCS_NONE ||
2467 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
2468 pi->fcs = L2CAP_FCS_NONE;
2469 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
2470 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002471 break;
2472 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002473
2474 /* FIXME: Need actual value of the flush timeout */
2475 //if (flush_to != L2CAP_DEFAULT_FLUSH_TO)
2476 // l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2, pi->flush_to);
2477
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002478 req->dcid = cpu_to_le16(pi->dcid);
2479 req->flags = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002480
2481 return ptr - data;
2482}
2483
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002484static int l2cap_parse_conf_req(struct sock *sk, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002485{
2486 struct l2cap_pinfo *pi = l2cap_pi(sk);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002487 struct l2cap_conf_rsp *rsp = data;
2488 void *ptr = rsp->data;
2489 void *req = pi->conf_req;
2490 int len = pi->conf_len;
2491 int type, hint, olen;
2492 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002493 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Marcel Holtmann861d6882007-10-20 13:37:06 +02002494 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002495 u16 result = L2CAP_CONF_SUCCESS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002496
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002497 BT_DBG("sk %p", sk);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01002498
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002499 while (len >= L2CAP_CONF_OPT_SIZE) {
2500 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002501
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03002502 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07002503 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002504
2505 switch (type) {
2506 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002507 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002508 break;
2509
2510 case L2CAP_CONF_FLUSH_TO:
2511 pi->flush_to = val;
2512 break;
2513
2514 case L2CAP_CONF_QOS:
2515 break;
2516
Marcel Holtmann6464f352007-10-20 13:39:51 +02002517 case L2CAP_CONF_RFC:
2518 if (olen == sizeof(rfc))
2519 memcpy(&rfc, (void *) val, olen);
2520 break;
2521
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002522 case L2CAP_CONF_FCS:
2523 if (val == L2CAP_FCS_NONE)
2524 pi->conf_state |= L2CAP_CONF_NO_FCS_RECV;
2525
2526 break;
2527
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002528 default:
2529 if (hint)
2530 break;
2531
2532 result = L2CAP_CONF_UNKNOWN;
2533 *((u8 *) ptr++) = type;
2534 break;
2535 }
2536 }
2537
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002538 if (pi->num_conf_rsp || pi->num_conf_req)
2539 goto done;
2540
2541 switch (pi->mode) {
2542 case L2CAP_MODE_STREAMING:
2543 case L2CAP_MODE_ERTM:
2544 pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
2545 if (!l2cap_mode_supported(pi->mode, pi->conn->feat_mask))
2546 return -ECONNREFUSED;
2547 break;
2548 default:
2549 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
2550 break;
2551 }
2552
2553done:
2554 if (pi->mode != rfc.mode) {
2555 result = L2CAP_CONF_UNACCEPT;
2556 rfc.mode = pi->mode;
2557
2558 if (pi->num_conf_rsp == 1)
2559 return -ECONNREFUSED;
2560
2561 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2562 sizeof(rfc), (unsigned long) &rfc);
2563 }
2564
2565
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002566 if (result == L2CAP_CONF_SUCCESS) {
2567 /* Configure output options and let the other side know
2568 * which ones we don't like. */
2569
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002570 if (mtu < L2CAP_DEFAULT_MIN_MTU)
2571 result = L2CAP_CONF_UNACCEPT;
2572 else {
2573 pi->omtu = mtu;
2574 pi->conf_state |= L2CAP_CONF_MTU_DONE;
2575 }
2576 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002577
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002578 switch (rfc.mode) {
2579 case L2CAP_MODE_BASIC:
2580 pi->fcs = L2CAP_FCS_NONE;
2581 pi->conf_state |= L2CAP_CONF_MODE_DONE;
2582 break;
2583
2584 case L2CAP_MODE_ERTM:
2585 pi->remote_tx_win = rfc.txwin_size;
2586 pi->remote_max_tx = rfc.max_transmit;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002587 if (rfc.max_pdu_size > pi->conn->mtu - 10)
2588 rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10);
2589
2590 pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002591
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002592 rfc.retrans_timeout =
2593 le16_to_cpu(L2CAP_DEFAULT_RETRANS_TO);
2594 rfc.monitor_timeout =
2595 le16_to_cpu(L2CAP_DEFAULT_MONITOR_TO);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002596
2597 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03002598
2599 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2600 sizeof(rfc), (unsigned long) &rfc);
2601
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002602 break;
2603
2604 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002605 if (rfc.max_pdu_size > pi->conn->mtu - 10)
2606 rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10);
2607
2608 pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002609
2610 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03002611
2612 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2613 sizeof(rfc), (unsigned long) &rfc);
2614
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002615 break;
2616
2617 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02002618 result = L2CAP_CONF_UNACCEPT;
2619
2620 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002621 rfc.mode = pi->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002622 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002623
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002624 if (result == L2CAP_CONF_SUCCESS)
2625 pi->conf_state |= L2CAP_CONF_OUTPUT_DONE;
2626 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002627 rsp->scid = cpu_to_le16(pi->dcid);
2628 rsp->result = cpu_to_le16(result);
2629 rsp->flags = cpu_to_le16(0x0000);
2630
2631 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002632}
2633
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002634static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data, u16 *result)
2635{
2636 struct l2cap_pinfo *pi = l2cap_pi(sk);
2637 struct l2cap_conf_req *req = data;
2638 void *ptr = req->data;
2639 int type, olen;
2640 unsigned long val;
2641 struct l2cap_conf_rfc rfc;
2642
2643 BT_DBG("sk %p, rsp %p, len %d, req %p", sk, rsp, len, data);
2644
2645 while (len >= L2CAP_CONF_OPT_SIZE) {
2646 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
2647
2648 switch (type) {
2649 case L2CAP_CONF_MTU:
2650 if (val < L2CAP_DEFAULT_MIN_MTU) {
2651 *result = L2CAP_CONF_UNACCEPT;
2652 pi->omtu = L2CAP_DEFAULT_MIN_MTU;
2653 } else
2654 pi->omtu = val;
2655 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
2656 break;
2657
2658 case L2CAP_CONF_FLUSH_TO:
2659 pi->flush_to = val;
2660 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
2661 2, pi->flush_to);
2662 break;
2663
2664 case L2CAP_CONF_RFC:
2665 if (olen == sizeof(rfc))
2666 memcpy(&rfc, (void *)val, olen);
2667
2668 if ((pi->conf_state & L2CAP_CONF_STATE2_DEVICE) &&
2669 rfc.mode != pi->mode)
2670 return -ECONNREFUSED;
2671
2672 pi->mode = rfc.mode;
2673 pi->fcs = 0;
2674
2675 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2676 sizeof(rfc), (unsigned long) &rfc);
2677 break;
2678 }
2679 }
2680
2681 if (*result == L2CAP_CONF_SUCCESS) {
2682 switch (rfc.mode) {
2683 case L2CAP_MODE_ERTM:
2684 pi->remote_tx_win = rfc.txwin_size;
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002685 pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
2686 pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002687 pi->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002688 break;
2689 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002690 pi->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002691 }
2692 }
2693
2694 req->dcid = cpu_to_le16(pi->dcid);
2695 req->flags = cpu_to_le16(0x0000);
2696
2697 return ptr - data;
2698}
2699
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002700static int l2cap_build_conf_rsp(struct sock *sk, void *data, u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002701{
2702 struct l2cap_conf_rsp *rsp = data;
2703 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002704
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002705 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002706
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002707 rsp->scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002708 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002709 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002710
2711 return ptr - data;
2712}
2713
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002714static void l2cap_conf_rfc_get(struct sock *sk, void *rsp, int len)
2715{
2716 struct l2cap_pinfo *pi = l2cap_pi(sk);
2717 int type, olen;
2718 unsigned long val;
2719 struct l2cap_conf_rfc rfc;
2720
2721 BT_DBG("sk %p, rsp %p, len %d", sk, rsp, len);
2722
2723 if ((pi->mode != L2CAP_MODE_ERTM) && (pi->mode != L2CAP_MODE_STREAMING))
2724 return;
2725
2726 while (len >= L2CAP_CONF_OPT_SIZE) {
2727 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
2728
2729 switch (type) {
2730 case L2CAP_CONF_RFC:
2731 if (olen == sizeof(rfc))
2732 memcpy(&rfc, (void *)val, olen);
2733 goto done;
2734 }
2735 }
2736
2737done:
2738 switch (rfc.mode) {
2739 case L2CAP_MODE_ERTM:
2740 pi->remote_tx_win = rfc.txwin_size;
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002741 pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
2742 pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002743 pi->mps = le16_to_cpu(rfc.max_pdu_size);
2744 break;
2745 case L2CAP_MODE_STREAMING:
2746 pi->mps = le16_to_cpu(rfc.max_pdu_size);
2747 }
2748}
2749
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002750static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2751{
2752 struct l2cap_cmd_rej *rej = (struct l2cap_cmd_rej *) data;
2753
2754 if (rej->reason != 0x0000)
2755 return 0;
2756
2757 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
2758 cmd->ident == conn->info_ident) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002759 del_timer(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01002760
2761 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002762 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01002763
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002764 l2cap_conn_start(conn);
2765 }
2766
2767 return 0;
2768}
2769
Linus Torvalds1da177e2005-04-16 15:20:36 -07002770static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2771{
2772 struct l2cap_chan_list *list = &conn->chan_list;
2773 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
2774 struct l2cap_conn_rsp rsp;
2775 struct sock *sk, *parent;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002776 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002777
2778 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002779 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002780
2781 BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
2782
2783 /* Check if we have socket listening on psm */
2784 parent = l2cap_get_sock_by_psm(BT_LISTEN, psm, conn->src);
2785 if (!parent) {
2786 result = L2CAP_CR_BAD_PSM;
2787 goto sendresp;
2788 }
2789
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002790 /* Check if the ACL is secure enough (if not SDP) */
2791 if (psm != cpu_to_le16(0x0001) &&
2792 !hci_conn_check_link_mode(conn->hcon)) {
Marcel Holtmann2950f212009-02-12 14:02:50 +01002793 conn->disc_reason = 0x05;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002794 result = L2CAP_CR_SEC_BLOCK;
2795 goto response;
2796 }
2797
Linus Torvalds1da177e2005-04-16 15:20:36 -07002798 result = L2CAP_CR_NO_MEM;
2799
2800 /* Check for backlog size */
2801 if (sk_acceptq_is_full(parent)) {
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09002802 BT_DBG("backlog full %d", parent->sk_ack_backlog);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002803 goto response;
2804 }
2805
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09002806 sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002807 if (!sk)
2808 goto response;
2809
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002810 write_lock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002811
2812 /* Check if we already have channel with that dcid */
2813 if (__l2cap_get_chan_by_dcid(list, scid)) {
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002814 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002815 sock_set_flag(sk, SOCK_ZAPPED);
2816 l2cap_sock_kill(sk);
2817 goto response;
2818 }
2819
2820 hci_conn_hold(conn->hcon);
2821
2822 l2cap_sock_init(sk, parent);
2823 bacpy(&bt_sk(sk)->src, conn->src);
2824 bacpy(&bt_sk(sk)->dst, conn->dst);
2825 l2cap_pi(sk)->psm = psm;
2826 l2cap_pi(sk)->dcid = scid;
2827
2828 __l2cap_chan_add(conn, sk, parent);
2829 dcid = l2cap_pi(sk)->scid;
2830
2831 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
2832
Linus Torvalds1da177e2005-04-16 15:20:36 -07002833 l2cap_pi(sk)->ident = cmd->ident;
2834
Marcel Holtmann984947d2009-02-06 23:35:19 +01002835 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002836 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002837 if (bt_sk(sk)->defer_setup) {
2838 sk->sk_state = BT_CONNECT2;
2839 result = L2CAP_CR_PEND;
2840 status = L2CAP_CS_AUTHOR_PEND;
2841 parent->sk_data_ready(parent, 0);
2842 } else {
2843 sk->sk_state = BT_CONFIG;
2844 result = L2CAP_CR_SUCCESS;
2845 status = L2CAP_CS_NO_INFO;
2846 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002847 } else {
2848 sk->sk_state = BT_CONNECT2;
2849 result = L2CAP_CR_PEND;
2850 status = L2CAP_CS_AUTHEN_PEND;
2851 }
2852 } else {
2853 sk->sk_state = BT_CONNECT2;
2854 result = L2CAP_CR_PEND;
2855 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002856 }
2857
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002858 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002859
2860response:
2861 bh_unlock_sock(parent);
2862
2863sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002864 rsp.scid = cpu_to_le16(scid);
2865 rsp.dcid = cpu_to_le16(dcid);
2866 rsp.result = cpu_to_le16(result);
2867 rsp.status = cpu_to_le16(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002868 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002869
2870 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
2871 struct l2cap_info_req info;
2872 info.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
2873
2874 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
2875 conn->info_ident = l2cap_get_ident(conn);
2876
2877 mod_timer(&conn->info_timer, jiffies +
2878 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
2879
2880 l2cap_send_cmd(conn, conn->info_ident,
2881 L2CAP_INFO_REQ, sizeof(info), &info);
2882 }
2883
Linus Torvalds1da177e2005-04-16 15:20:36 -07002884 return 0;
2885}
2886
2887static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2888{
2889 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
2890 u16 scid, dcid, result, status;
2891 struct sock *sk;
2892 u8 req[128];
2893
2894 scid = __le16_to_cpu(rsp->scid);
2895 dcid = __le16_to_cpu(rsp->dcid);
2896 result = __le16_to_cpu(rsp->result);
2897 status = __le16_to_cpu(rsp->status);
2898
2899 BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
2900
2901 if (scid) {
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002902 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2903 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002904 return 0;
2905 } else {
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002906 sk = l2cap_get_chan_by_ident(&conn->chan_list, cmd->ident);
2907 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002908 return 0;
2909 }
2910
2911 switch (result) {
2912 case L2CAP_CR_SUCCESS:
2913 sk->sk_state = BT_CONFIG;
2914 l2cap_pi(sk)->ident = 0;
2915 l2cap_pi(sk)->dcid = dcid;
2916 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002917 l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_CONNECT_PEND;
2918
Linus Torvalds1da177e2005-04-16 15:20:36 -07002919 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
2920 l2cap_build_conf_req(sk, req), req);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002921 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002922 break;
2923
2924 case L2CAP_CR_PEND:
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002925 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002926 break;
2927
2928 default:
2929 l2cap_chan_del(sk, ECONNREFUSED);
2930 break;
2931 }
2932
2933 bh_unlock_sock(sk);
2934 return 0;
2935}
2936
Al Viro88219a02007-07-29 00:17:25 -07002937static 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 -07002938{
2939 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
2940 u16 dcid, flags;
2941 u8 rsp[64];
2942 struct sock *sk;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002943 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002944
2945 dcid = __le16_to_cpu(req->dcid);
2946 flags = __le16_to_cpu(req->flags);
2947
2948 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
2949
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002950 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
2951 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002952 return -ENOENT;
2953
Marcel Holtmann354f60a2006-11-18 22:15:20 +01002954 if (sk->sk_state == BT_DISCONN)
2955 goto unlock;
2956
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002957 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07002958 len = cmd_len - sizeof(*req);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002959 if (l2cap_pi(sk)->conf_len + len > sizeof(l2cap_pi(sk)->conf_req)) {
2960 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
2961 l2cap_build_conf_rsp(sk, rsp,
2962 L2CAP_CONF_REJECT, flags), rsp);
2963 goto unlock;
2964 }
2965
2966 /* Store config. */
2967 memcpy(l2cap_pi(sk)->conf_req + l2cap_pi(sk)->conf_len, req->data, len);
2968 l2cap_pi(sk)->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002969
2970 if (flags & 0x0001) {
2971 /* Incomplete config. Send empty response. */
2972 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002973 l2cap_build_conf_rsp(sk, rsp,
2974 L2CAP_CONF_SUCCESS, 0x0001), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002975 goto unlock;
2976 }
2977
2978 /* Complete config. */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002979 len = l2cap_parse_conf_req(sk, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002980 if (len < 0) {
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002981 l2cap_send_disconn_req(conn, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002982 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002983 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002984
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002985 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002986 l2cap_pi(sk)->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002987
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002988 /* Reset config buffer. */
2989 l2cap_pi(sk)->conf_len = 0;
2990
Marcel Holtmann876d9482007-10-20 13:35:42 +02002991 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE))
2992 goto unlock;
2993
Linus Torvalds1da177e2005-04-16 15:20:36 -07002994 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) {
Joe Perchesf64f9e72009-11-29 16:55:45 -08002995 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) ||
2996 l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002997 l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
2998
Linus Torvalds1da177e2005-04-16 15:20:36 -07002999 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003000
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003001 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003002 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003003 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003004 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
3005 l2cap_ertm_init(sk);
3006
Linus Torvalds1da177e2005-04-16 15:20:36 -07003007 l2cap_chan_ready(sk);
Marcel Holtmann876d9482007-10-20 13:35:42 +02003008 goto unlock;
3009 }
3010
3011 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003012 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003013 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003014 l2cap_build_conf_req(sk, buf), buf);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003015 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003016 }
3017
3018unlock:
3019 bh_unlock_sock(sk);
3020 return 0;
3021}
3022
3023static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3024{
3025 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
3026 u16 scid, flags, result;
3027 struct sock *sk;
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003028 int len = cmd->len - sizeof(*rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003029
3030 scid = __le16_to_cpu(rsp->scid);
3031 flags = __le16_to_cpu(rsp->flags);
3032 result = __le16_to_cpu(rsp->result);
3033
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03003034 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x",
3035 scid, flags, result);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003036
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03003037 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
3038 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003039 return 0;
3040
3041 switch (result) {
3042 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003043 l2cap_conf_rfc_get(sk, rsp->data, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003044 break;
3045
3046 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003047 if (l2cap_pi(sk)->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003048 char req[64];
3049
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02003050 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
3051 l2cap_send_disconn_req(conn, sk);
3052 goto done;
3053 }
3054
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003055 /* throw out any old stored conf requests */
3056 result = L2CAP_CONF_SUCCESS;
3057 len = l2cap_parse_conf_rsp(sk, rsp->data,
3058 len, req, &result);
3059 if (len < 0) {
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03003060 l2cap_send_disconn_req(conn, sk);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003061 goto done;
3062 }
3063
3064 l2cap_send_cmd(conn, l2cap_get_ident(conn),
3065 L2CAP_CONF_REQ, len, req);
3066 l2cap_pi(sk)->num_conf_req++;
3067 if (result != L2CAP_CONF_SUCCESS)
3068 goto done;
3069 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003070 }
3071
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09003072 default:
Linus Torvalds1da177e2005-04-16 15:20:36 -07003073 sk->sk_state = BT_DISCONN;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02003074 sk->sk_err = ECONNRESET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003075 l2cap_sock_set_timer(sk, HZ * 5);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03003076 l2cap_send_disconn_req(conn, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003077 goto done;
3078 }
3079
3080 if (flags & 0x01)
3081 goto done;
3082
Linus Torvalds1da177e2005-04-16 15:20:36 -07003083 l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE;
3084
3085 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) {
Joe Perchesf64f9e72009-11-29 16:55:45 -08003086 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) ||
3087 l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003088 l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
3089
Linus Torvalds1da177e2005-04-16 15:20:36 -07003090 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003091 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003092 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003093 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003094 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
3095 l2cap_ertm_init(sk);
3096
Linus Torvalds1da177e2005-04-16 15:20:36 -07003097 l2cap_chan_ready(sk);
3098 }
3099
3100done:
3101 bh_unlock_sock(sk);
3102 return 0;
3103}
3104
3105static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3106{
3107 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
3108 struct l2cap_disconn_rsp rsp;
3109 u16 dcid, scid;
3110 struct sock *sk;
3111
3112 scid = __le16_to_cpu(req->scid);
3113 dcid = __le16_to_cpu(req->dcid);
3114
3115 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
3116
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03003117 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
3118 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003119 return 0;
3120
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003121 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
3122 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003123 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
3124
3125 sk->sk_shutdown = SHUTDOWN_MASK;
3126
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003127 skb_queue_purge(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003128
3129 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
3130 skb_queue_purge(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003131 skb_queue_purge(BUSY_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003132 del_timer(&l2cap_pi(sk)->retrans_timer);
3133 del_timer(&l2cap_pi(sk)->monitor_timer);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003134 del_timer(&l2cap_pi(sk)->ack_timer);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003135 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003136
Linus Torvalds1da177e2005-04-16 15:20:36 -07003137 l2cap_chan_del(sk, ECONNRESET);
3138 bh_unlock_sock(sk);
3139
3140 l2cap_sock_kill(sk);
3141 return 0;
3142}
3143
3144static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3145{
3146 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
3147 u16 dcid, scid;
3148 struct sock *sk;
3149
3150 scid = __le16_to_cpu(rsp->scid);
3151 dcid = __le16_to_cpu(rsp->dcid);
3152
3153 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
3154
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03003155 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
3156 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003157 return 0;
3158
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003159 skb_queue_purge(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003160
3161 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
3162 skb_queue_purge(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003163 skb_queue_purge(BUSY_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003164 del_timer(&l2cap_pi(sk)->retrans_timer);
3165 del_timer(&l2cap_pi(sk)->monitor_timer);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003166 del_timer(&l2cap_pi(sk)->ack_timer);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003167 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003168
Linus Torvalds1da177e2005-04-16 15:20:36 -07003169 l2cap_chan_del(sk, 0);
3170 bh_unlock_sock(sk);
3171
3172 l2cap_sock_kill(sk);
3173 return 0;
3174}
3175
3176static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3177{
3178 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003179 u16 type;
3180
3181 type = __le16_to_cpu(req->type);
3182
3183 BT_DBG("type 0x%4.4x", type);
3184
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003185 if (type == L2CAP_IT_FEAT_MASK) {
3186 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003187 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003188 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
3189 rsp->type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
3190 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003191 if (enable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003192 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
3193 | L2CAP_FEAT_FCS;
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03003194 put_unaligned_le32(feat_mask, rsp->data);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003195 l2cap_send_cmd(conn, cmd->ident,
3196 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003197 } else if (type == L2CAP_IT_FIXED_CHAN) {
3198 u8 buf[12];
3199 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
3200 rsp->type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3201 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
3202 memcpy(buf + 4, l2cap_fixed_chan, 8);
3203 l2cap_send_cmd(conn, cmd->ident,
3204 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003205 } else {
3206 struct l2cap_info_rsp rsp;
3207 rsp.type = cpu_to_le16(type);
3208 rsp.result = cpu_to_le16(L2CAP_IR_NOTSUPP);
3209 l2cap_send_cmd(conn, cmd->ident,
3210 L2CAP_INFO_RSP, sizeof(rsp), &rsp);
3211 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003212
3213 return 0;
3214}
3215
3216static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3217{
3218 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
3219 u16 type, result;
3220
3221 type = __le16_to_cpu(rsp->type);
3222 result = __le16_to_cpu(rsp->result);
3223
3224 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
3225
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003226 del_timer(&conn->info_timer);
3227
Marcel Holtmann984947d2009-02-06 23:35:19 +01003228 if (type == L2CAP_IT_FEAT_MASK) {
Harvey Harrison83985312008-05-02 16:25:46 -07003229 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003230
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003231 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003232 struct l2cap_info_req req;
3233 req.type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3234
3235 conn->info_ident = l2cap_get_ident(conn);
3236
3237 l2cap_send_cmd(conn, conn->info_ident,
3238 L2CAP_INFO_REQ, sizeof(req), &req);
3239 } else {
3240 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
3241 conn->info_ident = 0;
3242
3243 l2cap_conn_start(conn);
3244 }
3245 } else if (type == L2CAP_IT_FIXED_CHAN) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01003246 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003247 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003248
3249 l2cap_conn_start(conn);
3250 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003251
Linus Torvalds1da177e2005-04-16 15:20:36 -07003252 return 0;
3253}
3254
3255static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
3256{
3257 u8 *data = skb->data;
3258 int len = skb->len;
3259 struct l2cap_cmd_hdr cmd;
3260 int err = 0;
3261
3262 l2cap_raw_recv(conn, skb);
3263
3264 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07003265 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003266 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
3267 data += L2CAP_CMD_HDR_SIZE;
3268 len -= L2CAP_CMD_HDR_SIZE;
3269
Al Viro88219a02007-07-29 00:17:25 -07003270 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003271
Al Viro88219a02007-07-29 00:17:25 -07003272 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 -07003273
Al Viro88219a02007-07-29 00:17:25 -07003274 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003275 BT_DBG("corrupted command");
3276 break;
3277 }
3278
3279 switch (cmd.code) {
3280 case L2CAP_COMMAND_REJ:
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003281 l2cap_command_rej(conn, &cmd, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003282 break;
3283
3284 case L2CAP_CONN_REQ:
3285 err = l2cap_connect_req(conn, &cmd, data);
3286 break;
3287
3288 case L2CAP_CONN_RSP:
3289 err = l2cap_connect_rsp(conn, &cmd, data);
3290 break;
3291
3292 case L2CAP_CONF_REQ:
Al Viro88219a02007-07-29 00:17:25 -07003293 err = l2cap_config_req(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003294 break;
3295
3296 case L2CAP_CONF_RSP:
3297 err = l2cap_config_rsp(conn, &cmd, data);
3298 break;
3299
3300 case L2CAP_DISCONN_REQ:
3301 err = l2cap_disconnect_req(conn, &cmd, data);
3302 break;
3303
3304 case L2CAP_DISCONN_RSP:
3305 err = l2cap_disconnect_rsp(conn, &cmd, data);
3306 break;
3307
3308 case L2CAP_ECHO_REQ:
Al Viro88219a02007-07-29 00:17:25 -07003309 l2cap_send_cmd(conn, cmd.ident, L2CAP_ECHO_RSP, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003310 break;
3311
3312 case L2CAP_ECHO_RSP:
3313 break;
3314
3315 case L2CAP_INFO_REQ:
3316 err = l2cap_information_req(conn, &cmd, data);
3317 break;
3318
3319 case L2CAP_INFO_RSP:
3320 err = l2cap_information_rsp(conn, &cmd, data);
3321 break;
3322
3323 default:
3324 BT_ERR("Unknown signaling command 0x%2.2x", cmd.code);
3325 err = -EINVAL;
3326 break;
3327 }
3328
3329 if (err) {
3330 struct l2cap_cmd_rej rej;
3331 BT_DBG("error %d", err);
3332
3333 /* FIXME: Map err to a valid reason */
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003334 rej.reason = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003335 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
3336 }
3337
Al Viro88219a02007-07-29 00:17:25 -07003338 data += cmd_len;
3339 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003340 }
3341
3342 kfree_skb(skb);
3343}
3344
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003345static int l2cap_check_fcs(struct l2cap_pinfo *pi, struct sk_buff *skb)
3346{
3347 u16 our_fcs, rcv_fcs;
3348 int hdr_size = L2CAP_HDR_SIZE + 2;
3349
3350 if (pi->fcs == L2CAP_FCS_CRC16) {
3351 skb_trim(skb, skb->len - 2);
3352 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
3353 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
3354
3355 if (our_fcs != rcv_fcs)
3356 return -EINVAL;
3357 }
3358 return 0;
3359}
3360
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003361static inline void l2cap_send_i_or_rr_or_rnr(struct sock *sk)
3362{
3363 struct l2cap_pinfo *pi = l2cap_pi(sk);
3364 u16 control = 0;
3365
3366 pi->frames_sent = 0;
3367 pi->conn_state |= L2CAP_CONN_SEND_FBIT;
3368
3369 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3370
3371 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
3372 control |= L2CAP_SUPER_RCV_NOT_READY | L2CAP_CTRL_FINAL;
3373 l2cap_send_sframe(pi, control);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003374 pi->conn_state |= L2CAP_CONN_RNR_SENT;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003375 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
3376 }
3377
3378 if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY && pi->unacked_frames > 0)
3379 __mod_retrans_timer();
3380
Gustavo F. Padovan844c0972010-05-04 23:16:01 -03003381 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
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;
3397
3398 bt_cb(skb)->tx_seq = tx_seq;
3399 bt_cb(skb)->sar = sar;
3400
3401 next_skb = skb_peek(SREJ_QUEUE(sk));
3402 if (!next_skb) {
3403 __skb_queue_tail(SREJ_QUEUE(sk), skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003404 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003405 }
3406
3407 do {
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003408 if (bt_cb(next_skb)->tx_seq == tx_seq)
3409 return -EINVAL;
3410
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003411 if (bt_cb(next_skb)->tx_seq > tx_seq) {
3412 __skb_queue_before(SREJ_QUEUE(sk), next_skb, skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003413 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003414 }
3415
3416 if (skb_queue_is_last(SREJ_QUEUE(sk), next_skb))
3417 break;
3418
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003419 } while ((next_skb = skb_queue_next(SREJ_QUEUE(sk), next_skb)));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003420
3421 __skb_queue_tail(SREJ_QUEUE(sk), skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003422
3423 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003424}
3425
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003426static int l2cap_ertm_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
3427{
3428 struct l2cap_pinfo *pi = l2cap_pi(sk);
3429 struct sk_buff *_skb;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003430 int err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003431
3432 switch (control & L2CAP_CTRL_SAR) {
3433 case L2CAP_SDU_UNSEGMENTED:
3434 if (pi->conn_state & L2CAP_CONN_SAR_SDU)
3435 goto drop;
3436
3437 err = sock_queue_rcv_skb(sk, skb);
3438 if (!err)
3439 return err;
3440
3441 break;
3442
3443 case L2CAP_SDU_START:
3444 if (pi->conn_state & L2CAP_CONN_SAR_SDU)
3445 goto drop;
3446
3447 pi->sdu_len = get_unaligned_le16(skb->data);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003448
3449 if (pi->sdu_len > pi->imtu)
3450 goto disconnect;
3451
3452 pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003453 if (!pi->sdu)
3454 return -ENOMEM;
3455
3456 /* pull sdu_len bytes only after alloc, because of Local Busy
3457 * condition we have to be sure that this will be executed
3458 * only once, i.e., when alloc does not fail */
3459 skb_pull(skb, 2);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003460
3461 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3462
3463 pi->conn_state |= L2CAP_CONN_SAR_SDU;
3464 pi->partial_sdu_len = skb->len;
3465 break;
3466
3467 case L2CAP_SDU_CONTINUE:
3468 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3469 goto disconnect;
3470
3471 if (!pi->sdu)
3472 goto disconnect;
3473
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003474 pi->partial_sdu_len += skb->len;
3475 if (pi->partial_sdu_len > pi->sdu_len)
3476 goto drop;
3477
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03003478 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3479
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003480 break;
3481
3482 case L2CAP_SDU_END:
3483 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3484 goto disconnect;
3485
3486 if (!pi->sdu)
3487 goto disconnect;
3488
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003489 if (!(pi->conn_state & L2CAP_CONN_SAR_RETRY)) {
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003490 pi->partial_sdu_len += skb->len;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003491
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003492 if (pi->partial_sdu_len > pi->imtu)
3493 goto drop;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003494
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003495 if (pi->partial_sdu_len != pi->sdu_len)
3496 goto drop;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03003497
3498 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003499 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003500
3501 _skb = skb_clone(pi->sdu, GFP_ATOMIC);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003502 if (!_skb) {
3503 pi->conn_state |= L2CAP_CONN_SAR_RETRY;
3504 return -ENOMEM;
3505 }
3506
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003507 err = sock_queue_rcv_skb(sk, _skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003508 if (err < 0) {
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003509 kfree_skb(_skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003510 pi->conn_state |= L2CAP_CONN_SAR_RETRY;
3511 return err;
3512 }
3513
3514 pi->conn_state &= ~L2CAP_CONN_SAR_RETRY;
3515 pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003516
3517 kfree_skb(pi->sdu);
3518 break;
3519 }
3520
3521 kfree_skb(skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003522 return 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003523
3524drop:
3525 kfree_skb(pi->sdu);
3526 pi->sdu = NULL;
3527
3528disconnect:
3529 l2cap_send_disconn_req(pi->conn, sk);
3530 kfree_skb(skb);
3531 return 0;
3532}
3533
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003534static void l2cap_busy_work(struct work_struct *work)
3535{
3536 DECLARE_WAITQUEUE(wait, current);
3537 struct l2cap_pinfo *pi =
3538 container_of(work, struct l2cap_pinfo, busy_work);
3539 struct sock *sk = (struct sock *)pi;
3540 int n_tries = 0, timeo = HZ/5, err;
3541 struct sk_buff *skb;
3542 u16 control;
3543
3544 lock_sock(sk);
3545
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02003546 add_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003547 while ((skb = skb_peek(BUSY_QUEUE(sk)))) {
3548 set_current_state(TASK_INTERRUPTIBLE);
3549
3550 if (n_tries++ > L2CAP_LOCAL_BUSY_TRIES) {
3551 err = -EBUSY;
3552 l2cap_send_disconn_req(pi->conn, sk);
3553 goto done;
3554 }
3555
3556 if (!timeo)
3557 timeo = HZ/5;
3558
3559 if (signal_pending(current)) {
3560 err = sock_intr_errno(timeo);
3561 goto done;
3562 }
3563
3564 release_sock(sk);
3565 timeo = schedule_timeout(timeo);
3566 lock_sock(sk);
3567
3568 err = sock_error(sk);
3569 if (err)
3570 goto done;
3571
3572 while ((skb = skb_dequeue(BUSY_QUEUE(sk)))) {
3573 control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
3574 err = l2cap_ertm_reassembly_sdu(sk, skb, control);
3575 if (err < 0) {
3576 skb_queue_head(BUSY_QUEUE(sk), skb);
3577 break;
3578 }
3579
3580 pi->buffer_seq = (pi->buffer_seq + 1) % 64;
3581 }
3582
3583 if (!skb)
3584 break;
3585 }
3586
3587 if (!(pi->conn_state & L2CAP_CONN_RNR_SENT))
3588 goto done;
3589
3590 control = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3591 control |= L2CAP_SUPER_RCV_READY | L2CAP_CTRL_POLL;
3592 l2cap_send_sframe(pi, control);
3593 l2cap_pi(sk)->retry_count = 1;
3594
3595 del_timer(&pi->retrans_timer);
3596 __mod_monitor_timer();
3597
3598 l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
3599
3600done:
3601 pi->conn_state &= ~L2CAP_CONN_LOCAL_BUSY;
3602 pi->conn_state &= ~L2CAP_CONN_RNR_SENT;
3603
3604 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02003605 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003606
3607 release_sock(sk);
3608}
3609
3610static int l2cap_push_rx_skb(struct sock *sk, struct sk_buff *skb, u16 control)
3611{
3612 struct l2cap_pinfo *pi = l2cap_pi(sk);
3613 int sctrl, err;
3614
3615 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
3616 bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT;
3617 __skb_queue_tail(BUSY_QUEUE(sk), skb);
3618 return -EBUSY;
3619 }
3620
3621 err = l2cap_ertm_reassembly_sdu(sk, skb, control);
3622 if (err >= 0) {
3623 pi->buffer_seq = (pi->buffer_seq + 1) % 64;
3624 return err;
3625 }
3626
3627 /* Busy Condition */
3628 pi->conn_state |= L2CAP_CONN_LOCAL_BUSY;
3629 bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT;
3630 __skb_queue_tail(BUSY_QUEUE(sk), skb);
3631
3632 sctrl = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3633 sctrl |= L2CAP_SUPER_RCV_NOT_READY;
3634 l2cap_send_sframe(pi, sctrl);
3635
3636 pi->conn_state |= L2CAP_CONN_RNR_SENT;
3637
3638 queue_work(_busy_wq, &pi->busy_work);
3639
3640 return err;
3641}
3642
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003643static int l2cap_streaming_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003644{
3645 struct l2cap_pinfo *pi = l2cap_pi(sk);
3646 struct sk_buff *_skb;
3647 int err = -EINVAL;
3648
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003649 /*
3650 * TODO: We have to notify the userland if some data is lost with the
3651 * Streaming Mode.
3652 */
3653
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003654 switch (control & L2CAP_CTRL_SAR) {
3655 case L2CAP_SDU_UNSEGMENTED:
3656 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3657 kfree_skb(pi->sdu);
3658 break;
3659 }
3660
3661 err = sock_queue_rcv_skb(sk, skb);
3662 if (!err)
3663 return 0;
3664
3665 break;
3666
3667 case L2CAP_SDU_START:
3668 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3669 kfree_skb(pi->sdu);
3670 break;
3671 }
3672
3673 pi->sdu_len = get_unaligned_le16(skb->data);
3674 skb_pull(skb, 2);
3675
Gustavo F. Padovan052897c2010-05-01 16:15:40 -03003676 if (pi->sdu_len > pi->imtu) {
3677 err = -EMSGSIZE;
3678 break;
3679 }
3680
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003681 pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
3682 if (!pi->sdu) {
3683 err = -ENOMEM;
3684 break;
3685 }
3686
3687 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3688
3689 pi->conn_state |= L2CAP_CONN_SAR_SDU;
3690 pi->partial_sdu_len = skb->len;
3691 err = 0;
3692 break;
3693
3694 case L2CAP_SDU_CONTINUE:
3695 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3696 break;
3697
3698 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3699
3700 pi->partial_sdu_len += skb->len;
3701 if (pi->partial_sdu_len > pi->sdu_len)
3702 kfree_skb(pi->sdu);
3703 else
3704 err = 0;
3705
3706 break;
3707
3708 case L2CAP_SDU_END:
3709 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3710 break;
3711
3712 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3713
3714 pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
3715 pi->partial_sdu_len += skb->len;
3716
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003717 if (pi->partial_sdu_len > pi->imtu)
3718 goto drop;
3719
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003720 if (pi->partial_sdu_len == pi->sdu_len) {
3721 _skb = skb_clone(pi->sdu, GFP_ATOMIC);
3722 err = sock_queue_rcv_skb(sk, _skb);
3723 if (err < 0)
3724 kfree_skb(_skb);
3725 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003726 err = 0;
3727
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003728drop:
3729 kfree_skb(pi->sdu);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003730 break;
3731 }
3732
3733 kfree_skb(skb);
3734 return err;
3735}
3736
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003737static void l2cap_check_srej_gap(struct sock *sk, u8 tx_seq)
3738{
3739 struct sk_buff *skb;
Gustavo F. Padovanafefdbc2010-05-01 16:15:43 -03003740 u16 control;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003741
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003742 while ((skb = skb_peek(SREJ_QUEUE(sk)))) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003743 if (bt_cb(skb)->tx_seq != tx_seq)
3744 break;
3745
3746 skb = skb_dequeue(SREJ_QUEUE(sk));
Gustavo F. Padovanafefdbc2010-05-01 16:15:43 -03003747 control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003748 l2cap_ertm_reassembly_sdu(sk, skb, control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003749 l2cap_pi(sk)->buffer_seq_srej =
3750 (l2cap_pi(sk)->buffer_seq_srej + 1) % 64;
3751 tx_seq++;
3752 }
3753}
3754
3755static void l2cap_resend_srejframe(struct sock *sk, u8 tx_seq)
3756{
3757 struct l2cap_pinfo *pi = l2cap_pi(sk);
3758 struct srej_list *l, *tmp;
3759 u16 control;
3760
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003761 list_for_each_entry_safe(l, tmp, SREJ_LIST(sk), list) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003762 if (l->tx_seq == tx_seq) {
3763 list_del(&l->list);
3764 kfree(l);
3765 return;
3766 }
3767 control = L2CAP_SUPER_SELECT_REJECT;
3768 control |= l->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3769 l2cap_send_sframe(pi, control);
3770 list_del(&l->list);
3771 list_add_tail(&l->list, SREJ_LIST(sk));
3772 }
3773}
3774
3775static void l2cap_send_srejframe(struct sock *sk, u8 tx_seq)
3776{
3777 struct l2cap_pinfo *pi = l2cap_pi(sk);
3778 struct srej_list *new;
3779 u16 control;
3780
3781 while (tx_seq != pi->expected_tx_seq) {
3782 control = L2CAP_SUPER_SELECT_REJECT;
3783 control |= pi->expected_tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3784 l2cap_send_sframe(pi, control);
3785
3786 new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC);
3787 new->tx_seq = pi->expected_tx_seq++;
3788 list_add_tail(&new->list, SREJ_LIST(sk));
3789 }
3790 pi->expected_tx_seq++;
3791}
3792
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003793static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
3794{
3795 struct l2cap_pinfo *pi = l2cap_pi(sk);
3796 u8 tx_seq = __get_txseq(rx_control);
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003797 u8 req_seq = __get_reqseq(rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003798 u8 sar = rx_control >> L2CAP_CTRL_SAR_SHIFT;
Gustavo F. Padovanf6337c72010-05-10 18:32:04 -03003799 int tx_seq_offset, expected_tx_seq_offset;
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03003800 int num_to_ack = (pi->tx_win/6) + 1;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003801 int err = 0;
3802
3803 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
3804
Gustavo F. Padovan9b16dc62010-05-05 20:05:57 -03003805 if (L2CAP_CTRL_FINAL & rx_control &&
3806 l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) {
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003807 del_timer(&pi->monitor_timer);
3808 if (pi->unacked_frames > 0)
3809 __mod_retrans_timer();
3810 pi->conn_state &= ~L2CAP_CONN_WAIT_F;
3811 }
3812
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003813 pi->expected_ack_seq = req_seq;
3814 l2cap_drop_acked_frames(sk);
3815
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003816 if (tx_seq == pi->expected_tx_seq)
3817 goto expected;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003818
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003819 tx_seq_offset = (tx_seq - pi->buffer_seq) % 64;
3820 if (tx_seq_offset < 0)
3821 tx_seq_offset += 64;
3822
3823 /* invalid tx_seq */
3824 if (tx_seq_offset >= pi->tx_win) {
3825 l2cap_send_disconn_req(pi->conn, sk);
3826 goto drop;
3827 }
3828
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003829 if (pi->conn_state == L2CAP_CONN_LOCAL_BUSY)
3830 goto drop;
3831
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003832 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3833 struct srej_list *first;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003834
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003835 first = list_first_entry(SREJ_LIST(sk),
3836 struct srej_list, list);
3837 if (tx_seq == first->tx_seq) {
3838 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3839 l2cap_check_srej_gap(sk, tx_seq);
3840
3841 list_del(&first->list);
3842 kfree(first);
3843
3844 if (list_empty(SREJ_LIST(sk))) {
3845 pi->buffer_seq = pi->buffer_seq_srej;
3846 pi->conn_state &= ~L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan855666c2010-05-01 16:15:40 -03003847 l2cap_send_ack(pi);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003848 }
3849 } else {
3850 struct srej_list *l;
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003851
3852 /* duplicated tx_seq */
3853 if (l2cap_add_to_srej_queue(sk, skb, tx_seq, sar) < 0)
3854 goto drop;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003855
3856 list_for_each_entry(l, SREJ_LIST(sk), list) {
3857 if (l->tx_seq == tx_seq) {
3858 l2cap_resend_srejframe(sk, tx_seq);
3859 return 0;
3860 }
3861 }
3862 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003863 }
3864 } else {
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003865 expected_tx_seq_offset =
3866 (pi->expected_tx_seq - pi->buffer_seq) % 64;
3867 if (expected_tx_seq_offset < 0)
3868 expected_tx_seq_offset += 64;
3869
3870 /* duplicated tx_seq */
3871 if (tx_seq_offset < expected_tx_seq_offset)
3872 goto drop;
3873
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003874 pi->conn_state |= L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003875
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003876 INIT_LIST_HEAD(SREJ_LIST(sk));
3877 pi->buffer_seq_srej = pi->buffer_seq;
3878
3879 __skb_queue_head_init(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003880 __skb_queue_head_init(BUSY_QUEUE(sk));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003881 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3882
Gustavo F. Padovanef54fd92009-08-20 22:26:04 -03003883 pi->conn_state |= L2CAP_CONN_SEND_PBIT;
3884
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003885 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003886 }
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003887 return 0;
3888
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003889expected:
3890 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
3891
3892 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
Gustavo F. Padovan3b1a9f32010-05-01 16:15:42 -03003893 bt_cb(skb)->tx_seq = tx_seq;
3894 bt_cb(skb)->sar = sar;
3895 __skb_queue_tail(SREJ_QUEUE(sk), skb);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003896 return 0;
3897 }
3898
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03003899 if (rx_control & L2CAP_CTRL_FINAL) {
3900 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3901 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003902 else
3903 l2cap_retransmit_frames(sk);
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03003904 }
3905
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003906 err = l2cap_push_rx_skb(sk, skb, rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003907 if (err < 0)
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003908 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003909
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003910 __mod_ack_timer();
3911
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03003912 pi->num_acked = (pi->num_acked + 1) % num_to_ack;
3913 if (pi->num_acked == num_to_ack - 1)
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03003914 l2cap_send_ack(pi);
3915
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003916 return 0;
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003917
3918drop:
3919 kfree_skb(skb);
3920 return 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003921}
3922
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003923static inline void l2cap_data_channel_rrframe(struct sock *sk, u16 rx_control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003924{
3925 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan6e3a5982010-05-01 16:15:38 -03003926
3927 pi->expected_ack_seq = __get_reqseq(rx_control);
3928 l2cap_drop_acked_frames(sk);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003929
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003930 if (rx_control & L2CAP_CTRL_POLL) {
Gustavo F. Padovan05fbd892010-05-01 16:15:39 -03003931 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3932 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
3933 (pi->unacked_frames > 0))
3934 __mod_retrans_timer();
3935
3936 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3937 l2cap_send_srejtail(sk);
3938 } else {
3939 l2cap_send_i_or_rr_or_rnr(sk);
Gustavo F. Padovan05fbd892010-05-01 16:15:39 -03003940 }
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003941
3942 } else if (rx_control & L2CAP_CTRL_FINAL) {
3943 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003944
3945 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3946 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003947 else
3948 l2cap_retransmit_frames(sk);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003949
3950 } else {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003951 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
3952 (pi->unacked_frames > 0))
3953 __mod_retrans_timer();
3954
3955 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003956 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003957 l2cap_send_ack(pi);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003958 } else {
3959 spin_lock_bh(&pi->send_lock);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003960 l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003961 spin_unlock_bh(&pi->send_lock);
3962 }
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003963 }
3964}
3965
3966static inline void l2cap_data_channel_rejframe(struct sock *sk, u16 rx_control)
3967{
3968 struct l2cap_pinfo *pi = l2cap_pi(sk);
3969 u8 tx_seq = __get_reqseq(rx_control);
3970
3971 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3972
Gustavo F. Padovan8abb52e2010-05-01 16:15:38 -03003973 pi->expected_ack_seq = tx_seq;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003974 l2cap_drop_acked_frames(sk);
3975
3976 if (rx_control & L2CAP_CTRL_FINAL) {
3977 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3978 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003979 else
3980 l2cap_retransmit_frames(sk);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003981 } else {
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003982 l2cap_retransmit_frames(sk);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003983
Gustavo F. Padovan0301ef02010-05-05 20:56:43 -03003984 if (pi->conn_state & L2CAP_CONN_WAIT_F)
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003985 pi->conn_state |= L2CAP_CONN_REJ_ACT;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003986 }
3987}
3988static inline void l2cap_data_channel_srejframe(struct sock *sk, u16 rx_control)
3989{
3990 struct l2cap_pinfo *pi = l2cap_pi(sk);
3991 u8 tx_seq = __get_reqseq(rx_control);
3992
3993 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3994
3995 if (rx_control & L2CAP_CTRL_POLL) {
3996 pi->expected_ack_seq = tx_seq;
3997 l2cap_drop_acked_frames(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003998 l2cap_retransmit_one_frame(sk, tx_seq);
3999
4000 spin_lock_bh(&pi->send_lock);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004001 l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004002 spin_unlock_bh(&pi->send_lock);
4003
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004004 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
4005 pi->srej_save_reqseq = tx_seq;
4006 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
4007 }
4008 } else if (rx_control & L2CAP_CTRL_FINAL) {
4009 if ((pi->conn_state & L2CAP_CONN_SREJ_ACT) &&
4010 pi->srej_save_reqseq == tx_seq)
4011 pi->conn_state &= ~L2CAP_CONN_SREJ_ACT;
4012 else
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004013 l2cap_retransmit_one_frame(sk, tx_seq);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004014 } else {
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004015 l2cap_retransmit_one_frame(sk, tx_seq);
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 }
4021}
4022
4023static inline void l2cap_data_channel_rnrframe(struct sock *sk, u16 rx_control)
4024{
4025 struct l2cap_pinfo *pi = l2cap_pi(sk);
4026 u8 tx_seq = __get_reqseq(rx_control);
4027
4028 pi->conn_state |= L2CAP_CONN_REMOTE_BUSY;
4029 pi->expected_ack_seq = tx_seq;
4030 l2cap_drop_acked_frames(sk);
4031
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03004032 if (!(pi->conn_state & L2CAP_CONN_SREJ_SENT)) {
4033 del_timer(&pi->retrans_timer);
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -03004034 if (rx_control & L2CAP_CTRL_POLL)
4035 l2cap_send_rr_or_rnr(pi, L2CAP_CTRL_FINAL);
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03004036 return;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004037 }
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03004038
4039 if (rx_control & L2CAP_CTRL_POLL)
4040 l2cap_send_srejtail(sk);
4041 else
4042 l2cap_send_sframe(pi, L2CAP_SUPER_RCV_READY);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004043}
4044
4045static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
4046{
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004047 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
4048
Gustavo F. Padovan9b16dc62010-05-05 20:05:57 -03004049 if (L2CAP_CTRL_FINAL & rx_control &&
4050 l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004051 del_timer(&l2cap_pi(sk)->monitor_timer);
4052 if (l2cap_pi(sk)->unacked_frames > 0)
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03004053 __mod_retrans_timer();
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004054 l2cap_pi(sk)->conn_state &= ~L2CAP_CONN_WAIT_F;
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03004055 }
4056
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004057 switch (rx_control & L2CAP_CTRL_SUPERVISE) {
4058 case L2CAP_SUPER_RCV_READY:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004059 l2cap_data_channel_rrframe(sk, rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004060 break;
4061
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004062 case L2CAP_SUPER_REJECT:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004063 l2cap_data_channel_rejframe(sk, rx_control);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03004064 break;
4065
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004066 case L2CAP_SUPER_SELECT_REJECT:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004067 l2cap_data_channel_srejframe(sk, rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004068 break;
4069
4070 case L2CAP_SUPER_RCV_NOT_READY:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004071 l2cap_data_channel_rnrframe(sk, rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004072 break;
4073 }
4074
Gustavo F. Padovanfaaebd12010-05-01 16:15:35 -03004075 kfree_skb(skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004076 return 0;
4077}
4078
Linus Torvalds1da177e2005-04-16 15:20:36 -07004079static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk_buff *skb)
4080{
4081 struct sock *sk;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004082 struct l2cap_pinfo *pi;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03004083 u16 control, len;
Gustavo F. Padovanf6337c72010-05-10 18:32:04 -03004084 u8 tx_seq, req_seq;
4085 int next_tx_seq_offset, req_seq_offset;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004086
4087 sk = l2cap_get_chan_by_scid(&conn->chan_list, cid);
4088 if (!sk) {
4089 BT_DBG("unknown cid 0x%4.4x", cid);
4090 goto drop;
4091 }
4092
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004093 pi = l2cap_pi(sk);
4094
Linus Torvalds1da177e2005-04-16 15:20:36 -07004095 BT_DBG("sk %p, len %d", sk, skb->len);
4096
4097 if (sk->sk_state != BT_CONNECTED)
4098 goto drop;
4099
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004100 switch (pi->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004101 case L2CAP_MODE_BASIC:
4102 /* If socket recv buffers overflows we drop data here
4103 * which is *bad* because L2CAP has to be reliable.
4104 * But we don't have any other choice. L2CAP doesn't
4105 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07004106
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004107 if (pi->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004108 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004109
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004110 if (!sock_queue_rcv_skb(sk, skb))
4111 goto done;
4112 break;
4113
4114 case L2CAP_MODE_ERTM:
4115 control = get_unaligned_le16(skb->data);
4116 skb_pull(skb, 2);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03004117 len = skb->len;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004118
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03004119 if (__is_sar_start(control))
4120 len -= 2;
4121
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004122 if (pi->fcs == L2CAP_FCS_CRC16)
4123 len -= 2;
4124
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03004125 /*
4126 * We can just drop the corrupted I-frame here.
4127 * Receiver will miss it and start proper recovery
4128 * procedures and ask retransmission.
4129 */
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004130 if (len > pi->mps) {
4131 l2cap_send_disconn_req(pi->conn, sk);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004132 goto drop;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004133 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004134
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004135 if (l2cap_check_fcs(pi, skb))
4136 goto drop;
4137
João Paulo Rechi Vita01760bd2010-05-01 16:15:43 -03004138 req_seq = __get_reqseq(control);
4139 req_seq_offset = (req_seq - pi->expected_ack_seq) % 64;
4140 if (req_seq_offset < 0)
4141 req_seq_offset += 64;
4142
4143 next_tx_seq_offset =
4144 (pi->next_tx_seq - pi->expected_ack_seq) % 64;
4145 if (next_tx_seq_offset < 0)
4146 next_tx_seq_offset += 64;
4147
4148 /* check for invalid req-seq */
4149 if (req_seq_offset > next_tx_seq_offset) {
4150 l2cap_send_disconn_req(pi->conn, sk);
4151 goto drop;
4152 }
4153
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004154 if (__is_iframe(control)) {
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004155 if (len < 4) {
4156 l2cap_send_disconn_req(pi->conn, sk);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004157 goto drop;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004158 }
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004159
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02004160 l2cap_data_channel_iframe(sk, control, skb);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004161 } else {
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004162 if (len != 0) {
4163 l2cap_send_disconn_req(pi->conn, sk);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004164 goto drop;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004165 }
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004166
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02004167 l2cap_data_channel_sframe(sk, control, skb);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004168 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004169
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02004170 goto done;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004171
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004172 case L2CAP_MODE_STREAMING:
4173 control = get_unaligned_le16(skb->data);
4174 skb_pull(skb, 2);
4175 len = skb->len;
4176
4177 if (__is_sar_start(control))
4178 len -= 2;
4179
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004180 if (pi->fcs == L2CAP_FCS_CRC16)
4181 len -= 2;
4182
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03004183 if (len > pi->mps || len < 4 || __is_sframe(control))
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004184 goto drop;
4185
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004186 if (l2cap_check_fcs(pi, skb))
4187 goto drop;
4188
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004189 tx_seq = __get_txseq(control);
4190
4191 if (pi->expected_tx_seq == tx_seq)
4192 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
4193 else
Gustavo F. Padovan7dffe422010-05-01 16:15:36 -03004194 pi->expected_tx_seq = (tx_seq + 1) % 64;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004195
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004196 l2cap_streaming_reassembly_sdu(sk, skb, control);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004197
4198 goto done;
4199
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004200 default:
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03004201 BT_DBG("sk %p: bad mode 0x%2.2x", sk, pi->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004202 break;
4203 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004204
4205drop:
4206 kfree_skb(skb);
4207
4208done:
Marcel Holtmann01394182006-07-03 10:02:46 +02004209 if (sk)
4210 bh_unlock_sock(sk);
4211
Linus Torvalds1da177e2005-04-16 15:20:36 -07004212 return 0;
4213}
4214
Al Viro8e036fc2007-07-29 00:16:36 -07004215static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004216{
4217 struct sock *sk;
4218
4219 sk = l2cap_get_sock_by_psm(0, psm, conn->src);
4220 if (!sk)
4221 goto drop;
4222
4223 BT_DBG("sk %p, len %d", sk, skb->len);
4224
4225 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_CONNECTED)
4226 goto drop;
4227
4228 if (l2cap_pi(sk)->imtu < skb->len)
4229 goto drop;
4230
4231 if (!sock_queue_rcv_skb(sk, skb))
4232 goto done;
4233
4234drop:
4235 kfree_skb(skb);
4236
4237done:
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03004238 if (sk)
4239 bh_unlock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004240 return 0;
4241}
4242
4243static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
4244{
4245 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07004246 u16 cid, len;
4247 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004248
4249 skb_pull(skb, L2CAP_HDR_SIZE);
4250 cid = __le16_to_cpu(lh->cid);
4251 len = __le16_to_cpu(lh->len);
4252
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004253 if (len != skb->len) {
4254 kfree_skb(skb);
4255 return;
4256 }
4257
Linus Torvalds1da177e2005-04-16 15:20:36 -07004258 BT_DBG("len %d, cid 0x%4.4x", len, cid);
4259
4260 switch (cid) {
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03004261 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07004262 l2cap_sig_channel(conn, skb);
4263 break;
4264
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03004265 case L2CAP_CID_CONN_LESS:
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03004266 psm = get_unaligned_le16(skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004267 skb_pull(skb, 2);
4268 l2cap_conless_channel(conn, psm, skb);
4269 break;
4270
4271 default:
4272 l2cap_data_channel(conn, cid, skb);
4273 break;
4274 }
4275}
4276
4277/* ---- L2CAP interface with lower layer (HCI) ---- */
4278
4279static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
4280{
4281 int exact = 0, lm1 = 0, lm2 = 0;
4282 register struct sock *sk;
4283 struct hlist_node *node;
4284
4285 if (type != ACL_LINK)
4286 return 0;
4287
4288 BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
4289
4290 /* Find listening sockets and check their link_mode */
4291 read_lock(&l2cap_sk_list.lock);
4292 sk_for_each(sk, node, &l2cap_sk_list.head) {
4293 if (sk->sk_state != BT_LISTEN)
4294 continue;
4295
4296 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01004297 lm1 |= HCI_LM_ACCEPT;
4298 if (l2cap_pi(sk)->role_switch)
4299 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004300 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01004301 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
4302 lm2 |= HCI_LM_ACCEPT;
4303 if (l2cap_pi(sk)->role_switch)
4304 lm2 |= HCI_LM_MASTER;
4305 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004306 }
4307 read_unlock(&l2cap_sk_list.lock);
4308
4309 return exact ? lm1 : lm2;
4310}
4311
4312static int l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
4313{
Marcel Holtmann01394182006-07-03 10:02:46 +02004314 struct l2cap_conn *conn;
4315
Linus Torvalds1da177e2005-04-16 15:20:36 -07004316 BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
4317
4318 if (hcon->type != ACL_LINK)
4319 return 0;
4320
4321 if (!status) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004322 conn = l2cap_conn_add(hcon, status);
4323 if (conn)
4324 l2cap_conn_ready(conn);
Marcel Holtmann01394182006-07-03 10:02:46 +02004325 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -07004326 l2cap_conn_del(hcon, bt_err(status));
4327
4328 return 0;
4329}
4330
Marcel Holtmann2950f212009-02-12 14:02:50 +01004331static int l2cap_disconn_ind(struct hci_conn *hcon)
4332{
4333 struct l2cap_conn *conn = hcon->l2cap_data;
4334
4335 BT_DBG("hcon %p", hcon);
4336
4337 if (hcon->type != ACL_LINK || !conn)
4338 return 0x13;
4339
4340 return conn->disc_reason;
4341}
4342
4343static int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004344{
4345 BT_DBG("hcon %p reason %d", hcon, reason);
4346
4347 if (hcon->type != ACL_LINK)
4348 return 0;
4349
4350 l2cap_conn_del(hcon, bt_err(reason));
Marcel Holtmann01394182006-07-03 10:02:46 +02004351
Linus Torvalds1da177e2005-04-16 15:20:36 -07004352 return 0;
4353}
4354
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004355static inline void l2cap_check_encryption(struct sock *sk, u8 encrypt)
4356{
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03004357 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM)
Marcel Holtmann255c7602009-02-04 21:07:19 +01004358 return;
4359
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004360 if (encrypt == 0x00) {
4361 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM) {
4362 l2cap_sock_clear_timer(sk);
4363 l2cap_sock_set_timer(sk, HZ * 5);
4364 } else if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
4365 __l2cap_sock_close(sk, ECONNREFUSED);
4366 } else {
4367 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM)
4368 l2cap_sock_clear_timer(sk);
4369 }
4370}
4371
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004372static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004373{
4374 struct l2cap_chan_list *l;
Marcel Holtmann40be4922008-07-14 20:13:50 +02004375 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004376 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004377
Marcel Holtmann01394182006-07-03 10:02:46 +02004378 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004379 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02004380
Linus Torvalds1da177e2005-04-16 15:20:36 -07004381 l = &conn->chan_list;
4382
4383 BT_DBG("conn %p", conn);
4384
4385 read_lock(&l->lock);
4386
4387 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
4388 bh_lock_sock(sk);
4389
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01004390 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND) {
4391 bh_unlock_sock(sk);
4392 continue;
4393 }
4394
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004395 if (!status && (sk->sk_state == BT_CONNECTED ||
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004396 sk->sk_state == BT_CONFIG)) {
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004397 l2cap_check_encryption(sk, encrypt);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02004398 bh_unlock_sock(sk);
4399 continue;
4400 }
4401
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004402 if (sk->sk_state == BT_CONNECT) {
4403 if (!status) {
4404 struct l2cap_conn_req req;
4405 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
4406 req.psm = l2cap_pi(sk)->psm;
4407
4408 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03004409 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004410
4411 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
4412 L2CAP_CONN_REQ, sizeof(req), &req);
4413 } else {
4414 l2cap_sock_clear_timer(sk);
4415 l2cap_sock_set_timer(sk, HZ / 10);
4416 }
4417 } else if (sk->sk_state == BT_CONNECT2) {
4418 struct l2cap_conn_rsp rsp;
4419 __u16 result;
4420
4421 if (!status) {
4422 sk->sk_state = BT_CONFIG;
4423 result = L2CAP_CR_SUCCESS;
4424 } else {
4425 sk->sk_state = BT_DISCONN;
4426 l2cap_sock_set_timer(sk, HZ / 10);
4427 result = L2CAP_CR_SEC_BLOCK;
4428 }
4429
4430 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
4431 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
4432 rsp.result = cpu_to_le16(result);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02004433 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004434 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
4435 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004436 }
4437
Linus Torvalds1da177e2005-04-16 15:20:36 -07004438 bh_unlock_sock(sk);
4439 }
4440
4441 read_unlock(&l->lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004442
Linus Torvalds1da177e2005-04-16 15:20:36 -07004443 return 0;
4444}
4445
4446static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
4447{
4448 struct l2cap_conn *conn = hcon->l2cap_data;
4449
4450 if (!conn && !(conn = l2cap_conn_add(hcon, 0)))
4451 goto drop;
4452
4453 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
4454
4455 if (flags & ACL_START) {
4456 struct l2cap_hdr *hdr;
4457 int len;
4458
4459 if (conn->rx_len) {
4460 BT_ERR("Unexpected start frame (len %d)", skb->len);
4461 kfree_skb(conn->rx_skb);
4462 conn->rx_skb = NULL;
4463 conn->rx_len = 0;
4464 l2cap_conn_unreliable(conn, ECOMM);
4465 }
4466
4467 if (skb->len < 2) {
4468 BT_ERR("Frame is too short (len %d)", skb->len);
4469 l2cap_conn_unreliable(conn, ECOMM);
4470 goto drop;
4471 }
4472
4473 hdr = (struct l2cap_hdr *) skb->data;
4474 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
4475
4476 if (len == skb->len) {
4477 /* Complete frame received */
4478 l2cap_recv_frame(conn, skb);
4479 return 0;
4480 }
4481
4482 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
4483
4484 if (skb->len > len) {
4485 BT_ERR("Frame is too long (len %d, expected len %d)",
4486 skb->len, len);
4487 l2cap_conn_unreliable(conn, ECOMM);
4488 goto drop;
4489 }
4490
4491 /* Allocate skb for the complete frame (with header) */
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03004492 conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC);
4493 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004494 goto drop;
4495
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03004496 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004497 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004498 conn->rx_len = len - skb->len;
4499 } else {
4500 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
4501
4502 if (!conn->rx_len) {
4503 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
4504 l2cap_conn_unreliable(conn, ECOMM);
4505 goto drop;
4506 }
4507
4508 if (skb->len > conn->rx_len) {
4509 BT_ERR("Fragment is too long (len %d, expected %d)",
4510 skb->len, conn->rx_len);
4511 kfree_skb(conn->rx_skb);
4512 conn->rx_skb = NULL;
4513 conn->rx_len = 0;
4514 l2cap_conn_unreliable(conn, ECOMM);
4515 goto drop;
4516 }
4517
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03004518 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004519 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004520 conn->rx_len -= skb->len;
4521
4522 if (!conn->rx_len) {
4523 /* Complete frame received */
4524 l2cap_recv_frame(conn, conn->rx_skb);
4525 conn->rx_skb = NULL;
4526 }
4527 }
4528
4529drop:
4530 kfree_skb(skb);
4531 return 0;
4532}
4533
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004534static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004535{
4536 struct sock *sk;
4537 struct hlist_node *node;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004538
4539 read_lock_bh(&l2cap_sk_list.lock);
4540
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004541 sk_for_each(sk, node, &l2cap_sk_list.head) {
4542 struct l2cap_pinfo *pi = l2cap_pi(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004543
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004544 seq_printf(f, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d\n",
4545 batostr(&bt_sk(sk)->src),
4546 batostr(&bt_sk(sk)->dst),
4547 sk->sk_state, __le16_to_cpu(pi->psm),
4548 pi->scid, pi->dcid,
4549 pi->imtu, pi->omtu, pi->sec_level);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004550 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004551
Linus Torvalds1da177e2005-04-16 15:20:36 -07004552 read_unlock_bh(&l2cap_sk_list.lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004553
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004554 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004555}
4556
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004557static int l2cap_debugfs_open(struct inode *inode, struct file *file)
4558{
4559 return single_open(file, l2cap_debugfs_show, inode->i_private);
4560}
4561
4562static const struct file_operations l2cap_debugfs_fops = {
4563 .open = l2cap_debugfs_open,
4564 .read = seq_read,
4565 .llseek = seq_lseek,
4566 .release = single_release,
4567};
4568
4569static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004570
Eric Dumazet90ddc4f2005-12-22 12:49:22 -08004571static const struct proto_ops l2cap_sock_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004572 .family = PF_BLUETOOTH,
4573 .owner = THIS_MODULE,
4574 .release = l2cap_sock_release,
4575 .bind = l2cap_sock_bind,
4576 .connect = l2cap_sock_connect,
4577 .listen = l2cap_sock_listen,
4578 .accept = l2cap_sock_accept,
4579 .getname = l2cap_sock_getname,
4580 .sendmsg = l2cap_sock_sendmsg,
Marcel Holtmannf66dc812009-01-15 21:57:00 +01004581 .recvmsg = l2cap_sock_recvmsg,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004582 .poll = bt_sock_poll,
Marcel Holtmann3241ad82008-07-14 20:13:50 +02004583 .ioctl = bt_sock_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004584 .mmap = sock_no_mmap,
4585 .socketpair = sock_no_socketpair,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004586 .shutdown = l2cap_sock_shutdown,
4587 .setsockopt = l2cap_sock_setsockopt,
4588 .getsockopt = l2cap_sock_getsockopt
4589};
4590
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +00004591static const struct net_proto_family l2cap_sock_family_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004592 .family = PF_BLUETOOTH,
4593 .owner = THIS_MODULE,
4594 .create = l2cap_sock_create,
4595};
4596
4597static struct hci_proto l2cap_hci_proto = {
4598 .name = "L2CAP",
4599 .id = HCI_PROTO_L2CAP,
4600 .connect_ind = l2cap_connect_ind,
4601 .connect_cfm = l2cap_connect_cfm,
4602 .disconn_ind = l2cap_disconn_ind,
Marcel Holtmann2950f212009-02-12 14:02:50 +01004603 .disconn_cfm = l2cap_disconn_cfm,
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004604 .security_cfm = l2cap_security_cfm,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004605 .recv_acldata = l2cap_recv_acldata
4606};
4607
4608static int __init l2cap_init(void)
4609{
4610 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004611
Linus Torvalds1da177e2005-04-16 15:20:36 -07004612 err = proto_register(&l2cap_proto, 0);
4613 if (err < 0)
4614 return err;
4615
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004616 _busy_wq = create_singlethread_workqueue("l2cap");
4617 if (!_busy_wq)
4618 goto error;
4619
Linus Torvalds1da177e2005-04-16 15:20:36 -07004620 err = bt_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops);
4621 if (err < 0) {
4622 BT_ERR("L2CAP socket registration failed");
4623 goto error;
4624 }
4625
4626 err = hci_register_proto(&l2cap_hci_proto);
4627 if (err < 0) {
4628 BT_ERR("L2CAP protocol registration failed");
4629 bt_sock_unregister(BTPROTO_L2CAP);
4630 goto error;
4631 }
4632
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004633 if (bt_debugfs) {
4634 l2cap_debugfs = debugfs_create_file("l2cap", 0444,
4635 bt_debugfs, NULL, &l2cap_debugfs_fops);
4636 if (!l2cap_debugfs)
4637 BT_ERR("Failed to create L2CAP debug file");
4638 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004639
4640 BT_INFO("L2CAP ver %s", VERSION);
4641 BT_INFO("L2CAP socket layer initialized");
4642
4643 return 0;
4644
4645error:
4646 proto_unregister(&l2cap_proto);
4647 return err;
4648}
4649
4650static void __exit l2cap_exit(void)
4651{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004652 debugfs_remove(l2cap_debugfs);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004653
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004654 flush_workqueue(_busy_wq);
4655 destroy_workqueue(_busy_wq);
4656
Linus Torvalds1da177e2005-04-16 15:20:36 -07004657 if (bt_sock_unregister(BTPROTO_L2CAP) < 0)
4658 BT_ERR("L2CAP socket unregistration failed");
4659
4660 if (hci_unregister_proto(&l2cap_hci_proto) < 0)
4661 BT_ERR("L2CAP protocol unregistration failed");
4662
4663 proto_unregister(&l2cap_proto);
4664}
4665
4666void l2cap_load(void)
4667{
4668 /* Dummy function to trigger automatic L2CAP module loading by
4669 * other modules that use L2CAP sockets but don't use any other
4670 * symbols from it. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07004671}
4672EXPORT_SYMBOL(l2cap_load);
4673
4674module_init(l2cap_init);
4675module_exit(l2cap_exit);
4676
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07004677module_param(enable_ertm, bool, 0644);
4678MODULE_PARM_DESC(enable_ertm, "Enable enhanced retransmission mode");
4679
Marcel Holtmann63fbd242008-08-18 13:23:53 +02004680MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004681MODULE_DESCRIPTION("Bluetooth L2CAP ver " VERSION);
4682MODULE_VERSION(VERSION);
4683MODULE_LICENSE("GPL");
4684MODULE_ALIAS("bt-proto-0");