blob: 65c6a989449af49c459c31c286e63d626da7d173 [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. Padovan9b108fc2010-05-20 16:21:53 -0300459static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct sock *sk, int err)
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300460{
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. Padovan9b108fc2010-05-20 16:21:53 -0300480 sk->sk_err = err;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300481}
482
Linus Torvalds1da177e2005-04-16 15:20:36 -0700483/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200484static void l2cap_conn_start(struct l2cap_conn *conn)
485{
486 struct l2cap_chan_list *l = &conn->chan_list;
487 struct sock *sk;
488
489 BT_DBG("conn %p", conn);
490
491 read_lock(&l->lock);
492
493 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
494 bh_lock_sock(sk);
495
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300496 if (sk->sk_type != SOCK_SEQPACKET &&
497 sk->sk_type != SOCK_STREAM) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200498 bh_unlock_sock(sk);
499 continue;
500 }
501
502 if (sk->sk_state == BT_CONNECT) {
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300503 if (l2cap_check_security(sk) &&
504 __l2cap_no_conn_pending(sk)) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200505 struct l2cap_conn_req req;
506 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
507 req.psm = l2cap_pi(sk)->psm;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200508
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200509 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300510 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200511
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200512 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200513 L2CAP_CONN_REQ, sizeof(req), &req);
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200514 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200515 } else if (sk->sk_state == BT_CONNECT2) {
516 struct l2cap_conn_rsp rsp;
517 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
518 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
519
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100520 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100521 if (bt_sk(sk)->defer_setup) {
522 struct sock *parent = bt_sk(sk)->parent;
523 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
524 rsp.status = cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
525 parent->sk_data_ready(parent, 0);
526
527 } else {
528 sk->sk_state = BT_CONFIG;
529 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
530 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
531 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200532 } else {
533 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
534 rsp.status = cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
535 }
536
537 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
538 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
539 }
540
541 bh_unlock_sock(sk);
542 }
543
544 read_unlock(&l->lock);
545}
546
547static void l2cap_conn_ready(struct l2cap_conn *conn)
548{
549 struct l2cap_chan_list *l = &conn->chan_list;
550 struct sock *sk;
551
552 BT_DBG("conn %p", conn);
553
554 read_lock(&l->lock);
555
556 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
557 bh_lock_sock(sk);
558
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300559 if (sk->sk_type != SOCK_SEQPACKET &&
560 sk->sk_type != SOCK_STREAM) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200561 l2cap_sock_clear_timer(sk);
562 sk->sk_state = BT_CONNECTED;
563 sk->sk_state_change(sk);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200564 } else if (sk->sk_state == BT_CONNECT)
565 l2cap_do_start(sk);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200566
567 bh_unlock_sock(sk);
568 }
569
570 read_unlock(&l->lock);
571}
572
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200573/* Notify sockets that we cannot guaranty reliability anymore */
574static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
575{
576 struct l2cap_chan_list *l = &conn->chan_list;
577 struct sock *sk;
578
579 BT_DBG("conn %p", conn);
580
581 read_lock(&l->lock);
582
583 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100584 if (l2cap_pi(sk)->force_reliable)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200585 sk->sk_err = err;
586 }
587
588 read_unlock(&l->lock);
589}
590
591static void l2cap_info_timeout(unsigned long arg)
592{
593 struct l2cap_conn *conn = (void *) arg;
594
Marcel Holtmann984947d2009-02-06 23:35:19 +0100595 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +0100596 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +0100597
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200598 l2cap_conn_start(conn);
599}
600
Linus Torvalds1da177e2005-04-16 15:20:36 -0700601static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
602{
Marcel Holtmann01394182006-07-03 10:02:46 +0200603 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700604
Marcel Holtmann01394182006-07-03 10:02:46 +0200605 if (conn || status)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700606 return conn;
607
Marcel Holtmann01394182006-07-03 10:02:46 +0200608 conn = kzalloc(sizeof(struct l2cap_conn), GFP_ATOMIC);
609 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700610 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700611
612 hcon->l2cap_data = conn;
613 conn->hcon = hcon;
614
Marcel Holtmann01394182006-07-03 10:02:46 +0200615 BT_DBG("hcon %p conn %p", hcon, conn);
616
Linus Torvalds1da177e2005-04-16 15:20:36 -0700617 conn->mtu = hcon->hdev->acl_mtu;
618 conn->src = &hcon->hdev->bdaddr;
619 conn->dst = &hcon->dst;
620
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200621 conn->feat_mask = 0;
622
Linus Torvalds1da177e2005-04-16 15:20:36 -0700623 spin_lock_init(&conn->lock);
624 rwlock_init(&conn->chan_list.lock);
625
Dave Young45054dc2009-10-18 20:28:30 +0000626 setup_timer(&conn->info_timer, l2cap_info_timeout,
627 (unsigned long) conn);
628
Marcel Holtmann2950f212009-02-12 14:02:50 +0100629 conn->disc_reason = 0x13;
630
Linus Torvalds1da177e2005-04-16 15:20:36 -0700631 return conn;
632}
633
Marcel Holtmann01394182006-07-03 10:02:46 +0200634static void l2cap_conn_del(struct hci_conn *hcon, int err)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700635{
Marcel Holtmann01394182006-07-03 10:02:46 +0200636 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700637 struct sock *sk;
638
Marcel Holtmann01394182006-07-03 10:02:46 +0200639 if (!conn)
640 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700641
642 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
643
Wei Yongjun7585b972009-02-25 18:29:52 +0800644 kfree_skb(conn->rx_skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700645
646 /* Kill channels */
647 while ((sk = conn->chan_list.head)) {
648 bh_lock_sock(sk);
649 l2cap_chan_del(sk, err);
650 bh_unlock_sock(sk);
651 l2cap_sock_kill(sk);
652 }
653
Dave Young8e8440f2008-03-03 12:18:55 -0800654 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
655 del_timer_sync(&conn->info_timer);
Thomas Gleixner3ab22732008-02-26 17:42:56 -0800656
Linus Torvalds1da177e2005-04-16 15:20:36 -0700657 hcon->l2cap_data = NULL;
658 kfree(conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700659}
660
661static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
662{
663 struct l2cap_chan_list *l = &conn->chan_list;
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200664 write_lock_bh(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700665 __l2cap_chan_add(conn, sk, parent);
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200666 write_unlock_bh(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700667}
668
Linus Torvalds1da177e2005-04-16 15:20:36 -0700669/* ---- Socket interface ---- */
Al Viro8e036fc2007-07-29 00:16:36 -0700670static struct sock *__l2cap_get_sock_by_addr(__le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700671{
672 struct sock *sk;
673 struct hlist_node *node;
674 sk_for_each(sk, node, &l2cap_sk_list.head)
675 if (l2cap_pi(sk)->sport == psm && !bacmp(&bt_sk(sk)->src, src))
676 goto found;
677 sk = NULL;
678found:
679 return sk;
680}
681
682/* Find socket with psm and source bdaddr.
683 * Returns closest match.
684 */
Al Viro8e036fc2007-07-29 00:16:36 -0700685static struct sock *__l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700686{
687 struct sock *sk = NULL, *sk1 = NULL;
688 struct hlist_node *node;
689
690 sk_for_each(sk, node, &l2cap_sk_list.head) {
691 if (state && sk->sk_state != state)
692 continue;
693
694 if (l2cap_pi(sk)->psm == psm) {
695 /* Exact match. */
696 if (!bacmp(&bt_sk(sk)->src, src))
697 break;
698
699 /* Closest match */
700 if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY))
701 sk1 = sk;
702 }
703 }
704 return node ? sk : sk1;
705}
706
707/* Find socket with given address (psm, src).
708 * Returns locked socket */
Al Viro8e036fc2007-07-29 00:16:36 -0700709static inline struct sock *l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700710{
711 struct sock *s;
712 read_lock(&l2cap_sk_list.lock);
713 s = __l2cap_get_sock_by_psm(state, psm, src);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300714 if (s)
715 bh_lock_sock(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700716 read_unlock(&l2cap_sk_list.lock);
717 return s;
718}
719
720static void l2cap_sock_destruct(struct sock *sk)
721{
722 BT_DBG("sk %p", sk);
723
724 skb_queue_purge(&sk->sk_receive_queue);
725 skb_queue_purge(&sk->sk_write_queue);
726}
727
728static void l2cap_sock_cleanup_listen(struct sock *parent)
729{
730 struct sock *sk;
731
732 BT_DBG("parent %p", parent);
733
734 /* Close not yet accepted channels */
735 while ((sk = bt_accept_dequeue(parent, NULL)))
736 l2cap_sock_close(sk);
737
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200738 parent->sk_state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700739 sock_set_flag(parent, SOCK_ZAPPED);
740}
741
742/* Kill socket (only if zapped and orphan)
743 * Must be called on unlocked socket.
744 */
745static void l2cap_sock_kill(struct sock *sk)
746{
747 if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket)
748 return;
749
750 BT_DBG("sk %p state %d", sk, sk->sk_state);
751
752 /* Kill poor orphan */
753 bt_sock_unlink(&l2cap_sk_list, sk);
754 sock_set_flag(sk, SOCK_DEAD);
755 sock_put(sk);
756}
757
758static void __l2cap_sock_close(struct sock *sk, int reason)
759{
760 BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket);
761
762 switch (sk->sk_state) {
763 case BT_LISTEN:
764 l2cap_sock_cleanup_listen(sk);
765 break;
766
767 case BT_CONNECTED:
768 case BT_CONFIG:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300769 if (sk->sk_type == SOCK_SEQPACKET ||
770 sk->sk_type == SOCK_STREAM) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700771 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700772
Linus Torvalds1da177e2005-04-16 15:20:36 -0700773 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -0300774 l2cap_send_disconn_req(conn, sk, reason);
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200775 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -0700776 l2cap_chan_del(sk, reason);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700777 break;
778
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100779 case BT_CONNECT2:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300780 if (sk->sk_type == SOCK_SEQPACKET ||
781 sk->sk_type == SOCK_STREAM) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100782 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
783 struct l2cap_conn_rsp rsp;
784 __u16 result;
785
786 if (bt_sk(sk)->defer_setup)
787 result = L2CAP_CR_SEC_BLOCK;
788 else
789 result = L2CAP_CR_BAD_PSM;
790
791 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
792 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
793 rsp.result = cpu_to_le16(result);
794 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
795 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
796 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
797 } else
798 l2cap_chan_del(sk, reason);
799 break;
800
Linus Torvalds1da177e2005-04-16 15:20:36 -0700801 case BT_CONNECT:
802 case BT_DISCONN:
803 l2cap_chan_del(sk, reason);
804 break;
805
806 default:
807 sock_set_flag(sk, SOCK_ZAPPED);
808 break;
809 }
810}
811
812/* Must be called on unlocked socket. */
813static void l2cap_sock_close(struct sock *sk)
814{
815 l2cap_sock_clear_timer(sk);
816 lock_sock(sk);
817 __l2cap_sock_close(sk, ECONNRESET);
818 release_sock(sk);
819 l2cap_sock_kill(sk);
820}
821
822static void l2cap_sock_init(struct sock *sk, struct sock *parent)
823{
824 struct l2cap_pinfo *pi = l2cap_pi(sk);
825
826 BT_DBG("sk %p", sk);
827
828 if (parent) {
829 sk->sk_type = parent->sk_type;
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100830 bt_sk(sk)->defer_setup = bt_sk(parent)->defer_setup;
831
Linus Torvalds1da177e2005-04-16 15:20:36 -0700832 pi->imtu = l2cap_pi(parent)->imtu;
833 pi->omtu = l2cap_pi(parent)->omtu;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -0700834 pi->mode = l2cap_pi(parent)->mode;
835 pi->fcs = l2cap_pi(parent)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -0300836 pi->max_tx = l2cap_pi(parent)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -0300837 pi->tx_win = l2cap_pi(parent)->tx_win;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100838 pi->sec_level = l2cap_pi(parent)->sec_level;
839 pi->role_switch = l2cap_pi(parent)->role_switch;
840 pi->force_reliable = l2cap_pi(parent)->force_reliable;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700841 } else {
842 pi->imtu = L2CAP_DEFAULT_MTU;
843 pi->omtu = 0;
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300844 if (enable_ertm && sk->sk_type == SOCK_STREAM)
845 pi->mode = L2CAP_MODE_ERTM;
846 else
847 pi->mode = L2CAP_MODE_BASIC;
Gustavo F. Padovanfd059b92010-05-10 14:22:56 -0300848 pi->max_tx = L2CAP_DEFAULT_MAX_TX;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -0700849 pi->fcs = L2CAP_FCS_CRC16;
Gustavo F. Padovanfd059b92010-05-10 14:22:56 -0300850 pi->tx_win = L2CAP_DEFAULT_TX_WINDOW;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100851 pi->sec_level = BT_SECURITY_LOW;
852 pi->role_switch = 0;
853 pi->force_reliable = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700854 }
855
856 /* Default config options */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +0200857 pi->conf_len = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700858 pi->flush_to = L2CAP_DEFAULT_FLUSH_TO;
Dave Young45054dc2009-10-18 20:28:30 +0000859 skb_queue_head_init(TX_QUEUE(sk));
860 skb_queue_head_init(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -0300861 skb_queue_head_init(BUSY_QUEUE(sk));
Dave Young45054dc2009-10-18 20:28:30 +0000862 INIT_LIST_HEAD(SREJ_LIST(sk));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700863}
864
865static struct proto l2cap_proto = {
866 .name = "L2CAP",
867 .owner = THIS_MODULE,
868 .obj_size = sizeof(struct l2cap_pinfo)
869};
870
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700871static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700872{
873 struct sock *sk;
874
Pavel Emelyanov6257ff22007-11-01 00:39:31 -0700875 sk = sk_alloc(net, PF_BLUETOOTH, prio, &l2cap_proto);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700876 if (!sk)
877 return NULL;
878
879 sock_init_data(sock, sk);
880 INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
881
882 sk->sk_destruct = l2cap_sock_destruct;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200883 sk->sk_sndtimeo = msecs_to_jiffies(L2CAP_CONN_TIMEOUT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700884
885 sock_reset_flag(sk, SOCK_ZAPPED);
886
887 sk->sk_protocol = proto;
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200888 sk->sk_state = BT_OPEN;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700889
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200890 setup_timer(&sk->sk_timer, l2cap_sock_timeout, (unsigned long) sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700891
892 bt_sock_link(&l2cap_sk_list, sk);
893 return sk;
894}
895
Eric Paris3f378b62009-11-05 22:18:14 -0800896static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol,
897 int kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700898{
899 struct sock *sk;
900
901 BT_DBG("sock %p", sock);
902
903 sock->state = SS_UNCONNECTED;
904
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300905 if (sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM &&
Linus Torvalds1da177e2005-04-16 15:20:36 -0700906 sock->type != SOCK_DGRAM && sock->type != SOCK_RAW)
907 return -ESOCKTNOSUPPORT;
908
Eric Parisc84b3262009-11-05 20:45:52 -0800909 if (sock->type == SOCK_RAW && !kern && !capable(CAP_NET_RAW))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700910 return -EPERM;
911
912 sock->ops = &l2cap_sock_ops;
913
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700914 sk = l2cap_sock_alloc(net, sock, protocol, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700915 if (!sk)
916 return -ENOMEM;
917
918 l2cap_sock_init(sk, NULL);
919 return 0;
920}
921
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100922static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700923{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700924 struct sock *sk = sock->sk;
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100925 struct sockaddr_l2 la;
926 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700927
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100928 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700929
930 if (!addr || addr->sa_family != AF_BLUETOOTH)
931 return -EINVAL;
932
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100933 memset(&la, 0, sizeof(la));
934 len = min_t(unsigned int, sizeof(la), alen);
935 memcpy(&la, addr, len);
936
Marcel Holtmann2a517ca2009-02-16 03:20:31 +0100937 if (la.l2_cid)
938 return -EINVAL;
939
Linus Torvalds1da177e2005-04-16 15:20:36 -0700940 lock_sock(sk);
941
942 if (sk->sk_state != BT_OPEN) {
943 err = -EBADFD;
944 goto done;
945 }
946
Marcel Holtmannb4324b52009-06-07 18:06:51 +0200947 if (la.l2_psm && __le16_to_cpu(la.l2_psm) < 0x1001 &&
Marcel Holtmann847641d2007-01-22 22:00:45 +0100948 !capable(CAP_NET_BIND_SERVICE)) {
949 err = -EACCES;
950 goto done;
951 }
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900952
Linus Torvalds1da177e2005-04-16 15:20:36 -0700953 write_lock_bh(&l2cap_sk_list.lock);
954
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100955 if (la.l2_psm && __l2cap_get_sock_by_addr(la.l2_psm, &la.l2_bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700956 err = -EADDRINUSE;
957 } else {
958 /* Save source address */
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100959 bacpy(&bt_sk(sk)->src, &la.l2_bdaddr);
960 l2cap_pi(sk)->psm = la.l2_psm;
961 l2cap_pi(sk)->sport = la.l2_psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700962 sk->sk_state = BT_BOUND;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100963
Marcel Holtmannb4324b52009-06-07 18:06:51 +0200964 if (__le16_to_cpu(la.l2_psm) == 0x0001 ||
965 __le16_to_cpu(la.l2_psm) == 0x0003)
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100966 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700967 }
968
969 write_unlock_bh(&l2cap_sk_list.lock);
970
971done:
972 release_sock(sk);
973 return err;
974}
975
976static int l2cap_do_connect(struct sock *sk)
977{
978 bdaddr_t *src = &bt_sk(sk)->src;
979 bdaddr_t *dst = &bt_sk(sk)->dst;
980 struct l2cap_conn *conn;
981 struct hci_conn *hcon;
982 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200983 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +0200984 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700985
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100986 BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst),
987 l2cap_pi(sk)->psm);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700988
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300989 hdev = hci_get_route(dst, src);
990 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700991 return -EHOSTUNREACH;
992
993 hci_dev_lock_bh(hdev);
994
995 err = -ENOMEM;
996
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100997 if (sk->sk_type == SOCK_RAW) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100998 switch (l2cap_pi(sk)->sec_level) {
999 case BT_SECURITY_HIGH:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001000 auth_type = HCI_AT_DEDICATED_BONDING_MITM;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001001 break;
1002 case BT_SECURITY_MEDIUM:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001003 auth_type = HCI_AT_DEDICATED_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001004 break;
1005 default:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001006 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001007 break;
1008 }
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001009 } else if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001010 if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001011 auth_type = HCI_AT_NO_BONDING_MITM;
1012 else
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001013 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann435fef22009-02-09 03:55:28 +01001014
1015 if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW)
1016 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001017 } else {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001018 switch (l2cap_pi(sk)->sec_level) {
1019 case BT_SECURITY_HIGH:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001020 auth_type = HCI_AT_GENERAL_BONDING_MITM;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001021 break;
1022 case BT_SECURITY_MEDIUM:
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001023 auth_type = HCI_AT_GENERAL_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001024 break;
1025 default:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001026 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001027 break;
1028 }
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001029 }
1030
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001031 hcon = hci_connect(hdev, ACL_LINK, dst,
1032 l2cap_pi(sk)->sec_level, auth_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001033 if (!hcon)
1034 goto done;
1035
1036 conn = l2cap_conn_add(hcon, 0);
1037 if (!conn) {
1038 hci_conn_put(hcon);
1039 goto done;
1040 }
1041
1042 err = 0;
1043
1044 /* Update source addr of the socket */
1045 bacpy(src, conn->src);
1046
1047 l2cap_chan_add(conn, sk, NULL);
1048
1049 sk->sk_state = BT_CONNECT;
1050 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
1051
1052 if (hcon->state == BT_CONNECTED) {
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001053 if (sk->sk_type != SOCK_SEQPACKET &&
1054 sk->sk_type != SOCK_STREAM) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001055 l2cap_sock_clear_timer(sk);
1056 sk->sk_state = BT_CONNECTED;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001057 } else
1058 l2cap_do_start(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001059 }
1060
1061done:
1062 hci_dev_unlock_bh(hdev);
1063 hci_dev_put(hdev);
1064 return err;
1065}
1066
1067static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
1068{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001069 struct sock *sk = sock->sk;
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001070 struct sockaddr_l2 la;
1071 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001072
Linus Torvalds1da177e2005-04-16 15:20:36 -07001073 BT_DBG("sk %p", sk);
1074
Changli Gao6503d962010-03-31 22:58:26 +00001075 if (!addr || alen < sizeof(addr->sa_family) ||
1076 addr->sa_family != AF_BLUETOOTH)
Marcel Holtmann2a517ca2009-02-16 03:20:31 +01001077 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001078
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001079 memset(&la, 0, sizeof(la));
1080 len = min_t(unsigned int, sizeof(la), alen);
1081 memcpy(&la, addr, len);
1082
Marcel Holtmann2a517ca2009-02-16 03:20:31 +01001083 if (la.l2_cid)
1084 return -EINVAL;
1085
1086 lock_sock(sk);
1087
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001088 if ((sk->sk_type == SOCK_SEQPACKET || sk->sk_type == SOCK_STREAM)
1089 && !la.l2_psm) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001090 err = -EINVAL;
1091 goto done;
1092 }
1093
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001094 switch (l2cap_pi(sk)->mode) {
1095 case L2CAP_MODE_BASIC:
1096 break;
1097 case L2CAP_MODE_ERTM:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001098 case L2CAP_MODE_STREAMING:
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001099 if (enable_ertm)
1100 break;
1101 /* fall through */
1102 default:
1103 err = -ENOTSUPP;
1104 goto done;
1105 }
1106
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001107 switch (sk->sk_state) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001108 case BT_CONNECT:
1109 case BT_CONNECT2:
1110 case BT_CONFIG:
1111 /* Already connecting */
1112 goto wait;
1113
1114 case BT_CONNECTED:
1115 /* Already connected */
1116 goto done;
1117
1118 case BT_OPEN:
1119 case BT_BOUND:
1120 /* Can connect */
1121 break;
1122
1123 default:
1124 err = -EBADFD;
1125 goto done;
1126 }
1127
1128 /* Set destination address and psm */
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001129 bacpy(&bt_sk(sk)->dst, &la.l2_bdaddr);
1130 l2cap_pi(sk)->psm = la.l2_psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001131
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001132 err = l2cap_do_connect(sk);
1133 if (err)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001134 goto done;
1135
1136wait:
1137 err = bt_sock_wait_state(sk, BT_CONNECTED,
1138 sock_sndtimeo(sk, flags & O_NONBLOCK));
1139done:
1140 release_sock(sk);
1141 return err;
1142}
1143
1144static int l2cap_sock_listen(struct socket *sock, int backlog)
1145{
1146 struct sock *sk = sock->sk;
1147 int err = 0;
1148
1149 BT_DBG("sk %p backlog %d", sk, backlog);
1150
1151 lock_sock(sk);
1152
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001153 if ((sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM)
1154 || sk->sk_state != BT_BOUND) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001155 err = -EBADFD;
1156 goto done;
1157 }
1158
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001159 switch (l2cap_pi(sk)->mode) {
1160 case L2CAP_MODE_BASIC:
1161 break;
1162 case L2CAP_MODE_ERTM:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001163 case L2CAP_MODE_STREAMING:
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001164 if (enable_ertm)
1165 break;
1166 /* fall through */
1167 default:
1168 err = -ENOTSUPP;
1169 goto done;
1170 }
1171
Linus Torvalds1da177e2005-04-16 15:20:36 -07001172 if (!l2cap_pi(sk)->psm) {
1173 bdaddr_t *src = &bt_sk(sk)->src;
1174 u16 psm;
1175
1176 err = -EINVAL;
1177
1178 write_lock_bh(&l2cap_sk_list.lock);
1179
1180 for (psm = 0x1001; psm < 0x1100; psm += 2)
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001181 if (!__l2cap_get_sock_by_addr(cpu_to_le16(psm), src)) {
1182 l2cap_pi(sk)->psm = cpu_to_le16(psm);
1183 l2cap_pi(sk)->sport = cpu_to_le16(psm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001184 err = 0;
1185 break;
1186 }
1187
1188 write_unlock_bh(&l2cap_sk_list.lock);
1189
1190 if (err < 0)
1191 goto done;
1192 }
1193
1194 sk->sk_max_ack_backlog = backlog;
1195 sk->sk_ack_backlog = 0;
1196 sk->sk_state = BT_LISTEN;
1197
1198done:
1199 release_sock(sk);
1200 return err;
1201}
1202
1203static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int flags)
1204{
1205 DECLARE_WAITQUEUE(wait, current);
1206 struct sock *sk = sock->sk, *nsk;
1207 long timeo;
1208 int err = 0;
1209
Peter Zijlstrafcc70d52006-11-08 22:44:35 -08001210 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001211
1212 if (sk->sk_state != BT_LISTEN) {
1213 err = -EBADFD;
1214 goto done;
1215 }
1216
1217 timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
1218
1219 BT_DBG("sk %p timeo %ld", sk, timeo);
1220
1221 /* Wait for an incoming connection. (wake-one). */
Eric Dumazetaa395142010-04-20 13:03:51 +00001222 add_wait_queue_exclusive(sk_sleep(sk), &wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001223 while (!(nsk = bt_accept_dequeue(sk, newsock))) {
1224 set_current_state(TASK_INTERRUPTIBLE);
1225 if (!timeo) {
1226 err = -EAGAIN;
1227 break;
1228 }
1229
1230 release_sock(sk);
1231 timeo = schedule_timeout(timeo);
Peter Zijlstrafcc70d52006-11-08 22:44:35 -08001232 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001233
1234 if (sk->sk_state != BT_LISTEN) {
1235 err = -EBADFD;
1236 break;
1237 }
1238
1239 if (signal_pending(current)) {
1240 err = sock_intr_errno(timeo);
1241 break;
1242 }
1243 }
1244 set_current_state(TASK_RUNNING);
Eric Dumazetaa395142010-04-20 13:03:51 +00001245 remove_wait_queue(sk_sleep(sk), &wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001246
1247 if (err)
1248 goto done;
1249
1250 newsock->state = SS_CONNECTED;
1251
1252 BT_DBG("new socket %p", nsk);
1253
1254done:
1255 release_sock(sk);
1256 return err;
1257}
1258
1259static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
1260{
1261 struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
1262 struct sock *sk = sock->sk;
1263
1264 BT_DBG("sock %p, sk %p", sock, sk);
1265
1266 addr->sa_family = AF_BLUETOOTH;
1267 *len = sizeof(struct sockaddr_l2);
1268
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001269 if (peer) {
1270 la->l2_psm = l2cap_pi(sk)->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001271 bacpy(&la->l2_bdaddr, &bt_sk(sk)->dst);
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001272 la->l2_cid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001273 } else {
1274 la->l2_psm = l2cap_pi(sk)->sport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001275 bacpy(&la->l2_bdaddr, &bt_sk(sk)->src);
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001276 la->l2_cid = cpu_to_le16(l2cap_pi(sk)->scid);
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001277 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001278
Linus Torvalds1da177e2005-04-16 15:20:36 -07001279 return 0;
1280}
1281
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001282static int __l2cap_wait_ack(struct sock *sk)
1283{
1284 DECLARE_WAITQUEUE(wait, current);
1285 int err = 0;
1286 int timeo = HZ/5;
1287
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001288 add_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001289 while ((l2cap_pi(sk)->unacked_frames > 0 && l2cap_pi(sk)->conn)) {
1290 set_current_state(TASK_INTERRUPTIBLE);
1291
1292 if (!timeo)
1293 timeo = HZ/5;
1294
1295 if (signal_pending(current)) {
1296 err = sock_intr_errno(timeo);
1297 break;
1298 }
1299
1300 release_sock(sk);
1301 timeo = schedule_timeout(timeo);
1302 lock_sock(sk);
1303
1304 err = sock_error(sk);
1305 if (err)
1306 break;
1307 }
1308 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001309 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001310 return err;
1311}
1312
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001313static void l2cap_monitor_timeout(unsigned long arg)
1314{
1315 struct sock *sk = (void *) arg;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001316
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001317 BT_DBG("sk %p", sk);
1318
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001319 bh_lock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001320 if (l2cap_pi(sk)->retry_count >= l2cap_pi(sk)->remote_max_tx) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03001321 l2cap_send_disconn_req(l2cap_pi(sk)->conn, sk, ECONNABORTED);
Andrei Emeltchenkob13f5862009-12-15 11:38:04 +02001322 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001323 return;
1324 }
1325
1326 l2cap_pi(sk)->retry_count++;
1327 __mod_monitor_timer();
1328
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -03001329 l2cap_send_rr_or_rnr(l2cap_pi(sk), L2CAP_CTRL_POLL);
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001330 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001331}
1332
1333static void l2cap_retrans_timeout(unsigned long arg)
1334{
1335 struct sock *sk = (void *) arg;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001336
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001337 BT_DBG("sk %p", sk);
1338
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001339 bh_lock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001340 l2cap_pi(sk)->retry_count = 1;
1341 __mod_monitor_timer();
1342
1343 l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
1344
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -03001345 l2cap_send_rr_or_rnr(l2cap_pi(sk), L2CAP_CTRL_POLL);
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001346 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001347}
1348
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001349static void l2cap_drop_acked_frames(struct sock *sk)
1350{
1351 struct sk_buff *skb;
1352
Gustavo F. Padovan812e7372010-05-01 16:15:42 -03001353 while ((skb = skb_peek(TX_QUEUE(sk))) &&
1354 l2cap_pi(sk)->unacked_frames) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001355 if (bt_cb(skb)->tx_seq == l2cap_pi(sk)->expected_ack_seq)
1356 break;
1357
1358 skb = skb_dequeue(TX_QUEUE(sk));
1359 kfree_skb(skb);
1360
1361 l2cap_pi(sk)->unacked_frames--;
1362 }
1363
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001364 if (!l2cap_pi(sk)->unacked_frames)
1365 del_timer(&l2cap_pi(sk)->retrans_timer);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001366}
1367
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001368static inline void l2cap_do_send(struct sock *sk, struct sk_buff *skb)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001369{
1370 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001371
1372 BT_DBG("sk %p, skb %p len %d", sk, skb, skb->len);
1373
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001374 hci_send_acl(pi->conn->hcon, skb, 0);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001375}
1376
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001377static int l2cap_streaming_send(struct sock *sk)
1378{
1379 struct sk_buff *skb, *tx_skb;
1380 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001381 u16 control, fcs;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001382
1383 while ((skb = sk->sk_send_head)) {
1384 tx_skb = skb_clone(skb, GFP_ATOMIC);
1385
1386 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
1387 control |= pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT;
1388 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1389
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001390 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001391 fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
1392 put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
1393 }
1394
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001395 l2cap_do_send(sk, tx_skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001396
1397 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
1398
1399 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1400 sk->sk_send_head = NULL;
1401 else
1402 sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
1403
1404 skb = skb_dequeue(TX_QUEUE(sk));
1405 kfree_skb(skb);
1406 }
1407 return 0;
1408}
1409
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001410static void l2cap_retransmit_one_frame(struct sock *sk, u8 tx_seq)
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001411{
1412 struct l2cap_pinfo *pi = l2cap_pi(sk);
1413 struct sk_buff *skb, *tx_skb;
1414 u16 control, fcs;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001415
1416 skb = skb_peek(TX_QUEUE(sk));
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001417 if (!skb)
1418 return;
1419
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001420 do {
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001421 if (bt_cb(skb)->tx_seq == tx_seq)
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001422 break;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001423
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001424 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1425 return;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001426
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001427 } while ((skb = skb_queue_next(TX_QUEUE(sk), skb)));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001428
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001429 if (pi->remote_max_tx &&
1430 bt_cb(skb)->retries == pi->remote_max_tx) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03001431 l2cap_send_disconn_req(pi->conn, sk, ECONNABORTED);
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001432 return;
1433 }
1434
1435 tx_skb = skb_clone(skb, GFP_ATOMIC);
1436 bt_cb(skb)->retries++;
1437 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03001438
1439 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
1440 control |= L2CAP_CTRL_FINAL;
1441 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
1442 }
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03001443
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001444 control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
1445 | (tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03001446
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001447 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1448
1449 if (pi->fcs == L2CAP_FCS_CRC16) {
1450 fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
1451 put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
1452 }
1453
1454 l2cap_do_send(sk, tx_skb);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001455}
1456
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001457static int l2cap_ertm_send(struct sock *sk)
1458{
1459 struct sk_buff *skb, *tx_skb;
1460 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001461 u16 control, fcs;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001462 int nsent = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001463
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001464 if (sk->sk_state != BT_CONNECTED)
1465 return -ENOTCONN;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001466
Gustavo F. Padovan6e2b6722010-06-01 18:52:58 -03001467 while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(sk))) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001468
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001469 if (pi->remote_max_tx &&
1470 bt_cb(skb)->retries == pi->remote_max_tx) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03001471 l2cap_send_disconn_req(pi->conn, sk, ECONNABORTED);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001472 break;
1473 }
1474
Andrei Emeltchenkoe420aba2009-12-23 13:07:14 +02001475 tx_skb = skb_clone(skb, GFP_ATOMIC);
1476
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001477 bt_cb(skb)->retries++;
1478
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001479 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03001480 control &= L2CAP_CTRL_SAR;
1481
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001482 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
1483 control |= L2CAP_CTRL_FINAL;
1484 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
1485 }
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03001486 control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001487 | (pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
1488 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1489
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001490
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001491 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001492 fcs = crc16(0, (u8 *)skb->data, tx_skb->len - 2);
1493 put_unaligned_le16(fcs, skb->data + tx_skb->len - 2);
1494 }
1495
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001496 l2cap_do_send(sk, tx_skb);
1497
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001498 __mod_retrans_timer();
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001499
1500 bt_cb(skb)->tx_seq = pi->next_tx_seq;
1501 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
1502
1503 pi->unacked_frames++;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001504 pi->frames_sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001505
1506 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1507 sk->sk_send_head = NULL;
1508 else
1509 sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001510
1511 nsent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001512 }
1513
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001514 return nsent;
1515}
1516
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001517static int l2cap_retransmit_frames(struct sock *sk)
1518{
1519 struct l2cap_pinfo *pi = l2cap_pi(sk);
1520 int ret;
1521
1522 spin_lock_bh(&pi->send_lock);
1523
1524 if (!skb_queue_empty(TX_QUEUE(sk)))
1525 sk->sk_send_head = TX_QUEUE(sk)->next;
1526
1527 pi->next_tx_seq = pi->expected_ack_seq;
1528 ret = l2cap_ertm_send(sk);
1529
1530 spin_unlock_bh(&pi->send_lock);
1531
1532 return ret;
1533}
1534
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001535static void l2cap_send_ack(struct l2cap_pinfo *pi)
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001536{
1537 struct sock *sk = (struct sock *)pi;
1538 u16 control = 0;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001539 int nframes;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001540
1541 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1542
1543 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
1544 control |= L2CAP_SUPER_RCV_NOT_READY;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03001545 pi->conn_state |= L2CAP_CONN_RNR_SENT;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001546 l2cap_send_sframe(pi, control);
1547 return;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001548 }
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001549
1550 spin_lock_bh(&pi->send_lock);
1551 nframes = l2cap_ertm_send(sk);
1552 spin_unlock_bh(&pi->send_lock);
1553
1554 if (nframes > 0)
1555 return;
1556
1557 control |= L2CAP_SUPER_RCV_READY;
1558 l2cap_send_sframe(pi, control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001559}
1560
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001561static void l2cap_send_srejtail(struct sock *sk)
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03001562{
1563 struct srej_list *tail;
1564 u16 control;
1565
1566 control = L2CAP_SUPER_SELECT_REJECT;
1567 control |= L2CAP_CTRL_FINAL;
1568
1569 tail = list_entry(SREJ_LIST(sk)->prev, struct srej_list, list);
1570 control |= tail->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1571
1572 l2cap_send_sframe(l2cap_pi(sk), control);
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03001573}
1574
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001575static 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 -07001576{
1577 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001578 struct sk_buff **frag;
1579 int err, sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001580
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03001581 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001582 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001583
1584 sent += count;
1585 len -= count;
1586
1587 /* Continuation fragments (no L2CAP header) */
1588 frag = &skb_shinfo(skb)->frag_list;
1589 while (len) {
1590 count = min_t(unsigned int, conn->mtu, len);
1591
1592 *frag = bt_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err);
1593 if (!*frag)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001594 return -EFAULT;
1595 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
1596 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001597
1598 sent += count;
1599 len -= count;
1600
1601 frag = &(*frag)->next;
1602 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001603
1604 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001605}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001606
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001607static struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, size_t len)
1608{
1609 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1610 struct sk_buff *skb;
1611 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1612 struct l2cap_hdr *lh;
1613
1614 BT_DBG("sk %p len %d", sk, (int)len);
1615
1616 count = min_t(unsigned int, (conn->mtu - hlen), len);
1617 skb = bt_skb_send_alloc(sk, count + hlen,
1618 msg->msg_flags & MSG_DONTWAIT, &err);
1619 if (!skb)
1620 return ERR_PTR(-ENOMEM);
1621
1622 /* Create L2CAP header */
1623 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1624 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1625 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1626 put_unaligned_le16(l2cap_pi(sk)->psm, skb_put(skb, 2));
1627
1628 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1629 if (unlikely(err < 0)) {
1630 kfree_skb(skb);
1631 return ERR_PTR(err);
1632 }
1633 return skb;
1634}
1635
1636static struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *msg, size_t len)
1637{
1638 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1639 struct sk_buff *skb;
1640 int err, count, hlen = L2CAP_HDR_SIZE;
1641 struct l2cap_hdr *lh;
1642
1643 BT_DBG("sk %p len %d", sk, (int)len);
1644
1645 count = min_t(unsigned int, (conn->mtu - hlen), len);
1646 skb = bt_skb_send_alloc(sk, count + hlen,
1647 msg->msg_flags & MSG_DONTWAIT, &err);
1648 if (!skb)
1649 return ERR_PTR(-ENOMEM);
1650
1651 /* Create L2CAP header */
1652 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1653 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1654 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1655
1656 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1657 if (unlikely(err < 0)) {
1658 kfree_skb(skb);
1659 return ERR_PTR(err);
1660 }
1661 return skb;
1662}
1663
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001664static 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 -03001665{
1666 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1667 struct sk_buff *skb;
1668 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1669 struct l2cap_hdr *lh;
1670
1671 BT_DBG("sk %p len %d", sk, (int)len);
1672
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03001673 if (!conn)
1674 return ERR_PTR(-ENOTCONN);
1675
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001676 if (sdulen)
1677 hlen += 2;
1678
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001679 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1680 hlen += 2;
1681
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001682 count = min_t(unsigned int, (conn->mtu - hlen), len);
1683 skb = bt_skb_send_alloc(sk, count + hlen,
1684 msg->msg_flags & MSG_DONTWAIT, &err);
1685 if (!skb)
1686 return ERR_PTR(-ENOMEM);
1687
1688 /* Create L2CAP header */
1689 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1690 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1691 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1692 put_unaligned_le16(control, skb_put(skb, 2));
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001693 if (sdulen)
1694 put_unaligned_le16(sdulen, skb_put(skb, 2));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001695
1696 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1697 if (unlikely(err < 0)) {
1698 kfree_skb(skb);
1699 return ERR_PTR(err);
1700 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001701
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001702 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1703 put_unaligned_le16(0, skb_put(skb, 2));
1704
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001705 bt_cb(skb)->retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001706 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001707}
1708
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001709static inline int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len)
1710{
1711 struct l2cap_pinfo *pi = l2cap_pi(sk);
1712 struct sk_buff *skb;
1713 struct sk_buff_head sar_queue;
1714 u16 control;
1715 size_t size = 0;
1716
Gustavo F. Padovanff12fd62010-05-05 22:09:15 -03001717 skb_queue_head_init(&sar_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001718 control = L2CAP_SDU_START;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001719 skb = l2cap_create_iframe_pdu(sk, msg, pi->remote_mps, control, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001720 if (IS_ERR(skb))
1721 return PTR_ERR(skb);
1722
1723 __skb_queue_tail(&sar_queue, skb);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001724 len -= pi->remote_mps;
1725 size += pi->remote_mps;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001726
1727 while (len > 0) {
1728 size_t buflen;
1729
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001730 if (len > pi->remote_mps) {
Gustavo F. Padovan44651b82010-05-01 16:15:43 -03001731 control = L2CAP_SDU_CONTINUE;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001732 buflen = pi->remote_mps;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001733 } else {
Gustavo F. Padovan44651b82010-05-01 16:15:43 -03001734 control = L2CAP_SDU_END;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001735 buflen = len;
1736 }
1737
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001738 skb = l2cap_create_iframe_pdu(sk, msg, buflen, control, 0);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001739 if (IS_ERR(skb)) {
1740 skb_queue_purge(&sar_queue);
1741 return PTR_ERR(skb);
1742 }
1743
1744 __skb_queue_tail(&sar_queue, skb);
1745 len -= buflen;
1746 size += buflen;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001747 }
1748 skb_queue_splice_tail(&sar_queue, TX_QUEUE(sk));
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001749 spin_lock_bh(&pi->send_lock);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001750 if (sk->sk_send_head == NULL)
1751 sk->sk_send_head = sar_queue.next;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001752 spin_unlock_bh(&pi->send_lock);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001753
1754 return size;
1755}
1756
Linus Torvalds1da177e2005-04-16 15:20:36 -07001757static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len)
1758{
1759 struct sock *sk = sock->sk;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001760 struct l2cap_pinfo *pi = l2cap_pi(sk);
1761 struct sk_buff *skb;
1762 u16 control;
1763 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001764
1765 BT_DBG("sock %p, sk %p", sock, sk);
1766
Benjamin LaHaisec1cbe4b2005-12-13 23:22:19 -08001767 err = sock_error(sk);
1768 if (err)
1769 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001770
1771 if (msg->msg_flags & MSG_OOB)
1772 return -EOPNOTSUPP;
1773
Linus Torvalds1da177e2005-04-16 15:20:36 -07001774 lock_sock(sk);
1775
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001776 if (sk->sk_state != BT_CONNECTED) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001777 err = -ENOTCONN;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001778 goto done;
1779 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001780
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001781 /* Connectionless channel */
1782 if (sk->sk_type == SOCK_DGRAM) {
1783 skb = l2cap_create_connless_pdu(sk, msg, len);
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001784 if (IS_ERR(skb)) {
Dan Carpenter477fffb2010-04-21 23:52:01 +00001785 err = PTR_ERR(skb);
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001786 } else {
1787 l2cap_do_send(sk, skb);
1788 err = len;
1789 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001790 goto done;
1791 }
1792
1793 switch (pi->mode) {
1794 case L2CAP_MODE_BASIC:
Gustavo F. Padovanc69163e2010-05-01 16:15:35 -03001795 /* Check outgoing MTU */
1796 if (len > pi->omtu) {
1797 err = -EINVAL;
1798 goto done;
1799 }
1800
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001801 /* Create a basic PDU */
1802 skb = l2cap_create_basic_pdu(sk, msg, len);
1803 if (IS_ERR(skb)) {
1804 err = PTR_ERR(skb);
1805 goto done;
1806 }
1807
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001808 l2cap_do_send(sk, skb);
1809 err = len;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001810 break;
1811
1812 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001813 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001814 /* Entire SDU fits into one PDU */
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001815 if (len <= pi->remote_mps) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001816 control = L2CAP_SDU_UNSEGMENTED;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001817 skb = l2cap_create_iframe_pdu(sk, msg, len, control, 0);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001818 if (IS_ERR(skb)) {
1819 err = PTR_ERR(skb);
1820 goto done;
1821 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001822 __skb_queue_tail(TX_QUEUE(sk), skb);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001823
1824 if (pi->mode == L2CAP_MODE_ERTM)
1825 spin_lock_bh(&pi->send_lock);
1826
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001827 if (sk->sk_send_head == NULL)
1828 sk->sk_send_head = skb;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001829
1830 if (pi->mode == L2CAP_MODE_ERTM)
1831 spin_unlock_bh(&pi->send_lock);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001832 } else {
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001833 /* Segment SDU into multiples PDUs */
1834 err = l2cap_sar_segment_sdu(sk, msg, len);
1835 if (err < 0)
1836 goto done;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001837 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001838
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001839 if (pi->mode == L2CAP_MODE_STREAMING) {
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001840 err = l2cap_streaming_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001841 } else {
Gustavo F. Padovan6e2b6722010-06-01 18:52:58 -03001842 if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY &&
1843 pi->conn_state && L2CAP_CONN_WAIT_F) {
1844 err = len;
1845 break;
1846 }
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001847 spin_lock_bh(&pi->send_lock);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001848 err = l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001849 spin_unlock_bh(&pi->send_lock);
1850 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001851
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001852 if (err >= 0)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001853 err = len;
1854 break;
1855
1856 default:
1857 BT_DBG("bad state %1.1x", pi->mode);
1858 err = -EINVAL;
1859 }
1860
1861done:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001862 release_sock(sk);
1863 return err;
1864}
1865
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001866static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags)
1867{
1868 struct sock *sk = sock->sk;
1869
1870 lock_sock(sk);
1871
1872 if (sk->sk_state == BT_CONNECT2 && bt_sk(sk)->defer_setup) {
1873 struct l2cap_conn_rsp rsp;
1874
1875 sk->sk_state = BT_CONFIG;
1876
1877 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
1878 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
1879 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
1880 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
1881 l2cap_send_cmd(l2cap_pi(sk)->conn, l2cap_pi(sk)->ident,
1882 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
1883
1884 release_sock(sk);
1885 return 0;
1886 }
1887
1888 release_sock(sk);
1889
1890 return bt_sock_recvmsg(iocb, sock, msg, len, flags);
1891}
1892
David S. Millerb7058842009-09-30 16:12:20 -07001893static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001894{
1895 struct sock *sk = sock->sk;
1896 struct l2cap_options opts;
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001897 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001898 u32 opt;
1899
1900 BT_DBG("sk %p", sk);
1901
1902 lock_sock(sk);
1903
1904 switch (optname) {
1905 case L2CAP_OPTIONS:
Marcel Holtmann0878b662007-05-05 00:35:59 +02001906 opts.imtu = l2cap_pi(sk)->imtu;
1907 opts.omtu = l2cap_pi(sk)->omtu;
1908 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001909 opts.mode = l2cap_pi(sk)->mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001910 opts.fcs = l2cap_pi(sk)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03001911 opts.max_tx = l2cap_pi(sk)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03001912 opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
Marcel Holtmann0878b662007-05-05 00:35:59 +02001913
Linus Torvalds1da177e2005-04-16 15:20:36 -07001914 len = min_t(unsigned int, sizeof(opts), optlen);
1915 if (copy_from_user((char *) &opts, optval, len)) {
1916 err = -EFAULT;
1917 break;
1918 }
Marcel Holtmann0878b662007-05-05 00:35:59 +02001919
Gustavo F. Padovan45d65c42010-06-07 19:21:30 -03001920 if (opts.txwin_size > L2CAP_DEFAULT_TX_WINDOW) {
1921 err = -EINVAL;
1922 break;
1923 }
1924
João Paulo Rechi Vita0041ecf2010-05-01 16:15:42 -03001925 l2cap_pi(sk)->mode = opts.mode;
1926 switch (l2cap_pi(sk)->mode) {
1927 case L2CAP_MODE_BASIC:
1928 break;
1929 case L2CAP_MODE_ERTM:
1930 case L2CAP_MODE_STREAMING:
1931 if (enable_ertm)
1932 break;
1933 /* fall through */
1934 default:
1935 err = -EINVAL;
1936 break;
1937 }
1938
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001939 l2cap_pi(sk)->imtu = opts.imtu;
1940 l2cap_pi(sk)->omtu = opts.omtu;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001941 l2cap_pi(sk)->fcs = opts.fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03001942 l2cap_pi(sk)->max_tx = opts.max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03001943 l2cap_pi(sk)->tx_win = (__u8)opts.txwin_size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001944 break;
1945
1946 case L2CAP_LM:
1947 if (get_user(opt, (u32 __user *) optval)) {
1948 err = -EFAULT;
1949 break;
1950 }
1951
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001952 if (opt & L2CAP_LM_AUTH)
1953 l2cap_pi(sk)->sec_level = BT_SECURITY_LOW;
1954 if (opt & L2CAP_LM_ENCRYPT)
1955 l2cap_pi(sk)->sec_level = BT_SECURITY_MEDIUM;
1956 if (opt & L2CAP_LM_SECURE)
1957 l2cap_pi(sk)->sec_level = BT_SECURITY_HIGH;
1958
1959 l2cap_pi(sk)->role_switch = (opt & L2CAP_LM_MASTER);
1960 l2cap_pi(sk)->force_reliable = (opt & L2CAP_LM_RELIABLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001961 break;
1962
1963 default:
1964 err = -ENOPROTOOPT;
1965 break;
1966 }
1967
1968 release_sock(sk);
1969 return err;
1970}
1971
David S. Millerb7058842009-09-30 16:12:20 -07001972static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001973{
1974 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001975 struct bt_security sec;
1976 int len, err = 0;
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001977 u32 opt;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001978
1979 BT_DBG("sk %p", sk);
1980
1981 if (level == SOL_L2CAP)
1982 return l2cap_sock_setsockopt_old(sock, optname, optval, optlen);
1983
Marcel Holtmann0588d942009-01-16 10:06:13 +01001984 if (level != SOL_BLUETOOTH)
1985 return -ENOPROTOOPT;
1986
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001987 lock_sock(sk);
1988
1989 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001990 case BT_SECURITY:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001991 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
1992 && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01001993 err = -EINVAL;
1994 break;
1995 }
1996
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001997 sec.level = BT_SECURITY_LOW;
1998
1999 len = min_t(unsigned int, sizeof(sec), optlen);
2000 if (copy_from_user((char *) &sec, optval, len)) {
2001 err = -EFAULT;
2002 break;
2003 }
2004
2005 if (sec.level < BT_SECURITY_LOW ||
2006 sec.level > BT_SECURITY_HIGH) {
2007 err = -EINVAL;
2008 break;
2009 }
2010
2011 l2cap_pi(sk)->sec_level = sec.level;
2012 break;
2013
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002014 case BT_DEFER_SETUP:
2015 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
2016 err = -EINVAL;
2017 break;
2018 }
2019
2020 if (get_user(opt, (u32 __user *) optval)) {
2021 err = -EFAULT;
2022 break;
2023 }
2024
2025 bt_sk(sk)->defer_setup = opt;
2026 break;
2027
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002028 default:
2029 err = -ENOPROTOOPT;
2030 break;
2031 }
2032
2033 release_sock(sk);
2034 return err;
2035}
2036
2037static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002038{
2039 struct sock *sk = sock->sk;
2040 struct l2cap_options opts;
2041 struct l2cap_conninfo cinfo;
2042 int len, err = 0;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002043 u32 opt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002044
2045 BT_DBG("sk %p", sk);
2046
2047 if (get_user(len, optlen))
2048 return -EFAULT;
2049
2050 lock_sock(sk);
2051
2052 switch (optname) {
2053 case L2CAP_OPTIONS:
2054 opts.imtu = l2cap_pi(sk)->imtu;
2055 opts.omtu = l2cap_pi(sk)->omtu;
2056 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07002057 opts.mode = l2cap_pi(sk)->mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002058 opts.fcs = l2cap_pi(sk)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03002059 opts.max_tx = l2cap_pi(sk)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03002060 opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002061
2062 len = min_t(unsigned int, len, sizeof(opts));
2063 if (copy_to_user(optval, (char *) &opts, len))
2064 err = -EFAULT;
2065
2066 break;
2067
2068 case L2CAP_LM:
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002069 switch (l2cap_pi(sk)->sec_level) {
2070 case BT_SECURITY_LOW:
2071 opt = L2CAP_LM_AUTH;
2072 break;
2073 case BT_SECURITY_MEDIUM:
2074 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT;
2075 break;
2076 case BT_SECURITY_HIGH:
2077 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT |
2078 L2CAP_LM_SECURE;
2079 break;
2080 default:
2081 opt = 0;
2082 break;
2083 }
2084
2085 if (l2cap_pi(sk)->role_switch)
2086 opt |= L2CAP_LM_MASTER;
2087
2088 if (l2cap_pi(sk)->force_reliable)
2089 opt |= L2CAP_LM_RELIABLE;
2090
2091 if (put_user(opt, (u32 __user *) optval))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002092 err = -EFAULT;
2093 break;
2094
2095 case L2CAP_CONNINFO:
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002096 if (sk->sk_state != BT_CONNECTED &&
2097 !(sk->sk_state == BT_CONNECT2 &&
2098 bt_sk(sk)->defer_setup)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002099 err = -ENOTCONN;
2100 break;
2101 }
2102
2103 cinfo.hci_handle = l2cap_pi(sk)->conn->hcon->handle;
2104 memcpy(cinfo.dev_class, l2cap_pi(sk)->conn->hcon->dev_class, 3);
2105
2106 len = min_t(unsigned int, len, sizeof(cinfo));
2107 if (copy_to_user(optval, (char *) &cinfo, len))
2108 err = -EFAULT;
2109
2110 break;
2111
2112 default:
2113 err = -ENOPROTOOPT;
2114 break;
2115 }
2116
2117 release_sock(sk);
2118 return err;
2119}
2120
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002121static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
2122{
2123 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002124 struct bt_security sec;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002125 int len, err = 0;
2126
2127 BT_DBG("sk %p", sk);
2128
2129 if (level == SOL_L2CAP)
2130 return l2cap_sock_getsockopt_old(sock, optname, optval, optlen);
2131
Marcel Holtmann0588d942009-01-16 10:06:13 +01002132 if (level != SOL_BLUETOOTH)
2133 return -ENOPROTOOPT;
2134
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002135 if (get_user(len, optlen))
2136 return -EFAULT;
2137
2138 lock_sock(sk);
2139
2140 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002141 case BT_SECURITY:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03002142 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
2143 && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01002144 err = -EINVAL;
2145 break;
2146 }
2147
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002148 sec.level = l2cap_pi(sk)->sec_level;
2149
2150 len = min_t(unsigned int, len, sizeof(sec));
2151 if (copy_to_user(optval, (char *) &sec, len))
2152 err = -EFAULT;
2153
2154 break;
2155
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002156 case BT_DEFER_SETUP:
2157 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
2158 err = -EINVAL;
2159 break;
2160 }
2161
2162 if (put_user(bt_sk(sk)->defer_setup, (u32 __user *) optval))
2163 err = -EFAULT;
2164
2165 break;
2166
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002167 default:
2168 err = -ENOPROTOOPT;
2169 break;
2170 }
2171
2172 release_sock(sk);
2173 return err;
2174}
2175
Linus Torvalds1da177e2005-04-16 15:20:36 -07002176static int l2cap_sock_shutdown(struct socket *sock, int how)
2177{
2178 struct sock *sk = sock->sk;
2179 int err = 0;
2180
2181 BT_DBG("sock %p, sk %p", sock, sk);
2182
2183 if (!sk)
2184 return 0;
2185
2186 lock_sock(sk);
2187 if (!sk->sk_shutdown) {
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03002188 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
2189 err = __l2cap_wait_ack(sk);
2190
Linus Torvalds1da177e2005-04-16 15:20:36 -07002191 sk->sk_shutdown = SHUTDOWN_MASK;
2192 l2cap_sock_clear_timer(sk);
2193 __l2cap_sock_close(sk, 0);
2194
2195 if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
Marcel Holtmannb1235d72008-07-14 20:13:54 +02002196 err = bt_sock_wait_state(sk, BT_CLOSED,
2197 sk->sk_lingertime);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002198 }
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03002199
2200 if (!err && sk->sk_err)
2201 err = -sk->sk_err;
2202
Linus Torvalds1da177e2005-04-16 15:20:36 -07002203 release_sock(sk);
2204 return err;
2205}
2206
2207static int l2cap_sock_release(struct socket *sock)
2208{
2209 struct sock *sk = sock->sk;
2210 int err;
2211
2212 BT_DBG("sock %p, sk %p", sock, sk);
2213
2214 if (!sk)
2215 return 0;
2216
2217 err = l2cap_sock_shutdown(sock, 2);
2218
2219 sock_orphan(sk);
2220 l2cap_sock_kill(sk);
2221 return err;
2222}
2223
Linus Torvalds1da177e2005-04-16 15:20:36 -07002224static void l2cap_chan_ready(struct sock *sk)
2225{
2226 struct sock *parent = bt_sk(sk)->parent;
2227
2228 BT_DBG("sk %p, parent %p", sk, parent);
2229
2230 l2cap_pi(sk)->conf_state = 0;
2231 l2cap_sock_clear_timer(sk);
2232
2233 if (!parent) {
2234 /* Outgoing channel.
2235 * Wake up socket sleeping on connect.
2236 */
2237 sk->sk_state = BT_CONNECTED;
2238 sk->sk_state_change(sk);
2239 } else {
2240 /* Incoming channel.
2241 * Wake up socket sleeping on accept.
2242 */
2243 parent->sk_data_ready(parent, 0);
2244 }
2245}
2246
2247/* Copy frame to all raw sockets on that connection */
2248static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2249{
2250 struct l2cap_chan_list *l = &conn->chan_list;
2251 struct sk_buff *nskb;
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002252 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002253
2254 BT_DBG("conn %p", conn);
2255
2256 read_lock(&l->lock);
2257 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
2258 if (sk->sk_type != SOCK_RAW)
2259 continue;
2260
2261 /* Don't send frame to the socket it came from */
2262 if (skb->sk == sk)
2263 continue;
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002264 nskb = skb_clone(skb, GFP_ATOMIC);
2265 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002266 continue;
2267
2268 if (sock_queue_rcv_skb(sk, nskb))
2269 kfree_skb(nskb);
2270 }
2271 read_unlock(&l->lock);
2272}
2273
2274/* ---- L2CAP signalling commands ---- */
2275static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
2276 u8 code, u8 ident, u16 dlen, void *data)
2277{
2278 struct sk_buff *skb, **frag;
2279 struct l2cap_cmd_hdr *cmd;
2280 struct l2cap_hdr *lh;
2281 int len, count;
2282
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002283 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d",
2284 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002285
2286 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2287 count = min_t(unsigned int, conn->mtu, len);
2288
2289 skb = bt_skb_alloc(count, GFP_ATOMIC);
2290 if (!skb)
2291 return NULL;
2292
2293 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002294 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03002295 lh->cid = cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002296
2297 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2298 cmd->code = code;
2299 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002300 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002301
2302 if (dlen) {
2303 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2304 memcpy(skb_put(skb, count), data, count);
2305 data += count;
2306 }
2307
2308 len -= skb->len;
2309
2310 /* Continuation fragments (no L2CAP header) */
2311 frag = &skb_shinfo(skb)->frag_list;
2312 while (len) {
2313 count = min_t(unsigned int, conn->mtu, len);
2314
2315 *frag = bt_skb_alloc(count, GFP_ATOMIC);
2316 if (!*frag)
2317 goto fail;
2318
2319 memcpy(skb_put(*frag, count), data, count);
2320
2321 len -= count;
2322 data += count;
2323
2324 frag = &(*frag)->next;
2325 }
2326
2327 return skb;
2328
2329fail:
2330 kfree_skb(skb);
2331 return NULL;
2332}
2333
2334static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned long *val)
2335{
2336 struct l2cap_conf_opt *opt = *ptr;
2337 int len;
2338
2339 len = L2CAP_CONF_OPT_SIZE + opt->len;
2340 *ptr += len;
2341
2342 *type = opt->type;
2343 *olen = opt->len;
2344
2345 switch (opt->len) {
2346 case 1:
2347 *val = *((u8 *) opt->val);
2348 break;
2349
2350 case 2:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002351 *val = __le16_to_cpu(*((__le16 *) opt->val));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002352 break;
2353
2354 case 4:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002355 *val = __le32_to_cpu(*((__le32 *) opt->val));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002356 break;
2357
2358 default:
2359 *val = (unsigned long) opt->val;
2360 break;
2361 }
2362
2363 BT_DBG("type 0x%2.2x len %d val 0x%lx", *type, opt->len, *val);
2364 return len;
2365}
2366
Linus Torvalds1da177e2005-04-16 15:20:36 -07002367static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2368{
2369 struct l2cap_conf_opt *opt = *ptr;
2370
2371 BT_DBG("type 0x%2.2x len %d val 0x%lx", type, len, val);
2372
2373 opt->type = type;
2374 opt->len = len;
2375
2376 switch (len) {
2377 case 1:
2378 *((u8 *) opt->val) = val;
2379 break;
2380
2381 case 2:
Al Viro8e036fc2007-07-29 00:16:36 -07002382 *((__le16 *) opt->val) = cpu_to_le16(val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002383 break;
2384
2385 case 4:
Al Viro8e036fc2007-07-29 00:16:36 -07002386 *((__le32 *) opt->val) = cpu_to_le32(val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002387 break;
2388
2389 default:
2390 memcpy(opt->val, (void *) val, len);
2391 break;
2392 }
2393
2394 *ptr += L2CAP_CONF_OPT_SIZE + len;
2395}
2396
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002397static void l2cap_ack_timeout(unsigned long arg)
2398{
2399 struct sock *sk = (void *) arg;
2400
2401 bh_lock_sock(sk);
2402 l2cap_send_ack(l2cap_pi(sk));
2403 bh_unlock_sock(sk);
2404}
2405
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002406static inline void l2cap_ertm_init(struct sock *sk)
2407{
2408 l2cap_pi(sk)->expected_ack_seq = 0;
2409 l2cap_pi(sk)->unacked_frames = 0;
2410 l2cap_pi(sk)->buffer_seq = 0;
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03002411 l2cap_pi(sk)->num_acked = 0;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03002412 l2cap_pi(sk)->frames_sent = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002413
2414 setup_timer(&l2cap_pi(sk)->retrans_timer,
2415 l2cap_retrans_timeout, (unsigned long) sk);
2416 setup_timer(&l2cap_pi(sk)->monitor_timer,
2417 l2cap_monitor_timeout, (unsigned long) sk);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002418 setup_timer(&l2cap_pi(sk)->ack_timer,
2419 l2cap_ack_timeout, (unsigned long) sk);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002420
2421 __skb_queue_head_init(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002422 __skb_queue_head_init(BUSY_QUEUE(sk));
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03002423 spin_lock_init(&l2cap_pi(sk)->send_lock);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002424
2425 INIT_WORK(&l2cap_pi(sk)->busy_work, l2cap_busy_work);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002426}
2427
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002428static int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
2429{
2430 u32 local_feat_mask = l2cap_feat_mask;
2431 if (enable_ertm)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002432 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002433
2434 switch (mode) {
2435 case L2CAP_MODE_ERTM:
2436 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
2437 case L2CAP_MODE_STREAMING:
2438 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
2439 default:
2440 return 0x00;
2441 }
2442}
2443
2444static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
2445{
2446 switch (mode) {
2447 case L2CAP_MODE_STREAMING:
2448 case L2CAP_MODE_ERTM:
2449 if (l2cap_mode_supported(mode, remote_feat_mask))
2450 return mode;
2451 /* fall through */
2452 default:
2453 return L2CAP_MODE_BASIC;
2454 }
2455}
2456
Linus Torvalds1da177e2005-04-16 15:20:36 -07002457static int l2cap_build_conf_req(struct sock *sk, void *data)
2458{
2459 struct l2cap_pinfo *pi = l2cap_pi(sk);
2460 struct l2cap_conf_req *req = data;
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03002461 struct l2cap_conf_rfc rfc = { .mode = pi->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07002462 void *ptr = req->data;
2463
2464 BT_DBG("sk %p", sk);
2465
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002466 if (pi->num_conf_req || pi->num_conf_rsp)
2467 goto done;
2468
2469 switch (pi->mode) {
2470 case L2CAP_MODE_STREAMING:
2471 case L2CAP_MODE_ERTM:
2472 pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002473 if (!l2cap_mode_supported(pi->mode, pi->conn->feat_mask))
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03002474 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002475 break;
2476 default:
2477 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
2478 break;
2479 }
2480
2481done:
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002482 switch (pi->mode) {
2483 case L2CAP_MODE_BASIC:
2484 if (pi->imtu != L2CAP_DEFAULT_MTU)
2485 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
2486 break;
2487
2488 case L2CAP_MODE_ERTM:
2489 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03002490 rfc.txwin_size = pi->tx_win;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03002491 rfc.max_transmit = pi->max_tx;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002492 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);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002497
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 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002509 break;
2510
2511 case L2CAP_MODE_STREAMING:
2512 rfc.mode = L2CAP_MODE_STREAMING;
2513 rfc.txwin_size = 0;
2514 rfc.max_transmit = 0;
2515 rfc.retrans_timeout = 0;
2516 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002517 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03002518 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002519 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002520
2521 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2522 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002523
2524 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2525 break;
2526
2527 if (pi->fcs == L2CAP_FCS_NONE ||
2528 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
2529 pi->fcs = L2CAP_FCS_NONE;
2530 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
2531 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002532 break;
2533 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002534
2535 /* FIXME: Need actual value of the flush timeout */
2536 //if (flush_to != L2CAP_DEFAULT_FLUSH_TO)
2537 // l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2, pi->flush_to);
2538
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002539 req->dcid = cpu_to_le16(pi->dcid);
2540 req->flags = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002541
2542 return ptr - data;
2543}
2544
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002545static int l2cap_parse_conf_req(struct sock *sk, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002546{
2547 struct l2cap_pinfo *pi = l2cap_pi(sk);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002548 struct l2cap_conf_rsp *rsp = data;
2549 void *ptr = rsp->data;
2550 void *req = pi->conf_req;
2551 int len = pi->conf_len;
2552 int type, hint, olen;
2553 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002554 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Marcel Holtmann861d6882007-10-20 13:37:06 +02002555 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002556 u16 result = L2CAP_CONF_SUCCESS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002557
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002558 BT_DBG("sk %p", sk);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01002559
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002560 while (len >= L2CAP_CONF_OPT_SIZE) {
2561 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002562
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03002563 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07002564 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002565
2566 switch (type) {
2567 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002568 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002569 break;
2570
2571 case L2CAP_CONF_FLUSH_TO:
2572 pi->flush_to = val;
2573 break;
2574
2575 case L2CAP_CONF_QOS:
2576 break;
2577
Marcel Holtmann6464f352007-10-20 13:39:51 +02002578 case L2CAP_CONF_RFC:
2579 if (olen == sizeof(rfc))
2580 memcpy(&rfc, (void *) val, olen);
2581 break;
2582
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002583 case L2CAP_CONF_FCS:
2584 if (val == L2CAP_FCS_NONE)
2585 pi->conf_state |= L2CAP_CONF_NO_FCS_RECV;
2586
2587 break;
2588
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002589 default:
2590 if (hint)
2591 break;
2592
2593 result = L2CAP_CONF_UNKNOWN;
2594 *((u8 *) ptr++) = type;
2595 break;
2596 }
2597 }
2598
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002599 if (pi->num_conf_rsp || pi->num_conf_req)
2600 goto done;
2601
2602 switch (pi->mode) {
2603 case L2CAP_MODE_STREAMING:
2604 case L2CAP_MODE_ERTM:
2605 pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
2606 if (!l2cap_mode_supported(pi->mode, pi->conn->feat_mask))
2607 return -ECONNREFUSED;
2608 break;
2609 default:
2610 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
2611 break;
2612 }
2613
2614done:
2615 if (pi->mode != rfc.mode) {
2616 result = L2CAP_CONF_UNACCEPT;
2617 rfc.mode = pi->mode;
2618
2619 if (pi->num_conf_rsp == 1)
2620 return -ECONNREFUSED;
2621
2622 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2623 sizeof(rfc), (unsigned long) &rfc);
2624 }
2625
2626
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002627 if (result == L2CAP_CONF_SUCCESS) {
2628 /* Configure output options and let the other side know
2629 * which ones we don't like. */
2630
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002631 if (mtu < L2CAP_DEFAULT_MIN_MTU)
2632 result = L2CAP_CONF_UNACCEPT;
2633 else {
2634 pi->omtu = mtu;
2635 pi->conf_state |= L2CAP_CONF_MTU_DONE;
2636 }
2637 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002638
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002639 switch (rfc.mode) {
2640 case L2CAP_MODE_BASIC:
2641 pi->fcs = L2CAP_FCS_NONE;
2642 pi->conf_state |= L2CAP_CONF_MODE_DONE;
2643 break;
2644
2645 case L2CAP_MODE_ERTM:
2646 pi->remote_tx_win = rfc.txwin_size;
2647 pi->remote_max_tx = rfc.max_transmit;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002648 if (rfc.max_pdu_size > pi->conn->mtu - 10)
2649 rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10);
2650
2651 pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002652
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002653 rfc.retrans_timeout =
2654 le16_to_cpu(L2CAP_DEFAULT_RETRANS_TO);
2655 rfc.monitor_timeout =
2656 le16_to_cpu(L2CAP_DEFAULT_MONITOR_TO);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002657
2658 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03002659
2660 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2661 sizeof(rfc), (unsigned long) &rfc);
2662
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002663 break;
2664
2665 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002666 if (rfc.max_pdu_size > pi->conn->mtu - 10)
2667 rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10);
2668
2669 pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002670
2671 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03002672
2673 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2674 sizeof(rfc), (unsigned long) &rfc);
2675
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002676 break;
2677
2678 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02002679 result = L2CAP_CONF_UNACCEPT;
2680
2681 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002682 rfc.mode = pi->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002683 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002684
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002685 if (result == L2CAP_CONF_SUCCESS)
2686 pi->conf_state |= L2CAP_CONF_OUTPUT_DONE;
2687 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002688 rsp->scid = cpu_to_le16(pi->dcid);
2689 rsp->result = cpu_to_le16(result);
2690 rsp->flags = cpu_to_le16(0x0000);
2691
2692 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002693}
2694
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002695static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data, u16 *result)
2696{
2697 struct l2cap_pinfo *pi = l2cap_pi(sk);
2698 struct l2cap_conf_req *req = data;
2699 void *ptr = req->data;
2700 int type, olen;
2701 unsigned long val;
2702 struct l2cap_conf_rfc rfc;
2703
2704 BT_DBG("sk %p, rsp %p, len %d, req %p", sk, rsp, len, data);
2705
2706 while (len >= L2CAP_CONF_OPT_SIZE) {
2707 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
2708
2709 switch (type) {
2710 case L2CAP_CONF_MTU:
2711 if (val < L2CAP_DEFAULT_MIN_MTU) {
2712 *result = L2CAP_CONF_UNACCEPT;
2713 pi->omtu = L2CAP_DEFAULT_MIN_MTU;
2714 } else
2715 pi->omtu = val;
2716 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
2717 break;
2718
2719 case L2CAP_CONF_FLUSH_TO:
2720 pi->flush_to = val;
2721 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
2722 2, pi->flush_to);
2723 break;
2724
2725 case L2CAP_CONF_RFC:
2726 if (olen == sizeof(rfc))
2727 memcpy(&rfc, (void *)val, olen);
2728
2729 if ((pi->conf_state & L2CAP_CONF_STATE2_DEVICE) &&
2730 rfc.mode != pi->mode)
2731 return -ECONNREFUSED;
2732
2733 pi->mode = rfc.mode;
2734 pi->fcs = 0;
2735
2736 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2737 sizeof(rfc), (unsigned long) &rfc);
2738 break;
2739 }
2740 }
2741
2742 if (*result == L2CAP_CONF_SUCCESS) {
2743 switch (rfc.mode) {
2744 case L2CAP_MODE_ERTM:
2745 pi->remote_tx_win = rfc.txwin_size;
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002746 pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
2747 pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002748 pi->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002749 break;
2750 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002751 pi->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002752 }
2753 }
2754
2755 req->dcid = cpu_to_le16(pi->dcid);
2756 req->flags = cpu_to_le16(0x0000);
2757
2758 return ptr - data;
2759}
2760
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002761static int l2cap_build_conf_rsp(struct sock *sk, void *data, u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002762{
2763 struct l2cap_conf_rsp *rsp = data;
2764 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002765
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002766 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002767
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002768 rsp->scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002769 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002770 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002771
2772 return ptr - data;
2773}
2774
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002775static void l2cap_conf_rfc_get(struct sock *sk, void *rsp, int len)
2776{
2777 struct l2cap_pinfo *pi = l2cap_pi(sk);
2778 int type, olen;
2779 unsigned long val;
2780 struct l2cap_conf_rfc rfc;
2781
2782 BT_DBG("sk %p, rsp %p, len %d", sk, rsp, len);
2783
2784 if ((pi->mode != L2CAP_MODE_ERTM) && (pi->mode != L2CAP_MODE_STREAMING))
2785 return;
2786
2787 while (len >= L2CAP_CONF_OPT_SIZE) {
2788 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
2789
2790 switch (type) {
2791 case L2CAP_CONF_RFC:
2792 if (olen == sizeof(rfc))
2793 memcpy(&rfc, (void *)val, olen);
2794 goto done;
2795 }
2796 }
2797
2798done:
2799 switch (rfc.mode) {
2800 case L2CAP_MODE_ERTM:
2801 pi->remote_tx_win = rfc.txwin_size;
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002802 pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
2803 pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002804 pi->mps = le16_to_cpu(rfc.max_pdu_size);
2805 break;
2806 case L2CAP_MODE_STREAMING:
2807 pi->mps = le16_to_cpu(rfc.max_pdu_size);
2808 }
2809}
2810
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002811static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2812{
2813 struct l2cap_cmd_rej *rej = (struct l2cap_cmd_rej *) data;
2814
2815 if (rej->reason != 0x0000)
2816 return 0;
2817
2818 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
2819 cmd->ident == conn->info_ident) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002820 del_timer(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01002821
2822 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002823 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01002824
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002825 l2cap_conn_start(conn);
2826 }
2827
2828 return 0;
2829}
2830
Linus Torvalds1da177e2005-04-16 15:20:36 -07002831static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2832{
2833 struct l2cap_chan_list *list = &conn->chan_list;
2834 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
2835 struct l2cap_conn_rsp rsp;
2836 struct sock *sk, *parent;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002837 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002838
2839 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002840 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002841
2842 BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
2843
2844 /* Check if we have socket listening on psm */
2845 parent = l2cap_get_sock_by_psm(BT_LISTEN, psm, conn->src);
2846 if (!parent) {
2847 result = L2CAP_CR_BAD_PSM;
2848 goto sendresp;
2849 }
2850
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002851 /* Check if the ACL is secure enough (if not SDP) */
2852 if (psm != cpu_to_le16(0x0001) &&
2853 !hci_conn_check_link_mode(conn->hcon)) {
Marcel Holtmann2950f212009-02-12 14:02:50 +01002854 conn->disc_reason = 0x05;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002855 result = L2CAP_CR_SEC_BLOCK;
2856 goto response;
2857 }
2858
Linus Torvalds1da177e2005-04-16 15:20:36 -07002859 result = L2CAP_CR_NO_MEM;
2860
2861 /* Check for backlog size */
2862 if (sk_acceptq_is_full(parent)) {
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09002863 BT_DBG("backlog full %d", parent->sk_ack_backlog);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002864 goto response;
2865 }
2866
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09002867 sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002868 if (!sk)
2869 goto response;
2870
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002871 write_lock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002872
2873 /* Check if we already have channel with that dcid */
2874 if (__l2cap_get_chan_by_dcid(list, scid)) {
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002875 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002876 sock_set_flag(sk, SOCK_ZAPPED);
2877 l2cap_sock_kill(sk);
2878 goto response;
2879 }
2880
2881 hci_conn_hold(conn->hcon);
2882
2883 l2cap_sock_init(sk, parent);
2884 bacpy(&bt_sk(sk)->src, conn->src);
2885 bacpy(&bt_sk(sk)->dst, conn->dst);
2886 l2cap_pi(sk)->psm = psm;
2887 l2cap_pi(sk)->dcid = scid;
2888
2889 __l2cap_chan_add(conn, sk, parent);
2890 dcid = l2cap_pi(sk)->scid;
2891
2892 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
2893
Linus Torvalds1da177e2005-04-16 15:20:36 -07002894 l2cap_pi(sk)->ident = cmd->ident;
2895
Marcel Holtmann984947d2009-02-06 23:35:19 +01002896 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002897 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002898 if (bt_sk(sk)->defer_setup) {
2899 sk->sk_state = BT_CONNECT2;
2900 result = L2CAP_CR_PEND;
2901 status = L2CAP_CS_AUTHOR_PEND;
2902 parent->sk_data_ready(parent, 0);
2903 } else {
2904 sk->sk_state = BT_CONFIG;
2905 result = L2CAP_CR_SUCCESS;
2906 status = L2CAP_CS_NO_INFO;
2907 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002908 } else {
2909 sk->sk_state = BT_CONNECT2;
2910 result = L2CAP_CR_PEND;
2911 status = L2CAP_CS_AUTHEN_PEND;
2912 }
2913 } else {
2914 sk->sk_state = BT_CONNECT2;
2915 result = L2CAP_CR_PEND;
2916 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002917 }
2918
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002919 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002920
2921response:
2922 bh_unlock_sock(parent);
2923
2924sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002925 rsp.scid = cpu_to_le16(scid);
2926 rsp.dcid = cpu_to_le16(dcid);
2927 rsp.result = cpu_to_le16(result);
2928 rsp.status = cpu_to_le16(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002929 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002930
2931 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
2932 struct l2cap_info_req info;
2933 info.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
2934
2935 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
2936 conn->info_ident = l2cap_get_ident(conn);
2937
2938 mod_timer(&conn->info_timer, jiffies +
2939 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
2940
2941 l2cap_send_cmd(conn, conn->info_ident,
2942 L2CAP_INFO_REQ, sizeof(info), &info);
2943 }
2944
Linus Torvalds1da177e2005-04-16 15:20:36 -07002945 return 0;
2946}
2947
2948static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2949{
2950 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
2951 u16 scid, dcid, result, status;
2952 struct sock *sk;
2953 u8 req[128];
2954
2955 scid = __le16_to_cpu(rsp->scid);
2956 dcid = __le16_to_cpu(rsp->dcid);
2957 result = __le16_to_cpu(rsp->result);
2958 status = __le16_to_cpu(rsp->status);
2959
2960 BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
2961
2962 if (scid) {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002963 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2964 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002965 return 0;
2966 } else {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002967 sk = l2cap_get_chan_by_ident(&conn->chan_list, cmd->ident);
2968 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002969 return 0;
2970 }
2971
2972 switch (result) {
2973 case L2CAP_CR_SUCCESS:
2974 sk->sk_state = BT_CONFIG;
2975 l2cap_pi(sk)->ident = 0;
2976 l2cap_pi(sk)->dcid = dcid;
2977 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002978 l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_CONNECT_PEND;
2979
Linus Torvalds1da177e2005-04-16 15:20:36 -07002980 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
2981 l2cap_build_conf_req(sk, req), req);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002982 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002983 break;
2984
2985 case L2CAP_CR_PEND:
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002986 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002987 break;
2988
2989 default:
2990 l2cap_chan_del(sk, ECONNREFUSED);
2991 break;
2992 }
2993
2994 bh_unlock_sock(sk);
2995 return 0;
2996}
2997
Al Viro88219a02007-07-29 00:17:25 -07002998static 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 -07002999{
3000 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
3001 u16 dcid, flags;
3002 u8 rsp[64];
3003 struct sock *sk;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003004 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003005
3006 dcid = __le16_to_cpu(req->dcid);
3007 flags = __le16_to_cpu(req->flags);
3008
3009 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
3010
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003011 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
3012 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003013 return -ENOENT;
3014
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003015 if (sk->sk_state == BT_DISCONN)
3016 goto unlock;
3017
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003018 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07003019 len = cmd_len - sizeof(*req);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003020 if (l2cap_pi(sk)->conf_len + len > sizeof(l2cap_pi(sk)->conf_req)) {
3021 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
3022 l2cap_build_conf_rsp(sk, rsp,
3023 L2CAP_CONF_REJECT, flags), rsp);
3024 goto unlock;
3025 }
3026
3027 /* Store config. */
3028 memcpy(l2cap_pi(sk)->conf_req + l2cap_pi(sk)->conf_len, req->data, len);
3029 l2cap_pi(sk)->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003030
3031 if (flags & 0x0001) {
3032 /* Incomplete config. Send empty response. */
3033 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003034 l2cap_build_conf_rsp(sk, rsp,
3035 L2CAP_CONF_SUCCESS, 0x0001), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003036 goto unlock;
3037 }
3038
3039 /* Complete config. */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003040 len = l2cap_parse_conf_req(sk, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003041 if (len < 0) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03003042 l2cap_send_disconn_req(conn, sk, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003043 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003044 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003045
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003046 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003047 l2cap_pi(sk)->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003048
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003049 /* Reset config buffer. */
3050 l2cap_pi(sk)->conf_len = 0;
3051
Marcel Holtmann876d9482007-10-20 13:35:42 +02003052 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE))
3053 goto unlock;
3054
Linus Torvalds1da177e2005-04-16 15:20:36 -07003055 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) {
Joe Perchesf64f9e72009-11-29 16:55:45 -08003056 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) ||
3057 l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003058 l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
3059
Linus Torvalds1da177e2005-04-16 15:20:36 -07003060 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003061
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003062 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003063 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003064 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003065 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
3066 l2cap_ertm_init(sk);
3067
Linus Torvalds1da177e2005-04-16 15:20:36 -07003068 l2cap_chan_ready(sk);
Marcel Holtmann876d9482007-10-20 13:35:42 +02003069 goto unlock;
3070 }
3071
3072 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003073 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003074 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003075 l2cap_build_conf_req(sk, buf), buf);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003076 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003077 }
3078
3079unlock:
3080 bh_unlock_sock(sk);
3081 return 0;
3082}
3083
3084static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3085{
3086 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
3087 u16 scid, flags, result;
3088 struct sock *sk;
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003089 int len = cmd->len - sizeof(*rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003090
3091 scid = __le16_to_cpu(rsp->scid);
3092 flags = __le16_to_cpu(rsp->flags);
3093 result = __le16_to_cpu(rsp->result);
3094
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003095 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x",
3096 scid, flags, result);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003097
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003098 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
3099 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003100 return 0;
3101
3102 switch (result) {
3103 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003104 l2cap_conf_rfc_get(sk, rsp->data, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003105 break;
3106
3107 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003108 if (l2cap_pi(sk)->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003109 char req[64];
3110
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02003111 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03003112 l2cap_send_disconn_req(conn, sk, ECONNRESET);
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02003113 goto done;
3114 }
3115
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003116 /* throw out any old stored conf requests */
3117 result = L2CAP_CONF_SUCCESS;
3118 len = l2cap_parse_conf_rsp(sk, rsp->data,
3119 len, req, &result);
3120 if (len < 0) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03003121 l2cap_send_disconn_req(conn, sk, ECONNRESET);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003122 goto done;
3123 }
3124
3125 l2cap_send_cmd(conn, l2cap_get_ident(conn),
3126 L2CAP_CONF_REQ, len, req);
3127 l2cap_pi(sk)->num_conf_req++;
3128 if (result != L2CAP_CONF_SUCCESS)
3129 goto done;
3130 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003131 }
3132
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09003133 default:
Marcel Holtmannb1235d72008-07-14 20:13:54 +02003134 sk->sk_err = ECONNRESET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003135 l2cap_sock_set_timer(sk, HZ * 5);
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03003136 l2cap_send_disconn_req(conn, sk, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003137 goto done;
3138 }
3139
3140 if (flags & 0x01)
3141 goto done;
3142
Linus Torvalds1da177e2005-04-16 15:20:36 -07003143 l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE;
3144
3145 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) {
Joe Perchesf64f9e72009-11-29 16:55:45 -08003146 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) ||
3147 l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003148 l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
3149
Linus Torvalds1da177e2005-04-16 15:20:36 -07003150 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003151 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003152 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003153 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003154 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
3155 l2cap_ertm_init(sk);
3156
Linus Torvalds1da177e2005-04-16 15:20:36 -07003157 l2cap_chan_ready(sk);
3158 }
3159
3160done:
3161 bh_unlock_sock(sk);
3162 return 0;
3163}
3164
3165static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3166{
3167 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
3168 struct l2cap_disconn_rsp rsp;
3169 u16 dcid, scid;
3170 struct sock *sk;
3171
3172 scid = __le16_to_cpu(req->scid);
3173 dcid = __le16_to_cpu(req->dcid);
3174
3175 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
3176
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003177 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
3178 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003179 return 0;
3180
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003181 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
3182 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003183 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
3184
3185 sk->sk_shutdown = SHUTDOWN_MASK;
3186
3187 l2cap_chan_del(sk, ECONNRESET);
3188 bh_unlock_sock(sk);
3189
3190 l2cap_sock_kill(sk);
3191 return 0;
3192}
3193
3194static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3195{
3196 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
3197 u16 dcid, scid;
3198 struct sock *sk;
3199
3200 scid = __le16_to_cpu(rsp->scid);
3201 dcid = __le16_to_cpu(rsp->dcid);
3202
3203 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
3204
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003205 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
3206 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003207 return 0;
3208
3209 l2cap_chan_del(sk, 0);
3210 bh_unlock_sock(sk);
3211
3212 l2cap_sock_kill(sk);
3213 return 0;
3214}
3215
3216static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3217{
3218 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003219 u16 type;
3220
3221 type = __le16_to_cpu(req->type);
3222
3223 BT_DBG("type 0x%4.4x", type);
3224
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003225 if (type == L2CAP_IT_FEAT_MASK) {
3226 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003227 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003228 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
3229 rsp->type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
3230 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003231 if (enable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003232 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
3233 | L2CAP_FEAT_FCS;
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03003234 put_unaligned_le32(feat_mask, rsp->data);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003235 l2cap_send_cmd(conn, cmd->ident,
3236 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003237 } else if (type == L2CAP_IT_FIXED_CHAN) {
3238 u8 buf[12];
3239 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
3240 rsp->type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3241 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
3242 memcpy(buf + 4, l2cap_fixed_chan, 8);
3243 l2cap_send_cmd(conn, cmd->ident,
3244 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003245 } else {
3246 struct l2cap_info_rsp rsp;
3247 rsp.type = cpu_to_le16(type);
3248 rsp.result = cpu_to_le16(L2CAP_IR_NOTSUPP);
3249 l2cap_send_cmd(conn, cmd->ident,
3250 L2CAP_INFO_RSP, sizeof(rsp), &rsp);
3251 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003252
3253 return 0;
3254}
3255
3256static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3257{
3258 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
3259 u16 type, result;
3260
3261 type = __le16_to_cpu(rsp->type);
3262 result = __le16_to_cpu(rsp->result);
3263
3264 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
3265
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003266 del_timer(&conn->info_timer);
3267
Marcel Holtmann984947d2009-02-06 23:35:19 +01003268 if (type == L2CAP_IT_FEAT_MASK) {
Harvey Harrison83985312008-05-02 16:25:46 -07003269 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003270
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003271 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003272 struct l2cap_info_req req;
3273 req.type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3274
3275 conn->info_ident = l2cap_get_ident(conn);
3276
3277 l2cap_send_cmd(conn, conn->info_ident,
3278 L2CAP_INFO_REQ, sizeof(req), &req);
3279 } else {
3280 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
3281 conn->info_ident = 0;
3282
3283 l2cap_conn_start(conn);
3284 }
3285 } else if (type == L2CAP_IT_FIXED_CHAN) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01003286 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003287 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003288
3289 l2cap_conn_start(conn);
3290 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003291
Linus Torvalds1da177e2005-04-16 15:20:36 -07003292 return 0;
3293}
3294
3295static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
3296{
3297 u8 *data = skb->data;
3298 int len = skb->len;
3299 struct l2cap_cmd_hdr cmd;
3300 int err = 0;
3301
3302 l2cap_raw_recv(conn, skb);
3303
3304 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07003305 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003306 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
3307 data += L2CAP_CMD_HDR_SIZE;
3308 len -= L2CAP_CMD_HDR_SIZE;
3309
Al Viro88219a02007-07-29 00:17:25 -07003310 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003311
Al Viro88219a02007-07-29 00:17:25 -07003312 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 -07003313
Al Viro88219a02007-07-29 00:17:25 -07003314 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003315 BT_DBG("corrupted command");
3316 break;
3317 }
3318
3319 switch (cmd.code) {
3320 case L2CAP_COMMAND_REJ:
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003321 l2cap_command_rej(conn, &cmd, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003322 break;
3323
3324 case L2CAP_CONN_REQ:
3325 err = l2cap_connect_req(conn, &cmd, data);
3326 break;
3327
3328 case L2CAP_CONN_RSP:
3329 err = l2cap_connect_rsp(conn, &cmd, data);
3330 break;
3331
3332 case L2CAP_CONF_REQ:
Al Viro88219a02007-07-29 00:17:25 -07003333 err = l2cap_config_req(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003334 break;
3335
3336 case L2CAP_CONF_RSP:
3337 err = l2cap_config_rsp(conn, &cmd, data);
3338 break;
3339
3340 case L2CAP_DISCONN_REQ:
3341 err = l2cap_disconnect_req(conn, &cmd, data);
3342 break;
3343
3344 case L2CAP_DISCONN_RSP:
3345 err = l2cap_disconnect_rsp(conn, &cmd, data);
3346 break;
3347
3348 case L2CAP_ECHO_REQ:
Al Viro88219a02007-07-29 00:17:25 -07003349 l2cap_send_cmd(conn, cmd.ident, L2CAP_ECHO_RSP, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003350 break;
3351
3352 case L2CAP_ECHO_RSP:
3353 break;
3354
3355 case L2CAP_INFO_REQ:
3356 err = l2cap_information_req(conn, &cmd, data);
3357 break;
3358
3359 case L2CAP_INFO_RSP:
3360 err = l2cap_information_rsp(conn, &cmd, data);
3361 break;
3362
3363 default:
3364 BT_ERR("Unknown signaling command 0x%2.2x", cmd.code);
3365 err = -EINVAL;
3366 break;
3367 }
3368
3369 if (err) {
3370 struct l2cap_cmd_rej rej;
3371 BT_DBG("error %d", err);
3372
3373 /* FIXME: Map err to a valid reason */
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003374 rej.reason = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003375 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
3376 }
3377
Al Viro88219a02007-07-29 00:17:25 -07003378 data += cmd_len;
3379 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003380 }
3381
3382 kfree_skb(skb);
3383}
3384
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003385static int l2cap_check_fcs(struct l2cap_pinfo *pi, struct sk_buff *skb)
3386{
3387 u16 our_fcs, rcv_fcs;
3388 int hdr_size = L2CAP_HDR_SIZE + 2;
3389
3390 if (pi->fcs == L2CAP_FCS_CRC16) {
3391 skb_trim(skb, skb->len - 2);
3392 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
3393 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
3394
3395 if (our_fcs != rcv_fcs)
3396 return -EINVAL;
3397 }
3398 return 0;
3399}
3400
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003401static inline void l2cap_send_i_or_rr_or_rnr(struct sock *sk)
3402{
3403 struct l2cap_pinfo *pi = l2cap_pi(sk);
3404 u16 control = 0;
3405
3406 pi->frames_sent = 0;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003407
3408 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3409
3410 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
Gustavo F. Padovan64988862010-05-10 14:54:14 -03003411 control |= L2CAP_SUPER_RCV_NOT_READY;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003412 l2cap_send_sframe(pi, control);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003413 pi->conn_state |= L2CAP_CONN_RNR_SENT;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003414 }
3415
Gustavo F. Padovan4ea727e2010-06-03 16:34:20 -03003416 if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY)
3417 l2cap_retransmit_frames(sk);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003418
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003419 spin_lock_bh(&pi->send_lock);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003420 l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003421 spin_unlock_bh(&pi->send_lock);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003422
3423 if (!(pi->conn_state & L2CAP_CONN_LOCAL_BUSY) &&
3424 pi->frames_sent == 0) {
3425 control |= L2CAP_SUPER_RCV_READY;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003426 l2cap_send_sframe(pi, control);
3427 }
3428}
3429
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003430static 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 -03003431{
3432 struct sk_buff *next_skb;
João Paulo Rechi Vitabfbacc12010-05-31 18:35:44 -03003433 struct l2cap_pinfo *pi = l2cap_pi(sk);
3434 int tx_seq_offset, next_tx_seq_offset;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003435
3436 bt_cb(skb)->tx_seq = tx_seq;
3437 bt_cb(skb)->sar = sar;
3438
3439 next_skb = skb_peek(SREJ_QUEUE(sk));
3440 if (!next_skb) {
3441 __skb_queue_tail(SREJ_QUEUE(sk), skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003442 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003443 }
3444
João Paulo Rechi Vitabfbacc12010-05-31 18:35:44 -03003445 tx_seq_offset = (tx_seq - pi->buffer_seq) % 64;
3446 if (tx_seq_offset < 0)
3447 tx_seq_offset += 64;
3448
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003449 do {
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003450 if (bt_cb(next_skb)->tx_seq == tx_seq)
3451 return -EINVAL;
3452
João Paulo Rechi Vitabfbacc12010-05-31 18:35:44 -03003453 next_tx_seq_offset = (bt_cb(next_skb)->tx_seq -
3454 pi->buffer_seq) % 64;
3455 if (next_tx_seq_offset < 0)
3456 next_tx_seq_offset += 64;
3457
3458 if (next_tx_seq_offset > tx_seq_offset) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003459 __skb_queue_before(SREJ_QUEUE(sk), next_skb, skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003460 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003461 }
3462
3463 if (skb_queue_is_last(SREJ_QUEUE(sk), next_skb))
3464 break;
3465
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003466 } while ((next_skb = skb_queue_next(SREJ_QUEUE(sk), next_skb)));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003467
3468 __skb_queue_tail(SREJ_QUEUE(sk), skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003469
3470 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003471}
3472
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003473static int l2cap_ertm_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
3474{
3475 struct l2cap_pinfo *pi = l2cap_pi(sk);
3476 struct sk_buff *_skb;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003477 int err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003478
3479 switch (control & L2CAP_CTRL_SAR) {
3480 case L2CAP_SDU_UNSEGMENTED:
3481 if (pi->conn_state & L2CAP_CONN_SAR_SDU)
3482 goto drop;
3483
3484 err = sock_queue_rcv_skb(sk, skb);
3485 if (!err)
3486 return err;
3487
3488 break;
3489
3490 case L2CAP_SDU_START:
3491 if (pi->conn_state & L2CAP_CONN_SAR_SDU)
3492 goto drop;
3493
3494 pi->sdu_len = get_unaligned_le16(skb->data);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003495
3496 if (pi->sdu_len > pi->imtu)
3497 goto disconnect;
3498
3499 pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003500 if (!pi->sdu)
3501 return -ENOMEM;
3502
3503 /* pull sdu_len bytes only after alloc, because of Local Busy
3504 * condition we have to be sure that this will be executed
3505 * only once, i.e., when alloc does not fail */
3506 skb_pull(skb, 2);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003507
3508 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3509
3510 pi->conn_state |= L2CAP_CONN_SAR_SDU;
3511 pi->partial_sdu_len = skb->len;
3512 break;
3513
3514 case L2CAP_SDU_CONTINUE:
3515 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3516 goto disconnect;
3517
3518 if (!pi->sdu)
3519 goto disconnect;
3520
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003521 pi->partial_sdu_len += skb->len;
3522 if (pi->partial_sdu_len > pi->sdu_len)
3523 goto drop;
3524
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03003525 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3526
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003527 break;
3528
3529 case L2CAP_SDU_END:
3530 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3531 goto disconnect;
3532
3533 if (!pi->sdu)
3534 goto disconnect;
3535
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003536 if (!(pi->conn_state & L2CAP_CONN_SAR_RETRY)) {
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003537 pi->partial_sdu_len += skb->len;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003538
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003539 if (pi->partial_sdu_len > pi->imtu)
3540 goto drop;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003541
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003542 if (pi->partial_sdu_len != pi->sdu_len)
3543 goto drop;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03003544
3545 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003546 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003547
3548 _skb = skb_clone(pi->sdu, GFP_ATOMIC);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003549 if (!_skb) {
3550 pi->conn_state |= L2CAP_CONN_SAR_RETRY;
3551 return -ENOMEM;
3552 }
3553
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003554 err = sock_queue_rcv_skb(sk, _skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003555 if (err < 0) {
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003556 kfree_skb(_skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003557 pi->conn_state |= L2CAP_CONN_SAR_RETRY;
3558 return err;
3559 }
3560
3561 pi->conn_state &= ~L2CAP_CONN_SAR_RETRY;
3562 pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003563
3564 kfree_skb(pi->sdu);
3565 break;
3566 }
3567
3568 kfree_skb(skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003569 return 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003570
3571drop:
3572 kfree_skb(pi->sdu);
3573 pi->sdu = NULL;
3574
3575disconnect:
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03003576 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003577 kfree_skb(skb);
3578 return 0;
3579}
3580
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003581static void l2cap_busy_work(struct work_struct *work)
3582{
3583 DECLARE_WAITQUEUE(wait, current);
3584 struct l2cap_pinfo *pi =
3585 container_of(work, struct l2cap_pinfo, busy_work);
3586 struct sock *sk = (struct sock *)pi;
3587 int n_tries = 0, timeo = HZ/5, err;
3588 struct sk_buff *skb;
3589 u16 control;
3590
3591 lock_sock(sk);
3592
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02003593 add_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003594 while ((skb = skb_peek(BUSY_QUEUE(sk)))) {
3595 set_current_state(TASK_INTERRUPTIBLE);
3596
3597 if (n_tries++ > L2CAP_LOCAL_BUSY_TRIES) {
3598 err = -EBUSY;
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03003599 l2cap_send_disconn_req(pi->conn, sk, EBUSY);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003600 goto done;
3601 }
3602
3603 if (!timeo)
3604 timeo = HZ/5;
3605
3606 if (signal_pending(current)) {
3607 err = sock_intr_errno(timeo);
3608 goto done;
3609 }
3610
3611 release_sock(sk);
3612 timeo = schedule_timeout(timeo);
3613 lock_sock(sk);
3614
3615 err = sock_error(sk);
3616 if (err)
3617 goto done;
3618
3619 while ((skb = skb_dequeue(BUSY_QUEUE(sk)))) {
3620 control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
3621 err = l2cap_ertm_reassembly_sdu(sk, skb, control);
3622 if (err < 0) {
3623 skb_queue_head(BUSY_QUEUE(sk), skb);
3624 break;
3625 }
3626
3627 pi->buffer_seq = (pi->buffer_seq + 1) % 64;
3628 }
3629
3630 if (!skb)
3631 break;
3632 }
3633
3634 if (!(pi->conn_state & L2CAP_CONN_RNR_SENT))
3635 goto done;
3636
3637 control = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3638 control |= L2CAP_SUPER_RCV_READY | L2CAP_CTRL_POLL;
3639 l2cap_send_sframe(pi, control);
3640 l2cap_pi(sk)->retry_count = 1;
3641
3642 del_timer(&pi->retrans_timer);
3643 __mod_monitor_timer();
3644
3645 l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
3646
3647done:
3648 pi->conn_state &= ~L2CAP_CONN_LOCAL_BUSY;
3649 pi->conn_state &= ~L2CAP_CONN_RNR_SENT;
3650
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003651 BT_DBG("sk %p, Exit local busy", sk);
3652
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003653 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02003654 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003655
3656 release_sock(sk);
3657}
3658
3659static int l2cap_push_rx_skb(struct sock *sk, struct sk_buff *skb, u16 control)
3660{
3661 struct l2cap_pinfo *pi = l2cap_pi(sk);
3662 int sctrl, err;
3663
3664 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
3665 bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT;
3666 __skb_queue_tail(BUSY_QUEUE(sk), skb);
3667 return -EBUSY;
3668 }
3669
3670 err = l2cap_ertm_reassembly_sdu(sk, skb, control);
3671 if (err >= 0) {
3672 pi->buffer_seq = (pi->buffer_seq + 1) % 64;
3673 return err;
3674 }
3675
3676 /* Busy Condition */
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003677 BT_DBG("sk %p, Enter local busy", sk);
3678
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003679 pi->conn_state |= L2CAP_CONN_LOCAL_BUSY;
3680 bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT;
3681 __skb_queue_tail(BUSY_QUEUE(sk), skb);
3682
3683 sctrl = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3684 sctrl |= L2CAP_SUPER_RCV_NOT_READY;
3685 l2cap_send_sframe(pi, sctrl);
3686
3687 pi->conn_state |= L2CAP_CONN_RNR_SENT;
3688
Gustavo F. Padovan7fe9b292010-05-12 18:32:04 -03003689 del_timer(&pi->ack_timer);
3690
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003691 queue_work(_busy_wq, &pi->busy_work);
3692
3693 return err;
3694}
3695
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003696static int l2cap_streaming_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003697{
3698 struct l2cap_pinfo *pi = l2cap_pi(sk);
3699 struct sk_buff *_skb;
3700 int err = -EINVAL;
3701
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003702 /*
3703 * TODO: We have to notify the userland if some data is lost with the
3704 * Streaming Mode.
3705 */
3706
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003707 switch (control & L2CAP_CTRL_SAR) {
3708 case L2CAP_SDU_UNSEGMENTED:
3709 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3710 kfree_skb(pi->sdu);
3711 break;
3712 }
3713
3714 err = sock_queue_rcv_skb(sk, skb);
3715 if (!err)
3716 return 0;
3717
3718 break;
3719
3720 case L2CAP_SDU_START:
3721 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3722 kfree_skb(pi->sdu);
3723 break;
3724 }
3725
3726 pi->sdu_len = get_unaligned_le16(skb->data);
3727 skb_pull(skb, 2);
3728
Gustavo F. Padovan052897c2010-05-01 16:15:40 -03003729 if (pi->sdu_len > pi->imtu) {
3730 err = -EMSGSIZE;
3731 break;
3732 }
3733
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003734 pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
3735 if (!pi->sdu) {
3736 err = -ENOMEM;
3737 break;
3738 }
3739
3740 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3741
3742 pi->conn_state |= L2CAP_CONN_SAR_SDU;
3743 pi->partial_sdu_len = skb->len;
3744 err = 0;
3745 break;
3746
3747 case L2CAP_SDU_CONTINUE:
3748 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3749 break;
3750
3751 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3752
3753 pi->partial_sdu_len += skb->len;
3754 if (pi->partial_sdu_len > pi->sdu_len)
3755 kfree_skb(pi->sdu);
3756 else
3757 err = 0;
3758
3759 break;
3760
3761 case L2CAP_SDU_END:
3762 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3763 break;
3764
3765 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3766
3767 pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
3768 pi->partial_sdu_len += skb->len;
3769
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003770 if (pi->partial_sdu_len > pi->imtu)
3771 goto drop;
3772
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003773 if (pi->partial_sdu_len == pi->sdu_len) {
3774 _skb = skb_clone(pi->sdu, GFP_ATOMIC);
3775 err = sock_queue_rcv_skb(sk, _skb);
3776 if (err < 0)
3777 kfree_skb(_skb);
3778 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003779 err = 0;
3780
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003781drop:
3782 kfree_skb(pi->sdu);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003783 break;
3784 }
3785
3786 kfree_skb(skb);
3787 return err;
3788}
3789
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003790static void l2cap_check_srej_gap(struct sock *sk, u8 tx_seq)
3791{
3792 struct sk_buff *skb;
Gustavo F. Padovanafefdbc2010-05-01 16:15:43 -03003793 u16 control;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003794
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003795 while ((skb = skb_peek(SREJ_QUEUE(sk)))) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003796 if (bt_cb(skb)->tx_seq != tx_seq)
3797 break;
3798
3799 skb = skb_dequeue(SREJ_QUEUE(sk));
Gustavo F. Padovanafefdbc2010-05-01 16:15:43 -03003800 control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003801 l2cap_ertm_reassembly_sdu(sk, skb, control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003802 l2cap_pi(sk)->buffer_seq_srej =
3803 (l2cap_pi(sk)->buffer_seq_srej + 1) % 64;
Gustavo F. Padovan8ff50ec2010-05-10 19:34:11 -03003804 tx_seq = (tx_seq + 1) % 64;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003805 }
3806}
3807
3808static void l2cap_resend_srejframe(struct sock *sk, u8 tx_seq)
3809{
3810 struct l2cap_pinfo *pi = l2cap_pi(sk);
3811 struct srej_list *l, *tmp;
3812 u16 control;
3813
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003814 list_for_each_entry_safe(l, tmp, SREJ_LIST(sk), list) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003815 if (l->tx_seq == tx_seq) {
3816 list_del(&l->list);
3817 kfree(l);
3818 return;
3819 }
3820 control = L2CAP_SUPER_SELECT_REJECT;
3821 control |= l->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3822 l2cap_send_sframe(pi, control);
3823 list_del(&l->list);
3824 list_add_tail(&l->list, SREJ_LIST(sk));
3825 }
3826}
3827
3828static void l2cap_send_srejframe(struct sock *sk, u8 tx_seq)
3829{
3830 struct l2cap_pinfo *pi = l2cap_pi(sk);
3831 struct srej_list *new;
3832 u16 control;
3833
3834 while (tx_seq != pi->expected_tx_seq) {
3835 control = L2CAP_SUPER_SELECT_REJECT;
3836 control |= pi->expected_tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3837 l2cap_send_sframe(pi, control);
3838
3839 new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC);
Gustavo F. Padovan8ff50ec2010-05-10 19:34:11 -03003840 new->tx_seq = pi->expected_tx_seq;
3841 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003842 list_add_tail(&new->list, SREJ_LIST(sk));
3843 }
Gustavo F. Padovan8ff50ec2010-05-10 19:34:11 -03003844 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003845}
3846
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003847static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
3848{
3849 struct l2cap_pinfo *pi = l2cap_pi(sk);
3850 u8 tx_seq = __get_txseq(rx_control);
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003851 u8 req_seq = __get_reqseq(rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003852 u8 sar = rx_control >> L2CAP_CTRL_SAR_SHIFT;
Gustavo F. Padovanf6337c72010-05-10 18:32:04 -03003853 int tx_seq_offset, expected_tx_seq_offset;
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03003854 int num_to_ack = (pi->tx_win/6) + 1;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003855 int err = 0;
3856
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003857 BT_DBG("sk %p len %d tx_seq %d rx_control 0x%4.4x", sk, skb->len, tx_seq,
3858 rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003859
Gustavo F. Padovan9b16dc62010-05-05 20:05:57 -03003860 if (L2CAP_CTRL_FINAL & rx_control &&
3861 l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) {
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003862 del_timer(&pi->monitor_timer);
3863 if (pi->unacked_frames > 0)
3864 __mod_retrans_timer();
3865 pi->conn_state &= ~L2CAP_CONN_WAIT_F;
3866 }
3867
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003868 pi->expected_ack_seq = req_seq;
3869 l2cap_drop_acked_frames(sk);
3870
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003871 if (tx_seq == pi->expected_tx_seq)
3872 goto expected;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003873
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003874 tx_seq_offset = (tx_seq - pi->buffer_seq) % 64;
3875 if (tx_seq_offset < 0)
3876 tx_seq_offset += 64;
3877
3878 /* invalid tx_seq */
3879 if (tx_seq_offset >= pi->tx_win) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03003880 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003881 goto drop;
3882 }
3883
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003884 if (pi->conn_state == L2CAP_CONN_LOCAL_BUSY)
3885 goto drop;
3886
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003887 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3888 struct srej_list *first;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003889
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003890 first = list_first_entry(SREJ_LIST(sk),
3891 struct srej_list, list);
3892 if (tx_seq == first->tx_seq) {
3893 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3894 l2cap_check_srej_gap(sk, tx_seq);
3895
3896 list_del(&first->list);
3897 kfree(first);
3898
3899 if (list_empty(SREJ_LIST(sk))) {
3900 pi->buffer_seq = pi->buffer_seq_srej;
3901 pi->conn_state &= ~L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan855666cc2010-05-01 16:15:40 -03003902 l2cap_send_ack(pi);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003903 BT_DBG("sk %p, Exit SREJ_SENT", sk);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003904 }
3905 } else {
3906 struct srej_list *l;
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003907
3908 /* duplicated tx_seq */
3909 if (l2cap_add_to_srej_queue(sk, skb, tx_seq, sar) < 0)
3910 goto drop;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003911
3912 list_for_each_entry(l, SREJ_LIST(sk), list) {
3913 if (l->tx_seq == tx_seq) {
3914 l2cap_resend_srejframe(sk, tx_seq);
3915 return 0;
3916 }
3917 }
3918 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003919 }
3920 } else {
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003921 expected_tx_seq_offset =
3922 (pi->expected_tx_seq - pi->buffer_seq) % 64;
3923 if (expected_tx_seq_offset < 0)
3924 expected_tx_seq_offset += 64;
3925
3926 /* duplicated tx_seq */
3927 if (tx_seq_offset < expected_tx_seq_offset)
3928 goto drop;
3929
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003930 pi->conn_state |= L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003931
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003932 BT_DBG("sk %p, Enter SREJ", sk);
3933
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003934 INIT_LIST_HEAD(SREJ_LIST(sk));
3935 pi->buffer_seq_srej = pi->buffer_seq;
3936
3937 __skb_queue_head_init(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003938 __skb_queue_head_init(BUSY_QUEUE(sk));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003939 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3940
Gustavo F. Padovanef54fd92009-08-20 22:26:04 -03003941 pi->conn_state |= L2CAP_CONN_SEND_PBIT;
3942
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003943 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan7fe9b292010-05-12 18:32:04 -03003944
3945 del_timer(&pi->ack_timer);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003946 }
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003947 return 0;
3948
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003949expected:
3950 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
3951
3952 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
Gustavo F. Padovan3b1a9f32010-05-01 16:15:42 -03003953 bt_cb(skb)->tx_seq = tx_seq;
3954 bt_cb(skb)->sar = sar;
3955 __skb_queue_tail(SREJ_QUEUE(sk), skb);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003956 return 0;
3957 }
3958
Gustavo F. Padovan2ece3682010-06-16 17:21:44 -03003959 err = l2cap_push_rx_skb(sk, skb, rx_control);
3960 if (err < 0)
3961 return 0;
3962
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03003963 if (rx_control & L2CAP_CTRL_FINAL) {
3964 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3965 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003966 else
3967 l2cap_retransmit_frames(sk);
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03003968 }
3969
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003970 __mod_ack_timer();
3971
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03003972 pi->num_acked = (pi->num_acked + 1) % num_to_ack;
3973 if (pi->num_acked == num_to_ack - 1)
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03003974 l2cap_send_ack(pi);
3975
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003976 return 0;
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003977
3978drop:
3979 kfree_skb(skb);
3980 return 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003981}
3982
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003983static inline void l2cap_data_channel_rrframe(struct sock *sk, u16 rx_control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003984{
3985 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan6e3a5982010-05-01 16:15:38 -03003986
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03003987 BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, __get_reqseq(rx_control),
3988 rx_control);
3989
Gustavo F. Padovan6e3a5982010-05-01 16:15:38 -03003990 pi->expected_ack_seq = __get_reqseq(rx_control);
3991 l2cap_drop_acked_frames(sk);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003992
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003993 if (rx_control & L2CAP_CTRL_POLL) {
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03003994 pi->conn_state |= L2CAP_CONN_SEND_FBIT;
Gustavo F. Padovan05fbd892010-05-01 16:15:39 -03003995 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3996 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
3997 (pi->unacked_frames > 0))
3998 __mod_retrans_timer();
3999
4000 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
4001 l2cap_send_srejtail(sk);
4002 } else {
4003 l2cap_send_i_or_rr_or_rnr(sk);
Gustavo F. Padovan05fbd892010-05-01 16:15:39 -03004004 }
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004005
4006 } else if (rx_control & L2CAP_CTRL_FINAL) {
4007 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004008
4009 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
4010 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004011 else
4012 l2cap_retransmit_frames(sk);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004013
4014 } else {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004015 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
4016 (pi->unacked_frames > 0))
4017 __mod_retrans_timer();
4018
4019 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004020 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004021 l2cap_send_ack(pi);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004022 } else {
4023 spin_lock_bh(&pi->send_lock);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004024 l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004025 spin_unlock_bh(&pi->send_lock);
4026 }
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004027 }
4028}
4029
4030static inline void l2cap_data_channel_rejframe(struct sock *sk, u16 rx_control)
4031{
4032 struct l2cap_pinfo *pi = l2cap_pi(sk);
4033 u8 tx_seq = __get_reqseq(rx_control);
4034
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03004035 BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, tx_seq, rx_control);
4036
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004037 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
4038
Gustavo F. Padovan8abb52e2010-05-01 16:15:38 -03004039 pi->expected_ack_seq = tx_seq;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004040 l2cap_drop_acked_frames(sk);
4041
4042 if (rx_control & L2CAP_CTRL_FINAL) {
4043 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
4044 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004045 else
4046 l2cap_retransmit_frames(sk);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004047 } else {
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004048 l2cap_retransmit_frames(sk);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004049
Gustavo F. Padovan0301ef02010-05-05 20:56:43 -03004050 if (pi->conn_state & L2CAP_CONN_WAIT_F)
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004051 pi->conn_state |= L2CAP_CONN_REJ_ACT;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004052 }
4053}
4054static inline void l2cap_data_channel_srejframe(struct sock *sk, u16 rx_control)
4055{
4056 struct l2cap_pinfo *pi = l2cap_pi(sk);
4057 u8 tx_seq = __get_reqseq(rx_control);
4058
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03004059 BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, tx_seq, rx_control);
4060
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004061 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
4062
4063 if (rx_control & L2CAP_CTRL_POLL) {
4064 pi->expected_ack_seq = tx_seq;
4065 l2cap_drop_acked_frames(sk);
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03004066
4067 pi->conn_state |= L2CAP_CONN_SEND_FBIT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004068 l2cap_retransmit_one_frame(sk, tx_seq);
4069
4070 spin_lock_bh(&pi->send_lock);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004071 l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004072 spin_unlock_bh(&pi->send_lock);
4073
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004074 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
4075 pi->srej_save_reqseq = tx_seq;
4076 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
4077 }
4078 } else if (rx_control & L2CAP_CTRL_FINAL) {
4079 if ((pi->conn_state & L2CAP_CONN_SREJ_ACT) &&
4080 pi->srej_save_reqseq == tx_seq)
4081 pi->conn_state &= ~L2CAP_CONN_SREJ_ACT;
4082 else
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004083 l2cap_retransmit_one_frame(sk, tx_seq);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004084 } else {
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004085 l2cap_retransmit_one_frame(sk, tx_seq);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004086 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
4087 pi->srej_save_reqseq = tx_seq;
4088 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
4089 }
4090 }
4091}
4092
4093static inline void l2cap_data_channel_rnrframe(struct sock *sk, u16 rx_control)
4094{
4095 struct l2cap_pinfo *pi = l2cap_pi(sk);
4096 u8 tx_seq = __get_reqseq(rx_control);
4097
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03004098 BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, tx_seq, rx_control);
4099
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004100 pi->conn_state |= L2CAP_CONN_REMOTE_BUSY;
4101 pi->expected_ack_seq = tx_seq;
4102 l2cap_drop_acked_frames(sk);
4103
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03004104 if (rx_control & L2CAP_CTRL_POLL)
4105 pi->conn_state |= L2CAP_CONN_SEND_FBIT;
4106
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03004107 if (!(pi->conn_state & L2CAP_CONN_SREJ_SENT)) {
4108 del_timer(&pi->retrans_timer);
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -03004109 if (rx_control & L2CAP_CTRL_POLL)
4110 l2cap_send_rr_or_rnr(pi, L2CAP_CTRL_FINAL);
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03004111 return;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004112 }
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03004113
4114 if (rx_control & L2CAP_CTRL_POLL)
4115 l2cap_send_srejtail(sk);
4116 else
4117 l2cap_send_sframe(pi, L2CAP_SUPER_RCV_READY);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004118}
4119
4120static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
4121{
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004122 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
4123
Gustavo F. Padovan9b16dc62010-05-05 20:05:57 -03004124 if (L2CAP_CTRL_FINAL & rx_control &&
4125 l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004126 del_timer(&l2cap_pi(sk)->monitor_timer);
4127 if (l2cap_pi(sk)->unacked_frames > 0)
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03004128 __mod_retrans_timer();
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004129 l2cap_pi(sk)->conn_state &= ~L2CAP_CONN_WAIT_F;
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03004130 }
4131
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004132 switch (rx_control & L2CAP_CTRL_SUPERVISE) {
4133 case L2CAP_SUPER_RCV_READY:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004134 l2cap_data_channel_rrframe(sk, rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004135 break;
4136
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004137 case L2CAP_SUPER_REJECT:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004138 l2cap_data_channel_rejframe(sk, rx_control);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03004139 break;
4140
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004141 case L2CAP_SUPER_SELECT_REJECT:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004142 l2cap_data_channel_srejframe(sk, rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004143 break;
4144
4145 case L2CAP_SUPER_RCV_NOT_READY:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004146 l2cap_data_channel_rnrframe(sk, rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004147 break;
4148 }
4149
Gustavo F. Padovanfaaebd12010-05-01 16:15:35 -03004150 kfree_skb(skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004151 return 0;
4152}
4153
Linus Torvalds1da177e2005-04-16 15:20:36 -07004154static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk_buff *skb)
4155{
4156 struct sock *sk;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004157 struct l2cap_pinfo *pi;
Nathan Holstein51893f82010-06-09 15:46:25 -04004158 u16 control;
Gustavo F. Padovanf6337c72010-05-10 18:32:04 -03004159 u8 tx_seq, req_seq;
Nathan Holstein51893f82010-06-09 15:46:25 -04004160 int len, next_tx_seq_offset, req_seq_offset;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004161
4162 sk = l2cap_get_chan_by_scid(&conn->chan_list, cid);
4163 if (!sk) {
4164 BT_DBG("unknown cid 0x%4.4x", cid);
4165 goto drop;
4166 }
4167
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004168 pi = l2cap_pi(sk);
4169
Linus Torvalds1da177e2005-04-16 15:20:36 -07004170 BT_DBG("sk %p, len %d", sk, skb->len);
4171
4172 if (sk->sk_state != BT_CONNECTED)
4173 goto drop;
4174
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004175 switch (pi->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004176 case L2CAP_MODE_BASIC:
4177 /* If socket recv buffers overflows we drop data here
4178 * which is *bad* because L2CAP has to be reliable.
4179 * But we don't have any other choice. L2CAP doesn't
4180 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07004181
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004182 if (pi->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004183 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004184
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004185 if (!sock_queue_rcv_skb(sk, skb))
4186 goto done;
4187 break;
4188
4189 case L2CAP_MODE_ERTM:
4190 control = get_unaligned_le16(skb->data);
4191 skb_pull(skb, 2);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03004192 len = skb->len;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004193
Gustavo F. Padovan26000082010-05-11 22:02:00 -03004194 /*
4195 * We can just drop the corrupted I-frame here.
4196 * Receiver will miss it and start proper recovery
4197 * procedures and ask retransmission.
4198 */
4199 if (l2cap_check_fcs(pi, skb))
4200 goto drop;
4201
Gustavo F. Padovanbc1b1f82010-05-11 22:14:00 -03004202 if (__is_sar_start(control) && __is_iframe(control))
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03004203 len -= 2;
4204
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004205 if (pi->fcs == L2CAP_FCS_CRC16)
4206 len -= 2;
4207
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004208 if (len > pi->mps) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03004209 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004210 goto drop;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004211 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004212
João Paulo Rechi Vita01760bd2010-05-01 16:15:43 -03004213 req_seq = __get_reqseq(control);
4214 req_seq_offset = (req_seq - pi->expected_ack_seq) % 64;
4215 if (req_seq_offset < 0)
4216 req_seq_offset += 64;
4217
4218 next_tx_seq_offset =
4219 (pi->next_tx_seq - pi->expected_ack_seq) % 64;
4220 if (next_tx_seq_offset < 0)
4221 next_tx_seq_offset += 64;
4222
4223 /* check for invalid req-seq */
4224 if (req_seq_offset > next_tx_seq_offset) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03004225 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
João Paulo Rechi Vita01760bd2010-05-01 16:15:43 -03004226 goto drop;
4227 }
4228
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004229 if (__is_iframe(control)) {
Nathan Holstein51893f82010-06-09 15:46:25 -04004230 if (len < 0) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03004231 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004232 goto drop;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004233 }
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004234
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02004235 l2cap_data_channel_iframe(sk, control, skb);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004236 } else {
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004237 if (len != 0) {
Gustavo F. Padovan9b108fc2010-05-20 16:21:53 -03004238 l2cap_send_disconn_req(pi->conn, sk, ECONNRESET);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004239 goto drop;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004240 }
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004241
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02004242 l2cap_data_channel_sframe(sk, control, skb);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004243 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004244
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02004245 goto done;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004246
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004247 case L2CAP_MODE_STREAMING:
4248 control = get_unaligned_le16(skb->data);
4249 skb_pull(skb, 2);
4250 len = skb->len;
4251
Gustavo F. Padovan26000082010-05-11 22:02:00 -03004252 if (l2cap_check_fcs(pi, skb))
4253 goto drop;
4254
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004255 if (__is_sar_start(control))
4256 len -= 2;
4257
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004258 if (pi->fcs == L2CAP_FCS_CRC16)
4259 len -= 2;
4260
Nathan Holstein51893f82010-06-09 15:46:25 -04004261 if (len > pi->mps || len < 0 || __is_sframe(control))
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004262 goto drop;
4263
4264 tx_seq = __get_txseq(control);
4265
4266 if (pi->expected_tx_seq == tx_seq)
4267 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
4268 else
Gustavo F. Padovan7dffe422010-05-01 16:15:36 -03004269 pi->expected_tx_seq = (tx_seq + 1) % 64;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004270
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004271 l2cap_streaming_reassembly_sdu(sk, skb, control);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004272
4273 goto done;
4274
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004275 default:
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03004276 BT_DBG("sk %p: bad mode 0x%2.2x", sk, pi->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004277 break;
4278 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004279
4280drop:
4281 kfree_skb(skb);
4282
4283done:
Marcel Holtmann01394182006-07-03 10:02:46 +02004284 if (sk)
4285 bh_unlock_sock(sk);
4286
Linus Torvalds1da177e2005-04-16 15:20:36 -07004287 return 0;
4288}
4289
Al Viro8e036fc2007-07-29 00:16:36 -07004290static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004291{
4292 struct sock *sk;
4293
4294 sk = l2cap_get_sock_by_psm(0, psm, conn->src);
4295 if (!sk)
4296 goto drop;
4297
4298 BT_DBG("sk %p, len %d", sk, skb->len);
4299
4300 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_CONNECTED)
4301 goto drop;
4302
4303 if (l2cap_pi(sk)->imtu < skb->len)
4304 goto drop;
4305
4306 if (!sock_queue_rcv_skb(sk, skb))
4307 goto done;
4308
4309drop:
4310 kfree_skb(skb);
4311
4312done:
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03004313 if (sk)
4314 bh_unlock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004315 return 0;
4316}
4317
4318static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
4319{
4320 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07004321 u16 cid, len;
4322 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004323
4324 skb_pull(skb, L2CAP_HDR_SIZE);
4325 cid = __le16_to_cpu(lh->cid);
4326 len = __le16_to_cpu(lh->len);
4327
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004328 if (len != skb->len) {
4329 kfree_skb(skb);
4330 return;
4331 }
4332
Linus Torvalds1da177e2005-04-16 15:20:36 -07004333 BT_DBG("len %d, cid 0x%4.4x", len, cid);
4334
4335 switch (cid) {
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03004336 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07004337 l2cap_sig_channel(conn, skb);
4338 break;
4339
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03004340 case L2CAP_CID_CONN_LESS:
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03004341 psm = get_unaligned_le16(skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004342 skb_pull(skb, 2);
4343 l2cap_conless_channel(conn, psm, skb);
4344 break;
4345
4346 default:
4347 l2cap_data_channel(conn, cid, skb);
4348 break;
4349 }
4350}
4351
4352/* ---- L2CAP interface with lower layer (HCI) ---- */
4353
4354static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
4355{
4356 int exact = 0, lm1 = 0, lm2 = 0;
4357 register struct sock *sk;
4358 struct hlist_node *node;
4359
4360 if (type != ACL_LINK)
4361 return 0;
4362
4363 BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
4364
4365 /* Find listening sockets and check their link_mode */
4366 read_lock(&l2cap_sk_list.lock);
4367 sk_for_each(sk, node, &l2cap_sk_list.head) {
4368 if (sk->sk_state != BT_LISTEN)
4369 continue;
4370
4371 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01004372 lm1 |= HCI_LM_ACCEPT;
4373 if (l2cap_pi(sk)->role_switch)
4374 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004375 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01004376 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
4377 lm2 |= HCI_LM_ACCEPT;
4378 if (l2cap_pi(sk)->role_switch)
4379 lm2 |= HCI_LM_MASTER;
4380 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004381 }
4382 read_unlock(&l2cap_sk_list.lock);
4383
4384 return exact ? lm1 : lm2;
4385}
4386
4387static int l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
4388{
Marcel Holtmann01394182006-07-03 10:02:46 +02004389 struct l2cap_conn *conn;
4390
Linus Torvalds1da177e2005-04-16 15:20:36 -07004391 BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
4392
4393 if (hcon->type != ACL_LINK)
4394 return 0;
4395
4396 if (!status) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004397 conn = l2cap_conn_add(hcon, status);
4398 if (conn)
4399 l2cap_conn_ready(conn);
Marcel Holtmann01394182006-07-03 10:02:46 +02004400 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -07004401 l2cap_conn_del(hcon, bt_err(status));
4402
4403 return 0;
4404}
4405
Marcel Holtmann2950f212009-02-12 14:02:50 +01004406static int l2cap_disconn_ind(struct hci_conn *hcon)
4407{
4408 struct l2cap_conn *conn = hcon->l2cap_data;
4409
4410 BT_DBG("hcon %p", hcon);
4411
4412 if (hcon->type != ACL_LINK || !conn)
4413 return 0x13;
4414
4415 return conn->disc_reason;
4416}
4417
4418static int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004419{
4420 BT_DBG("hcon %p reason %d", hcon, reason);
4421
4422 if (hcon->type != ACL_LINK)
4423 return 0;
4424
4425 l2cap_conn_del(hcon, bt_err(reason));
Marcel Holtmann01394182006-07-03 10:02:46 +02004426
Linus Torvalds1da177e2005-04-16 15:20:36 -07004427 return 0;
4428}
4429
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004430static inline void l2cap_check_encryption(struct sock *sk, u8 encrypt)
4431{
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03004432 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM)
Marcel Holtmann255c7602009-02-04 21:07:19 +01004433 return;
4434
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004435 if (encrypt == 0x00) {
4436 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM) {
4437 l2cap_sock_clear_timer(sk);
4438 l2cap_sock_set_timer(sk, HZ * 5);
4439 } else if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
4440 __l2cap_sock_close(sk, ECONNREFUSED);
4441 } else {
4442 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM)
4443 l2cap_sock_clear_timer(sk);
4444 }
4445}
4446
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004447static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004448{
4449 struct l2cap_chan_list *l;
Marcel Holtmann40be4922008-07-14 20:13:50 +02004450 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004451 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004452
Marcel Holtmann01394182006-07-03 10:02:46 +02004453 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004454 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02004455
Linus Torvalds1da177e2005-04-16 15:20:36 -07004456 l = &conn->chan_list;
4457
4458 BT_DBG("conn %p", conn);
4459
4460 read_lock(&l->lock);
4461
4462 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
4463 bh_lock_sock(sk);
4464
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01004465 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND) {
4466 bh_unlock_sock(sk);
4467 continue;
4468 }
4469
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004470 if (!status && (sk->sk_state == BT_CONNECTED ||
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004471 sk->sk_state == BT_CONFIG)) {
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004472 l2cap_check_encryption(sk, encrypt);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02004473 bh_unlock_sock(sk);
4474 continue;
4475 }
4476
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004477 if (sk->sk_state == BT_CONNECT) {
4478 if (!status) {
4479 struct l2cap_conn_req req;
4480 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
4481 req.psm = l2cap_pi(sk)->psm;
4482
4483 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03004484 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004485
4486 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
4487 L2CAP_CONN_REQ, sizeof(req), &req);
4488 } else {
4489 l2cap_sock_clear_timer(sk);
4490 l2cap_sock_set_timer(sk, HZ / 10);
4491 }
4492 } else if (sk->sk_state == BT_CONNECT2) {
4493 struct l2cap_conn_rsp rsp;
4494 __u16 result;
4495
4496 if (!status) {
4497 sk->sk_state = BT_CONFIG;
4498 result = L2CAP_CR_SUCCESS;
4499 } else {
4500 sk->sk_state = BT_DISCONN;
4501 l2cap_sock_set_timer(sk, HZ / 10);
4502 result = L2CAP_CR_SEC_BLOCK;
4503 }
4504
4505 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
4506 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
4507 rsp.result = cpu_to_le16(result);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02004508 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004509 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
4510 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004511 }
4512
Linus Torvalds1da177e2005-04-16 15:20:36 -07004513 bh_unlock_sock(sk);
4514 }
4515
4516 read_unlock(&l->lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004517
Linus Torvalds1da177e2005-04-16 15:20:36 -07004518 return 0;
4519}
4520
4521static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
4522{
4523 struct l2cap_conn *conn = hcon->l2cap_data;
4524
4525 if (!conn && !(conn = l2cap_conn_add(hcon, 0)))
4526 goto drop;
4527
4528 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
4529
4530 if (flags & ACL_START) {
4531 struct l2cap_hdr *hdr;
4532 int len;
4533
4534 if (conn->rx_len) {
4535 BT_ERR("Unexpected start frame (len %d)", skb->len);
4536 kfree_skb(conn->rx_skb);
4537 conn->rx_skb = NULL;
4538 conn->rx_len = 0;
4539 l2cap_conn_unreliable(conn, ECOMM);
4540 }
4541
4542 if (skb->len < 2) {
4543 BT_ERR("Frame is too short (len %d)", skb->len);
4544 l2cap_conn_unreliable(conn, ECOMM);
4545 goto drop;
4546 }
4547
4548 hdr = (struct l2cap_hdr *) skb->data;
4549 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
4550
4551 if (len == skb->len) {
4552 /* Complete frame received */
4553 l2cap_recv_frame(conn, skb);
4554 return 0;
4555 }
4556
4557 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
4558
4559 if (skb->len > len) {
4560 BT_ERR("Frame is too long (len %d, expected len %d)",
4561 skb->len, len);
4562 l2cap_conn_unreliable(conn, ECOMM);
4563 goto drop;
4564 }
4565
4566 /* Allocate skb for the complete frame (with header) */
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03004567 conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC);
4568 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004569 goto drop;
4570
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03004571 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004572 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004573 conn->rx_len = len - skb->len;
4574 } else {
4575 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
4576
4577 if (!conn->rx_len) {
4578 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
4579 l2cap_conn_unreliable(conn, ECOMM);
4580 goto drop;
4581 }
4582
4583 if (skb->len > conn->rx_len) {
4584 BT_ERR("Fragment is too long (len %d, expected %d)",
4585 skb->len, conn->rx_len);
4586 kfree_skb(conn->rx_skb);
4587 conn->rx_skb = NULL;
4588 conn->rx_len = 0;
4589 l2cap_conn_unreliable(conn, ECOMM);
4590 goto drop;
4591 }
4592
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03004593 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004594 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004595 conn->rx_len -= skb->len;
4596
4597 if (!conn->rx_len) {
4598 /* Complete frame received */
4599 l2cap_recv_frame(conn, conn->rx_skb);
4600 conn->rx_skb = NULL;
4601 }
4602 }
4603
4604drop:
4605 kfree_skb(skb);
4606 return 0;
4607}
4608
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004609static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004610{
4611 struct sock *sk;
4612 struct hlist_node *node;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004613
4614 read_lock_bh(&l2cap_sk_list.lock);
4615
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004616 sk_for_each(sk, node, &l2cap_sk_list.head) {
4617 struct l2cap_pinfo *pi = l2cap_pi(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004618
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004619 seq_printf(f, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d\n",
4620 batostr(&bt_sk(sk)->src),
4621 batostr(&bt_sk(sk)->dst),
4622 sk->sk_state, __le16_to_cpu(pi->psm),
4623 pi->scid, pi->dcid,
4624 pi->imtu, pi->omtu, pi->sec_level);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004625 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004626
Linus Torvalds1da177e2005-04-16 15:20:36 -07004627 read_unlock_bh(&l2cap_sk_list.lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004628
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004629 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004630}
4631
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004632static int l2cap_debugfs_open(struct inode *inode, struct file *file)
4633{
4634 return single_open(file, l2cap_debugfs_show, inode->i_private);
4635}
4636
4637static const struct file_operations l2cap_debugfs_fops = {
4638 .open = l2cap_debugfs_open,
4639 .read = seq_read,
4640 .llseek = seq_lseek,
4641 .release = single_release,
4642};
4643
4644static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004645
Eric Dumazet90ddc4f2005-12-22 12:49:22 -08004646static const struct proto_ops l2cap_sock_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004647 .family = PF_BLUETOOTH,
4648 .owner = THIS_MODULE,
4649 .release = l2cap_sock_release,
4650 .bind = l2cap_sock_bind,
4651 .connect = l2cap_sock_connect,
4652 .listen = l2cap_sock_listen,
4653 .accept = l2cap_sock_accept,
4654 .getname = l2cap_sock_getname,
4655 .sendmsg = l2cap_sock_sendmsg,
Marcel Holtmannf66dc812009-01-15 21:57:00 +01004656 .recvmsg = l2cap_sock_recvmsg,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004657 .poll = bt_sock_poll,
Marcel Holtmann3241ad82008-07-14 20:13:50 +02004658 .ioctl = bt_sock_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004659 .mmap = sock_no_mmap,
4660 .socketpair = sock_no_socketpair,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004661 .shutdown = l2cap_sock_shutdown,
4662 .setsockopt = l2cap_sock_setsockopt,
4663 .getsockopt = l2cap_sock_getsockopt
4664};
4665
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +00004666static const struct net_proto_family l2cap_sock_family_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004667 .family = PF_BLUETOOTH,
4668 .owner = THIS_MODULE,
4669 .create = l2cap_sock_create,
4670};
4671
4672static struct hci_proto l2cap_hci_proto = {
4673 .name = "L2CAP",
4674 .id = HCI_PROTO_L2CAP,
4675 .connect_ind = l2cap_connect_ind,
4676 .connect_cfm = l2cap_connect_cfm,
4677 .disconn_ind = l2cap_disconn_ind,
Marcel Holtmann2950f212009-02-12 14:02:50 +01004678 .disconn_cfm = l2cap_disconn_cfm,
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004679 .security_cfm = l2cap_security_cfm,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004680 .recv_acldata = l2cap_recv_acldata
4681};
4682
4683static int __init l2cap_init(void)
4684{
4685 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004686
Linus Torvalds1da177e2005-04-16 15:20:36 -07004687 err = proto_register(&l2cap_proto, 0);
4688 if (err < 0)
4689 return err;
4690
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004691 _busy_wq = create_singlethread_workqueue("l2cap");
4692 if (!_busy_wq)
4693 goto error;
4694
Linus Torvalds1da177e2005-04-16 15:20:36 -07004695 err = bt_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops);
4696 if (err < 0) {
4697 BT_ERR("L2CAP socket registration failed");
4698 goto error;
4699 }
4700
4701 err = hci_register_proto(&l2cap_hci_proto);
4702 if (err < 0) {
4703 BT_ERR("L2CAP protocol registration failed");
4704 bt_sock_unregister(BTPROTO_L2CAP);
4705 goto error;
4706 }
4707
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004708 if (bt_debugfs) {
4709 l2cap_debugfs = debugfs_create_file("l2cap", 0444,
4710 bt_debugfs, NULL, &l2cap_debugfs_fops);
4711 if (!l2cap_debugfs)
4712 BT_ERR("Failed to create L2CAP debug file");
4713 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004714
4715 BT_INFO("L2CAP ver %s", VERSION);
4716 BT_INFO("L2CAP socket layer initialized");
4717
4718 return 0;
4719
4720error:
4721 proto_unregister(&l2cap_proto);
4722 return err;
4723}
4724
4725static void __exit l2cap_exit(void)
4726{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004727 debugfs_remove(l2cap_debugfs);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004728
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004729 flush_workqueue(_busy_wq);
4730 destroy_workqueue(_busy_wq);
4731
Linus Torvalds1da177e2005-04-16 15:20:36 -07004732 if (bt_sock_unregister(BTPROTO_L2CAP) < 0)
4733 BT_ERR("L2CAP socket unregistration failed");
4734
4735 if (hci_unregister_proto(&l2cap_hci_proto) < 0)
4736 BT_ERR("L2CAP protocol unregistration failed");
4737
4738 proto_unregister(&l2cap_proto);
4739}
4740
4741void l2cap_load(void)
4742{
4743 /* Dummy function to trigger automatic L2CAP module loading by
4744 * other modules that use L2CAP sockets but don't use any other
4745 * symbols from it. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07004746}
4747EXPORT_SYMBOL(l2cap_load);
4748
4749module_init(l2cap_init);
4750module_exit(l2cap_exit);
4751
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07004752module_param(enable_ertm, bool, 0644);
4753MODULE_PARM_DESC(enable_ertm, "Enable enhanced retransmission mode");
4754
Marcel Holtmann63fbd242008-08-18 13:23:53 +02004755MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004756MODULE_DESCRIPTION("Bluetooth L2CAP ver " VERSION);
4757MODULE_VERSION(VERSION);
4758MODULE_LICENSE("GPL");
4759MODULE_ALIAS("bt-proto-0");