blob: 4415eb48c6aeede5f25d8f0af347d7e3696fbb25 [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. Padovanaf05b30b2009-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. Padovanaf05b30b2009-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. Padovanaf05b30b2009-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. Padovanaf05b30b2009-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. Padovanaf05b30b2009-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);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300275
276 skb_queue_purge(TX_QUEUE(sk));
277
278 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
279 struct srej_list *l, *tmp;
280
281 del_timer(&l2cap_pi(sk)->retrans_timer);
282 del_timer(&l2cap_pi(sk)->monitor_timer);
283 del_timer(&l2cap_pi(sk)->ack_timer);
284
285 skb_queue_purge(SREJ_QUEUE(sk));
286 skb_queue_purge(BUSY_QUEUE(sk));
287
288 list_for_each_entry_safe(l, tmp, SREJ_LIST(sk), list) {
289 list_del(&l->list);
290 kfree(l);
291 }
292 }
Marcel Holtmann01394182006-07-03 10:02:46 +0200293}
294
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200295/* Service level security */
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100296static inline int l2cap_check_security(struct sock *sk)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200297{
298 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100299 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200300
Marcel Holtmann00ae4af2009-02-12 16:19:45 +0100301 if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) {
302 if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
303 auth_type = HCI_AT_NO_BONDING_MITM;
304 else
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300305 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann00ae4af2009-02-12 16:19:45 +0100306
307 if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW)
308 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
309 } else {
310 switch (l2cap_pi(sk)->sec_level) {
311 case BT_SECURITY_HIGH:
312 auth_type = HCI_AT_GENERAL_BONDING_MITM;
313 break;
314 case BT_SECURITY_MEDIUM:
315 auth_type = HCI_AT_GENERAL_BONDING;
316 break;
317 default:
318 auth_type = HCI_AT_NO_BONDING;
319 break;
320 }
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100321 }
322
323 return hci_conn_security(conn->hcon, l2cap_pi(sk)->sec_level,
324 auth_type);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200325}
326
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200327static inline u8 l2cap_get_ident(struct l2cap_conn *conn)
328{
329 u8 id;
330
331 /* Get next available identificator.
332 * 1 - 128 are used by kernel.
333 * 129 - 199 are reserved.
334 * 200 - 254 are used by utilities like l2ping, etc.
335 */
336
337 spin_lock_bh(&conn->lock);
338
339 if (++conn->tx_ident > 128)
340 conn->tx_ident = 1;
341
342 id = conn->tx_ident;
343
344 spin_unlock_bh(&conn->lock);
345
346 return id;
347}
348
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300349static inline void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200350{
351 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
352
353 BT_DBG("code 0x%2.2x", code);
354
355 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300356 return;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200357
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300358 hci_send_acl(conn->hcon, skb, 0);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200359}
360
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300361static inline void l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300362{
363 struct sk_buff *skb;
364 struct l2cap_hdr *lh;
365 struct l2cap_conn *conn = pi->conn;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300366 struct sock *sk = (struct sock *)pi;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300367 int count, hlen = L2CAP_HDR_SIZE + 2;
368
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300369 if (sk->sk_state != BT_CONNECTED)
370 return;
371
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300372 if (pi->fcs == L2CAP_FCS_CRC16)
373 hlen += 2;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300374
375 BT_DBG("pi %p, control 0x%2.2x", pi, control);
376
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300377 count = min_t(unsigned int, conn->mtu, hlen);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300378 control |= L2CAP_CTRL_FRAME_TYPE;
379
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -0300380 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
381 control |= L2CAP_CTRL_FINAL;
382 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
383 }
384
Gustavo F. Padovanf0946cc2010-05-01 16:15:37 -0300385 if (pi->conn_state & L2CAP_CONN_SEND_PBIT) {
386 control |= L2CAP_CTRL_POLL;
387 pi->conn_state &= ~L2CAP_CONN_SEND_PBIT;
388 }
389
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300390 skb = bt_skb_alloc(count, GFP_ATOMIC);
391 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300392 return;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300393
394 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300395 lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300396 lh->cid = cpu_to_le16(pi->dcid);
397 put_unaligned_le16(control, skb_put(skb, 2));
398
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300399 if (pi->fcs == L2CAP_FCS_CRC16) {
400 u16 fcs = crc16(0, (u8 *)lh, count - 2);
401 put_unaligned_le16(fcs, skb_put(skb, 2));
402 }
403
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300404 hci_send_acl(pi->conn->hcon, skb, 0);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300405}
406
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300407static inline void l2cap_send_rr_or_rnr(struct l2cap_pinfo *pi, u16 control)
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300408{
Gustavo F. Padovan1890d362010-05-01 16:15:44 -0300409 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300410 control |= L2CAP_SUPER_RCV_NOT_READY;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -0300411 pi->conn_state |= L2CAP_CONN_RNR_SENT;
412 } else
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300413 control |= L2CAP_SUPER_RCV_READY;
414
Gustavo F. Padovan2ab25cd2009-10-03 02:34:40 -0300415 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
416
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300417 l2cap_send_sframe(pi, control);
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300418}
419
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300420static inline int __l2cap_no_conn_pending(struct sock *sk)
421{
422 return !(l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND);
423}
424
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200425static void l2cap_do_start(struct sock *sk)
426{
427 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
428
429 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +0100430 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
431 return;
432
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300433 if (l2cap_check_security(sk) && __l2cap_no_conn_pending(sk)) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200434 struct l2cap_conn_req req;
435 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
436 req.psm = l2cap_pi(sk)->psm;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200437
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200438 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300439 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200440
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200441 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200442 L2CAP_CONN_REQ, sizeof(req), &req);
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200443 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200444 } else {
445 struct l2cap_info_req req;
446 req.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
447
448 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
449 conn->info_ident = l2cap_get_ident(conn);
450
451 mod_timer(&conn->info_timer, jiffies +
452 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
453
454 l2cap_send_cmd(conn, conn->info_ident,
455 L2CAP_INFO_REQ, sizeof(req), &req);
456 }
457}
458
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300459static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct sock *sk)
460{
461 struct l2cap_disconn_req req;
462
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300463 if (!conn)
464 return;
465
466 skb_queue_purge(TX_QUEUE(sk));
467
468 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
469 del_timer(&l2cap_pi(sk)->retrans_timer);
470 del_timer(&l2cap_pi(sk)->monitor_timer);
471 del_timer(&l2cap_pi(sk)->ack_timer);
472 }
473
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300474 req.dcid = cpu_to_le16(l2cap_pi(sk)->dcid);
475 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
476 l2cap_send_cmd(conn, l2cap_get_ident(conn),
477 L2CAP_DISCONN_REQ, sizeof(req), &req);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300478
479 sk->sk_state = BT_DISCONN;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300480}
481
Linus Torvalds1da177e2005-04-16 15:20:36 -0700482/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200483static void l2cap_conn_start(struct l2cap_conn *conn)
484{
485 struct l2cap_chan_list *l = &conn->chan_list;
486 struct sock *sk;
487
488 BT_DBG("conn %p", conn);
489
490 read_lock(&l->lock);
491
492 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
493 bh_lock_sock(sk);
494
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300495 if (sk->sk_type != SOCK_SEQPACKET &&
496 sk->sk_type != SOCK_STREAM) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200497 bh_unlock_sock(sk);
498 continue;
499 }
500
501 if (sk->sk_state == BT_CONNECT) {
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300502 if (l2cap_check_security(sk) &&
503 __l2cap_no_conn_pending(sk)) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200504 struct l2cap_conn_req req;
505 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
506 req.psm = l2cap_pi(sk)->psm;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200507
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200508 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300509 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200510
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200511 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200512 L2CAP_CONN_REQ, sizeof(req), &req);
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200513 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200514 } else if (sk->sk_state == BT_CONNECT2) {
515 struct l2cap_conn_rsp rsp;
516 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
517 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
518
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100519 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100520 if (bt_sk(sk)->defer_setup) {
521 struct sock *parent = bt_sk(sk)->parent;
522 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
523 rsp.status = cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
524 parent->sk_data_ready(parent, 0);
525
526 } else {
527 sk->sk_state = BT_CONFIG;
528 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
529 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
530 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200531 } else {
532 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
533 rsp.status = cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
534 }
535
536 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
537 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
538 }
539
540 bh_unlock_sock(sk);
541 }
542
543 read_unlock(&l->lock);
544}
545
546static void l2cap_conn_ready(struct l2cap_conn *conn)
547{
548 struct l2cap_chan_list *l = &conn->chan_list;
549 struct sock *sk;
550
551 BT_DBG("conn %p", conn);
552
553 read_lock(&l->lock);
554
555 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
556 bh_lock_sock(sk);
557
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300558 if (sk->sk_type != SOCK_SEQPACKET &&
559 sk->sk_type != SOCK_STREAM) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200560 l2cap_sock_clear_timer(sk);
561 sk->sk_state = BT_CONNECTED;
562 sk->sk_state_change(sk);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200563 } else if (sk->sk_state == BT_CONNECT)
564 l2cap_do_start(sk);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200565
566 bh_unlock_sock(sk);
567 }
568
569 read_unlock(&l->lock);
570}
571
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200572/* Notify sockets that we cannot guaranty reliability anymore */
573static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
574{
575 struct l2cap_chan_list *l = &conn->chan_list;
576 struct sock *sk;
577
578 BT_DBG("conn %p", conn);
579
580 read_lock(&l->lock);
581
582 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100583 if (l2cap_pi(sk)->force_reliable)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200584 sk->sk_err = err;
585 }
586
587 read_unlock(&l->lock);
588}
589
590static void l2cap_info_timeout(unsigned long arg)
591{
592 struct l2cap_conn *conn = (void *) arg;
593
Marcel Holtmann984947d2009-02-06 23:35:19 +0100594 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +0100595 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +0100596
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200597 l2cap_conn_start(conn);
598}
599
Linus Torvalds1da177e2005-04-16 15:20:36 -0700600static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
601{
Marcel Holtmann01394182006-07-03 10:02:46 +0200602 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700603
Marcel Holtmann01394182006-07-03 10:02:46 +0200604 if (conn || status)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700605 return conn;
606
Marcel Holtmann01394182006-07-03 10:02:46 +0200607 conn = kzalloc(sizeof(struct l2cap_conn), GFP_ATOMIC);
608 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700609 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700610
611 hcon->l2cap_data = conn;
612 conn->hcon = hcon;
613
Marcel Holtmann01394182006-07-03 10:02:46 +0200614 BT_DBG("hcon %p conn %p", hcon, conn);
615
Linus Torvalds1da177e2005-04-16 15:20:36 -0700616 conn->mtu = hcon->hdev->acl_mtu;
617 conn->src = &hcon->hdev->bdaddr;
618 conn->dst = &hcon->dst;
619
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200620 conn->feat_mask = 0;
621
Linus Torvalds1da177e2005-04-16 15:20:36 -0700622 spin_lock_init(&conn->lock);
623 rwlock_init(&conn->chan_list.lock);
624
Dave Young45054dc2009-10-18 20:28:30 +0000625 setup_timer(&conn->info_timer, l2cap_info_timeout,
626 (unsigned long) conn);
627
Marcel Holtmann2950f212009-02-12 14:02:50 +0100628 conn->disc_reason = 0x13;
629
Linus Torvalds1da177e2005-04-16 15:20:36 -0700630 return conn;
631}
632
Marcel Holtmann01394182006-07-03 10:02:46 +0200633static void l2cap_conn_del(struct hci_conn *hcon, int err)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700634{
Marcel Holtmann01394182006-07-03 10:02:46 +0200635 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700636 struct sock *sk;
637
Marcel Holtmann01394182006-07-03 10:02:46 +0200638 if (!conn)
639 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700640
641 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
642
Wei Yongjun7585b972009-02-25 18:29:52 +0800643 kfree_skb(conn->rx_skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700644
645 /* Kill channels */
646 while ((sk = conn->chan_list.head)) {
647 bh_lock_sock(sk);
648 l2cap_chan_del(sk, err);
649 bh_unlock_sock(sk);
650 l2cap_sock_kill(sk);
651 }
652
Dave Young8e8440f2008-03-03 12:18:55 -0800653 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
654 del_timer_sync(&conn->info_timer);
Thomas Gleixner3ab22732008-02-26 17:42:56 -0800655
Linus Torvalds1da177e2005-04-16 15:20:36 -0700656 hcon->l2cap_data = NULL;
657 kfree(conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700658}
659
660static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
661{
662 struct l2cap_chan_list *l = &conn->chan_list;
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200663 write_lock_bh(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700664 __l2cap_chan_add(conn, sk, parent);
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200665 write_unlock_bh(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700666}
667
Linus Torvalds1da177e2005-04-16 15:20:36 -0700668/* ---- Socket interface ---- */
Al Viro8e036fc2007-07-29 00:16:36 -0700669static struct sock *__l2cap_get_sock_by_addr(__le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700670{
671 struct sock *sk;
672 struct hlist_node *node;
673 sk_for_each(sk, node, &l2cap_sk_list.head)
674 if (l2cap_pi(sk)->sport == psm && !bacmp(&bt_sk(sk)->src, src))
675 goto found;
676 sk = NULL;
677found:
678 return sk;
679}
680
681/* Find socket with psm and source bdaddr.
682 * Returns closest match.
683 */
Al Viro8e036fc2007-07-29 00:16:36 -0700684static struct sock *__l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700685{
686 struct sock *sk = NULL, *sk1 = NULL;
687 struct hlist_node *node;
688
689 sk_for_each(sk, node, &l2cap_sk_list.head) {
690 if (state && sk->sk_state != state)
691 continue;
692
693 if (l2cap_pi(sk)->psm == psm) {
694 /* Exact match. */
695 if (!bacmp(&bt_sk(sk)->src, src))
696 break;
697
698 /* Closest match */
699 if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY))
700 sk1 = sk;
701 }
702 }
703 return node ? sk : sk1;
704}
705
706/* Find socket with given address (psm, src).
707 * Returns locked socket */
Al Viro8e036fc2007-07-29 00:16:36 -0700708static inline struct sock *l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700709{
710 struct sock *s;
711 read_lock(&l2cap_sk_list.lock);
712 s = __l2cap_get_sock_by_psm(state, psm, src);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300713 if (s)
714 bh_lock_sock(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700715 read_unlock(&l2cap_sk_list.lock);
716 return s;
717}
718
719static void l2cap_sock_destruct(struct sock *sk)
720{
721 BT_DBG("sk %p", sk);
722
723 skb_queue_purge(&sk->sk_receive_queue);
724 skb_queue_purge(&sk->sk_write_queue);
725}
726
727static void l2cap_sock_cleanup_listen(struct sock *parent)
728{
729 struct sock *sk;
730
731 BT_DBG("parent %p", parent);
732
733 /* Close not yet accepted channels */
734 while ((sk = bt_accept_dequeue(parent, NULL)))
735 l2cap_sock_close(sk);
736
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200737 parent->sk_state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700738 sock_set_flag(parent, SOCK_ZAPPED);
739}
740
741/* Kill socket (only if zapped and orphan)
742 * Must be called on unlocked socket.
743 */
744static void l2cap_sock_kill(struct sock *sk)
745{
746 if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket)
747 return;
748
749 BT_DBG("sk %p state %d", sk, sk->sk_state);
750
751 /* Kill poor orphan */
752 bt_sock_unlink(&l2cap_sk_list, sk);
753 sock_set_flag(sk, SOCK_DEAD);
754 sock_put(sk);
755}
756
757static void __l2cap_sock_close(struct sock *sk, int reason)
758{
759 BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket);
760
761 switch (sk->sk_state) {
762 case BT_LISTEN:
763 l2cap_sock_cleanup_listen(sk);
764 break;
765
766 case BT_CONNECTED:
767 case BT_CONFIG:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300768 if (sk->sk_type == SOCK_SEQPACKET ||
769 sk->sk_type == SOCK_STREAM) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700770 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700771
Linus Torvalds1da177e2005-04-16 15:20:36 -0700772 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300773 l2cap_send_disconn_req(conn, sk);
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200774 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -0700775 l2cap_chan_del(sk, reason);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700776 break;
777
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100778 case BT_CONNECT2:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300779 if (sk->sk_type == SOCK_SEQPACKET ||
780 sk->sk_type == SOCK_STREAM) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100781 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
782 struct l2cap_conn_rsp rsp;
783 __u16 result;
784
785 if (bt_sk(sk)->defer_setup)
786 result = L2CAP_CR_SEC_BLOCK;
787 else
788 result = L2CAP_CR_BAD_PSM;
789
790 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
791 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
792 rsp.result = cpu_to_le16(result);
793 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
794 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
795 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
796 } else
797 l2cap_chan_del(sk, reason);
798 break;
799
Linus Torvalds1da177e2005-04-16 15:20:36 -0700800 case BT_CONNECT:
801 case BT_DISCONN:
802 l2cap_chan_del(sk, reason);
803 break;
804
805 default:
806 sock_set_flag(sk, SOCK_ZAPPED);
807 break;
808 }
809}
810
811/* Must be called on unlocked socket. */
812static void l2cap_sock_close(struct sock *sk)
813{
814 l2cap_sock_clear_timer(sk);
815 lock_sock(sk);
816 __l2cap_sock_close(sk, ECONNRESET);
817 release_sock(sk);
818 l2cap_sock_kill(sk);
819}
820
821static void l2cap_sock_init(struct sock *sk, struct sock *parent)
822{
823 struct l2cap_pinfo *pi = l2cap_pi(sk);
824
825 BT_DBG("sk %p", sk);
826
827 if (parent) {
828 sk->sk_type = parent->sk_type;
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100829 bt_sk(sk)->defer_setup = bt_sk(parent)->defer_setup;
830
Linus Torvalds1da177e2005-04-16 15:20:36 -0700831 pi->imtu = l2cap_pi(parent)->imtu;
832 pi->omtu = l2cap_pi(parent)->omtu;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -0700833 pi->mode = l2cap_pi(parent)->mode;
834 pi->fcs = l2cap_pi(parent)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -0300835 pi->max_tx = l2cap_pi(parent)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -0300836 pi->tx_win = l2cap_pi(parent)->tx_win;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100837 pi->sec_level = l2cap_pi(parent)->sec_level;
838 pi->role_switch = l2cap_pi(parent)->role_switch;
839 pi->force_reliable = l2cap_pi(parent)->force_reliable;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700840 } else {
841 pi->imtu = L2CAP_DEFAULT_MTU;
842 pi->omtu = 0;
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300843 if (enable_ertm && sk->sk_type == SOCK_STREAM)
844 pi->mode = L2CAP_MODE_ERTM;
845 else
846 pi->mode = L2CAP_MODE_BASIC;
Gustavo F. Padovanfd059b92010-05-10 14:22:56 -0300847 pi->max_tx = L2CAP_DEFAULT_MAX_TX;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -0700848 pi->fcs = L2CAP_FCS_CRC16;
Gustavo F. Padovanfd059b92010-05-10 14:22:56 -0300849 pi->tx_win = L2CAP_DEFAULT_TX_WINDOW;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100850 pi->sec_level = BT_SECURITY_LOW;
851 pi->role_switch = 0;
852 pi->force_reliable = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700853 }
854
855 /* Default config options */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +0200856 pi->conf_len = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700857 pi->flush_to = L2CAP_DEFAULT_FLUSH_TO;
Dave Young45054dc2009-10-18 20:28:30 +0000858 skb_queue_head_init(TX_QUEUE(sk));
859 skb_queue_head_init(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -0300860 skb_queue_head_init(BUSY_QUEUE(sk));
Dave Young45054dc2009-10-18 20:28:30 +0000861 INIT_LIST_HEAD(SREJ_LIST(sk));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700862}
863
864static struct proto l2cap_proto = {
865 .name = "L2CAP",
866 .owner = THIS_MODULE,
867 .obj_size = sizeof(struct l2cap_pinfo)
868};
869
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700870static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700871{
872 struct sock *sk;
873
Pavel Emelyanov6257ff22007-11-01 00:39:31 -0700874 sk = sk_alloc(net, PF_BLUETOOTH, prio, &l2cap_proto);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700875 if (!sk)
876 return NULL;
877
878 sock_init_data(sock, sk);
879 INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
880
881 sk->sk_destruct = l2cap_sock_destruct;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200882 sk->sk_sndtimeo = msecs_to_jiffies(L2CAP_CONN_TIMEOUT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700883
884 sock_reset_flag(sk, SOCK_ZAPPED);
885
886 sk->sk_protocol = proto;
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200887 sk->sk_state = BT_OPEN;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700888
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200889 setup_timer(&sk->sk_timer, l2cap_sock_timeout, (unsigned long) sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700890
891 bt_sock_link(&l2cap_sk_list, sk);
892 return sk;
893}
894
Eric Paris3f378b62009-11-05 22:18:14 -0800895static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol,
896 int kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700897{
898 struct sock *sk;
899
900 BT_DBG("sock %p", sock);
901
902 sock->state = SS_UNCONNECTED;
903
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300904 if (sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM &&
Linus Torvalds1da177e2005-04-16 15:20:36 -0700905 sock->type != SOCK_DGRAM && sock->type != SOCK_RAW)
906 return -ESOCKTNOSUPPORT;
907
Eric Parisc84b3262009-11-05 20:45:52 -0800908 if (sock->type == SOCK_RAW && !kern && !capable(CAP_NET_RAW))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700909 return -EPERM;
910
911 sock->ops = &l2cap_sock_ops;
912
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700913 sk = l2cap_sock_alloc(net, sock, protocol, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700914 if (!sk)
915 return -ENOMEM;
916
917 l2cap_sock_init(sk, NULL);
918 return 0;
919}
920
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100921static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700922{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700923 struct sock *sk = sock->sk;
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100924 struct sockaddr_l2 la;
925 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700926
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100927 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700928
929 if (!addr || addr->sa_family != AF_BLUETOOTH)
930 return -EINVAL;
931
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100932 memset(&la, 0, sizeof(la));
933 len = min_t(unsigned int, sizeof(la), alen);
934 memcpy(&la, addr, len);
935
Marcel Holtmann2a517ca2009-02-16 03:20:31 +0100936 if (la.l2_cid)
937 return -EINVAL;
938
Linus Torvalds1da177e2005-04-16 15:20:36 -0700939 lock_sock(sk);
940
941 if (sk->sk_state != BT_OPEN) {
942 err = -EBADFD;
943 goto done;
944 }
945
Marcel Holtmannb4324b52009-06-07 18:06:51 +0200946 if (la.l2_psm && __le16_to_cpu(la.l2_psm) < 0x1001 &&
Marcel Holtmann847641d2007-01-22 22:00:45 +0100947 !capable(CAP_NET_BIND_SERVICE)) {
948 err = -EACCES;
949 goto done;
950 }
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900951
Linus Torvalds1da177e2005-04-16 15:20:36 -0700952 write_lock_bh(&l2cap_sk_list.lock);
953
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100954 if (la.l2_psm && __l2cap_get_sock_by_addr(la.l2_psm, &la.l2_bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700955 err = -EADDRINUSE;
956 } else {
957 /* Save source address */
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100958 bacpy(&bt_sk(sk)->src, &la.l2_bdaddr);
959 l2cap_pi(sk)->psm = la.l2_psm;
960 l2cap_pi(sk)->sport = la.l2_psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700961 sk->sk_state = BT_BOUND;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100962
Marcel Holtmannb4324b52009-06-07 18:06:51 +0200963 if (__le16_to_cpu(la.l2_psm) == 0x0001 ||
964 __le16_to_cpu(la.l2_psm) == 0x0003)
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100965 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700966 }
967
968 write_unlock_bh(&l2cap_sk_list.lock);
969
970done:
971 release_sock(sk);
972 return err;
973}
974
975static int l2cap_do_connect(struct sock *sk)
976{
977 bdaddr_t *src = &bt_sk(sk)->src;
978 bdaddr_t *dst = &bt_sk(sk)->dst;
979 struct l2cap_conn *conn;
980 struct hci_conn *hcon;
981 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200982 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +0200983 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700984
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100985 BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst),
986 l2cap_pi(sk)->psm);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700987
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300988 hdev = hci_get_route(dst, src);
989 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700990 return -EHOSTUNREACH;
991
992 hci_dev_lock_bh(hdev);
993
994 err = -ENOMEM;
995
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100996 if (sk->sk_type == SOCK_RAW) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100997 switch (l2cap_pi(sk)->sec_level) {
998 case BT_SECURITY_HIGH:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100999 auth_type = HCI_AT_DEDICATED_BONDING_MITM;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001000 break;
1001 case BT_SECURITY_MEDIUM:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001002 auth_type = HCI_AT_DEDICATED_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001003 break;
1004 default:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001005 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001006 break;
1007 }
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001008 } else if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001009 if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001010 auth_type = HCI_AT_NO_BONDING_MITM;
1011 else
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001012 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann435fef22009-02-09 03:55:28 +01001013
1014 if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW)
1015 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001016 } else {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001017 switch (l2cap_pi(sk)->sec_level) {
1018 case BT_SECURITY_HIGH:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001019 auth_type = HCI_AT_GENERAL_BONDING_MITM;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001020 break;
1021 case BT_SECURITY_MEDIUM:
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001022 auth_type = HCI_AT_GENERAL_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001023 break;
1024 default:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001025 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001026 break;
1027 }
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001028 }
1029
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001030 hcon = hci_connect(hdev, ACL_LINK, dst,
1031 l2cap_pi(sk)->sec_level, auth_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001032 if (!hcon)
1033 goto done;
1034
1035 conn = l2cap_conn_add(hcon, 0);
1036 if (!conn) {
1037 hci_conn_put(hcon);
1038 goto done;
1039 }
1040
1041 err = 0;
1042
1043 /* Update source addr of the socket */
1044 bacpy(src, conn->src);
1045
1046 l2cap_chan_add(conn, sk, NULL);
1047
1048 sk->sk_state = BT_CONNECT;
1049 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
1050
1051 if (hcon->state == BT_CONNECTED) {
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001052 if (sk->sk_type != SOCK_SEQPACKET &&
1053 sk->sk_type != SOCK_STREAM) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001054 l2cap_sock_clear_timer(sk);
1055 sk->sk_state = BT_CONNECTED;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001056 } else
1057 l2cap_do_start(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001058 }
1059
1060done:
1061 hci_dev_unlock_bh(hdev);
1062 hci_dev_put(hdev);
1063 return err;
1064}
1065
1066static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
1067{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001068 struct sock *sk = sock->sk;
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001069 struct sockaddr_l2 la;
1070 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001071
Linus Torvalds1da177e2005-04-16 15:20:36 -07001072 BT_DBG("sk %p", sk);
1073
Changli Gao6503d962010-03-31 22:58:26 +00001074 if (!addr || alen < sizeof(addr->sa_family) ||
1075 addr->sa_family != AF_BLUETOOTH)
Marcel Holtmann2a517ca2009-02-16 03:20:31 +01001076 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001077
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001078 memset(&la, 0, sizeof(la));
1079 len = min_t(unsigned int, sizeof(la), alen);
1080 memcpy(&la, addr, len);
1081
Marcel Holtmann2a517ca2009-02-16 03:20:31 +01001082 if (la.l2_cid)
1083 return -EINVAL;
1084
1085 lock_sock(sk);
1086
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001087 if ((sk->sk_type == SOCK_SEQPACKET || sk->sk_type == SOCK_STREAM)
1088 && !la.l2_psm) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001089 err = -EINVAL;
1090 goto done;
1091 }
1092
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001093 switch (l2cap_pi(sk)->mode) {
1094 case L2CAP_MODE_BASIC:
1095 break;
1096 case L2CAP_MODE_ERTM:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001097 case L2CAP_MODE_STREAMING:
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001098 if (enable_ertm)
1099 break;
1100 /* fall through */
1101 default:
1102 err = -ENOTSUPP;
1103 goto done;
1104 }
1105
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001106 switch (sk->sk_state) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001107 case BT_CONNECT:
1108 case BT_CONNECT2:
1109 case BT_CONFIG:
1110 /* Already connecting */
1111 goto wait;
1112
1113 case BT_CONNECTED:
1114 /* Already connected */
1115 goto done;
1116
1117 case BT_OPEN:
1118 case BT_BOUND:
1119 /* Can connect */
1120 break;
1121
1122 default:
1123 err = -EBADFD;
1124 goto done;
1125 }
1126
1127 /* Set destination address and psm */
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001128 bacpy(&bt_sk(sk)->dst, &la.l2_bdaddr);
1129 l2cap_pi(sk)->psm = la.l2_psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001130
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001131 err = l2cap_do_connect(sk);
1132 if (err)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001133 goto done;
1134
1135wait:
1136 err = bt_sock_wait_state(sk, BT_CONNECTED,
1137 sock_sndtimeo(sk, flags & O_NONBLOCK));
1138done:
1139 release_sock(sk);
1140 return err;
1141}
1142
1143static int l2cap_sock_listen(struct socket *sock, int backlog)
1144{
1145 struct sock *sk = sock->sk;
1146 int err = 0;
1147
1148 BT_DBG("sk %p backlog %d", sk, backlog);
1149
1150 lock_sock(sk);
1151
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001152 if ((sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM)
1153 || sk->sk_state != BT_BOUND) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001154 err = -EBADFD;
1155 goto done;
1156 }
1157
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001158 switch (l2cap_pi(sk)->mode) {
1159 case L2CAP_MODE_BASIC:
1160 break;
1161 case L2CAP_MODE_ERTM:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001162 case L2CAP_MODE_STREAMING:
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001163 if (enable_ertm)
1164 break;
1165 /* fall through */
1166 default:
1167 err = -ENOTSUPP;
1168 goto done;
1169 }
1170
Linus Torvalds1da177e2005-04-16 15:20:36 -07001171 if (!l2cap_pi(sk)->psm) {
1172 bdaddr_t *src = &bt_sk(sk)->src;
1173 u16 psm;
1174
1175 err = -EINVAL;
1176
1177 write_lock_bh(&l2cap_sk_list.lock);
1178
1179 for (psm = 0x1001; psm < 0x1100; psm += 2)
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001180 if (!__l2cap_get_sock_by_addr(cpu_to_le16(psm), src)) {
1181 l2cap_pi(sk)->psm = cpu_to_le16(psm);
1182 l2cap_pi(sk)->sport = cpu_to_le16(psm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001183 err = 0;
1184 break;
1185 }
1186
1187 write_unlock_bh(&l2cap_sk_list.lock);
1188
1189 if (err < 0)
1190 goto done;
1191 }
1192
1193 sk->sk_max_ack_backlog = backlog;
1194 sk->sk_ack_backlog = 0;
1195 sk->sk_state = BT_LISTEN;
1196
1197done:
1198 release_sock(sk);
1199 return err;
1200}
1201
1202static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int flags)
1203{
1204 DECLARE_WAITQUEUE(wait, current);
1205 struct sock *sk = sock->sk, *nsk;
1206 long timeo;
1207 int err = 0;
1208
Peter Zijlstrafcc70d52006-11-08 22:44:35 -08001209 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001210
1211 if (sk->sk_state != BT_LISTEN) {
1212 err = -EBADFD;
1213 goto done;
1214 }
1215
1216 timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
1217
1218 BT_DBG("sk %p timeo %ld", sk, timeo);
1219
1220 /* Wait for an incoming connection. (wake-one). */
Eric Dumazetaa395142010-04-20 13:03:51 +00001221 add_wait_queue_exclusive(sk_sleep(sk), &wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001222 while (!(nsk = bt_accept_dequeue(sk, newsock))) {
1223 set_current_state(TASK_INTERRUPTIBLE);
1224 if (!timeo) {
1225 err = -EAGAIN;
1226 break;
1227 }
1228
1229 release_sock(sk);
1230 timeo = schedule_timeout(timeo);
Peter Zijlstrafcc70d52006-11-08 22:44:35 -08001231 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001232
1233 if (sk->sk_state != BT_LISTEN) {
1234 err = -EBADFD;
1235 break;
1236 }
1237
1238 if (signal_pending(current)) {
1239 err = sock_intr_errno(timeo);
1240 break;
1241 }
1242 }
1243 set_current_state(TASK_RUNNING);
Eric Dumazetaa395142010-04-20 13:03:51 +00001244 remove_wait_queue(sk_sleep(sk), &wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001245
1246 if (err)
1247 goto done;
1248
1249 newsock->state = SS_CONNECTED;
1250
1251 BT_DBG("new socket %p", nsk);
1252
1253done:
1254 release_sock(sk);
1255 return err;
1256}
1257
1258static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
1259{
1260 struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
1261 struct sock *sk = sock->sk;
1262
1263 BT_DBG("sock %p, sk %p", sock, sk);
1264
1265 addr->sa_family = AF_BLUETOOTH;
1266 *len = sizeof(struct sockaddr_l2);
1267
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001268 if (peer) {
1269 la->l2_psm = l2cap_pi(sk)->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001270 bacpy(&la->l2_bdaddr, &bt_sk(sk)->dst);
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001271 la->l2_cid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001272 } else {
1273 la->l2_psm = l2cap_pi(sk)->sport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001274 bacpy(&la->l2_bdaddr, &bt_sk(sk)->src);
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001275 la->l2_cid = cpu_to_le16(l2cap_pi(sk)->scid);
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001276 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001277
Linus Torvalds1da177e2005-04-16 15:20:36 -07001278 return 0;
1279}
1280
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001281static int __l2cap_wait_ack(struct sock *sk)
1282{
1283 DECLARE_WAITQUEUE(wait, current);
1284 int err = 0;
1285 int timeo = HZ/5;
1286
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001287 add_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001288 while ((l2cap_pi(sk)->unacked_frames > 0 && l2cap_pi(sk)->conn)) {
1289 set_current_state(TASK_INTERRUPTIBLE);
1290
1291 if (!timeo)
1292 timeo = HZ/5;
1293
1294 if (signal_pending(current)) {
1295 err = sock_intr_errno(timeo);
1296 break;
1297 }
1298
1299 release_sock(sk);
1300 timeo = schedule_timeout(timeo);
1301 lock_sock(sk);
1302
1303 err = sock_error(sk);
1304 if (err)
1305 break;
1306 }
1307 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001308 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001309 return err;
1310}
1311
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001312static void l2cap_monitor_timeout(unsigned long arg)
1313{
1314 struct sock *sk = (void *) arg;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001315
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001316 bh_lock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001317 if (l2cap_pi(sk)->retry_count >= l2cap_pi(sk)->remote_max_tx) {
1318 l2cap_send_disconn_req(l2cap_pi(sk)->conn, sk);
Andrei Emeltchenkob13f5862009-12-15 11:38:04 +02001319 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001320 return;
1321 }
1322
1323 l2cap_pi(sk)->retry_count++;
1324 __mod_monitor_timer();
1325
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -03001326 l2cap_send_rr_or_rnr(l2cap_pi(sk), L2CAP_CTRL_POLL);
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001327 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001328}
1329
1330static void l2cap_retrans_timeout(unsigned long arg)
1331{
1332 struct sock *sk = (void *) arg;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001333
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001334 bh_lock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001335 l2cap_pi(sk)->retry_count = 1;
1336 __mod_monitor_timer();
1337
1338 l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
1339
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -03001340 l2cap_send_rr_or_rnr(l2cap_pi(sk), L2CAP_CTRL_POLL);
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001341 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001342}
1343
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001344static void l2cap_drop_acked_frames(struct sock *sk)
1345{
1346 struct sk_buff *skb;
1347
Gustavo F. Padovan812e7372010-05-01 16:15:42 -03001348 while ((skb = skb_peek(TX_QUEUE(sk))) &&
1349 l2cap_pi(sk)->unacked_frames) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001350 if (bt_cb(skb)->tx_seq == l2cap_pi(sk)->expected_ack_seq)
1351 break;
1352
1353 skb = skb_dequeue(TX_QUEUE(sk));
1354 kfree_skb(skb);
1355
1356 l2cap_pi(sk)->unacked_frames--;
1357 }
1358
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001359 if (!l2cap_pi(sk)->unacked_frames)
1360 del_timer(&l2cap_pi(sk)->retrans_timer);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001361}
1362
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001363static inline void l2cap_do_send(struct sock *sk, struct sk_buff *skb)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001364{
1365 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001366
1367 BT_DBG("sk %p, skb %p len %d", sk, skb, skb->len);
1368
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001369 hci_send_acl(pi->conn->hcon, skb, 0);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001370}
1371
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001372static int l2cap_streaming_send(struct sock *sk)
1373{
1374 struct sk_buff *skb, *tx_skb;
1375 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001376 u16 control, fcs;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001377
1378 while ((skb = sk->sk_send_head)) {
1379 tx_skb = skb_clone(skb, GFP_ATOMIC);
1380
1381 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
1382 control |= pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT;
1383 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1384
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001385 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001386 fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
1387 put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
1388 }
1389
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001390 l2cap_do_send(sk, tx_skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001391
1392 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
1393
1394 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1395 sk->sk_send_head = NULL;
1396 else
1397 sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
1398
1399 skb = skb_dequeue(TX_QUEUE(sk));
1400 kfree_skb(skb);
1401 }
1402 return 0;
1403}
1404
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001405static void l2cap_retransmit_one_frame(struct sock *sk, u8 tx_seq)
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001406{
1407 struct l2cap_pinfo *pi = l2cap_pi(sk);
1408 struct sk_buff *skb, *tx_skb;
1409 u16 control, fcs;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001410
1411 skb = skb_peek(TX_QUEUE(sk));
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001412 if (!skb)
1413 return;
1414
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001415 do {
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001416 if (bt_cb(skb)->tx_seq == tx_seq)
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001417 break;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001418
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001419 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1420 return;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001421
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001422 } while ((skb = skb_queue_next(TX_QUEUE(sk), skb)));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001423
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001424 if (pi->remote_max_tx &&
1425 bt_cb(skb)->retries == pi->remote_max_tx) {
1426 l2cap_send_disconn_req(pi->conn, sk);
1427 return;
1428 }
1429
1430 tx_skb = skb_clone(skb, GFP_ATOMIC);
1431 bt_cb(skb)->retries++;
1432 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
1433 control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
1434 | (tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
1435 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1436
1437 if (pi->fcs == L2CAP_FCS_CRC16) {
1438 fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
1439 put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
1440 }
1441
1442 l2cap_do_send(sk, tx_skb);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001443}
1444
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001445static int l2cap_ertm_send(struct sock *sk)
1446{
1447 struct sk_buff *skb, *tx_skb;
1448 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001449 u16 control, fcs;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001450 int nsent = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001451
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001452 if (sk->sk_state != BT_CONNECTED)
1453 return -ENOTCONN;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001454
Gustavo F. Padovan6e2b6722010-06-01 18:52:58 -03001455 while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(sk))) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001456
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001457 if (pi->remote_max_tx &&
1458 bt_cb(skb)->retries == pi->remote_max_tx) {
1459 l2cap_send_disconn_req(pi->conn, sk);
1460 break;
1461 }
1462
Andrei Emeltchenkoe420aba2009-12-23 13:07:14 +02001463 tx_skb = skb_clone(skb, GFP_ATOMIC);
1464
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001465 bt_cb(skb)->retries++;
1466
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001467 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001468 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
1469 control |= L2CAP_CTRL_FINAL;
1470 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
1471 }
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03001472 control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001473 | (pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
1474 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1475
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001476
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001477 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001478 fcs = crc16(0, (u8 *)skb->data, tx_skb->len - 2);
1479 put_unaligned_le16(fcs, skb->data + tx_skb->len - 2);
1480 }
1481
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001482 l2cap_do_send(sk, tx_skb);
1483
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001484 __mod_retrans_timer();
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001485
1486 bt_cb(skb)->tx_seq = pi->next_tx_seq;
1487 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
1488
1489 pi->unacked_frames++;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001490 pi->frames_sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001491
1492 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1493 sk->sk_send_head = NULL;
1494 else
1495 sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001496
1497 nsent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001498 }
1499
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001500 return nsent;
1501}
1502
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001503static int l2cap_retransmit_frames(struct sock *sk)
1504{
1505 struct l2cap_pinfo *pi = l2cap_pi(sk);
1506 int ret;
1507
1508 spin_lock_bh(&pi->send_lock);
1509
1510 if (!skb_queue_empty(TX_QUEUE(sk)))
1511 sk->sk_send_head = TX_QUEUE(sk)->next;
1512
1513 pi->next_tx_seq = pi->expected_ack_seq;
1514 ret = l2cap_ertm_send(sk);
1515
1516 spin_unlock_bh(&pi->send_lock);
1517
1518 return ret;
1519}
1520
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001521static void l2cap_send_ack(struct l2cap_pinfo *pi)
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001522{
1523 struct sock *sk = (struct sock *)pi;
1524 u16 control = 0;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001525 int nframes;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001526
1527 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1528
1529 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
1530 control |= L2CAP_SUPER_RCV_NOT_READY;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03001531 pi->conn_state |= L2CAP_CONN_RNR_SENT;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001532 l2cap_send_sframe(pi, control);
1533 return;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001534 }
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001535
1536 spin_lock_bh(&pi->send_lock);
1537 nframes = l2cap_ertm_send(sk);
1538 spin_unlock_bh(&pi->send_lock);
1539
1540 if (nframes > 0)
1541 return;
1542
1543 control |= L2CAP_SUPER_RCV_READY;
1544 l2cap_send_sframe(pi, control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001545}
1546
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001547static void l2cap_send_srejtail(struct sock *sk)
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03001548{
1549 struct srej_list *tail;
1550 u16 control;
1551
1552 control = L2CAP_SUPER_SELECT_REJECT;
1553 control |= L2CAP_CTRL_FINAL;
1554
1555 tail = list_entry(SREJ_LIST(sk)->prev, struct srej_list, list);
1556 control |= tail->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1557
1558 l2cap_send_sframe(l2cap_pi(sk), control);
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03001559}
1560
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001561static 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 -07001562{
1563 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001564 struct sk_buff **frag;
1565 int err, sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001566
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03001567 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001568 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001569
1570 sent += count;
1571 len -= count;
1572
1573 /* Continuation fragments (no L2CAP header) */
1574 frag = &skb_shinfo(skb)->frag_list;
1575 while (len) {
1576 count = min_t(unsigned int, conn->mtu, len);
1577
1578 *frag = bt_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err);
1579 if (!*frag)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001580 return -EFAULT;
1581 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
1582 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001583
1584 sent += count;
1585 len -= count;
1586
1587 frag = &(*frag)->next;
1588 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001589
1590 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001591}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001592
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001593static struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, size_t len)
1594{
1595 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1596 struct sk_buff *skb;
1597 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1598 struct l2cap_hdr *lh;
1599
1600 BT_DBG("sk %p len %d", sk, (int)len);
1601
1602 count = min_t(unsigned int, (conn->mtu - hlen), len);
1603 skb = bt_skb_send_alloc(sk, count + hlen,
1604 msg->msg_flags & MSG_DONTWAIT, &err);
1605 if (!skb)
1606 return ERR_PTR(-ENOMEM);
1607
1608 /* Create L2CAP header */
1609 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1610 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1611 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1612 put_unaligned_le16(l2cap_pi(sk)->psm, skb_put(skb, 2));
1613
1614 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1615 if (unlikely(err < 0)) {
1616 kfree_skb(skb);
1617 return ERR_PTR(err);
1618 }
1619 return skb;
1620}
1621
1622static struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *msg, size_t len)
1623{
1624 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1625 struct sk_buff *skb;
1626 int err, count, hlen = L2CAP_HDR_SIZE;
1627 struct l2cap_hdr *lh;
1628
1629 BT_DBG("sk %p len %d", sk, (int)len);
1630
1631 count = min_t(unsigned int, (conn->mtu - hlen), len);
1632 skb = bt_skb_send_alloc(sk, count + hlen,
1633 msg->msg_flags & MSG_DONTWAIT, &err);
1634 if (!skb)
1635 return ERR_PTR(-ENOMEM);
1636
1637 /* Create L2CAP header */
1638 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1639 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1640 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1641
1642 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1643 if (unlikely(err < 0)) {
1644 kfree_skb(skb);
1645 return ERR_PTR(err);
1646 }
1647 return skb;
1648}
1649
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001650static 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 -03001651{
1652 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1653 struct sk_buff *skb;
1654 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1655 struct l2cap_hdr *lh;
1656
1657 BT_DBG("sk %p len %d", sk, (int)len);
1658
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03001659 if (!conn)
1660 return ERR_PTR(-ENOTCONN);
1661
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001662 if (sdulen)
1663 hlen += 2;
1664
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001665 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1666 hlen += 2;
1667
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001668 count = min_t(unsigned int, (conn->mtu - hlen), len);
1669 skb = bt_skb_send_alloc(sk, count + hlen,
1670 msg->msg_flags & MSG_DONTWAIT, &err);
1671 if (!skb)
1672 return ERR_PTR(-ENOMEM);
1673
1674 /* Create L2CAP header */
1675 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1676 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1677 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1678 put_unaligned_le16(control, skb_put(skb, 2));
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001679 if (sdulen)
1680 put_unaligned_le16(sdulen, skb_put(skb, 2));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001681
1682 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1683 if (unlikely(err < 0)) {
1684 kfree_skb(skb);
1685 return ERR_PTR(err);
1686 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001687
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001688 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1689 put_unaligned_le16(0, skb_put(skb, 2));
1690
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001691 bt_cb(skb)->retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001692 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001693}
1694
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001695static inline int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len)
1696{
1697 struct l2cap_pinfo *pi = l2cap_pi(sk);
1698 struct sk_buff *skb;
1699 struct sk_buff_head sar_queue;
1700 u16 control;
1701 size_t size = 0;
1702
Gustavo F. Padovanff12fd62010-05-05 22:09:15 -03001703 skb_queue_head_init(&sar_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001704 control = L2CAP_SDU_START;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001705 skb = l2cap_create_iframe_pdu(sk, msg, pi->remote_mps, control, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001706 if (IS_ERR(skb))
1707 return PTR_ERR(skb);
1708
1709 __skb_queue_tail(&sar_queue, skb);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001710 len -= pi->remote_mps;
1711 size += pi->remote_mps;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001712
1713 while (len > 0) {
1714 size_t buflen;
1715
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001716 if (len > pi->remote_mps) {
Gustavo F. Padovan44651b82010-05-01 16:15:43 -03001717 control = L2CAP_SDU_CONTINUE;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001718 buflen = pi->remote_mps;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001719 } else {
Gustavo F. Padovan44651b82010-05-01 16:15:43 -03001720 control = L2CAP_SDU_END;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001721 buflen = len;
1722 }
1723
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001724 skb = l2cap_create_iframe_pdu(sk, msg, buflen, control, 0);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001725 if (IS_ERR(skb)) {
1726 skb_queue_purge(&sar_queue);
1727 return PTR_ERR(skb);
1728 }
1729
1730 __skb_queue_tail(&sar_queue, skb);
1731 len -= buflen;
1732 size += buflen;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001733 }
1734 skb_queue_splice_tail(&sar_queue, TX_QUEUE(sk));
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001735 spin_lock_bh(&pi->send_lock);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001736 if (sk->sk_send_head == NULL)
1737 sk->sk_send_head = sar_queue.next;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001738 spin_unlock_bh(&pi->send_lock);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001739
1740 return size;
1741}
1742
Linus Torvalds1da177e2005-04-16 15:20:36 -07001743static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len)
1744{
1745 struct sock *sk = sock->sk;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001746 struct l2cap_pinfo *pi = l2cap_pi(sk);
1747 struct sk_buff *skb;
1748 u16 control;
1749 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001750
1751 BT_DBG("sock %p, sk %p", sock, sk);
1752
Benjamin LaHaisec1cbe4b2005-12-13 23:22:19 -08001753 err = sock_error(sk);
1754 if (err)
1755 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001756
1757 if (msg->msg_flags & MSG_OOB)
1758 return -EOPNOTSUPP;
1759
Linus Torvalds1da177e2005-04-16 15:20:36 -07001760 lock_sock(sk);
1761
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001762 if (sk->sk_state != BT_CONNECTED) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001763 err = -ENOTCONN;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001764 goto done;
1765 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001766
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001767 /* Connectionless channel */
1768 if (sk->sk_type == SOCK_DGRAM) {
1769 skb = l2cap_create_connless_pdu(sk, msg, len);
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001770 if (IS_ERR(skb)) {
Dan Carpenter477fffb2010-04-21 23:52:01 +00001771 err = PTR_ERR(skb);
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001772 } else {
1773 l2cap_do_send(sk, skb);
1774 err = len;
1775 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001776 goto done;
1777 }
1778
1779 switch (pi->mode) {
1780 case L2CAP_MODE_BASIC:
Gustavo F. Padovanc69163e2010-05-01 16:15:35 -03001781 /* Check outgoing MTU */
1782 if (len > pi->omtu) {
1783 err = -EINVAL;
1784 goto done;
1785 }
1786
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001787 /* Create a basic PDU */
1788 skb = l2cap_create_basic_pdu(sk, msg, len);
1789 if (IS_ERR(skb)) {
1790 err = PTR_ERR(skb);
1791 goto done;
1792 }
1793
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001794 l2cap_do_send(sk, skb);
1795 err = len;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001796 break;
1797
1798 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001799 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001800 /* Entire SDU fits into one PDU */
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001801 if (len <= pi->remote_mps) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001802 control = L2CAP_SDU_UNSEGMENTED;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001803 skb = l2cap_create_iframe_pdu(sk, msg, len, control, 0);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001804 if (IS_ERR(skb)) {
1805 err = PTR_ERR(skb);
1806 goto done;
1807 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001808 __skb_queue_tail(TX_QUEUE(sk), skb);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001809
1810 if (pi->mode == L2CAP_MODE_ERTM)
1811 spin_lock_bh(&pi->send_lock);
1812
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001813 if (sk->sk_send_head == NULL)
1814 sk->sk_send_head = skb;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001815
1816 if (pi->mode == L2CAP_MODE_ERTM)
1817 spin_unlock_bh(&pi->send_lock);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001818 } else {
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001819 /* Segment SDU into multiples PDUs */
1820 err = l2cap_sar_segment_sdu(sk, msg, len);
1821 if (err < 0)
1822 goto done;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001823 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001824
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001825 if (pi->mode == L2CAP_MODE_STREAMING) {
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001826 err = l2cap_streaming_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001827 } else {
Gustavo F. Padovan6e2b6722010-06-01 18:52:58 -03001828 if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY &&
1829 pi->conn_state && L2CAP_CONN_WAIT_F) {
1830 err = len;
1831 break;
1832 }
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001833 spin_lock_bh(&pi->send_lock);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001834 err = l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001835 spin_unlock_bh(&pi->send_lock);
1836 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001837
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001838 if (err >= 0)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001839 err = len;
1840 break;
1841
1842 default:
1843 BT_DBG("bad state %1.1x", pi->mode);
1844 err = -EINVAL;
1845 }
1846
1847done:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001848 release_sock(sk);
1849 return err;
1850}
1851
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001852static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags)
1853{
1854 struct sock *sk = sock->sk;
1855
1856 lock_sock(sk);
1857
1858 if (sk->sk_state == BT_CONNECT2 && bt_sk(sk)->defer_setup) {
1859 struct l2cap_conn_rsp rsp;
1860
1861 sk->sk_state = BT_CONFIG;
1862
1863 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
1864 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
1865 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
1866 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
1867 l2cap_send_cmd(l2cap_pi(sk)->conn, l2cap_pi(sk)->ident,
1868 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
1869
1870 release_sock(sk);
1871 return 0;
1872 }
1873
1874 release_sock(sk);
1875
1876 return bt_sock_recvmsg(iocb, sock, msg, len, flags);
1877}
1878
David S. Millerb7058842009-09-30 16:12:20 -07001879static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001880{
1881 struct sock *sk = sock->sk;
1882 struct l2cap_options opts;
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001883 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001884 u32 opt;
1885
1886 BT_DBG("sk %p", sk);
1887
1888 lock_sock(sk);
1889
1890 switch (optname) {
1891 case L2CAP_OPTIONS:
Marcel Holtmann0878b662007-05-05 00:35:59 +02001892 opts.imtu = l2cap_pi(sk)->imtu;
1893 opts.omtu = l2cap_pi(sk)->omtu;
1894 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001895 opts.mode = l2cap_pi(sk)->mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001896 opts.fcs = l2cap_pi(sk)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03001897 opts.max_tx = l2cap_pi(sk)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03001898 opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
Marcel Holtmann0878b662007-05-05 00:35:59 +02001899
Linus Torvalds1da177e2005-04-16 15:20:36 -07001900 len = min_t(unsigned int, sizeof(opts), optlen);
1901 if (copy_from_user((char *) &opts, optval, len)) {
1902 err = -EFAULT;
1903 break;
1904 }
Marcel Holtmann0878b662007-05-05 00:35:59 +02001905
João Paulo Rechi Vita0041ecf2010-05-01 16:15:42 -03001906 l2cap_pi(sk)->mode = opts.mode;
1907 switch (l2cap_pi(sk)->mode) {
1908 case L2CAP_MODE_BASIC:
1909 break;
1910 case L2CAP_MODE_ERTM:
1911 case L2CAP_MODE_STREAMING:
1912 if (enable_ertm)
1913 break;
1914 /* fall through */
1915 default:
1916 err = -EINVAL;
1917 break;
1918 }
1919
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001920 l2cap_pi(sk)->imtu = opts.imtu;
1921 l2cap_pi(sk)->omtu = opts.omtu;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001922 l2cap_pi(sk)->fcs = opts.fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03001923 l2cap_pi(sk)->max_tx = opts.max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03001924 l2cap_pi(sk)->tx_win = (__u8)opts.txwin_size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001925 break;
1926
1927 case L2CAP_LM:
1928 if (get_user(opt, (u32 __user *) optval)) {
1929 err = -EFAULT;
1930 break;
1931 }
1932
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001933 if (opt & L2CAP_LM_AUTH)
1934 l2cap_pi(sk)->sec_level = BT_SECURITY_LOW;
1935 if (opt & L2CAP_LM_ENCRYPT)
1936 l2cap_pi(sk)->sec_level = BT_SECURITY_MEDIUM;
1937 if (opt & L2CAP_LM_SECURE)
1938 l2cap_pi(sk)->sec_level = BT_SECURITY_HIGH;
1939
1940 l2cap_pi(sk)->role_switch = (opt & L2CAP_LM_MASTER);
1941 l2cap_pi(sk)->force_reliable = (opt & L2CAP_LM_RELIABLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001942 break;
1943
1944 default:
1945 err = -ENOPROTOOPT;
1946 break;
1947 }
1948
1949 release_sock(sk);
1950 return err;
1951}
1952
David S. Millerb7058842009-09-30 16:12:20 -07001953static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001954{
1955 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001956 struct bt_security sec;
1957 int len, err = 0;
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001958 u32 opt;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001959
1960 BT_DBG("sk %p", sk);
1961
1962 if (level == SOL_L2CAP)
1963 return l2cap_sock_setsockopt_old(sock, optname, optval, optlen);
1964
Marcel Holtmann0588d942009-01-16 10:06:13 +01001965 if (level != SOL_BLUETOOTH)
1966 return -ENOPROTOOPT;
1967
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001968 lock_sock(sk);
1969
1970 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001971 case BT_SECURITY:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001972 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
1973 && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01001974 err = -EINVAL;
1975 break;
1976 }
1977
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001978 sec.level = BT_SECURITY_LOW;
1979
1980 len = min_t(unsigned int, sizeof(sec), optlen);
1981 if (copy_from_user((char *) &sec, optval, len)) {
1982 err = -EFAULT;
1983 break;
1984 }
1985
1986 if (sec.level < BT_SECURITY_LOW ||
1987 sec.level > BT_SECURITY_HIGH) {
1988 err = -EINVAL;
1989 break;
1990 }
1991
1992 l2cap_pi(sk)->sec_level = sec.level;
1993 break;
1994
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001995 case BT_DEFER_SETUP:
1996 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
1997 err = -EINVAL;
1998 break;
1999 }
2000
2001 if (get_user(opt, (u32 __user *) optval)) {
2002 err = -EFAULT;
2003 break;
2004 }
2005
2006 bt_sk(sk)->defer_setup = opt;
2007 break;
2008
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002009 default:
2010 err = -ENOPROTOOPT;
2011 break;
2012 }
2013
2014 release_sock(sk);
2015 return err;
2016}
2017
2018static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002019{
2020 struct sock *sk = sock->sk;
2021 struct l2cap_options opts;
2022 struct l2cap_conninfo cinfo;
2023 int len, err = 0;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002024 u32 opt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002025
2026 BT_DBG("sk %p", sk);
2027
2028 if (get_user(len, optlen))
2029 return -EFAULT;
2030
2031 lock_sock(sk);
2032
2033 switch (optname) {
2034 case L2CAP_OPTIONS:
2035 opts.imtu = l2cap_pi(sk)->imtu;
2036 opts.omtu = l2cap_pi(sk)->omtu;
2037 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07002038 opts.mode = l2cap_pi(sk)->mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002039 opts.fcs = l2cap_pi(sk)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03002040 opts.max_tx = l2cap_pi(sk)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03002041 opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002042
2043 len = min_t(unsigned int, len, sizeof(opts));
2044 if (copy_to_user(optval, (char *) &opts, len))
2045 err = -EFAULT;
2046
2047 break;
2048
2049 case L2CAP_LM:
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002050 switch (l2cap_pi(sk)->sec_level) {
2051 case BT_SECURITY_LOW:
2052 opt = L2CAP_LM_AUTH;
2053 break;
2054 case BT_SECURITY_MEDIUM:
2055 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT;
2056 break;
2057 case BT_SECURITY_HIGH:
2058 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT |
2059 L2CAP_LM_SECURE;
2060 break;
2061 default:
2062 opt = 0;
2063 break;
2064 }
2065
2066 if (l2cap_pi(sk)->role_switch)
2067 opt |= L2CAP_LM_MASTER;
2068
2069 if (l2cap_pi(sk)->force_reliable)
2070 opt |= L2CAP_LM_RELIABLE;
2071
2072 if (put_user(opt, (u32 __user *) optval))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002073 err = -EFAULT;
2074 break;
2075
2076 case L2CAP_CONNINFO:
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002077 if (sk->sk_state != BT_CONNECTED &&
2078 !(sk->sk_state == BT_CONNECT2 &&
2079 bt_sk(sk)->defer_setup)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002080 err = -ENOTCONN;
2081 break;
2082 }
2083
2084 cinfo.hci_handle = l2cap_pi(sk)->conn->hcon->handle;
2085 memcpy(cinfo.dev_class, l2cap_pi(sk)->conn->hcon->dev_class, 3);
2086
2087 len = min_t(unsigned int, len, sizeof(cinfo));
2088 if (copy_to_user(optval, (char *) &cinfo, len))
2089 err = -EFAULT;
2090
2091 break;
2092
2093 default:
2094 err = -ENOPROTOOPT;
2095 break;
2096 }
2097
2098 release_sock(sk);
2099 return err;
2100}
2101
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002102static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
2103{
2104 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002105 struct bt_security sec;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002106 int len, err = 0;
2107
2108 BT_DBG("sk %p", sk);
2109
2110 if (level == SOL_L2CAP)
2111 return l2cap_sock_getsockopt_old(sock, optname, optval, optlen);
2112
Marcel Holtmann0588d942009-01-16 10:06:13 +01002113 if (level != SOL_BLUETOOTH)
2114 return -ENOPROTOOPT;
2115
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002116 if (get_user(len, optlen))
2117 return -EFAULT;
2118
2119 lock_sock(sk);
2120
2121 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002122 case BT_SECURITY:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03002123 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
2124 && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01002125 err = -EINVAL;
2126 break;
2127 }
2128
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002129 sec.level = l2cap_pi(sk)->sec_level;
2130
2131 len = min_t(unsigned int, len, sizeof(sec));
2132 if (copy_to_user(optval, (char *) &sec, len))
2133 err = -EFAULT;
2134
2135 break;
2136
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002137 case BT_DEFER_SETUP:
2138 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
2139 err = -EINVAL;
2140 break;
2141 }
2142
2143 if (put_user(bt_sk(sk)->defer_setup, (u32 __user *) optval))
2144 err = -EFAULT;
2145
2146 break;
2147
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002148 default:
2149 err = -ENOPROTOOPT;
2150 break;
2151 }
2152
2153 release_sock(sk);
2154 return err;
2155}
2156
Linus Torvalds1da177e2005-04-16 15:20:36 -07002157static int l2cap_sock_shutdown(struct socket *sock, int how)
2158{
2159 struct sock *sk = sock->sk;
2160 int err = 0;
2161
2162 BT_DBG("sock %p, sk %p", sock, sk);
2163
2164 if (!sk)
2165 return 0;
2166
2167 lock_sock(sk);
2168 if (!sk->sk_shutdown) {
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03002169 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
2170 err = __l2cap_wait_ack(sk);
2171
Linus Torvalds1da177e2005-04-16 15:20:36 -07002172 sk->sk_shutdown = SHUTDOWN_MASK;
2173 l2cap_sock_clear_timer(sk);
2174 __l2cap_sock_close(sk, 0);
2175
2176 if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
Marcel Holtmannb1235d72008-07-14 20:13:54 +02002177 err = bt_sock_wait_state(sk, BT_CLOSED,
2178 sk->sk_lingertime);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002179 }
2180 release_sock(sk);
2181 return err;
2182}
2183
2184static int l2cap_sock_release(struct socket *sock)
2185{
2186 struct sock *sk = sock->sk;
2187 int err;
2188
2189 BT_DBG("sock %p, sk %p", sock, sk);
2190
2191 if (!sk)
2192 return 0;
2193
2194 err = l2cap_sock_shutdown(sock, 2);
2195
2196 sock_orphan(sk);
2197 l2cap_sock_kill(sk);
2198 return err;
2199}
2200
Linus Torvalds1da177e2005-04-16 15:20:36 -07002201static void l2cap_chan_ready(struct sock *sk)
2202{
2203 struct sock *parent = bt_sk(sk)->parent;
2204
2205 BT_DBG("sk %p, parent %p", sk, parent);
2206
2207 l2cap_pi(sk)->conf_state = 0;
2208 l2cap_sock_clear_timer(sk);
2209
2210 if (!parent) {
2211 /* Outgoing channel.
2212 * Wake up socket sleeping on connect.
2213 */
2214 sk->sk_state = BT_CONNECTED;
2215 sk->sk_state_change(sk);
2216 } else {
2217 /* Incoming channel.
2218 * Wake up socket sleeping on accept.
2219 */
2220 parent->sk_data_ready(parent, 0);
2221 }
2222}
2223
2224/* Copy frame to all raw sockets on that connection */
2225static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2226{
2227 struct l2cap_chan_list *l = &conn->chan_list;
2228 struct sk_buff *nskb;
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002229 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002230
2231 BT_DBG("conn %p", conn);
2232
2233 read_lock(&l->lock);
2234 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
2235 if (sk->sk_type != SOCK_RAW)
2236 continue;
2237
2238 /* Don't send frame to the socket it came from */
2239 if (skb->sk == sk)
2240 continue;
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002241 nskb = skb_clone(skb, GFP_ATOMIC);
2242 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002243 continue;
2244
2245 if (sock_queue_rcv_skb(sk, nskb))
2246 kfree_skb(nskb);
2247 }
2248 read_unlock(&l->lock);
2249}
2250
2251/* ---- L2CAP signalling commands ---- */
2252static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
2253 u8 code, u8 ident, u16 dlen, void *data)
2254{
2255 struct sk_buff *skb, **frag;
2256 struct l2cap_cmd_hdr *cmd;
2257 struct l2cap_hdr *lh;
2258 int len, count;
2259
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002260 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d",
2261 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002262
2263 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2264 count = min_t(unsigned int, conn->mtu, len);
2265
2266 skb = bt_skb_alloc(count, GFP_ATOMIC);
2267 if (!skb)
2268 return NULL;
2269
2270 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002271 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03002272 lh->cid = cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002273
2274 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2275 cmd->code = code;
2276 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002277 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002278
2279 if (dlen) {
2280 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2281 memcpy(skb_put(skb, count), data, count);
2282 data += count;
2283 }
2284
2285 len -= skb->len;
2286
2287 /* Continuation fragments (no L2CAP header) */
2288 frag = &skb_shinfo(skb)->frag_list;
2289 while (len) {
2290 count = min_t(unsigned int, conn->mtu, len);
2291
2292 *frag = bt_skb_alloc(count, GFP_ATOMIC);
2293 if (!*frag)
2294 goto fail;
2295
2296 memcpy(skb_put(*frag, count), data, count);
2297
2298 len -= count;
2299 data += count;
2300
2301 frag = &(*frag)->next;
2302 }
2303
2304 return skb;
2305
2306fail:
2307 kfree_skb(skb);
2308 return NULL;
2309}
2310
2311static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned long *val)
2312{
2313 struct l2cap_conf_opt *opt = *ptr;
2314 int len;
2315
2316 len = L2CAP_CONF_OPT_SIZE + opt->len;
2317 *ptr += len;
2318
2319 *type = opt->type;
2320 *olen = opt->len;
2321
2322 switch (opt->len) {
2323 case 1:
2324 *val = *((u8 *) opt->val);
2325 break;
2326
2327 case 2:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002328 *val = __le16_to_cpu(*((__le16 *) opt->val));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002329 break;
2330
2331 case 4:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002332 *val = __le32_to_cpu(*((__le32 *) opt->val));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002333 break;
2334
2335 default:
2336 *val = (unsigned long) opt->val;
2337 break;
2338 }
2339
2340 BT_DBG("type 0x%2.2x len %d val 0x%lx", *type, opt->len, *val);
2341 return len;
2342}
2343
Linus Torvalds1da177e2005-04-16 15:20:36 -07002344static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2345{
2346 struct l2cap_conf_opt *opt = *ptr;
2347
2348 BT_DBG("type 0x%2.2x len %d val 0x%lx", type, len, val);
2349
2350 opt->type = type;
2351 opt->len = len;
2352
2353 switch (len) {
2354 case 1:
2355 *((u8 *) opt->val) = val;
2356 break;
2357
2358 case 2:
Al Viro8e036fc2007-07-29 00:16:36 -07002359 *((__le16 *) opt->val) = cpu_to_le16(val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002360 break;
2361
2362 case 4:
Al Viro8e036fc2007-07-29 00:16:36 -07002363 *((__le32 *) opt->val) = cpu_to_le32(val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002364 break;
2365
2366 default:
2367 memcpy(opt->val, (void *) val, len);
2368 break;
2369 }
2370
2371 *ptr += L2CAP_CONF_OPT_SIZE + len;
2372}
2373
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002374static void l2cap_ack_timeout(unsigned long arg)
2375{
2376 struct sock *sk = (void *) arg;
2377
2378 bh_lock_sock(sk);
2379 l2cap_send_ack(l2cap_pi(sk));
2380 bh_unlock_sock(sk);
2381}
2382
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002383static inline void l2cap_ertm_init(struct sock *sk)
2384{
2385 l2cap_pi(sk)->expected_ack_seq = 0;
2386 l2cap_pi(sk)->unacked_frames = 0;
2387 l2cap_pi(sk)->buffer_seq = 0;
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03002388 l2cap_pi(sk)->num_acked = 0;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03002389 l2cap_pi(sk)->frames_sent = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002390
2391 setup_timer(&l2cap_pi(sk)->retrans_timer,
2392 l2cap_retrans_timeout, (unsigned long) sk);
2393 setup_timer(&l2cap_pi(sk)->monitor_timer,
2394 l2cap_monitor_timeout, (unsigned long) sk);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002395 setup_timer(&l2cap_pi(sk)->ack_timer,
2396 l2cap_ack_timeout, (unsigned long) sk);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002397
2398 __skb_queue_head_init(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002399 __skb_queue_head_init(BUSY_QUEUE(sk));
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03002400 spin_lock_init(&l2cap_pi(sk)->send_lock);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002401
2402 INIT_WORK(&l2cap_pi(sk)->busy_work, l2cap_busy_work);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002403}
2404
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002405static int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
2406{
2407 u32 local_feat_mask = l2cap_feat_mask;
2408 if (enable_ertm)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002409 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002410
2411 switch (mode) {
2412 case L2CAP_MODE_ERTM:
2413 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
2414 case L2CAP_MODE_STREAMING:
2415 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
2416 default:
2417 return 0x00;
2418 }
2419}
2420
2421static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
2422{
2423 switch (mode) {
2424 case L2CAP_MODE_STREAMING:
2425 case L2CAP_MODE_ERTM:
2426 if (l2cap_mode_supported(mode, remote_feat_mask))
2427 return mode;
2428 /* fall through */
2429 default:
2430 return L2CAP_MODE_BASIC;
2431 }
2432}
2433
Linus Torvalds1da177e2005-04-16 15:20:36 -07002434static int l2cap_build_conf_req(struct sock *sk, void *data)
2435{
2436 struct l2cap_pinfo *pi = l2cap_pi(sk);
2437 struct l2cap_conf_req *req = data;
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03002438 struct l2cap_conf_rfc rfc = { .mode = pi->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07002439 void *ptr = req->data;
2440
2441 BT_DBG("sk %p", sk);
2442
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002443 if (pi->num_conf_req || pi->num_conf_rsp)
2444 goto done;
2445
2446 switch (pi->mode) {
2447 case L2CAP_MODE_STREAMING:
2448 case L2CAP_MODE_ERTM:
2449 pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002450 if (!l2cap_mode_supported(pi->mode, pi->conn->feat_mask))
2451 l2cap_send_disconn_req(pi->conn, sk);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002452 break;
2453 default:
2454 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
2455 break;
2456 }
2457
2458done:
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002459 switch (pi->mode) {
2460 case L2CAP_MODE_BASIC:
2461 if (pi->imtu != L2CAP_DEFAULT_MTU)
2462 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
2463 break;
2464
2465 case L2CAP_MODE_ERTM:
2466 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03002467 rfc.txwin_size = pi->tx_win;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03002468 rfc.max_transmit = pi->max_tx;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002469 rfc.retrans_timeout = 0;
2470 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002471 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03002472 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002473 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002474
2475 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2476 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002477
2478 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2479 break;
2480
2481 if (pi->fcs == L2CAP_FCS_NONE ||
2482 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
2483 pi->fcs = L2CAP_FCS_NONE;
2484 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
2485 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002486 break;
2487
2488 case L2CAP_MODE_STREAMING:
2489 rfc.mode = L2CAP_MODE_STREAMING;
2490 rfc.txwin_size = 0;
2491 rfc.max_transmit = 0;
2492 rfc.retrans_timeout = 0;
2493 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002494 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03002495 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002496 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002497
2498 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2499 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002500
2501 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2502 break;
2503
2504 if (pi->fcs == L2CAP_FCS_NONE ||
2505 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
2506 pi->fcs = L2CAP_FCS_NONE;
2507 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
2508 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002509 break;
2510 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002511
2512 /* FIXME: Need actual value of the flush timeout */
2513 //if (flush_to != L2CAP_DEFAULT_FLUSH_TO)
2514 // l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2, pi->flush_to);
2515
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002516 req->dcid = cpu_to_le16(pi->dcid);
2517 req->flags = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002518
2519 return ptr - data;
2520}
2521
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002522static int l2cap_parse_conf_req(struct sock *sk, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002523{
2524 struct l2cap_pinfo *pi = l2cap_pi(sk);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002525 struct l2cap_conf_rsp *rsp = data;
2526 void *ptr = rsp->data;
2527 void *req = pi->conf_req;
2528 int len = pi->conf_len;
2529 int type, hint, olen;
2530 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002531 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Marcel Holtmann861d6882007-10-20 13:37:06 +02002532 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002533 u16 result = L2CAP_CONF_SUCCESS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002534
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002535 BT_DBG("sk %p", sk);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01002536
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002537 while (len >= L2CAP_CONF_OPT_SIZE) {
2538 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002539
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03002540 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07002541 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002542
2543 switch (type) {
2544 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002545 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002546 break;
2547
2548 case L2CAP_CONF_FLUSH_TO:
2549 pi->flush_to = val;
2550 break;
2551
2552 case L2CAP_CONF_QOS:
2553 break;
2554
Marcel Holtmann6464f352007-10-20 13:39:51 +02002555 case L2CAP_CONF_RFC:
2556 if (olen == sizeof(rfc))
2557 memcpy(&rfc, (void *) val, olen);
2558 break;
2559
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002560 case L2CAP_CONF_FCS:
2561 if (val == L2CAP_FCS_NONE)
2562 pi->conf_state |= L2CAP_CONF_NO_FCS_RECV;
2563
2564 break;
2565
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002566 default:
2567 if (hint)
2568 break;
2569
2570 result = L2CAP_CONF_UNKNOWN;
2571 *((u8 *) ptr++) = type;
2572 break;
2573 }
2574 }
2575
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002576 if (pi->num_conf_rsp || pi->num_conf_req)
2577 goto done;
2578
2579 switch (pi->mode) {
2580 case L2CAP_MODE_STREAMING:
2581 case L2CAP_MODE_ERTM:
2582 pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
2583 if (!l2cap_mode_supported(pi->mode, pi->conn->feat_mask))
2584 return -ECONNREFUSED;
2585 break;
2586 default:
2587 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
2588 break;
2589 }
2590
2591done:
2592 if (pi->mode != rfc.mode) {
2593 result = L2CAP_CONF_UNACCEPT;
2594 rfc.mode = pi->mode;
2595
2596 if (pi->num_conf_rsp == 1)
2597 return -ECONNREFUSED;
2598
2599 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2600 sizeof(rfc), (unsigned long) &rfc);
2601 }
2602
2603
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002604 if (result == L2CAP_CONF_SUCCESS) {
2605 /* Configure output options and let the other side know
2606 * which ones we don't like. */
2607
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002608 if (mtu < L2CAP_DEFAULT_MIN_MTU)
2609 result = L2CAP_CONF_UNACCEPT;
2610 else {
2611 pi->omtu = mtu;
2612 pi->conf_state |= L2CAP_CONF_MTU_DONE;
2613 }
2614 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002615
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002616 switch (rfc.mode) {
2617 case L2CAP_MODE_BASIC:
2618 pi->fcs = L2CAP_FCS_NONE;
2619 pi->conf_state |= L2CAP_CONF_MODE_DONE;
2620 break;
2621
2622 case L2CAP_MODE_ERTM:
2623 pi->remote_tx_win = rfc.txwin_size;
2624 pi->remote_max_tx = rfc.max_transmit;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002625 if (rfc.max_pdu_size > pi->conn->mtu - 10)
2626 rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10);
2627
2628 pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002629
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002630 rfc.retrans_timeout =
2631 le16_to_cpu(L2CAP_DEFAULT_RETRANS_TO);
2632 rfc.monitor_timeout =
2633 le16_to_cpu(L2CAP_DEFAULT_MONITOR_TO);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002634
2635 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03002636
2637 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2638 sizeof(rfc), (unsigned long) &rfc);
2639
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002640 break;
2641
2642 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002643 if (rfc.max_pdu_size > pi->conn->mtu - 10)
2644 rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10);
2645
2646 pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002647
2648 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03002649
2650 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2651 sizeof(rfc), (unsigned long) &rfc);
2652
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002653 break;
2654
2655 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02002656 result = L2CAP_CONF_UNACCEPT;
2657
2658 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002659 rfc.mode = pi->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002660 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002661
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002662 if (result == L2CAP_CONF_SUCCESS)
2663 pi->conf_state |= L2CAP_CONF_OUTPUT_DONE;
2664 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002665 rsp->scid = cpu_to_le16(pi->dcid);
2666 rsp->result = cpu_to_le16(result);
2667 rsp->flags = cpu_to_le16(0x0000);
2668
2669 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002670}
2671
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002672static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data, u16 *result)
2673{
2674 struct l2cap_pinfo *pi = l2cap_pi(sk);
2675 struct l2cap_conf_req *req = data;
2676 void *ptr = req->data;
2677 int type, olen;
2678 unsigned long val;
2679 struct l2cap_conf_rfc rfc;
2680
2681 BT_DBG("sk %p, rsp %p, len %d, req %p", sk, rsp, len, data);
2682
2683 while (len >= L2CAP_CONF_OPT_SIZE) {
2684 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
2685
2686 switch (type) {
2687 case L2CAP_CONF_MTU:
2688 if (val < L2CAP_DEFAULT_MIN_MTU) {
2689 *result = L2CAP_CONF_UNACCEPT;
2690 pi->omtu = L2CAP_DEFAULT_MIN_MTU;
2691 } else
2692 pi->omtu = val;
2693 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
2694 break;
2695
2696 case L2CAP_CONF_FLUSH_TO:
2697 pi->flush_to = val;
2698 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
2699 2, pi->flush_to);
2700 break;
2701
2702 case L2CAP_CONF_RFC:
2703 if (olen == sizeof(rfc))
2704 memcpy(&rfc, (void *)val, olen);
2705
2706 if ((pi->conf_state & L2CAP_CONF_STATE2_DEVICE) &&
2707 rfc.mode != pi->mode)
2708 return -ECONNREFUSED;
2709
2710 pi->mode = rfc.mode;
2711 pi->fcs = 0;
2712
2713 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2714 sizeof(rfc), (unsigned long) &rfc);
2715 break;
2716 }
2717 }
2718
2719 if (*result == L2CAP_CONF_SUCCESS) {
2720 switch (rfc.mode) {
2721 case L2CAP_MODE_ERTM:
2722 pi->remote_tx_win = rfc.txwin_size;
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002723 pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
2724 pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002725 pi->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002726 break;
2727 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002728 pi->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002729 }
2730 }
2731
2732 req->dcid = cpu_to_le16(pi->dcid);
2733 req->flags = cpu_to_le16(0x0000);
2734
2735 return ptr - data;
2736}
2737
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002738static int l2cap_build_conf_rsp(struct sock *sk, void *data, u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002739{
2740 struct l2cap_conf_rsp *rsp = data;
2741 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002742
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002743 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002744
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002745 rsp->scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002746 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002747 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002748
2749 return ptr - data;
2750}
2751
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002752static void l2cap_conf_rfc_get(struct sock *sk, void *rsp, int len)
2753{
2754 struct l2cap_pinfo *pi = l2cap_pi(sk);
2755 int type, olen;
2756 unsigned long val;
2757 struct l2cap_conf_rfc rfc;
2758
2759 BT_DBG("sk %p, rsp %p, len %d", sk, rsp, len);
2760
2761 if ((pi->mode != L2CAP_MODE_ERTM) && (pi->mode != L2CAP_MODE_STREAMING))
2762 return;
2763
2764 while (len >= L2CAP_CONF_OPT_SIZE) {
2765 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
2766
2767 switch (type) {
2768 case L2CAP_CONF_RFC:
2769 if (olen == sizeof(rfc))
2770 memcpy(&rfc, (void *)val, olen);
2771 goto done;
2772 }
2773 }
2774
2775done:
2776 switch (rfc.mode) {
2777 case L2CAP_MODE_ERTM:
2778 pi->remote_tx_win = rfc.txwin_size;
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002779 pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
2780 pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002781 pi->mps = le16_to_cpu(rfc.max_pdu_size);
2782 break;
2783 case L2CAP_MODE_STREAMING:
2784 pi->mps = le16_to_cpu(rfc.max_pdu_size);
2785 }
2786}
2787
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002788static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2789{
2790 struct l2cap_cmd_rej *rej = (struct l2cap_cmd_rej *) data;
2791
2792 if (rej->reason != 0x0000)
2793 return 0;
2794
2795 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
2796 cmd->ident == conn->info_ident) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002797 del_timer(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01002798
2799 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002800 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01002801
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002802 l2cap_conn_start(conn);
2803 }
2804
2805 return 0;
2806}
2807
Linus Torvalds1da177e2005-04-16 15:20:36 -07002808static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2809{
2810 struct l2cap_chan_list *list = &conn->chan_list;
2811 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
2812 struct l2cap_conn_rsp rsp;
2813 struct sock *sk, *parent;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002814 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002815
2816 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002817 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002818
2819 BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
2820
2821 /* Check if we have socket listening on psm */
2822 parent = l2cap_get_sock_by_psm(BT_LISTEN, psm, conn->src);
2823 if (!parent) {
2824 result = L2CAP_CR_BAD_PSM;
2825 goto sendresp;
2826 }
2827
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002828 /* Check if the ACL is secure enough (if not SDP) */
2829 if (psm != cpu_to_le16(0x0001) &&
2830 !hci_conn_check_link_mode(conn->hcon)) {
Marcel Holtmann2950f212009-02-12 14:02:50 +01002831 conn->disc_reason = 0x05;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002832 result = L2CAP_CR_SEC_BLOCK;
2833 goto response;
2834 }
2835
Linus Torvalds1da177e2005-04-16 15:20:36 -07002836 result = L2CAP_CR_NO_MEM;
2837
2838 /* Check for backlog size */
2839 if (sk_acceptq_is_full(parent)) {
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09002840 BT_DBG("backlog full %d", parent->sk_ack_backlog);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002841 goto response;
2842 }
2843
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09002844 sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002845 if (!sk)
2846 goto response;
2847
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002848 write_lock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002849
2850 /* Check if we already have channel with that dcid */
2851 if (__l2cap_get_chan_by_dcid(list, scid)) {
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002852 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002853 sock_set_flag(sk, SOCK_ZAPPED);
2854 l2cap_sock_kill(sk);
2855 goto response;
2856 }
2857
2858 hci_conn_hold(conn->hcon);
2859
2860 l2cap_sock_init(sk, parent);
2861 bacpy(&bt_sk(sk)->src, conn->src);
2862 bacpy(&bt_sk(sk)->dst, conn->dst);
2863 l2cap_pi(sk)->psm = psm;
2864 l2cap_pi(sk)->dcid = scid;
2865
2866 __l2cap_chan_add(conn, sk, parent);
2867 dcid = l2cap_pi(sk)->scid;
2868
2869 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
2870
Linus Torvalds1da177e2005-04-16 15:20:36 -07002871 l2cap_pi(sk)->ident = cmd->ident;
2872
Marcel Holtmann984947d2009-02-06 23:35:19 +01002873 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002874 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002875 if (bt_sk(sk)->defer_setup) {
2876 sk->sk_state = BT_CONNECT2;
2877 result = L2CAP_CR_PEND;
2878 status = L2CAP_CS_AUTHOR_PEND;
2879 parent->sk_data_ready(parent, 0);
2880 } else {
2881 sk->sk_state = BT_CONFIG;
2882 result = L2CAP_CR_SUCCESS;
2883 status = L2CAP_CS_NO_INFO;
2884 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002885 } else {
2886 sk->sk_state = BT_CONNECT2;
2887 result = L2CAP_CR_PEND;
2888 status = L2CAP_CS_AUTHEN_PEND;
2889 }
2890 } else {
2891 sk->sk_state = BT_CONNECT2;
2892 result = L2CAP_CR_PEND;
2893 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002894 }
2895
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002896 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002897
2898response:
2899 bh_unlock_sock(parent);
2900
2901sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002902 rsp.scid = cpu_to_le16(scid);
2903 rsp.dcid = cpu_to_le16(dcid);
2904 rsp.result = cpu_to_le16(result);
2905 rsp.status = cpu_to_le16(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002906 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002907
2908 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
2909 struct l2cap_info_req info;
2910 info.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
2911
2912 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
2913 conn->info_ident = l2cap_get_ident(conn);
2914
2915 mod_timer(&conn->info_timer, jiffies +
2916 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
2917
2918 l2cap_send_cmd(conn, conn->info_ident,
2919 L2CAP_INFO_REQ, sizeof(info), &info);
2920 }
2921
Linus Torvalds1da177e2005-04-16 15:20:36 -07002922 return 0;
2923}
2924
2925static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2926{
2927 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
2928 u16 scid, dcid, result, status;
2929 struct sock *sk;
2930 u8 req[128];
2931
2932 scid = __le16_to_cpu(rsp->scid);
2933 dcid = __le16_to_cpu(rsp->dcid);
2934 result = __le16_to_cpu(rsp->result);
2935 status = __le16_to_cpu(rsp->status);
2936
2937 BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
2938
2939 if (scid) {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002940 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2941 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002942 return 0;
2943 } else {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002944 sk = l2cap_get_chan_by_ident(&conn->chan_list, cmd->ident);
2945 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002946 return 0;
2947 }
2948
2949 switch (result) {
2950 case L2CAP_CR_SUCCESS:
2951 sk->sk_state = BT_CONFIG;
2952 l2cap_pi(sk)->ident = 0;
2953 l2cap_pi(sk)->dcid = dcid;
2954 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002955 l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_CONNECT_PEND;
2956
Linus Torvalds1da177e2005-04-16 15:20:36 -07002957 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
2958 l2cap_build_conf_req(sk, req), req);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002959 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002960 break;
2961
2962 case L2CAP_CR_PEND:
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002963 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002964 break;
2965
2966 default:
2967 l2cap_chan_del(sk, ECONNREFUSED);
2968 break;
2969 }
2970
2971 bh_unlock_sock(sk);
2972 return 0;
2973}
2974
Al Viro88219a02007-07-29 00:17:25 -07002975static 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 -07002976{
2977 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
2978 u16 dcid, flags;
2979 u8 rsp[64];
2980 struct sock *sk;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002981 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002982
2983 dcid = __le16_to_cpu(req->dcid);
2984 flags = __le16_to_cpu(req->flags);
2985
2986 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
2987
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002988 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
2989 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002990 return -ENOENT;
2991
Marcel Holtmann354f60a2006-11-18 22:15:20 +01002992 if (sk->sk_state == BT_DISCONN)
2993 goto unlock;
2994
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002995 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07002996 len = cmd_len - sizeof(*req);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002997 if (l2cap_pi(sk)->conf_len + len > sizeof(l2cap_pi(sk)->conf_req)) {
2998 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
2999 l2cap_build_conf_rsp(sk, rsp,
3000 L2CAP_CONF_REJECT, flags), rsp);
3001 goto unlock;
3002 }
3003
3004 /* Store config. */
3005 memcpy(l2cap_pi(sk)->conf_req + l2cap_pi(sk)->conf_len, req->data, len);
3006 l2cap_pi(sk)->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003007
3008 if (flags & 0x0001) {
3009 /* Incomplete config. Send empty response. */
3010 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003011 l2cap_build_conf_rsp(sk, rsp,
3012 L2CAP_CONF_SUCCESS, 0x0001), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003013 goto unlock;
3014 }
3015
3016 /* Complete config. */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003017 len = l2cap_parse_conf_req(sk, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003018 if (len < 0) {
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03003019 l2cap_send_disconn_req(conn, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003020 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003021 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003022
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003023 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003024 l2cap_pi(sk)->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003025
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003026 /* Reset config buffer. */
3027 l2cap_pi(sk)->conf_len = 0;
3028
Marcel Holtmann876d9482007-10-20 13:35:42 +02003029 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE))
3030 goto unlock;
3031
Linus Torvalds1da177e2005-04-16 15:20:36 -07003032 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) {
Joe Perchesf64f9e72009-11-29 16:55:45 -08003033 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) ||
3034 l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003035 l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
3036
Linus Torvalds1da177e2005-04-16 15:20:36 -07003037 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003038
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003039 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003040 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003041 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003042 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
3043 l2cap_ertm_init(sk);
3044
Linus Torvalds1da177e2005-04-16 15:20:36 -07003045 l2cap_chan_ready(sk);
Marcel Holtmann876d9482007-10-20 13:35:42 +02003046 goto unlock;
3047 }
3048
3049 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003050 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003051 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003052 l2cap_build_conf_req(sk, buf), buf);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003053 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003054 }
3055
3056unlock:
3057 bh_unlock_sock(sk);
3058 return 0;
3059}
3060
3061static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3062{
3063 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
3064 u16 scid, flags, result;
3065 struct sock *sk;
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003066 int len = cmd->len - sizeof(*rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003067
3068 scid = __le16_to_cpu(rsp->scid);
3069 flags = __le16_to_cpu(rsp->flags);
3070 result = __le16_to_cpu(rsp->result);
3071
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003072 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x",
3073 scid, flags, result);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003074
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003075 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
3076 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003077 return 0;
3078
3079 switch (result) {
3080 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003081 l2cap_conf_rfc_get(sk, rsp->data, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003082 break;
3083
3084 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003085 if (l2cap_pi(sk)->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003086 char req[64];
3087
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02003088 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
3089 l2cap_send_disconn_req(conn, sk);
3090 goto done;
3091 }
3092
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003093 /* throw out any old stored conf requests */
3094 result = L2CAP_CONF_SUCCESS;
3095 len = l2cap_parse_conf_rsp(sk, rsp->data,
3096 len, req, &result);
3097 if (len < 0) {
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03003098 l2cap_send_disconn_req(conn, sk);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003099 goto done;
3100 }
3101
3102 l2cap_send_cmd(conn, l2cap_get_ident(conn),
3103 L2CAP_CONF_REQ, len, req);
3104 l2cap_pi(sk)->num_conf_req++;
3105 if (result != L2CAP_CONF_SUCCESS)
3106 goto done;
3107 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003108 }
3109
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09003110 default:
Marcel Holtmannb1235d72008-07-14 20:13:54 +02003111 sk->sk_err = ECONNRESET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003112 l2cap_sock_set_timer(sk, HZ * 5);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03003113 l2cap_send_disconn_req(conn, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003114 goto done;
3115 }
3116
3117 if (flags & 0x01)
3118 goto done;
3119
Linus Torvalds1da177e2005-04-16 15:20:36 -07003120 l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE;
3121
3122 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) {
Joe Perchesf64f9e72009-11-29 16:55:45 -08003123 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) ||
3124 l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003125 l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
3126
Linus Torvalds1da177e2005-04-16 15:20:36 -07003127 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003128 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003129 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003130 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003131 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
3132 l2cap_ertm_init(sk);
3133
Linus Torvalds1da177e2005-04-16 15:20:36 -07003134 l2cap_chan_ready(sk);
3135 }
3136
3137done:
3138 bh_unlock_sock(sk);
3139 return 0;
3140}
3141
3142static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3143{
3144 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
3145 struct l2cap_disconn_rsp rsp;
3146 u16 dcid, scid;
3147 struct sock *sk;
3148
3149 scid = __le16_to_cpu(req->scid);
3150 dcid = __le16_to_cpu(req->dcid);
3151
3152 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
3153
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003154 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
3155 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003156 return 0;
3157
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003158 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
3159 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003160 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
3161
3162 sk->sk_shutdown = SHUTDOWN_MASK;
3163
3164 l2cap_chan_del(sk, ECONNRESET);
3165 bh_unlock_sock(sk);
3166
3167 l2cap_sock_kill(sk);
3168 return 0;
3169}
3170
3171static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3172{
3173 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
3174 u16 dcid, scid;
3175 struct sock *sk;
3176
3177 scid = __le16_to_cpu(rsp->scid);
3178 dcid = __le16_to_cpu(rsp->dcid);
3179
3180 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
3181
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003182 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
3183 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003184 return 0;
3185
3186 l2cap_chan_del(sk, 0);
3187 bh_unlock_sock(sk);
3188
3189 l2cap_sock_kill(sk);
3190 return 0;
3191}
3192
3193static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3194{
3195 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003196 u16 type;
3197
3198 type = __le16_to_cpu(req->type);
3199
3200 BT_DBG("type 0x%4.4x", type);
3201
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003202 if (type == L2CAP_IT_FEAT_MASK) {
3203 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003204 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003205 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
3206 rsp->type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
3207 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003208 if (enable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003209 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
3210 | L2CAP_FEAT_FCS;
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03003211 put_unaligned_le32(feat_mask, rsp->data);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003212 l2cap_send_cmd(conn, cmd->ident,
3213 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003214 } else if (type == L2CAP_IT_FIXED_CHAN) {
3215 u8 buf[12];
3216 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
3217 rsp->type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3218 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
3219 memcpy(buf + 4, l2cap_fixed_chan, 8);
3220 l2cap_send_cmd(conn, cmd->ident,
3221 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003222 } else {
3223 struct l2cap_info_rsp rsp;
3224 rsp.type = cpu_to_le16(type);
3225 rsp.result = cpu_to_le16(L2CAP_IR_NOTSUPP);
3226 l2cap_send_cmd(conn, cmd->ident,
3227 L2CAP_INFO_RSP, sizeof(rsp), &rsp);
3228 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003229
3230 return 0;
3231}
3232
3233static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3234{
3235 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
3236 u16 type, result;
3237
3238 type = __le16_to_cpu(rsp->type);
3239 result = __le16_to_cpu(rsp->result);
3240
3241 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
3242
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003243 del_timer(&conn->info_timer);
3244
Marcel Holtmann984947d2009-02-06 23:35:19 +01003245 if (type == L2CAP_IT_FEAT_MASK) {
Harvey Harrison83985312008-05-02 16:25:46 -07003246 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003247
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003248 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003249 struct l2cap_info_req req;
3250 req.type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3251
3252 conn->info_ident = l2cap_get_ident(conn);
3253
3254 l2cap_send_cmd(conn, conn->info_ident,
3255 L2CAP_INFO_REQ, sizeof(req), &req);
3256 } else {
3257 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
3258 conn->info_ident = 0;
3259
3260 l2cap_conn_start(conn);
3261 }
3262 } else if (type == L2CAP_IT_FIXED_CHAN) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01003263 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003264 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003265
3266 l2cap_conn_start(conn);
3267 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003268
Linus Torvalds1da177e2005-04-16 15:20:36 -07003269 return 0;
3270}
3271
3272static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
3273{
3274 u8 *data = skb->data;
3275 int len = skb->len;
3276 struct l2cap_cmd_hdr cmd;
3277 int err = 0;
3278
3279 l2cap_raw_recv(conn, skb);
3280
3281 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07003282 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003283 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
3284 data += L2CAP_CMD_HDR_SIZE;
3285 len -= L2CAP_CMD_HDR_SIZE;
3286
Al Viro88219a02007-07-29 00:17:25 -07003287 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003288
Al Viro88219a02007-07-29 00:17:25 -07003289 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 -07003290
Al Viro88219a02007-07-29 00:17:25 -07003291 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003292 BT_DBG("corrupted command");
3293 break;
3294 }
3295
3296 switch (cmd.code) {
3297 case L2CAP_COMMAND_REJ:
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003298 l2cap_command_rej(conn, &cmd, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003299 break;
3300
3301 case L2CAP_CONN_REQ:
3302 err = l2cap_connect_req(conn, &cmd, data);
3303 break;
3304
3305 case L2CAP_CONN_RSP:
3306 err = l2cap_connect_rsp(conn, &cmd, data);
3307 break;
3308
3309 case L2CAP_CONF_REQ:
Al Viro88219a02007-07-29 00:17:25 -07003310 err = l2cap_config_req(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003311 break;
3312
3313 case L2CAP_CONF_RSP:
3314 err = l2cap_config_rsp(conn, &cmd, data);
3315 break;
3316
3317 case L2CAP_DISCONN_REQ:
3318 err = l2cap_disconnect_req(conn, &cmd, data);
3319 break;
3320
3321 case L2CAP_DISCONN_RSP:
3322 err = l2cap_disconnect_rsp(conn, &cmd, data);
3323 break;
3324
3325 case L2CAP_ECHO_REQ:
Al Viro88219a02007-07-29 00:17:25 -07003326 l2cap_send_cmd(conn, cmd.ident, L2CAP_ECHO_RSP, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003327 break;
3328
3329 case L2CAP_ECHO_RSP:
3330 break;
3331
3332 case L2CAP_INFO_REQ:
3333 err = l2cap_information_req(conn, &cmd, data);
3334 break;
3335
3336 case L2CAP_INFO_RSP:
3337 err = l2cap_information_rsp(conn, &cmd, data);
3338 break;
3339
3340 default:
3341 BT_ERR("Unknown signaling command 0x%2.2x", cmd.code);
3342 err = -EINVAL;
3343 break;
3344 }
3345
3346 if (err) {
3347 struct l2cap_cmd_rej rej;
3348 BT_DBG("error %d", err);
3349
3350 /* FIXME: Map err to a valid reason */
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003351 rej.reason = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003352 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
3353 }
3354
Al Viro88219a02007-07-29 00:17:25 -07003355 data += cmd_len;
3356 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003357 }
3358
3359 kfree_skb(skb);
3360}
3361
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003362static int l2cap_check_fcs(struct l2cap_pinfo *pi, struct sk_buff *skb)
3363{
3364 u16 our_fcs, rcv_fcs;
3365 int hdr_size = L2CAP_HDR_SIZE + 2;
3366
3367 if (pi->fcs == L2CAP_FCS_CRC16) {
3368 skb_trim(skb, skb->len - 2);
3369 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
3370 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
3371
3372 if (our_fcs != rcv_fcs)
3373 return -EINVAL;
3374 }
3375 return 0;
3376}
3377
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003378static inline void l2cap_send_i_or_rr_or_rnr(struct sock *sk)
3379{
3380 struct l2cap_pinfo *pi = l2cap_pi(sk);
3381 u16 control = 0;
3382
3383 pi->frames_sent = 0;
3384 pi->conn_state |= L2CAP_CONN_SEND_FBIT;
3385
3386 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3387
3388 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
3389 control |= L2CAP_SUPER_RCV_NOT_READY | L2CAP_CTRL_FINAL;
3390 l2cap_send_sframe(pi, control);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003391 pi->conn_state |= L2CAP_CONN_RNR_SENT;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003392 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
3393 }
3394
3395 if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY && pi->unacked_frames > 0)
3396 __mod_retrans_timer();
3397
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003398 spin_lock_bh(&pi->send_lock);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003399 l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003400 spin_unlock_bh(&pi->send_lock);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003401
3402 if (!(pi->conn_state & L2CAP_CONN_LOCAL_BUSY) &&
3403 pi->frames_sent == 0) {
3404 control |= L2CAP_SUPER_RCV_READY;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003405 l2cap_send_sframe(pi, control);
3406 }
3407}
3408
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003409static 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 -03003410{
3411 struct sk_buff *next_skb;
João Paulo Rechi Vitabfbacc12010-05-31 18:35:44 -03003412 struct l2cap_pinfo *pi = l2cap_pi(sk);
3413 int tx_seq_offset, next_tx_seq_offset;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003414
3415 bt_cb(skb)->tx_seq = tx_seq;
3416 bt_cb(skb)->sar = sar;
3417
3418 next_skb = skb_peek(SREJ_QUEUE(sk));
3419 if (!next_skb) {
3420 __skb_queue_tail(SREJ_QUEUE(sk), skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003421 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003422 }
3423
João Paulo Rechi Vitabfbacc12010-05-31 18:35:44 -03003424 tx_seq_offset = (tx_seq - pi->buffer_seq) % 64;
3425 if (tx_seq_offset < 0)
3426 tx_seq_offset += 64;
3427
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003428 do {
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003429 if (bt_cb(next_skb)->tx_seq == tx_seq)
3430 return -EINVAL;
3431
João Paulo Rechi Vitabfbacc12010-05-31 18:35:44 -03003432 next_tx_seq_offset = (bt_cb(next_skb)->tx_seq -
3433 pi->buffer_seq) % 64;
3434 if (next_tx_seq_offset < 0)
3435 next_tx_seq_offset += 64;
3436
3437 if (next_tx_seq_offset > tx_seq_offset) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003438 __skb_queue_before(SREJ_QUEUE(sk), next_skb, skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003439 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003440 }
3441
3442 if (skb_queue_is_last(SREJ_QUEUE(sk), next_skb))
3443 break;
3444
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003445 } while ((next_skb = skb_queue_next(SREJ_QUEUE(sk), next_skb)));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003446
3447 __skb_queue_tail(SREJ_QUEUE(sk), skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003448
3449 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003450}
3451
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003452static int l2cap_ertm_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
3453{
3454 struct l2cap_pinfo *pi = l2cap_pi(sk);
3455 struct sk_buff *_skb;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003456 int err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003457
3458 switch (control & L2CAP_CTRL_SAR) {
3459 case L2CAP_SDU_UNSEGMENTED:
3460 if (pi->conn_state & L2CAP_CONN_SAR_SDU)
3461 goto drop;
3462
3463 err = sock_queue_rcv_skb(sk, skb);
3464 if (!err)
3465 return err;
3466
3467 break;
3468
3469 case L2CAP_SDU_START:
3470 if (pi->conn_state & L2CAP_CONN_SAR_SDU)
3471 goto drop;
3472
3473 pi->sdu_len = get_unaligned_le16(skb->data);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003474
3475 if (pi->sdu_len > pi->imtu)
3476 goto disconnect;
3477
3478 pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003479 if (!pi->sdu)
3480 return -ENOMEM;
3481
3482 /* pull sdu_len bytes only after alloc, because of Local Busy
3483 * condition we have to be sure that this will be executed
3484 * only once, i.e., when alloc does not fail */
3485 skb_pull(skb, 2);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003486
3487 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3488
3489 pi->conn_state |= L2CAP_CONN_SAR_SDU;
3490 pi->partial_sdu_len = skb->len;
3491 break;
3492
3493 case L2CAP_SDU_CONTINUE:
3494 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3495 goto disconnect;
3496
3497 if (!pi->sdu)
3498 goto disconnect;
3499
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003500 pi->partial_sdu_len += skb->len;
3501 if (pi->partial_sdu_len > pi->sdu_len)
3502 goto drop;
3503
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03003504 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3505
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003506 break;
3507
3508 case L2CAP_SDU_END:
3509 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3510 goto disconnect;
3511
3512 if (!pi->sdu)
3513 goto disconnect;
3514
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003515 if (!(pi->conn_state & L2CAP_CONN_SAR_RETRY)) {
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003516 pi->partial_sdu_len += skb->len;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003517
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003518 if (pi->partial_sdu_len > pi->imtu)
3519 goto drop;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003520
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003521 if (pi->partial_sdu_len != pi->sdu_len)
3522 goto drop;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03003523
3524 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003525 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003526
3527 _skb = skb_clone(pi->sdu, GFP_ATOMIC);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003528 if (!_skb) {
3529 pi->conn_state |= L2CAP_CONN_SAR_RETRY;
3530 return -ENOMEM;
3531 }
3532
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003533 err = sock_queue_rcv_skb(sk, _skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003534 if (err < 0) {
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003535 kfree_skb(_skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003536 pi->conn_state |= L2CAP_CONN_SAR_RETRY;
3537 return err;
3538 }
3539
3540 pi->conn_state &= ~L2CAP_CONN_SAR_RETRY;
3541 pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003542
3543 kfree_skb(pi->sdu);
3544 break;
3545 }
3546
3547 kfree_skb(skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003548 return 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003549
3550drop:
3551 kfree_skb(pi->sdu);
3552 pi->sdu = NULL;
3553
3554disconnect:
3555 l2cap_send_disconn_req(pi->conn, sk);
3556 kfree_skb(skb);
3557 return 0;
3558}
3559
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003560static void l2cap_busy_work(struct work_struct *work)
3561{
3562 DECLARE_WAITQUEUE(wait, current);
3563 struct l2cap_pinfo *pi =
3564 container_of(work, struct l2cap_pinfo, busy_work);
3565 struct sock *sk = (struct sock *)pi;
3566 int n_tries = 0, timeo = HZ/5, err;
3567 struct sk_buff *skb;
3568 u16 control;
3569
3570 lock_sock(sk);
3571
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02003572 add_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003573 while ((skb = skb_peek(BUSY_QUEUE(sk)))) {
3574 set_current_state(TASK_INTERRUPTIBLE);
3575
3576 if (n_tries++ > L2CAP_LOCAL_BUSY_TRIES) {
3577 err = -EBUSY;
3578 l2cap_send_disconn_req(pi->conn, sk);
3579 goto done;
3580 }
3581
3582 if (!timeo)
3583 timeo = HZ/5;
3584
3585 if (signal_pending(current)) {
3586 err = sock_intr_errno(timeo);
3587 goto done;
3588 }
3589
3590 release_sock(sk);
3591 timeo = schedule_timeout(timeo);
3592 lock_sock(sk);
3593
3594 err = sock_error(sk);
3595 if (err)
3596 goto done;
3597
3598 while ((skb = skb_dequeue(BUSY_QUEUE(sk)))) {
3599 control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
3600 err = l2cap_ertm_reassembly_sdu(sk, skb, control);
3601 if (err < 0) {
3602 skb_queue_head(BUSY_QUEUE(sk), skb);
3603 break;
3604 }
3605
3606 pi->buffer_seq = (pi->buffer_seq + 1) % 64;
3607 }
3608
3609 if (!skb)
3610 break;
3611 }
3612
3613 if (!(pi->conn_state & L2CAP_CONN_RNR_SENT))
3614 goto done;
3615
3616 control = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3617 control |= L2CAP_SUPER_RCV_READY | L2CAP_CTRL_POLL;
3618 l2cap_send_sframe(pi, control);
3619 l2cap_pi(sk)->retry_count = 1;
3620
3621 del_timer(&pi->retrans_timer);
3622 __mod_monitor_timer();
3623
3624 l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
3625
3626done:
3627 pi->conn_state &= ~L2CAP_CONN_LOCAL_BUSY;
3628 pi->conn_state &= ~L2CAP_CONN_RNR_SENT;
3629
3630 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02003631 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003632
3633 release_sock(sk);
3634}
3635
3636static int l2cap_push_rx_skb(struct sock *sk, struct sk_buff *skb, u16 control)
3637{
3638 struct l2cap_pinfo *pi = l2cap_pi(sk);
3639 int sctrl, err;
3640
3641 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
3642 bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT;
3643 __skb_queue_tail(BUSY_QUEUE(sk), skb);
3644 return -EBUSY;
3645 }
3646
3647 err = l2cap_ertm_reassembly_sdu(sk, skb, control);
3648 if (err >= 0) {
3649 pi->buffer_seq = (pi->buffer_seq + 1) % 64;
3650 return err;
3651 }
3652
3653 /* Busy Condition */
3654 pi->conn_state |= L2CAP_CONN_LOCAL_BUSY;
3655 bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT;
3656 __skb_queue_tail(BUSY_QUEUE(sk), skb);
3657
3658 sctrl = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3659 sctrl |= L2CAP_SUPER_RCV_NOT_READY;
3660 l2cap_send_sframe(pi, sctrl);
3661
3662 pi->conn_state |= L2CAP_CONN_RNR_SENT;
3663
3664 queue_work(_busy_wq, &pi->busy_work);
3665
3666 return err;
3667}
3668
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003669static int l2cap_streaming_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003670{
3671 struct l2cap_pinfo *pi = l2cap_pi(sk);
3672 struct sk_buff *_skb;
3673 int err = -EINVAL;
3674
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003675 /*
3676 * TODO: We have to notify the userland if some data is lost with the
3677 * Streaming Mode.
3678 */
3679
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003680 switch (control & L2CAP_CTRL_SAR) {
3681 case L2CAP_SDU_UNSEGMENTED:
3682 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3683 kfree_skb(pi->sdu);
3684 break;
3685 }
3686
3687 err = sock_queue_rcv_skb(sk, skb);
3688 if (!err)
3689 return 0;
3690
3691 break;
3692
3693 case L2CAP_SDU_START:
3694 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3695 kfree_skb(pi->sdu);
3696 break;
3697 }
3698
3699 pi->sdu_len = get_unaligned_le16(skb->data);
3700 skb_pull(skb, 2);
3701
Gustavo F. Padovan052897c2010-05-01 16:15:40 -03003702 if (pi->sdu_len > pi->imtu) {
3703 err = -EMSGSIZE;
3704 break;
3705 }
3706
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003707 pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
3708 if (!pi->sdu) {
3709 err = -ENOMEM;
3710 break;
3711 }
3712
3713 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3714
3715 pi->conn_state |= L2CAP_CONN_SAR_SDU;
3716 pi->partial_sdu_len = skb->len;
3717 err = 0;
3718 break;
3719
3720 case L2CAP_SDU_CONTINUE:
3721 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3722 break;
3723
3724 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3725
3726 pi->partial_sdu_len += skb->len;
3727 if (pi->partial_sdu_len > pi->sdu_len)
3728 kfree_skb(pi->sdu);
3729 else
3730 err = 0;
3731
3732 break;
3733
3734 case L2CAP_SDU_END:
3735 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3736 break;
3737
3738 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3739
3740 pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
3741 pi->partial_sdu_len += skb->len;
3742
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003743 if (pi->partial_sdu_len > pi->imtu)
3744 goto drop;
3745
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003746 if (pi->partial_sdu_len == pi->sdu_len) {
3747 _skb = skb_clone(pi->sdu, GFP_ATOMIC);
3748 err = sock_queue_rcv_skb(sk, _skb);
3749 if (err < 0)
3750 kfree_skb(_skb);
3751 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003752 err = 0;
3753
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003754drop:
3755 kfree_skb(pi->sdu);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003756 break;
3757 }
3758
3759 kfree_skb(skb);
3760 return err;
3761}
3762
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003763static void l2cap_check_srej_gap(struct sock *sk, u8 tx_seq)
3764{
3765 struct sk_buff *skb;
Gustavo F. Padovanafefdbc2010-05-01 16:15:43 -03003766 u16 control;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003767
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003768 while ((skb = skb_peek(SREJ_QUEUE(sk)))) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003769 if (bt_cb(skb)->tx_seq != tx_seq)
3770 break;
3771
3772 skb = skb_dequeue(SREJ_QUEUE(sk));
Gustavo F. Padovanafefdbc2010-05-01 16:15:43 -03003773 control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003774 l2cap_ertm_reassembly_sdu(sk, skb, control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003775 l2cap_pi(sk)->buffer_seq_srej =
3776 (l2cap_pi(sk)->buffer_seq_srej + 1) % 64;
Gustavo F. Padovan8ff50ec2010-05-10 19:34:11 -03003777 tx_seq = (tx_seq + 1) % 64;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003778 }
3779}
3780
3781static void l2cap_resend_srejframe(struct sock *sk, u8 tx_seq)
3782{
3783 struct l2cap_pinfo *pi = l2cap_pi(sk);
3784 struct srej_list *l, *tmp;
3785 u16 control;
3786
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003787 list_for_each_entry_safe(l, tmp, SREJ_LIST(sk), list) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003788 if (l->tx_seq == tx_seq) {
3789 list_del(&l->list);
3790 kfree(l);
3791 return;
3792 }
3793 control = L2CAP_SUPER_SELECT_REJECT;
3794 control |= l->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3795 l2cap_send_sframe(pi, control);
3796 list_del(&l->list);
3797 list_add_tail(&l->list, SREJ_LIST(sk));
3798 }
3799}
3800
3801static void l2cap_send_srejframe(struct sock *sk, u8 tx_seq)
3802{
3803 struct l2cap_pinfo *pi = l2cap_pi(sk);
3804 struct srej_list *new;
3805 u16 control;
3806
3807 while (tx_seq != pi->expected_tx_seq) {
3808 control = L2CAP_SUPER_SELECT_REJECT;
3809 control |= pi->expected_tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3810 l2cap_send_sframe(pi, control);
3811
3812 new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC);
Gustavo F. Padovan8ff50ec2010-05-10 19:34:11 -03003813 new->tx_seq = pi->expected_tx_seq;
3814 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003815 list_add_tail(&new->list, SREJ_LIST(sk));
3816 }
Gustavo F. Padovan8ff50ec2010-05-10 19:34:11 -03003817 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003818}
3819
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003820static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
3821{
3822 struct l2cap_pinfo *pi = l2cap_pi(sk);
3823 u8 tx_seq = __get_txseq(rx_control);
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003824 u8 req_seq = __get_reqseq(rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003825 u8 sar = rx_control >> L2CAP_CTRL_SAR_SHIFT;
Gustavo F. Padovanf6337c72010-05-10 18:32:04 -03003826 int tx_seq_offset, expected_tx_seq_offset;
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03003827 int num_to_ack = (pi->tx_win/6) + 1;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003828 int err = 0;
3829
3830 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
3831
Gustavo F. Padovan9b16dc62010-05-05 20:05:57 -03003832 if (L2CAP_CTRL_FINAL & rx_control &&
3833 l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) {
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003834 del_timer(&pi->monitor_timer);
3835 if (pi->unacked_frames > 0)
3836 __mod_retrans_timer();
3837 pi->conn_state &= ~L2CAP_CONN_WAIT_F;
3838 }
3839
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003840 pi->expected_ack_seq = req_seq;
3841 l2cap_drop_acked_frames(sk);
3842
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003843 if (tx_seq == pi->expected_tx_seq)
3844 goto expected;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003845
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003846 tx_seq_offset = (tx_seq - pi->buffer_seq) % 64;
3847 if (tx_seq_offset < 0)
3848 tx_seq_offset += 64;
3849
3850 /* invalid tx_seq */
3851 if (tx_seq_offset >= pi->tx_win) {
3852 l2cap_send_disconn_req(pi->conn, sk);
3853 goto drop;
3854 }
3855
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003856 if (pi->conn_state == L2CAP_CONN_LOCAL_BUSY)
3857 goto drop;
3858
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003859 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3860 struct srej_list *first;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003861
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003862 first = list_first_entry(SREJ_LIST(sk),
3863 struct srej_list, list);
3864 if (tx_seq == first->tx_seq) {
3865 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3866 l2cap_check_srej_gap(sk, tx_seq);
3867
3868 list_del(&first->list);
3869 kfree(first);
3870
3871 if (list_empty(SREJ_LIST(sk))) {
3872 pi->buffer_seq = pi->buffer_seq_srej;
3873 pi->conn_state &= ~L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan855666cc2010-05-01 16:15:40 -03003874 l2cap_send_ack(pi);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003875 }
3876 } else {
3877 struct srej_list *l;
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003878
3879 /* duplicated tx_seq */
3880 if (l2cap_add_to_srej_queue(sk, skb, tx_seq, sar) < 0)
3881 goto drop;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003882
3883 list_for_each_entry(l, SREJ_LIST(sk), list) {
3884 if (l->tx_seq == tx_seq) {
3885 l2cap_resend_srejframe(sk, tx_seq);
3886 return 0;
3887 }
3888 }
3889 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003890 }
3891 } else {
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003892 expected_tx_seq_offset =
3893 (pi->expected_tx_seq - pi->buffer_seq) % 64;
3894 if (expected_tx_seq_offset < 0)
3895 expected_tx_seq_offset += 64;
3896
3897 /* duplicated tx_seq */
3898 if (tx_seq_offset < expected_tx_seq_offset)
3899 goto drop;
3900
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003901 pi->conn_state |= L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003902
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003903 INIT_LIST_HEAD(SREJ_LIST(sk));
3904 pi->buffer_seq_srej = pi->buffer_seq;
3905
3906 __skb_queue_head_init(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003907 __skb_queue_head_init(BUSY_QUEUE(sk));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003908 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3909
Gustavo F. Padovanef54fd92009-08-20 22:26:04 -03003910 pi->conn_state |= L2CAP_CONN_SEND_PBIT;
3911
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003912 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003913 }
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003914 return 0;
3915
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003916expected:
3917 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
3918
3919 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
Gustavo F. Padovan3b1a9f32010-05-01 16:15:42 -03003920 bt_cb(skb)->tx_seq = tx_seq;
3921 bt_cb(skb)->sar = sar;
3922 __skb_queue_tail(SREJ_QUEUE(sk), skb);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003923 return 0;
3924 }
3925
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03003926 if (rx_control & L2CAP_CTRL_FINAL) {
3927 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3928 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003929 else
3930 l2cap_retransmit_frames(sk);
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03003931 }
3932
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003933 err = l2cap_push_rx_skb(sk, skb, rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003934 if (err < 0)
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003935 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003936
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003937 __mod_ack_timer();
3938
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03003939 pi->num_acked = (pi->num_acked + 1) % num_to_ack;
3940 if (pi->num_acked == num_to_ack - 1)
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03003941 l2cap_send_ack(pi);
3942
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003943 return 0;
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003944
3945drop:
3946 kfree_skb(skb);
3947 return 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003948}
3949
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003950static inline void l2cap_data_channel_rrframe(struct sock *sk, u16 rx_control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003951{
3952 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan6e3a5982010-05-01 16:15:38 -03003953
3954 pi->expected_ack_seq = __get_reqseq(rx_control);
3955 l2cap_drop_acked_frames(sk);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003956
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003957 if (rx_control & L2CAP_CTRL_POLL) {
Gustavo F. Padovan05fbd892010-05-01 16:15:39 -03003958 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3959 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
3960 (pi->unacked_frames > 0))
3961 __mod_retrans_timer();
3962
3963 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3964 l2cap_send_srejtail(sk);
3965 } else {
3966 l2cap_send_i_or_rr_or_rnr(sk);
Gustavo F. Padovan05fbd892010-05-01 16:15:39 -03003967 }
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003968
3969 } else if (rx_control & L2CAP_CTRL_FINAL) {
3970 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003971
3972 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3973 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003974 else
3975 l2cap_retransmit_frames(sk);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003976
3977 } else {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003978 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
3979 (pi->unacked_frames > 0))
3980 __mod_retrans_timer();
3981
3982 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003983 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003984 l2cap_send_ack(pi);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003985 } else {
3986 spin_lock_bh(&pi->send_lock);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003987 l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003988 spin_unlock_bh(&pi->send_lock);
3989 }
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003990 }
3991}
3992
3993static inline void l2cap_data_channel_rejframe(struct sock *sk, u16 rx_control)
3994{
3995 struct l2cap_pinfo *pi = l2cap_pi(sk);
3996 u8 tx_seq = __get_reqseq(rx_control);
3997
3998 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3999
Gustavo F. Padovan8abb52e2010-05-01 16:15:38 -03004000 pi->expected_ack_seq = tx_seq;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004001 l2cap_drop_acked_frames(sk);
4002
4003 if (rx_control & L2CAP_CTRL_FINAL) {
4004 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
4005 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004006 else
4007 l2cap_retransmit_frames(sk);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004008 } else {
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004009 l2cap_retransmit_frames(sk);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004010
Gustavo F. Padovan0301ef02010-05-05 20:56:43 -03004011 if (pi->conn_state & L2CAP_CONN_WAIT_F)
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004012 pi->conn_state |= L2CAP_CONN_REJ_ACT;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004013 }
4014}
4015static inline void l2cap_data_channel_srejframe(struct sock *sk, u16 rx_control)
4016{
4017 struct l2cap_pinfo *pi = l2cap_pi(sk);
4018 u8 tx_seq = __get_reqseq(rx_control);
4019
4020 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
4021
4022 if (rx_control & L2CAP_CTRL_POLL) {
4023 pi->expected_ack_seq = tx_seq;
4024 l2cap_drop_acked_frames(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004025 l2cap_retransmit_one_frame(sk, tx_seq);
4026
4027 spin_lock_bh(&pi->send_lock);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004028 l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004029 spin_unlock_bh(&pi->send_lock);
4030
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004031 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
4032 pi->srej_save_reqseq = tx_seq;
4033 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
4034 }
4035 } else if (rx_control & L2CAP_CTRL_FINAL) {
4036 if ((pi->conn_state & L2CAP_CONN_SREJ_ACT) &&
4037 pi->srej_save_reqseq == tx_seq)
4038 pi->conn_state &= ~L2CAP_CONN_SREJ_ACT;
4039 else
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004040 l2cap_retransmit_one_frame(sk, tx_seq);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004041 } else {
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004042 l2cap_retransmit_one_frame(sk, tx_seq);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004043 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
4044 pi->srej_save_reqseq = tx_seq;
4045 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
4046 }
4047 }
4048}
4049
4050static inline void l2cap_data_channel_rnrframe(struct sock *sk, u16 rx_control)
4051{
4052 struct l2cap_pinfo *pi = l2cap_pi(sk);
4053 u8 tx_seq = __get_reqseq(rx_control);
4054
4055 pi->conn_state |= L2CAP_CONN_REMOTE_BUSY;
4056 pi->expected_ack_seq = tx_seq;
4057 l2cap_drop_acked_frames(sk);
4058
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03004059 if (!(pi->conn_state & L2CAP_CONN_SREJ_SENT)) {
4060 del_timer(&pi->retrans_timer);
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -03004061 if (rx_control & L2CAP_CTRL_POLL)
4062 l2cap_send_rr_or_rnr(pi, L2CAP_CTRL_FINAL);
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03004063 return;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004064 }
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03004065
4066 if (rx_control & L2CAP_CTRL_POLL)
4067 l2cap_send_srejtail(sk);
4068 else
4069 l2cap_send_sframe(pi, L2CAP_SUPER_RCV_READY);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004070}
4071
4072static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
4073{
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004074 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
4075
Gustavo F. Padovan9b16dc62010-05-05 20:05:57 -03004076 if (L2CAP_CTRL_FINAL & rx_control &&
4077 l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004078 del_timer(&l2cap_pi(sk)->monitor_timer);
4079 if (l2cap_pi(sk)->unacked_frames > 0)
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03004080 __mod_retrans_timer();
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004081 l2cap_pi(sk)->conn_state &= ~L2CAP_CONN_WAIT_F;
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03004082 }
4083
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004084 switch (rx_control & L2CAP_CTRL_SUPERVISE) {
4085 case L2CAP_SUPER_RCV_READY:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004086 l2cap_data_channel_rrframe(sk, rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004087 break;
4088
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004089 case L2CAP_SUPER_REJECT:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004090 l2cap_data_channel_rejframe(sk, rx_control);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03004091 break;
4092
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004093 case L2CAP_SUPER_SELECT_REJECT:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004094 l2cap_data_channel_srejframe(sk, rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004095 break;
4096
4097 case L2CAP_SUPER_RCV_NOT_READY:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004098 l2cap_data_channel_rnrframe(sk, rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004099 break;
4100 }
4101
Gustavo F. Padovanfaaebd12010-05-01 16:15:35 -03004102 kfree_skb(skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004103 return 0;
4104}
4105
Linus Torvalds1da177e2005-04-16 15:20:36 -07004106static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk_buff *skb)
4107{
4108 struct sock *sk;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004109 struct l2cap_pinfo *pi;
Nathan Holstein51893f82010-06-09 15:46:25 -04004110 u16 control;
Gustavo F. Padovanf6337c72010-05-10 18:32:04 -03004111 u8 tx_seq, req_seq;
Nathan Holstein51893f82010-06-09 15:46:25 -04004112 int len, next_tx_seq_offset, req_seq_offset;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004113
4114 sk = l2cap_get_chan_by_scid(&conn->chan_list, cid);
4115 if (!sk) {
4116 BT_DBG("unknown cid 0x%4.4x", cid);
4117 goto drop;
4118 }
4119
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004120 pi = l2cap_pi(sk);
4121
Linus Torvalds1da177e2005-04-16 15:20:36 -07004122 BT_DBG("sk %p, len %d", sk, skb->len);
4123
4124 if (sk->sk_state != BT_CONNECTED)
4125 goto drop;
4126
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004127 switch (pi->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004128 case L2CAP_MODE_BASIC:
4129 /* If socket recv buffers overflows we drop data here
4130 * which is *bad* because L2CAP has to be reliable.
4131 * But we don't have any other choice. L2CAP doesn't
4132 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07004133
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004134 if (pi->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004135 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004136
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004137 if (!sock_queue_rcv_skb(sk, skb))
4138 goto done;
4139 break;
4140
4141 case L2CAP_MODE_ERTM:
4142 control = get_unaligned_le16(skb->data);
4143 skb_pull(skb, 2);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03004144 len = skb->len;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004145
Gustavo F. Padovanbc1b1f82010-05-11 22:14:00 -03004146 if (__is_sar_start(control) && __is_iframe(control))
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03004147 len -= 2;
4148
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004149 if (pi->fcs == L2CAP_FCS_CRC16)
4150 len -= 2;
4151
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03004152 /*
4153 * We can just drop the corrupted I-frame here.
4154 * Receiver will miss it and start proper recovery
4155 * procedures and ask retransmission.
4156 */
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004157 if (len > pi->mps) {
4158 l2cap_send_disconn_req(pi->conn, sk);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004159 goto drop;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004160 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004161
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004162 if (l2cap_check_fcs(pi, skb))
4163 goto drop;
4164
João Paulo Rechi Vita01760bd2010-05-01 16:15:43 -03004165 req_seq = __get_reqseq(control);
4166 req_seq_offset = (req_seq - pi->expected_ack_seq) % 64;
4167 if (req_seq_offset < 0)
4168 req_seq_offset += 64;
4169
4170 next_tx_seq_offset =
4171 (pi->next_tx_seq - pi->expected_ack_seq) % 64;
4172 if (next_tx_seq_offset < 0)
4173 next_tx_seq_offset += 64;
4174
4175 /* check for invalid req-seq */
4176 if (req_seq_offset > next_tx_seq_offset) {
4177 l2cap_send_disconn_req(pi->conn, sk);
4178 goto drop;
4179 }
4180
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004181 if (__is_iframe(control)) {
Nathan Holstein51893f82010-06-09 15:46:25 -04004182 if (len < 0) {
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004183 l2cap_send_disconn_req(pi->conn, sk);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004184 goto drop;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004185 }
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004186
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02004187 l2cap_data_channel_iframe(sk, control, skb);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004188 } else {
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004189 if (len != 0) {
4190 l2cap_send_disconn_req(pi->conn, sk);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004191 goto drop;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004192 }
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004193
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02004194 l2cap_data_channel_sframe(sk, control, skb);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004195 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004196
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02004197 goto done;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004198
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004199 case L2CAP_MODE_STREAMING:
4200 control = get_unaligned_le16(skb->data);
4201 skb_pull(skb, 2);
4202 len = skb->len;
4203
4204 if (__is_sar_start(control))
4205 len -= 2;
4206
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004207 if (pi->fcs == L2CAP_FCS_CRC16)
4208 len -= 2;
4209
Nathan Holstein51893f82010-06-09 15:46:25 -04004210 if (len > pi->mps || len < 0 || __is_sframe(control))
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004211 goto drop;
4212
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004213 if (l2cap_check_fcs(pi, skb))
4214 goto drop;
4215
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004216 tx_seq = __get_txseq(control);
4217
4218 if (pi->expected_tx_seq == tx_seq)
4219 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
4220 else
Gustavo F. Padovan7dffe422010-05-01 16:15:36 -03004221 pi->expected_tx_seq = (tx_seq + 1) % 64;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004222
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004223 l2cap_streaming_reassembly_sdu(sk, skb, control);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004224
4225 goto done;
4226
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004227 default:
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03004228 BT_DBG("sk %p: bad mode 0x%2.2x", sk, pi->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004229 break;
4230 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004231
4232drop:
4233 kfree_skb(skb);
4234
4235done:
Marcel Holtmann01394182006-07-03 10:02:46 +02004236 if (sk)
4237 bh_unlock_sock(sk);
4238
Linus Torvalds1da177e2005-04-16 15:20:36 -07004239 return 0;
4240}
4241
Al Viro8e036fc2007-07-29 00:16:36 -07004242static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004243{
4244 struct sock *sk;
4245
4246 sk = l2cap_get_sock_by_psm(0, psm, conn->src);
4247 if (!sk)
4248 goto drop;
4249
4250 BT_DBG("sk %p, len %d", sk, skb->len);
4251
4252 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_CONNECTED)
4253 goto drop;
4254
4255 if (l2cap_pi(sk)->imtu < skb->len)
4256 goto drop;
4257
4258 if (!sock_queue_rcv_skb(sk, skb))
4259 goto done;
4260
4261drop:
4262 kfree_skb(skb);
4263
4264done:
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03004265 if (sk)
4266 bh_unlock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004267 return 0;
4268}
4269
4270static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
4271{
4272 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07004273 u16 cid, len;
4274 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004275
4276 skb_pull(skb, L2CAP_HDR_SIZE);
4277 cid = __le16_to_cpu(lh->cid);
4278 len = __le16_to_cpu(lh->len);
4279
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004280 if (len != skb->len) {
4281 kfree_skb(skb);
4282 return;
4283 }
4284
Linus Torvalds1da177e2005-04-16 15:20:36 -07004285 BT_DBG("len %d, cid 0x%4.4x", len, cid);
4286
4287 switch (cid) {
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03004288 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07004289 l2cap_sig_channel(conn, skb);
4290 break;
4291
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03004292 case L2CAP_CID_CONN_LESS:
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03004293 psm = get_unaligned_le16(skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004294 skb_pull(skb, 2);
4295 l2cap_conless_channel(conn, psm, skb);
4296 break;
4297
4298 default:
4299 l2cap_data_channel(conn, cid, skb);
4300 break;
4301 }
4302}
4303
4304/* ---- L2CAP interface with lower layer (HCI) ---- */
4305
4306static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
4307{
4308 int exact = 0, lm1 = 0, lm2 = 0;
4309 register struct sock *sk;
4310 struct hlist_node *node;
4311
4312 if (type != ACL_LINK)
4313 return 0;
4314
4315 BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
4316
4317 /* Find listening sockets and check their link_mode */
4318 read_lock(&l2cap_sk_list.lock);
4319 sk_for_each(sk, node, &l2cap_sk_list.head) {
4320 if (sk->sk_state != BT_LISTEN)
4321 continue;
4322
4323 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01004324 lm1 |= HCI_LM_ACCEPT;
4325 if (l2cap_pi(sk)->role_switch)
4326 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004327 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01004328 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
4329 lm2 |= HCI_LM_ACCEPT;
4330 if (l2cap_pi(sk)->role_switch)
4331 lm2 |= HCI_LM_MASTER;
4332 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004333 }
4334 read_unlock(&l2cap_sk_list.lock);
4335
4336 return exact ? lm1 : lm2;
4337}
4338
4339static int l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
4340{
Marcel Holtmann01394182006-07-03 10:02:46 +02004341 struct l2cap_conn *conn;
4342
Linus Torvalds1da177e2005-04-16 15:20:36 -07004343 BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
4344
4345 if (hcon->type != ACL_LINK)
4346 return 0;
4347
4348 if (!status) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004349 conn = l2cap_conn_add(hcon, status);
4350 if (conn)
4351 l2cap_conn_ready(conn);
Marcel Holtmann01394182006-07-03 10:02:46 +02004352 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -07004353 l2cap_conn_del(hcon, bt_err(status));
4354
4355 return 0;
4356}
4357
Marcel Holtmann2950f212009-02-12 14:02:50 +01004358static int l2cap_disconn_ind(struct hci_conn *hcon)
4359{
4360 struct l2cap_conn *conn = hcon->l2cap_data;
4361
4362 BT_DBG("hcon %p", hcon);
4363
4364 if (hcon->type != ACL_LINK || !conn)
4365 return 0x13;
4366
4367 return conn->disc_reason;
4368}
4369
4370static int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004371{
4372 BT_DBG("hcon %p reason %d", hcon, reason);
4373
4374 if (hcon->type != ACL_LINK)
4375 return 0;
4376
4377 l2cap_conn_del(hcon, bt_err(reason));
Marcel Holtmann01394182006-07-03 10:02:46 +02004378
Linus Torvalds1da177e2005-04-16 15:20:36 -07004379 return 0;
4380}
4381
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004382static inline void l2cap_check_encryption(struct sock *sk, u8 encrypt)
4383{
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03004384 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM)
Marcel Holtmann255c7602009-02-04 21:07:19 +01004385 return;
4386
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004387 if (encrypt == 0x00) {
4388 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM) {
4389 l2cap_sock_clear_timer(sk);
4390 l2cap_sock_set_timer(sk, HZ * 5);
4391 } else if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
4392 __l2cap_sock_close(sk, ECONNREFUSED);
4393 } else {
4394 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM)
4395 l2cap_sock_clear_timer(sk);
4396 }
4397}
4398
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004399static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004400{
4401 struct l2cap_chan_list *l;
Marcel Holtmann40be4922008-07-14 20:13:50 +02004402 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004403 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004404
Marcel Holtmann01394182006-07-03 10:02:46 +02004405 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004406 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02004407
Linus Torvalds1da177e2005-04-16 15:20:36 -07004408 l = &conn->chan_list;
4409
4410 BT_DBG("conn %p", conn);
4411
4412 read_lock(&l->lock);
4413
4414 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
4415 bh_lock_sock(sk);
4416
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01004417 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND) {
4418 bh_unlock_sock(sk);
4419 continue;
4420 }
4421
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004422 if (!status && (sk->sk_state == BT_CONNECTED ||
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004423 sk->sk_state == BT_CONFIG)) {
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004424 l2cap_check_encryption(sk, encrypt);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02004425 bh_unlock_sock(sk);
4426 continue;
4427 }
4428
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004429 if (sk->sk_state == BT_CONNECT) {
4430 if (!status) {
4431 struct l2cap_conn_req req;
4432 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
4433 req.psm = l2cap_pi(sk)->psm;
4434
4435 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03004436 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004437
4438 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
4439 L2CAP_CONN_REQ, sizeof(req), &req);
4440 } else {
4441 l2cap_sock_clear_timer(sk);
4442 l2cap_sock_set_timer(sk, HZ / 10);
4443 }
4444 } else if (sk->sk_state == BT_CONNECT2) {
4445 struct l2cap_conn_rsp rsp;
4446 __u16 result;
4447
4448 if (!status) {
4449 sk->sk_state = BT_CONFIG;
4450 result = L2CAP_CR_SUCCESS;
4451 } else {
4452 sk->sk_state = BT_DISCONN;
4453 l2cap_sock_set_timer(sk, HZ / 10);
4454 result = L2CAP_CR_SEC_BLOCK;
4455 }
4456
4457 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
4458 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
4459 rsp.result = cpu_to_le16(result);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02004460 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004461 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
4462 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004463 }
4464
Linus Torvalds1da177e2005-04-16 15:20:36 -07004465 bh_unlock_sock(sk);
4466 }
4467
4468 read_unlock(&l->lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004469
Linus Torvalds1da177e2005-04-16 15:20:36 -07004470 return 0;
4471}
4472
4473static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
4474{
4475 struct l2cap_conn *conn = hcon->l2cap_data;
4476
4477 if (!conn && !(conn = l2cap_conn_add(hcon, 0)))
4478 goto drop;
4479
4480 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
4481
4482 if (flags & ACL_START) {
4483 struct l2cap_hdr *hdr;
4484 int len;
4485
4486 if (conn->rx_len) {
4487 BT_ERR("Unexpected start frame (len %d)", skb->len);
4488 kfree_skb(conn->rx_skb);
4489 conn->rx_skb = NULL;
4490 conn->rx_len = 0;
4491 l2cap_conn_unreliable(conn, ECOMM);
4492 }
4493
4494 if (skb->len < 2) {
4495 BT_ERR("Frame is too short (len %d)", skb->len);
4496 l2cap_conn_unreliable(conn, ECOMM);
4497 goto drop;
4498 }
4499
4500 hdr = (struct l2cap_hdr *) skb->data;
4501 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
4502
4503 if (len == skb->len) {
4504 /* Complete frame received */
4505 l2cap_recv_frame(conn, skb);
4506 return 0;
4507 }
4508
4509 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
4510
4511 if (skb->len > len) {
4512 BT_ERR("Frame is too long (len %d, expected len %d)",
4513 skb->len, len);
4514 l2cap_conn_unreliable(conn, ECOMM);
4515 goto drop;
4516 }
4517
4518 /* Allocate skb for the complete frame (with header) */
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03004519 conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC);
4520 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004521 goto drop;
4522
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03004523 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004524 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004525 conn->rx_len = len - skb->len;
4526 } else {
4527 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
4528
4529 if (!conn->rx_len) {
4530 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
4531 l2cap_conn_unreliable(conn, ECOMM);
4532 goto drop;
4533 }
4534
4535 if (skb->len > conn->rx_len) {
4536 BT_ERR("Fragment is too long (len %d, expected %d)",
4537 skb->len, conn->rx_len);
4538 kfree_skb(conn->rx_skb);
4539 conn->rx_skb = NULL;
4540 conn->rx_len = 0;
4541 l2cap_conn_unreliable(conn, ECOMM);
4542 goto drop;
4543 }
4544
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03004545 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004546 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004547 conn->rx_len -= skb->len;
4548
4549 if (!conn->rx_len) {
4550 /* Complete frame received */
4551 l2cap_recv_frame(conn, conn->rx_skb);
4552 conn->rx_skb = NULL;
4553 }
4554 }
4555
4556drop:
4557 kfree_skb(skb);
4558 return 0;
4559}
4560
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004561static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004562{
4563 struct sock *sk;
4564 struct hlist_node *node;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004565
4566 read_lock_bh(&l2cap_sk_list.lock);
4567
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004568 sk_for_each(sk, node, &l2cap_sk_list.head) {
4569 struct l2cap_pinfo *pi = l2cap_pi(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004570
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004571 seq_printf(f, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d\n",
4572 batostr(&bt_sk(sk)->src),
4573 batostr(&bt_sk(sk)->dst),
4574 sk->sk_state, __le16_to_cpu(pi->psm),
4575 pi->scid, pi->dcid,
4576 pi->imtu, pi->omtu, pi->sec_level);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004577 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004578
Linus Torvalds1da177e2005-04-16 15:20:36 -07004579 read_unlock_bh(&l2cap_sk_list.lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004580
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004581 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004582}
4583
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004584static int l2cap_debugfs_open(struct inode *inode, struct file *file)
4585{
4586 return single_open(file, l2cap_debugfs_show, inode->i_private);
4587}
4588
4589static const struct file_operations l2cap_debugfs_fops = {
4590 .open = l2cap_debugfs_open,
4591 .read = seq_read,
4592 .llseek = seq_lseek,
4593 .release = single_release,
4594};
4595
4596static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004597
Eric Dumazet90ddc4f2005-12-22 12:49:22 -08004598static const struct proto_ops l2cap_sock_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004599 .family = PF_BLUETOOTH,
4600 .owner = THIS_MODULE,
4601 .release = l2cap_sock_release,
4602 .bind = l2cap_sock_bind,
4603 .connect = l2cap_sock_connect,
4604 .listen = l2cap_sock_listen,
4605 .accept = l2cap_sock_accept,
4606 .getname = l2cap_sock_getname,
4607 .sendmsg = l2cap_sock_sendmsg,
Marcel Holtmannf66dc812009-01-15 21:57:00 +01004608 .recvmsg = l2cap_sock_recvmsg,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004609 .poll = bt_sock_poll,
Marcel Holtmann3241ad82008-07-14 20:13:50 +02004610 .ioctl = bt_sock_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004611 .mmap = sock_no_mmap,
4612 .socketpair = sock_no_socketpair,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004613 .shutdown = l2cap_sock_shutdown,
4614 .setsockopt = l2cap_sock_setsockopt,
4615 .getsockopt = l2cap_sock_getsockopt
4616};
4617
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +00004618static const struct net_proto_family l2cap_sock_family_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004619 .family = PF_BLUETOOTH,
4620 .owner = THIS_MODULE,
4621 .create = l2cap_sock_create,
4622};
4623
4624static struct hci_proto l2cap_hci_proto = {
4625 .name = "L2CAP",
4626 .id = HCI_PROTO_L2CAP,
4627 .connect_ind = l2cap_connect_ind,
4628 .connect_cfm = l2cap_connect_cfm,
4629 .disconn_ind = l2cap_disconn_ind,
Marcel Holtmann2950f212009-02-12 14:02:50 +01004630 .disconn_cfm = l2cap_disconn_cfm,
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004631 .security_cfm = l2cap_security_cfm,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004632 .recv_acldata = l2cap_recv_acldata
4633};
4634
4635static int __init l2cap_init(void)
4636{
4637 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004638
Linus Torvalds1da177e2005-04-16 15:20:36 -07004639 err = proto_register(&l2cap_proto, 0);
4640 if (err < 0)
4641 return err;
4642
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004643 _busy_wq = create_singlethread_workqueue("l2cap");
4644 if (!_busy_wq)
4645 goto error;
4646
Linus Torvalds1da177e2005-04-16 15:20:36 -07004647 err = bt_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops);
4648 if (err < 0) {
4649 BT_ERR("L2CAP socket registration failed");
4650 goto error;
4651 }
4652
4653 err = hci_register_proto(&l2cap_hci_proto);
4654 if (err < 0) {
4655 BT_ERR("L2CAP protocol registration failed");
4656 bt_sock_unregister(BTPROTO_L2CAP);
4657 goto error;
4658 }
4659
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004660 if (bt_debugfs) {
4661 l2cap_debugfs = debugfs_create_file("l2cap", 0444,
4662 bt_debugfs, NULL, &l2cap_debugfs_fops);
4663 if (!l2cap_debugfs)
4664 BT_ERR("Failed to create L2CAP debug file");
4665 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004666
4667 BT_INFO("L2CAP ver %s", VERSION);
4668 BT_INFO("L2CAP socket layer initialized");
4669
4670 return 0;
4671
4672error:
4673 proto_unregister(&l2cap_proto);
4674 return err;
4675}
4676
4677static void __exit l2cap_exit(void)
4678{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004679 debugfs_remove(l2cap_debugfs);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004680
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004681 flush_workqueue(_busy_wq);
4682 destroy_workqueue(_busy_wq);
4683
Linus Torvalds1da177e2005-04-16 15:20:36 -07004684 if (bt_sock_unregister(BTPROTO_L2CAP) < 0)
4685 BT_ERR("L2CAP socket unregistration failed");
4686
4687 if (hci_unregister_proto(&l2cap_hci_proto) < 0)
4688 BT_ERR("L2CAP protocol unregistration failed");
4689
4690 proto_unregister(&l2cap_proto);
4691}
4692
4693void l2cap_load(void)
4694{
4695 /* Dummy function to trigger automatic L2CAP module loading by
4696 * other modules that use L2CAP sockets but don't use any other
4697 * symbols from it. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07004698}
4699EXPORT_SYMBOL(l2cap_load);
4700
4701module_init(l2cap_init);
4702module_exit(l2cap_exit);
4703
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07004704module_param(enable_ertm, bool, 0644);
4705MODULE_PARM_DESC(enable_ertm, "Enable enhanced retransmission mode");
4706
Marcel Holtmann63fbd242008-08-18 13:23:53 +02004707MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004708MODULE_DESCRIPTION("Bluetooth L2CAP ver " VERSION);
4709MODULE_VERSION(VERSION);
4710MODULE_LICENSE("GPL");
4711MODULE_ALIAS("bt-proto-0");