blob: 7c22737329092a867970cee630ccb0eec2e63a1d [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 Holtmannb1235d7962008-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 Holtmannb1235d7962008-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 Holtmannb1235d7962008-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 Holtmannb1235d7962008-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. Padovan1c2acffb72009-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. Padovan1c2acffb72009-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. Padovan1c2acffb72009-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. Padovan1c2acffb72009-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. Padovan1c2acffb72009-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. Padovan1c2acffb72009-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. Padovan1c2acffb72009-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 Holtmannb1235d7962008-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 Holtmannb1235d7962008-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 Holtmannb1235d7962008-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 Holtmannb1235d7962008-07-14 20:13:54 +0200443 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200444 } else {
445 struct l2cap_info_req req;
446 req.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
447
448 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
449 conn->info_ident = l2cap_get_ident(conn);
450
451 mod_timer(&conn->info_timer, jiffies +
452 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
453
454 l2cap_send_cmd(conn, conn->info_ident,
455 L2CAP_INFO_REQ, sizeof(req), &req);
456 }
457}
458
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300459static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct sock *sk)
460{
461 struct l2cap_disconn_req req;
462
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300463 if (!conn)
464 return;
465
466 skb_queue_purge(TX_QUEUE(sk));
467
468 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
469 del_timer(&l2cap_pi(sk)->retrans_timer);
470 del_timer(&l2cap_pi(sk)->monitor_timer);
471 del_timer(&l2cap_pi(sk)->ack_timer);
472 }
473
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300474 req.dcid = cpu_to_le16(l2cap_pi(sk)->dcid);
475 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
476 l2cap_send_cmd(conn, l2cap_get_ident(conn),
477 L2CAP_DISCONN_REQ, sizeof(req), &req);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300478
479 sk->sk_state = BT_DISCONN;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300480}
481
Linus Torvalds1da177e2005-04-16 15:20:36 -0700482/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200483static void l2cap_conn_start(struct l2cap_conn *conn)
484{
485 struct l2cap_chan_list *l = &conn->chan_list;
486 struct sock *sk;
487
488 BT_DBG("conn %p", conn);
489
490 read_lock(&l->lock);
491
492 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
493 bh_lock_sock(sk);
494
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300495 if (sk->sk_type != SOCK_SEQPACKET &&
496 sk->sk_type != SOCK_STREAM) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200497 bh_unlock_sock(sk);
498 continue;
499 }
500
501 if (sk->sk_state == BT_CONNECT) {
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300502 if (l2cap_check_security(sk) &&
503 __l2cap_no_conn_pending(sk)) {
Marcel Holtmannb1235d7962008-07-14 20:13:54 +0200504 struct l2cap_conn_req req;
505 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
506 req.psm = l2cap_pi(sk)->psm;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200507
Marcel Holtmannb1235d7962008-07-14 20:13:54 +0200508 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300509 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200510
Marcel Holtmannb1235d7962008-07-14 20:13:54 +0200511 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200512 L2CAP_CONN_REQ, sizeof(req), &req);
Marcel Holtmannb1235d7962008-07-14 20:13:54 +0200513 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200514 } else if (sk->sk_state == BT_CONNECT2) {
515 struct l2cap_conn_rsp rsp;
516 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
517 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
518
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100519 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100520 if (bt_sk(sk)->defer_setup) {
521 struct sock *parent = bt_sk(sk)->parent;
522 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
523 rsp.status = cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
524 parent->sk_data_ready(parent, 0);
525
526 } else {
527 sk->sk_state = BT_CONFIG;
528 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
529 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
530 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200531 } else {
532 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
533 rsp.status = cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
534 }
535
536 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
537 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
538 }
539
540 bh_unlock_sock(sk);
541 }
542
543 read_unlock(&l->lock);
544}
545
546static void l2cap_conn_ready(struct l2cap_conn *conn)
547{
548 struct l2cap_chan_list *l = &conn->chan_list;
549 struct sock *sk;
550
551 BT_DBG("conn %p", conn);
552
553 read_lock(&l->lock);
554
555 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
556 bh_lock_sock(sk);
557
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300558 if (sk->sk_type != SOCK_SEQPACKET &&
559 sk->sk_type != SOCK_STREAM) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200560 l2cap_sock_clear_timer(sk);
561 sk->sk_state = BT_CONNECTED;
562 sk->sk_state_change(sk);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200563 } else if (sk->sk_state == BT_CONNECT)
564 l2cap_do_start(sk);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200565
566 bh_unlock_sock(sk);
567 }
568
569 read_unlock(&l->lock);
570}
571
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200572/* Notify sockets that we cannot guaranty reliability anymore */
573static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
574{
575 struct l2cap_chan_list *l = &conn->chan_list;
576 struct sock *sk;
577
578 BT_DBG("conn %p", conn);
579
580 read_lock(&l->lock);
581
582 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100583 if (l2cap_pi(sk)->force_reliable)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200584 sk->sk_err = err;
585 }
586
587 read_unlock(&l->lock);
588}
589
590static void l2cap_info_timeout(unsigned long arg)
591{
592 struct l2cap_conn *conn = (void *) arg;
593
Marcel Holtmann984947d2009-02-06 23:35:19 +0100594 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +0100595 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +0100596
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200597 l2cap_conn_start(conn);
598}
599
Linus Torvalds1da177e2005-04-16 15:20:36 -0700600static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
601{
Marcel Holtmann01394182006-07-03 10:02:46 +0200602 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700603
Marcel Holtmann01394182006-07-03 10:02:46 +0200604 if (conn || status)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700605 return conn;
606
Marcel Holtmann01394182006-07-03 10:02:46 +0200607 conn = kzalloc(sizeof(struct l2cap_conn), GFP_ATOMIC);
608 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700609 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700610
611 hcon->l2cap_data = conn;
612 conn->hcon = hcon;
613
Marcel Holtmann01394182006-07-03 10:02:46 +0200614 BT_DBG("hcon %p conn %p", hcon, conn);
615
Linus Torvalds1da177e2005-04-16 15:20:36 -0700616 conn->mtu = hcon->hdev->acl_mtu;
617 conn->src = &hcon->hdev->bdaddr;
618 conn->dst = &hcon->dst;
619
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200620 conn->feat_mask = 0;
621
Linus Torvalds1da177e2005-04-16 15:20:36 -0700622 spin_lock_init(&conn->lock);
623 rwlock_init(&conn->chan_list.lock);
624
Dave Young45054dc2009-10-18 20:28:30 +0000625 setup_timer(&conn->info_timer, l2cap_info_timeout,
626 (unsigned long) conn);
627
Marcel Holtmann2950f212009-02-12 14:02:50 +0100628 conn->disc_reason = 0x13;
629
Linus Torvalds1da177e2005-04-16 15:20:36 -0700630 return conn;
631}
632
Marcel Holtmann01394182006-07-03 10:02:46 +0200633static void l2cap_conn_del(struct hci_conn *hcon, int err)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700634{
Marcel Holtmann01394182006-07-03 10:02:46 +0200635 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700636 struct sock *sk;
637
Marcel Holtmann01394182006-07-03 10:02:46 +0200638 if (!conn)
639 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700640
641 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
642
Wei Yongjun7585b972009-02-25 18:29:52 +0800643 kfree_skb(conn->rx_skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700644
645 /* Kill channels */
646 while ((sk = conn->chan_list.head)) {
647 bh_lock_sock(sk);
648 l2cap_chan_del(sk, err);
649 bh_unlock_sock(sk);
650 l2cap_sock_kill(sk);
651 }
652
Dave Young8e8440f2008-03-03 12:18:55 -0800653 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
654 del_timer_sync(&conn->info_timer);
Thomas Gleixner3ab22732008-02-26 17:42:56 -0800655
Linus Torvalds1da177e2005-04-16 15:20:36 -0700656 hcon->l2cap_data = NULL;
657 kfree(conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700658}
659
660static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
661{
662 struct l2cap_chan_list *l = &conn->chan_list;
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200663 write_lock_bh(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700664 __l2cap_chan_add(conn, sk, parent);
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200665 write_unlock_bh(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700666}
667
Linus Torvalds1da177e2005-04-16 15:20:36 -0700668/* ---- Socket interface ---- */
Al Viro8e036fc2007-07-29 00:16:36 -0700669static struct sock *__l2cap_get_sock_by_addr(__le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700670{
671 struct sock *sk;
672 struct hlist_node *node;
673 sk_for_each(sk, node, &l2cap_sk_list.head)
674 if (l2cap_pi(sk)->sport == psm && !bacmp(&bt_sk(sk)->src, src))
675 goto found;
676 sk = NULL;
677found:
678 return sk;
679}
680
681/* Find socket with psm and source bdaddr.
682 * Returns closest match.
683 */
Al Viro8e036fc2007-07-29 00:16:36 -0700684static struct sock *__l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700685{
686 struct sock *sk = NULL, *sk1 = NULL;
687 struct hlist_node *node;
688
689 sk_for_each(sk, node, &l2cap_sk_list.head) {
690 if (state && sk->sk_state != state)
691 continue;
692
693 if (l2cap_pi(sk)->psm == psm) {
694 /* Exact match. */
695 if (!bacmp(&bt_sk(sk)->src, src))
696 break;
697
698 /* Closest match */
699 if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY))
700 sk1 = sk;
701 }
702 }
703 return node ? sk : sk1;
704}
705
706/* Find socket with given address (psm, src).
707 * Returns locked socket */
Al Viro8e036fc2007-07-29 00:16:36 -0700708static inline struct sock *l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700709{
710 struct sock *s;
711 read_lock(&l2cap_sk_list.lock);
712 s = __l2cap_get_sock_by_psm(state, psm, src);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300713 if (s)
714 bh_lock_sock(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700715 read_unlock(&l2cap_sk_list.lock);
716 return s;
717}
718
719static void l2cap_sock_destruct(struct sock *sk)
720{
721 BT_DBG("sk %p", sk);
722
723 skb_queue_purge(&sk->sk_receive_queue);
724 skb_queue_purge(&sk->sk_write_queue);
725}
726
727static void l2cap_sock_cleanup_listen(struct sock *parent)
728{
729 struct sock *sk;
730
731 BT_DBG("parent %p", parent);
732
733 /* Close not yet accepted channels */
734 while ((sk = bt_accept_dequeue(parent, NULL)))
735 l2cap_sock_close(sk);
736
Marcel Holtmannb1235d7962008-07-14 20:13:54 +0200737 parent->sk_state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700738 sock_set_flag(parent, SOCK_ZAPPED);
739}
740
741/* Kill socket (only if zapped and orphan)
742 * Must be called on unlocked socket.
743 */
744static void l2cap_sock_kill(struct sock *sk)
745{
746 if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket)
747 return;
748
749 BT_DBG("sk %p state %d", sk, sk->sk_state);
750
751 /* Kill poor orphan */
752 bt_sock_unlink(&l2cap_sk_list, sk);
753 sock_set_flag(sk, SOCK_DEAD);
754 sock_put(sk);
755}
756
757static void __l2cap_sock_close(struct sock *sk, int reason)
758{
759 BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket);
760
761 switch (sk->sk_state) {
762 case BT_LISTEN:
763 l2cap_sock_cleanup_listen(sk);
764 break;
765
766 case BT_CONNECTED:
767 case BT_CONFIG:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300768 if (sk->sk_type == SOCK_SEQPACKET ||
769 sk->sk_type == SOCK_STREAM) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700770 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700771
Linus Torvalds1da177e2005-04-16 15:20:36 -0700772 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300773 l2cap_send_disconn_req(conn, sk);
Marcel Holtmannb1235d7962008-07-14 20:13:54 +0200774 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -0700775 l2cap_chan_del(sk, reason);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700776 break;
777
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100778 case BT_CONNECT2:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300779 if (sk->sk_type == SOCK_SEQPACKET ||
780 sk->sk_type == SOCK_STREAM) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100781 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
782 struct l2cap_conn_rsp rsp;
783 __u16 result;
784
785 if (bt_sk(sk)->defer_setup)
786 result = L2CAP_CR_SEC_BLOCK;
787 else
788 result = L2CAP_CR_BAD_PSM;
789
790 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
791 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
792 rsp.result = cpu_to_le16(result);
793 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
794 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
795 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
796 } else
797 l2cap_chan_del(sk, reason);
798 break;
799
Linus Torvalds1da177e2005-04-16 15:20:36 -0700800 case BT_CONNECT:
801 case BT_DISCONN:
802 l2cap_chan_del(sk, reason);
803 break;
804
805 default:
806 sock_set_flag(sk, SOCK_ZAPPED);
807 break;
808 }
809}
810
811/* Must be called on unlocked socket. */
812static void l2cap_sock_close(struct sock *sk)
813{
814 l2cap_sock_clear_timer(sk);
815 lock_sock(sk);
816 __l2cap_sock_close(sk, ECONNRESET);
817 release_sock(sk);
818 l2cap_sock_kill(sk);
819}
820
821static void l2cap_sock_init(struct sock *sk, struct sock *parent)
822{
823 struct l2cap_pinfo *pi = l2cap_pi(sk);
824
825 BT_DBG("sk %p", sk);
826
827 if (parent) {
828 sk->sk_type = parent->sk_type;
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100829 bt_sk(sk)->defer_setup = bt_sk(parent)->defer_setup;
830
Linus Torvalds1da177e2005-04-16 15:20:36 -0700831 pi->imtu = l2cap_pi(parent)->imtu;
832 pi->omtu = l2cap_pi(parent)->omtu;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -0700833 pi->mode = l2cap_pi(parent)->mode;
834 pi->fcs = l2cap_pi(parent)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -0300835 pi->max_tx = l2cap_pi(parent)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -0300836 pi->tx_win = l2cap_pi(parent)->tx_win;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100837 pi->sec_level = l2cap_pi(parent)->sec_level;
838 pi->role_switch = l2cap_pi(parent)->role_switch;
839 pi->force_reliable = l2cap_pi(parent)->force_reliable;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700840 } else {
841 pi->imtu = L2CAP_DEFAULT_MTU;
842 pi->omtu = 0;
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300843 if (enable_ertm && sk->sk_type == SOCK_STREAM)
844 pi->mode = L2CAP_MODE_ERTM;
845 else
846 pi->mode = L2CAP_MODE_BASIC;
Gustavo F. Padovanfd059b92010-05-10 14:22:56 -0300847 pi->max_tx = L2CAP_DEFAULT_MAX_TX;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -0700848 pi->fcs = L2CAP_FCS_CRC16;
Gustavo F. Padovanfd059b92010-05-10 14:22:56 -0300849 pi->tx_win = L2CAP_DEFAULT_TX_WINDOW;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100850 pi->sec_level = BT_SECURITY_LOW;
851 pi->role_switch = 0;
852 pi->force_reliable = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700853 }
854
855 /* Default config options */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +0200856 pi->conf_len = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700857 pi->flush_to = L2CAP_DEFAULT_FLUSH_TO;
Dave Young45054dc2009-10-18 20:28:30 +0000858 skb_queue_head_init(TX_QUEUE(sk));
859 skb_queue_head_init(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -0300860 skb_queue_head_init(BUSY_QUEUE(sk));
Dave Young45054dc2009-10-18 20:28:30 +0000861 INIT_LIST_HEAD(SREJ_LIST(sk));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700862}
863
864static struct proto l2cap_proto = {
865 .name = "L2CAP",
866 .owner = THIS_MODULE,
867 .obj_size = sizeof(struct l2cap_pinfo)
868};
869
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700870static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700871{
872 struct sock *sk;
873
Pavel Emelyanov6257ff22007-11-01 00:39:31 -0700874 sk = sk_alloc(net, PF_BLUETOOTH, prio, &l2cap_proto);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700875 if (!sk)
876 return NULL;
877
878 sock_init_data(sock, sk);
879 INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
880
881 sk->sk_destruct = l2cap_sock_destruct;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200882 sk->sk_sndtimeo = msecs_to_jiffies(L2CAP_CONN_TIMEOUT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700883
884 sock_reset_flag(sk, SOCK_ZAPPED);
885
886 sk->sk_protocol = proto;
Marcel Holtmannb1235d7962008-07-14 20:13:54 +0200887 sk->sk_state = BT_OPEN;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700888
Marcel Holtmannb1235d7962008-07-14 20:13:54 +0200889 setup_timer(&sk->sk_timer, l2cap_sock_timeout, (unsigned long) sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700890
891 bt_sock_link(&l2cap_sk_list, sk);
892 return sk;
893}
894
Eric Paris3f378b62009-11-05 22:18:14 -0800895static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol,
896 int kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700897{
898 struct sock *sk;
899
900 BT_DBG("sock %p", sock);
901
902 sock->state = SS_UNCONNECTED;
903
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300904 if (sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM &&
Linus Torvalds1da177e2005-04-16 15:20:36 -0700905 sock->type != SOCK_DGRAM && sock->type != SOCK_RAW)
906 return -ESOCKTNOSUPPORT;
907
Eric Parisc84b3262009-11-05 20:45:52 -0800908 if (sock->type == SOCK_RAW && !kern && !capable(CAP_NET_RAW))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700909 return -EPERM;
910
911 sock->ops = &l2cap_sock_ops;
912
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700913 sk = l2cap_sock_alloc(net, sock, protocol, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700914 if (!sk)
915 return -ENOMEM;
916
917 l2cap_sock_init(sk, NULL);
918 return 0;
919}
920
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100921static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700922{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700923 struct sock *sk = sock->sk;
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100924 struct sockaddr_l2 la;
925 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700926
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100927 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700928
929 if (!addr || addr->sa_family != AF_BLUETOOTH)
930 return -EINVAL;
931
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100932 memset(&la, 0, sizeof(la));
933 len = min_t(unsigned int, sizeof(la), alen);
934 memcpy(&la, addr, len);
935
Marcel Holtmann2a517ca2009-02-16 03:20:31 +0100936 if (la.l2_cid)
937 return -EINVAL;
938
Linus Torvalds1da177e2005-04-16 15:20:36 -0700939 lock_sock(sk);
940
941 if (sk->sk_state != BT_OPEN) {
942 err = -EBADFD;
943 goto done;
944 }
945
Marcel Holtmannb4324b52009-06-07 18:06:51 +0200946 if (la.l2_psm && __le16_to_cpu(la.l2_psm) < 0x1001 &&
Marcel Holtmann847641d2007-01-22 22:00:45 +0100947 !capable(CAP_NET_BIND_SERVICE)) {
948 err = -EACCES;
949 goto done;
950 }
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900951
Linus Torvalds1da177e2005-04-16 15:20:36 -0700952 write_lock_bh(&l2cap_sk_list.lock);
953
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100954 if (la.l2_psm && __l2cap_get_sock_by_addr(la.l2_psm, &la.l2_bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700955 err = -EADDRINUSE;
956 } else {
957 /* Save source address */
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100958 bacpy(&bt_sk(sk)->src, &la.l2_bdaddr);
959 l2cap_pi(sk)->psm = la.l2_psm;
960 l2cap_pi(sk)->sport = la.l2_psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700961 sk->sk_state = BT_BOUND;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100962
Marcel Holtmannb4324b52009-06-07 18:06:51 +0200963 if (__le16_to_cpu(la.l2_psm) == 0x0001 ||
964 __le16_to_cpu(la.l2_psm) == 0x0003)
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100965 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700966 }
967
968 write_unlock_bh(&l2cap_sk_list.lock);
969
970done:
971 release_sock(sk);
972 return err;
973}
974
975static int l2cap_do_connect(struct sock *sk)
976{
977 bdaddr_t *src = &bt_sk(sk)->src;
978 bdaddr_t *dst = &bt_sk(sk)->dst;
979 struct l2cap_conn *conn;
980 struct hci_conn *hcon;
981 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200982 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +0200983 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700984
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100985 BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst),
986 l2cap_pi(sk)->psm);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700987
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300988 hdev = hci_get_route(dst, src);
989 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700990 return -EHOSTUNREACH;
991
992 hci_dev_lock_bh(hdev);
993
994 err = -ENOMEM;
995
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100996 if (sk->sk_type == SOCK_RAW) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100997 switch (l2cap_pi(sk)->sec_level) {
998 case BT_SECURITY_HIGH:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100999 auth_type = HCI_AT_DEDICATED_BONDING_MITM;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001000 break;
1001 case BT_SECURITY_MEDIUM:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001002 auth_type = HCI_AT_DEDICATED_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001003 break;
1004 default:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001005 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001006 break;
1007 }
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001008 } else if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001009 if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001010 auth_type = HCI_AT_NO_BONDING_MITM;
1011 else
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001012 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann435fef22009-02-09 03:55:28 +01001013
1014 if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW)
1015 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001016 } else {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001017 switch (l2cap_pi(sk)->sec_level) {
1018 case BT_SECURITY_HIGH:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001019 auth_type = HCI_AT_GENERAL_BONDING_MITM;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001020 break;
1021 case BT_SECURITY_MEDIUM:
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001022 auth_type = HCI_AT_GENERAL_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001023 break;
1024 default:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01001025 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001026 break;
1027 }
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001028 }
1029
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001030 hcon = hci_connect(hdev, ACL_LINK, dst,
1031 l2cap_pi(sk)->sec_level, auth_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001032 if (!hcon)
1033 goto done;
1034
1035 conn = l2cap_conn_add(hcon, 0);
1036 if (!conn) {
1037 hci_conn_put(hcon);
1038 goto done;
1039 }
1040
1041 err = 0;
1042
1043 /* Update source addr of the socket */
1044 bacpy(src, conn->src);
1045
1046 l2cap_chan_add(conn, sk, NULL);
1047
1048 sk->sk_state = BT_CONNECT;
1049 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
1050
1051 if (hcon->state == BT_CONNECTED) {
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001052 if (sk->sk_type != SOCK_SEQPACKET &&
1053 sk->sk_type != SOCK_STREAM) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001054 l2cap_sock_clear_timer(sk);
1055 sk->sk_state = BT_CONNECTED;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001056 } else
1057 l2cap_do_start(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001058 }
1059
1060done:
1061 hci_dev_unlock_bh(hdev);
1062 hci_dev_put(hdev);
1063 return err;
1064}
1065
1066static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
1067{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001068 struct sock *sk = sock->sk;
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001069 struct sockaddr_l2 la;
1070 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001071
Linus Torvalds1da177e2005-04-16 15:20:36 -07001072 BT_DBG("sk %p", sk);
1073
Changli Gao6503d962010-03-31 22:58:26 +00001074 if (!addr || alen < sizeof(addr->sa_family) ||
1075 addr->sa_family != AF_BLUETOOTH)
Marcel Holtmann2a517ca2009-02-16 03:20:31 +01001076 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001077
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001078 memset(&la, 0, sizeof(la));
1079 len = min_t(unsigned int, sizeof(la), alen);
1080 memcpy(&la, addr, len);
1081
Marcel Holtmann2a517ca2009-02-16 03:20:31 +01001082 if (la.l2_cid)
1083 return -EINVAL;
1084
1085 lock_sock(sk);
1086
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001087 if ((sk->sk_type == SOCK_SEQPACKET || sk->sk_type == SOCK_STREAM)
1088 && !la.l2_psm) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001089 err = -EINVAL;
1090 goto done;
1091 }
1092
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001093 switch (l2cap_pi(sk)->mode) {
1094 case L2CAP_MODE_BASIC:
1095 break;
1096 case L2CAP_MODE_ERTM:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001097 case L2CAP_MODE_STREAMING:
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001098 if (enable_ertm)
1099 break;
1100 /* fall through */
1101 default:
1102 err = -ENOTSUPP;
1103 goto done;
1104 }
1105
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001106 switch (sk->sk_state) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001107 case BT_CONNECT:
1108 case BT_CONNECT2:
1109 case BT_CONFIG:
1110 /* Already connecting */
1111 goto wait;
1112
1113 case BT_CONNECTED:
1114 /* Already connected */
1115 goto done;
1116
1117 case BT_OPEN:
1118 case BT_BOUND:
1119 /* Can connect */
1120 break;
1121
1122 default:
1123 err = -EBADFD;
1124 goto done;
1125 }
1126
1127 /* Set destination address and psm */
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001128 bacpy(&bt_sk(sk)->dst, &la.l2_bdaddr);
1129 l2cap_pi(sk)->psm = la.l2_psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001130
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001131 err = l2cap_do_connect(sk);
1132 if (err)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001133 goto done;
1134
1135wait:
1136 err = bt_sock_wait_state(sk, BT_CONNECTED,
1137 sock_sndtimeo(sk, flags & O_NONBLOCK));
1138done:
1139 release_sock(sk);
1140 return err;
1141}
1142
1143static int l2cap_sock_listen(struct socket *sock, int backlog)
1144{
1145 struct sock *sk = sock->sk;
1146 int err = 0;
1147
1148 BT_DBG("sk %p backlog %d", sk, backlog);
1149
1150 lock_sock(sk);
1151
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001152 if ((sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM)
1153 || sk->sk_state != BT_BOUND) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001154 err = -EBADFD;
1155 goto done;
1156 }
1157
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001158 switch (l2cap_pi(sk)->mode) {
1159 case L2CAP_MODE_BASIC:
1160 break;
1161 case L2CAP_MODE_ERTM:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001162 case L2CAP_MODE_STREAMING:
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001163 if (enable_ertm)
1164 break;
1165 /* fall through */
1166 default:
1167 err = -ENOTSUPP;
1168 goto done;
1169 }
1170
Linus Torvalds1da177e2005-04-16 15:20:36 -07001171 if (!l2cap_pi(sk)->psm) {
1172 bdaddr_t *src = &bt_sk(sk)->src;
1173 u16 psm;
1174
1175 err = -EINVAL;
1176
1177 write_lock_bh(&l2cap_sk_list.lock);
1178
1179 for (psm = 0x1001; psm < 0x1100; psm += 2)
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001180 if (!__l2cap_get_sock_by_addr(cpu_to_le16(psm), src)) {
1181 l2cap_pi(sk)->psm = cpu_to_le16(psm);
1182 l2cap_pi(sk)->sport = cpu_to_le16(psm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001183 err = 0;
1184 break;
1185 }
1186
1187 write_unlock_bh(&l2cap_sk_list.lock);
1188
1189 if (err < 0)
1190 goto done;
1191 }
1192
1193 sk->sk_max_ack_backlog = backlog;
1194 sk->sk_ack_backlog = 0;
1195 sk->sk_state = BT_LISTEN;
1196
1197done:
1198 release_sock(sk);
1199 return err;
1200}
1201
1202static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int flags)
1203{
1204 DECLARE_WAITQUEUE(wait, current);
1205 struct sock *sk = sock->sk, *nsk;
1206 long timeo;
1207 int err = 0;
1208
Peter Zijlstrafcc70d52006-11-08 22:44:35 -08001209 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001210
1211 if (sk->sk_state != BT_LISTEN) {
1212 err = -EBADFD;
1213 goto done;
1214 }
1215
1216 timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
1217
1218 BT_DBG("sk %p timeo %ld", sk, timeo);
1219
1220 /* Wait for an incoming connection. (wake-one). */
Eric Dumazetaa395142010-04-20 13:03:51 +00001221 add_wait_queue_exclusive(sk_sleep(sk), &wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001222 while (!(nsk = bt_accept_dequeue(sk, newsock))) {
1223 set_current_state(TASK_INTERRUPTIBLE);
1224 if (!timeo) {
1225 err = -EAGAIN;
1226 break;
1227 }
1228
1229 release_sock(sk);
1230 timeo = schedule_timeout(timeo);
Peter Zijlstrafcc70d52006-11-08 22:44:35 -08001231 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001232
1233 if (sk->sk_state != BT_LISTEN) {
1234 err = -EBADFD;
1235 break;
1236 }
1237
1238 if (signal_pending(current)) {
1239 err = sock_intr_errno(timeo);
1240 break;
1241 }
1242 }
1243 set_current_state(TASK_RUNNING);
Eric Dumazetaa395142010-04-20 13:03:51 +00001244 remove_wait_queue(sk_sleep(sk), &wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001245
1246 if (err)
1247 goto done;
1248
1249 newsock->state = SS_CONNECTED;
1250
1251 BT_DBG("new socket %p", nsk);
1252
1253done:
1254 release_sock(sk);
1255 return err;
1256}
1257
1258static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
1259{
1260 struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
1261 struct sock *sk = sock->sk;
1262
1263 BT_DBG("sock %p, sk %p", sock, sk);
1264
1265 addr->sa_family = AF_BLUETOOTH;
1266 *len = sizeof(struct sockaddr_l2);
1267
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001268 if (peer) {
1269 la->l2_psm = l2cap_pi(sk)->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001270 bacpy(&la->l2_bdaddr, &bt_sk(sk)->dst);
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001271 la->l2_cid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001272 } else {
1273 la->l2_psm = l2cap_pi(sk)->sport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001274 bacpy(&la->l2_bdaddr, &bt_sk(sk)->src);
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001275 la->l2_cid = cpu_to_le16(l2cap_pi(sk)->scid);
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001276 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001277
Linus Torvalds1da177e2005-04-16 15:20:36 -07001278 return 0;
1279}
1280
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001281static int __l2cap_wait_ack(struct sock *sk)
1282{
1283 DECLARE_WAITQUEUE(wait, current);
1284 int err = 0;
1285 int timeo = HZ/5;
1286
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001287 add_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001288 while ((l2cap_pi(sk)->unacked_frames > 0 && l2cap_pi(sk)->conn)) {
1289 set_current_state(TASK_INTERRUPTIBLE);
1290
1291 if (!timeo)
1292 timeo = HZ/5;
1293
1294 if (signal_pending(current)) {
1295 err = sock_intr_errno(timeo);
1296 break;
1297 }
1298
1299 release_sock(sk);
1300 timeo = schedule_timeout(timeo);
1301 lock_sock(sk);
1302
1303 err = sock_error(sk);
1304 if (err)
1305 break;
1306 }
1307 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001308 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001309 return err;
1310}
1311
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001312static void l2cap_monitor_timeout(unsigned long arg)
1313{
1314 struct sock *sk = (void *) arg;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001315
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001316 bh_lock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001317 if (l2cap_pi(sk)->retry_count >= l2cap_pi(sk)->remote_max_tx) {
1318 l2cap_send_disconn_req(l2cap_pi(sk)->conn, sk);
Andrei Emeltchenkob13f5862009-12-15 11:38:04 +02001319 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001320 return;
1321 }
1322
1323 l2cap_pi(sk)->retry_count++;
1324 __mod_monitor_timer();
1325
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -03001326 l2cap_send_rr_or_rnr(l2cap_pi(sk), L2CAP_CTRL_POLL);
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001327 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001328}
1329
1330static void l2cap_retrans_timeout(unsigned long arg)
1331{
1332 struct sock *sk = (void *) arg;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001333
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001334 bh_lock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001335 l2cap_pi(sk)->retry_count = 1;
1336 __mod_monitor_timer();
1337
1338 l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
1339
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -03001340 l2cap_send_rr_or_rnr(l2cap_pi(sk), L2CAP_CTRL_POLL);
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001341 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001342}
1343
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001344static void l2cap_drop_acked_frames(struct sock *sk)
1345{
1346 struct sk_buff *skb;
1347
Gustavo F. Padovan812e7372010-05-01 16:15:42 -03001348 while ((skb = skb_peek(TX_QUEUE(sk))) &&
1349 l2cap_pi(sk)->unacked_frames) {
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001350 if (bt_cb(skb)->tx_seq == l2cap_pi(sk)->expected_ack_seq)
1351 break;
1352
1353 skb = skb_dequeue(TX_QUEUE(sk));
1354 kfree_skb(skb);
1355
1356 l2cap_pi(sk)->unacked_frames--;
1357 }
1358
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001359 if (!l2cap_pi(sk)->unacked_frames)
1360 del_timer(&l2cap_pi(sk)->retrans_timer);
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001361}
1362
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001363static inline void l2cap_do_send(struct sock *sk, struct sk_buff *skb)
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001364{
1365 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001366
1367 BT_DBG("sk %p, skb %p len %d", sk, skb, skb->len);
1368
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001369 hci_send_acl(pi->conn->hcon, skb, 0);
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001370}
1371
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001372static int l2cap_streaming_send(struct sock *sk)
1373{
1374 struct sk_buff *skb, *tx_skb;
1375 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001376 u16 control, fcs;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001377
1378 while ((skb = sk->sk_send_head)) {
1379 tx_skb = skb_clone(skb, GFP_ATOMIC);
1380
1381 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
1382 control |= pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT;
1383 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1384
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001385 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001386 fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
1387 put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
1388 }
1389
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001390 l2cap_do_send(sk, tx_skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001391
1392 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
1393
1394 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1395 sk->sk_send_head = NULL;
1396 else
1397 sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
1398
1399 skb = skb_dequeue(TX_QUEUE(sk));
1400 kfree_skb(skb);
1401 }
1402 return 0;
1403}
1404
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001405static void l2cap_retransmit_one_frame(struct sock *sk, u8 tx_seq)
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001406{
1407 struct l2cap_pinfo *pi = l2cap_pi(sk);
1408 struct sk_buff *skb, *tx_skb;
1409 u16 control, fcs;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001410
1411 skb = skb_peek(TX_QUEUE(sk));
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001412 if (!skb)
1413 return;
1414
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001415 do {
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001416 if (bt_cb(skb)->tx_seq == tx_seq)
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001417 break;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001418
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001419 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1420 return;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001421
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001422 } while ((skb = skb_queue_next(TX_QUEUE(sk), skb)));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001423
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001424 if (pi->remote_max_tx &&
1425 bt_cb(skb)->retries == pi->remote_max_tx) {
1426 l2cap_send_disconn_req(pi->conn, sk);
1427 return;
1428 }
1429
1430 tx_skb = skb_clone(skb, GFP_ATOMIC);
1431 bt_cb(skb)->retries++;
1432 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03001433
1434 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
1435 control |= L2CAP_CTRL_FINAL;
1436 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
1437 }
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03001438
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001439 control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
1440 | (tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03001441
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001442 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1443
1444 if (pi->fcs == L2CAP_FCS_CRC16) {
1445 fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
1446 put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
1447 }
1448
1449 l2cap_do_send(sk, tx_skb);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001450}
1451
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001452static int l2cap_ertm_send(struct sock *sk)
1453{
1454 struct sk_buff *skb, *tx_skb;
1455 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001456 u16 control, fcs;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001457 int nsent = 0;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001458
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001459 if (sk->sk_state != BT_CONNECTED)
1460 return -ENOTCONN;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001461
Gustavo F. Padovan6e2b6722010-06-01 18:52:58 -03001462 while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(sk))) {
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001463
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001464 if (pi->remote_max_tx &&
1465 bt_cb(skb)->retries == pi->remote_max_tx) {
1466 l2cap_send_disconn_req(pi->conn, sk);
1467 break;
1468 }
1469
Andrei Emeltchenkoe420aba2009-12-23 13:07:14 +02001470 tx_skb = skb_clone(skb, GFP_ATOMIC);
1471
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001472 bt_cb(skb)->retries++;
1473
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001474 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03001475 control &= L2CAP_CTRL_SAR;
1476
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001477 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
1478 control |= L2CAP_CTRL_FINAL;
1479 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
1480 }
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03001481 control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001482 | (pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
1483 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1484
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001485
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001486 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001487 fcs = crc16(0, (u8 *)skb->data, tx_skb->len - 2);
1488 put_unaligned_le16(fcs, skb->data + tx_skb->len - 2);
1489 }
1490
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001491 l2cap_do_send(sk, tx_skb);
1492
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001493 __mod_retrans_timer();
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001494
1495 bt_cb(skb)->tx_seq = pi->next_tx_seq;
1496 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
1497
1498 pi->unacked_frames++;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001499 pi->frames_sent++;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001500
1501 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1502 sk->sk_send_head = NULL;
1503 else
1504 sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001505
1506 nsent++;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001507 }
1508
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001509 return nsent;
1510}
1511
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001512static int l2cap_retransmit_frames(struct sock *sk)
1513{
1514 struct l2cap_pinfo *pi = l2cap_pi(sk);
1515 int ret;
1516
1517 spin_lock_bh(&pi->send_lock);
1518
1519 if (!skb_queue_empty(TX_QUEUE(sk)))
1520 sk->sk_send_head = TX_QUEUE(sk)->next;
1521
1522 pi->next_tx_seq = pi->expected_ack_seq;
1523 ret = l2cap_ertm_send(sk);
1524
1525 spin_unlock_bh(&pi->send_lock);
1526
1527 return ret;
1528}
1529
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001530static void l2cap_send_ack(struct l2cap_pinfo *pi)
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001531{
1532 struct sock *sk = (struct sock *)pi;
1533 u16 control = 0;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001534 int nframes;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001535
1536 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1537
1538 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
1539 control |= L2CAP_SUPER_RCV_NOT_READY;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03001540 pi->conn_state |= L2CAP_CONN_RNR_SENT;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001541 l2cap_send_sframe(pi, control);
1542 return;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001543 }
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001544
1545 spin_lock_bh(&pi->send_lock);
1546 nframes = l2cap_ertm_send(sk);
1547 spin_unlock_bh(&pi->send_lock);
1548
1549 if (nframes > 0)
1550 return;
1551
1552 control |= L2CAP_SUPER_RCV_READY;
1553 l2cap_send_sframe(pi, control);
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001554}
1555
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001556static void l2cap_send_srejtail(struct sock *sk)
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03001557{
1558 struct srej_list *tail;
1559 u16 control;
1560
1561 control = L2CAP_SUPER_SELECT_REJECT;
1562 control |= L2CAP_CTRL_FINAL;
1563
1564 tail = list_entry(SREJ_LIST(sk)->prev, struct srej_list, list);
1565 control |= tail->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1566
1567 l2cap_send_sframe(l2cap_pi(sk), control);
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03001568}
1569
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001570static 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 -07001571{
1572 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001573 struct sk_buff **frag;
1574 int err, sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001575
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03001576 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001577 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001578
1579 sent += count;
1580 len -= count;
1581
1582 /* Continuation fragments (no L2CAP header) */
1583 frag = &skb_shinfo(skb)->frag_list;
1584 while (len) {
1585 count = min_t(unsigned int, conn->mtu, len);
1586
1587 *frag = bt_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err);
1588 if (!*frag)
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001589 return -EFAULT;
1590 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
1591 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001592
1593 sent += count;
1594 len -= count;
1595
1596 frag = &(*frag)->next;
1597 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001598
1599 return sent;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001600}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001601
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001602static struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, size_t len)
1603{
1604 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1605 struct sk_buff *skb;
1606 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1607 struct l2cap_hdr *lh;
1608
1609 BT_DBG("sk %p len %d", sk, (int)len);
1610
1611 count = min_t(unsigned int, (conn->mtu - hlen), len);
1612 skb = bt_skb_send_alloc(sk, count + hlen,
1613 msg->msg_flags & MSG_DONTWAIT, &err);
1614 if (!skb)
1615 return ERR_PTR(-ENOMEM);
1616
1617 /* Create L2CAP header */
1618 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1619 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1620 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1621 put_unaligned_le16(l2cap_pi(sk)->psm, skb_put(skb, 2));
1622
1623 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1624 if (unlikely(err < 0)) {
1625 kfree_skb(skb);
1626 return ERR_PTR(err);
1627 }
1628 return skb;
1629}
1630
1631static struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *msg, size_t len)
1632{
1633 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1634 struct sk_buff *skb;
1635 int err, count, hlen = L2CAP_HDR_SIZE;
1636 struct l2cap_hdr *lh;
1637
1638 BT_DBG("sk %p len %d", sk, (int)len);
1639
1640 count = min_t(unsigned int, (conn->mtu - hlen), len);
1641 skb = bt_skb_send_alloc(sk, count + hlen,
1642 msg->msg_flags & MSG_DONTWAIT, &err);
1643 if (!skb)
1644 return ERR_PTR(-ENOMEM);
1645
1646 /* Create L2CAP header */
1647 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1648 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1649 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1650
1651 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1652 if (unlikely(err < 0)) {
1653 kfree_skb(skb);
1654 return ERR_PTR(err);
1655 }
1656 return skb;
1657}
1658
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001659static struct sk_buff *l2cap_create_iframe_pdu(struct sock *sk, struct msghdr *msg, size_t len, u16 control, u16 sdulen)
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001660{
1661 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1662 struct sk_buff *skb;
1663 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1664 struct l2cap_hdr *lh;
1665
1666 BT_DBG("sk %p len %d", sk, (int)len);
1667
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03001668 if (!conn)
1669 return ERR_PTR(-ENOTCONN);
1670
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001671 if (sdulen)
1672 hlen += 2;
1673
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001674 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1675 hlen += 2;
1676
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001677 count = min_t(unsigned int, (conn->mtu - hlen), len);
1678 skb = bt_skb_send_alloc(sk, count + hlen,
1679 msg->msg_flags & MSG_DONTWAIT, &err);
1680 if (!skb)
1681 return ERR_PTR(-ENOMEM);
1682
1683 /* Create L2CAP header */
1684 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1685 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1686 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1687 put_unaligned_le16(control, skb_put(skb, 2));
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001688 if (sdulen)
1689 put_unaligned_le16(sdulen, skb_put(skb, 2));
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001690
1691 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1692 if (unlikely(err < 0)) {
1693 kfree_skb(skb);
1694 return ERR_PTR(err);
1695 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001696
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001697 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1698 put_unaligned_le16(0, skb_put(skb, 2));
1699
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001700 bt_cb(skb)->retries = 0;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001701 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001702}
1703
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001704static inline int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len)
1705{
1706 struct l2cap_pinfo *pi = l2cap_pi(sk);
1707 struct sk_buff *skb;
1708 struct sk_buff_head sar_queue;
1709 u16 control;
1710 size_t size = 0;
1711
Gustavo F. Padovanff12fd62010-05-05 22:09:15 -03001712 skb_queue_head_init(&sar_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001713 control = L2CAP_SDU_START;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001714 skb = l2cap_create_iframe_pdu(sk, msg, pi->remote_mps, control, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001715 if (IS_ERR(skb))
1716 return PTR_ERR(skb);
1717
1718 __skb_queue_tail(&sar_queue, skb);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001719 len -= pi->remote_mps;
1720 size += pi->remote_mps;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001721
1722 while (len > 0) {
1723 size_t buflen;
1724
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001725 if (len > pi->remote_mps) {
Gustavo F. Padovan44651b82010-05-01 16:15:43 -03001726 control = L2CAP_SDU_CONTINUE;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001727 buflen = pi->remote_mps;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001728 } else {
Gustavo F. Padovan44651b82010-05-01 16:15:43 -03001729 control = L2CAP_SDU_END;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001730 buflen = len;
1731 }
1732
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001733 skb = l2cap_create_iframe_pdu(sk, msg, buflen, control, 0);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001734 if (IS_ERR(skb)) {
1735 skb_queue_purge(&sar_queue);
1736 return PTR_ERR(skb);
1737 }
1738
1739 __skb_queue_tail(&sar_queue, skb);
1740 len -= buflen;
1741 size += buflen;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001742 }
1743 skb_queue_splice_tail(&sar_queue, TX_QUEUE(sk));
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001744 spin_lock_bh(&pi->send_lock);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001745 if (sk->sk_send_head == NULL)
1746 sk->sk_send_head = sar_queue.next;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001747 spin_unlock_bh(&pi->send_lock);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001748
1749 return size;
1750}
1751
Linus Torvalds1da177e2005-04-16 15:20:36 -07001752static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len)
1753{
1754 struct sock *sk = sock->sk;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001755 struct l2cap_pinfo *pi = l2cap_pi(sk);
1756 struct sk_buff *skb;
1757 u16 control;
1758 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001759
1760 BT_DBG("sock %p, sk %p", sock, sk);
1761
Benjamin LaHaisec1cbe4b2005-12-13 23:22:19 -08001762 err = sock_error(sk);
1763 if (err)
1764 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001765
1766 if (msg->msg_flags & MSG_OOB)
1767 return -EOPNOTSUPP;
1768
Linus Torvalds1da177e2005-04-16 15:20:36 -07001769 lock_sock(sk);
1770
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001771 if (sk->sk_state != BT_CONNECTED) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001772 err = -ENOTCONN;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001773 goto done;
1774 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001775
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001776 /* Connectionless channel */
1777 if (sk->sk_type == SOCK_DGRAM) {
1778 skb = l2cap_create_connless_pdu(sk, msg, len);
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001779 if (IS_ERR(skb)) {
Dan Carpenter477fffb2010-04-21 23:52:01 +00001780 err = PTR_ERR(skb);
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001781 } else {
1782 l2cap_do_send(sk, skb);
1783 err = len;
1784 }
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001785 goto done;
1786 }
1787
1788 switch (pi->mode) {
1789 case L2CAP_MODE_BASIC:
Gustavo F. Padovanc69163e2010-05-01 16:15:35 -03001790 /* Check outgoing MTU */
1791 if (len > pi->omtu) {
1792 err = -EINVAL;
1793 goto done;
1794 }
1795
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001796 /* Create a basic PDU */
1797 skb = l2cap_create_basic_pdu(sk, msg, len);
1798 if (IS_ERR(skb)) {
1799 err = PTR_ERR(skb);
1800 goto done;
1801 }
1802
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001803 l2cap_do_send(sk, skb);
1804 err = len;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001805 break;
1806
1807 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001808 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001809 /* Entire SDU fits into one PDU */
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001810 if (len <= pi->remote_mps) {
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001811 control = L2CAP_SDU_UNSEGMENTED;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001812 skb = l2cap_create_iframe_pdu(sk, msg, len, control, 0);
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001813 if (IS_ERR(skb)) {
1814 err = PTR_ERR(skb);
1815 goto done;
1816 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001817 __skb_queue_tail(TX_QUEUE(sk), skb);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001818
1819 if (pi->mode == L2CAP_MODE_ERTM)
1820 spin_lock_bh(&pi->send_lock);
1821
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001822 if (sk->sk_send_head == NULL)
1823 sk->sk_send_head = skb;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001824
1825 if (pi->mode == L2CAP_MODE_ERTM)
1826 spin_unlock_bh(&pi->send_lock);
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001827 } else {
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001828 /* Segment SDU into multiples PDUs */
1829 err = l2cap_sar_segment_sdu(sk, msg, len);
1830 if (err < 0)
1831 goto done;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001832 }
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001833
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001834 if (pi->mode == L2CAP_MODE_STREAMING) {
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001835 err = l2cap_streaming_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001836 } else {
Gustavo F. Padovan6e2b6722010-06-01 18:52:58 -03001837 if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY &&
1838 pi->conn_state && L2CAP_CONN_WAIT_F) {
1839 err = len;
1840 break;
1841 }
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001842 spin_lock_bh(&pi->send_lock);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001843 err = l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001844 spin_unlock_bh(&pi->send_lock);
1845 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001846
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001847 if (err >= 0)
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001848 err = len;
1849 break;
1850
1851 default:
1852 BT_DBG("bad state %1.1x", pi->mode);
1853 err = -EINVAL;
1854 }
1855
1856done:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001857 release_sock(sk);
1858 return err;
1859}
1860
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001861static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags)
1862{
1863 struct sock *sk = sock->sk;
1864
1865 lock_sock(sk);
1866
1867 if (sk->sk_state == BT_CONNECT2 && bt_sk(sk)->defer_setup) {
1868 struct l2cap_conn_rsp rsp;
1869
1870 sk->sk_state = BT_CONFIG;
1871
1872 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
1873 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
1874 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
1875 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
1876 l2cap_send_cmd(l2cap_pi(sk)->conn, l2cap_pi(sk)->ident,
1877 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
1878
1879 release_sock(sk);
1880 return 0;
1881 }
1882
1883 release_sock(sk);
1884
1885 return bt_sock_recvmsg(iocb, sock, msg, len, flags);
1886}
1887
David S. Millerb7058842009-09-30 16:12:20 -07001888static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001889{
1890 struct sock *sk = sock->sk;
1891 struct l2cap_options opts;
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001892 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001893 u32 opt;
1894
1895 BT_DBG("sk %p", sk);
1896
1897 lock_sock(sk);
1898
1899 switch (optname) {
1900 case L2CAP_OPTIONS:
Marcel Holtmann0878b662007-05-05 00:35:59 +02001901 opts.imtu = l2cap_pi(sk)->imtu;
1902 opts.omtu = l2cap_pi(sk)->omtu;
1903 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001904 opts.mode = l2cap_pi(sk)->mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001905 opts.fcs = l2cap_pi(sk)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03001906 opts.max_tx = l2cap_pi(sk)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03001907 opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
Marcel Holtmann0878b662007-05-05 00:35:59 +02001908
Linus Torvalds1da177e2005-04-16 15:20:36 -07001909 len = min_t(unsigned int, sizeof(opts), optlen);
1910 if (copy_from_user((char *) &opts, optval, len)) {
1911 err = -EFAULT;
1912 break;
1913 }
Marcel Holtmann0878b662007-05-05 00:35:59 +02001914
Gustavo F. Padovan45d65c42010-06-07 19:21:30 -03001915 if (opts.txwin_size > L2CAP_DEFAULT_TX_WINDOW) {
1916 err = -EINVAL;
1917 break;
1918 }
1919
João Paulo Rechi Vita0041ecf2010-05-01 16:15:42 -03001920 l2cap_pi(sk)->mode = opts.mode;
1921 switch (l2cap_pi(sk)->mode) {
1922 case L2CAP_MODE_BASIC:
1923 break;
1924 case L2CAP_MODE_ERTM:
1925 case L2CAP_MODE_STREAMING:
1926 if (enable_ertm)
1927 break;
1928 /* fall through */
1929 default:
1930 err = -EINVAL;
1931 break;
1932 }
1933
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001934 l2cap_pi(sk)->imtu = opts.imtu;
1935 l2cap_pi(sk)->omtu = opts.omtu;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001936 l2cap_pi(sk)->fcs = opts.fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03001937 l2cap_pi(sk)->max_tx = opts.max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03001938 l2cap_pi(sk)->tx_win = (__u8)opts.txwin_size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001939 break;
1940
1941 case L2CAP_LM:
1942 if (get_user(opt, (u32 __user *) optval)) {
1943 err = -EFAULT;
1944 break;
1945 }
1946
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001947 if (opt & L2CAP_LM_AUTH)
1948 l2cap_pi(sk)->sec_level = BT_SECURITY_LOW;
1949 if (opt & L2CAP_LM_ENCRYPT)
1950 l2cap_pi(sk)->sec_level = BT_SECURITY_MEDIUM;
1951 if (opt & L2CAP_LM_SECURE)
1952 l2cap_pi(sk)->sec_level = BT_SECURITY_HIGH;
1953
1954 l2cap_pi(sk)->role_switch = (opt & L2CAP_LM_MASTER);
1955 l2cap_pi(sk)->force_reliable = (opt & L2CAP_LM_RELIABLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001956 break;
1957
1958 default:
1959 err = -ENOPROTOOPT;
1960 break;
1961 }
1962
1963 release_sock(sk);
1964 return err;
1965}
1966
David S. Millerb7058842009-09-30 16:12:20 -07001967static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001968{
1969 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001970 struct bt_security sec;
1971 int len, err = 0;
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001972 u32 opt;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001973
1974 BT_DBG("sk %p", sk);
1975
1976 if (level == SOL_L2CAP)
1977 return l2cap_sock_setsockopt_old(sock, optname, optval, optlen);
1978
Marcel Holtmann0588d942009-01-16 10:06:13 +01001979 if (level != SOL_BLUETOOTH)
1980 return -ENOPROTOOPT;
1981
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001982 lock_sock(sk);
1983
1984 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001985 case BT_SECURITY:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001986 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
1987 && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01001988 err = -EINVAL;
1989 break;
1990 }
1991
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001992 sec.level = BT_SECURITY_LOW;
1993
1994 len = min_t(unsigned int, sizeof(sec), optlen);
1995 if (copy_from_user((char *) &sec, optval, len)) {
1996 err = -EFAULT;
1997 break;
1998 }
1999
2000 if (sec.level < BT_SECURITY_LOW ||
2001 sec.level > BT_SECURITY_HIGH) {
2002 err = -EINVAL;
2003 break;
2004 }
2005
2006 l2cap_pi(sk)->sec_level = sec.level;
2007 break;
2008
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002009 case BT_DEFER_SETUP:
2010 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
2011 err = -EINVAL;
2012 break;
2013 }
2014
2015 if (get_user(opt, (u32 __user *) optval)) {
2016 err = -EFAULT;
2017 break;
2018 }
2019
2020 bt_sk(sk)->defer_setup = opt;
2021 break;
2022
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002023 default:
2024 err = -ENOPROTOOPT;
2025 break;
2026 }
2027
2028 release_sock(sk);
2029 return err;
2030}
2031
2032static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002033{
2034 struct sock *sk = sock->sk;
2035 struct l2cap_options opts;
2036 struct l2cap_conninfo cinfo;
2037 int len, err = 0;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002038 u32 opt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002039
2040 BT_DBG("sk %p", sk);
2041
2042 if (get_user(len, optlen))
2043 return -EFAULT;
2044
2045 lock_sock(sk);
2046
2047 switch (optname) {
2048 case L2CAP_OPTIONS:
2049 opts.imtu = l2cap_pi(sk)->imtu;
2050 opts.omtu = l2cap_pi(sk)->omtu;
2051 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07002052 opts.mode = l2cap_pi(sk)->mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002053 opts.fcs = l2cap_pi(sk)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03002054 opts.max_tx = l2cap_pi(sk)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03002055 opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002056
2057 len = min_t(unsigned int, len, sizeof(opts));
2058 if (copy_to_user(optval, (char *) &opts, len))
2059 err = -EFAULT;
2060
2061 break;
2062
2063 case L2CAP_LM:
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002064 switch (l2cap_pi(sk)->sec_level) {
2065 case BT_SECURITY_LOW:
2066 opt = L2CAP_LM_AUTH;
2067 break;
2068 case BT_SECURITY_MEDIUM:
2069 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT;
2070 break;
2071 case BT_SECURITY_HIGH:
2072 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT |
2073 L2CAP_LM_SECURE;
2074 break;
2075 default:
2076 opt = 0;
2077 break;
2078 }
2079
2080 if (l2cap_pi(sk)->role_switch)
2081 opt |= L2CAP_LM_MASTER;
2082
2083 if (l2cap_pi(sk)->force_reliable)
2084 opt |= L2CAP_LM_RELIABLE;
2085
2086 if (put_user(opt, (u32 __user *) optval))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002087 err = -EFAULT;
2088 break;
2089
2090 case L2CAP_CONNINFO:
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002091 if (sk->sk_state != BT_CONNECTED &&
2092 !(sk->sk_state == BT_CONNECT2 &&
2093 bt_sk(sk)->defer_setup)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002094 err = -ENOTCONN;
2095 break;
2096 }
2097
2098 cinfo.hci_handle = l2cap_pi(sk)->conn->hcon->handle;
2099 memcpy(cinfo.dev_class, l2cap_pi(sk)->conn->hcon->dev_class, 3);
2100
2101 len = min_t(unsigned int, len, sizeof(cinfo));
2102 if (copy_to_user(optval, (char *) &cinfo, len))
2103 err = -EFAULT;
2104
2105 break;
2106
2107 default:
2108 err = -ENOPROTOOPT;
2109 break;
2110 }
2111
2112 release_sock(sk);
2113 return err;
2114}
2115
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002116static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
2117{
2118 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002119 struct bt_security sec;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002120 int len, err = 0;
2121
2122 BT_DBG("sk %p", sk);
2123
2124 if (level == SOL_L2CAP)
2125 return l2cap_sock_getsockopt_old(sock, optname, optval, optlen);
2126
Marcel Holtmann0588d942009-01-16 10:06:13 +01002127 if (level != SOL_BLUETOOTH)
2128 return -ENOPROTOOPT;
2129
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002130 if (get_user(len, optlen))
2131 return -EFAULT;
2132
2133 lock_sock(sk);
2134
2135 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002136 case BT_SECURITY:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03002137 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
2138 && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01002139 err = -EINVAL;
2140 break;
2141 }
2142
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002143 sec.level = l2cap_pi(sk)->sec_level;
2144
2145 len = min_t(unsigned int, len, sizeof(sec));
2146 if (copy_to_user(optval, (char *) &sec, len))
2147 err = -EFAULT;
2148
2149 break;
2150
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002151 case BT_DEFER_SETUP:
2152 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
2153 err = -EINVAL;
2154 break;
2155 }
2156
2157 if (put_user(bt_sk(sk)->defer_setup, (u32 __user *) optval))
2158 err = -EFAULT;
2159
2160 break;
2161
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002162 default:
2163 err = -ENOPROTOOPT;
2164 break;
2165 }
2166
2167 release_sock(sk);
2168 return err;
2169}
2170
Linus Torvalds1da177e2005-04-16 15:20:36 -07002171static int l2cap_sock_shutdown(struct socket *sock, int how)
2172{
2173 struct sock *sk = sock->sk;
2174 int err = 0;
2175
2176 BT_DBG("sock %p, sk %p", sock, sk);
2177
2178 if (!sk)
2179 return 0;
2180
2181 lock_sock(sk);
2182 if (!sk->sk_shutdown) {
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03002183 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
2184 err = __l2cap_wait_ack(sk);
2185
Linus Torvalds1da177e2005-04-16 15:20:36 -07002186 sk->sk_shutdown = SHUTDOWN_MASK;
2187 l2cap_sock_clear_timer(sk);
2188 __l2cap_sock_close(sk, 0);
2189
2190 if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
Marcel Holtmannb1235d7962008-07-14 20:13:54 +02002191 err = bt_sock_wait_state(sk, BT_CLOSED,
2192 sk->sk_lingertime);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002193 }
2194 release_sock(sk);
2195 return err;
2196}
2197
2198static int l2cap_sock_release(struct socket *sock)
2199{
2200 struct sock *sk = sock->sk;
2201 int err;
2202
2203 BT_DBG("sock %p, sk %p", sock, sk);
2204
2205 if (!sk)
2206 return 0;
2207
2208 err = l2cap_sock_shutdown(sock, 2);
2209
2210 sock_orphan(sk);
2211 l2cap_sock_kill(sk);
2212 return err;
2213}
2214
Linus Torvalds1da177e2005-04-16 15:20:36 -07002215static void l2cap_chan_ready(struct sock *sk)
2216{
2217 struct sock *parent = bt_sk(sk)->parent;
2218
2219 BT_DBG("sk %p, parent %p", sk, parent);
2220
2221 l2cap_pi(sk)->conf_state = 0;
2222 l2cap_sock_clear_timer(sk);
2223
2224 if (!parent) {
2225 /* Outgoing channel.
2226 * Wake up socket sleeping on connect.
2227 */
2228 sk->sk_state = BT_CONNECTED;
2229 sk->sk_state_change(sk);
2230 } else {
2231 /* Incoming channel.
2232 * Wake up socket sleeping on accept.
2233 */
2234 parent->sk_data_ready(parent, 0);
2235 }
2236}
2237
2238/* Copy frame to all raw sockets on that connection */
2239static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2240{
2241 struct l2cap_chan_list *l = &conn->chan_list;
2242 struct sk_buff *nskb;
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002243 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002244
2245 BT_DBG("conn %p", conn);
2246
2247 read_lock(&l->lock);
2248 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
2249 if (sk->sk_type != SOCK_RAW)
2250 continue;
2251
2252 /* Don't send frame to the socket it came from */
2253 if (skb->sk == sk)
2254 continue;
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002255 nskb = skb_clone(skb, GFP_ATOMIC);
2256 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002257 continue;
2258
2259 if (sock_queue_rcv_skb(sk, nskb))
2260 kfree_skb(nskb);
2261 }
2262 read_unlock(&l->lock);
2263}
2264
2265/* ---- L2CAP signalling commands ---- */
2266static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
2267 u8 code, u8 ident, u16 dlen, void *data)
2268{
2269 struct sk_buff *skb, **frag;
2270 struct l2cap_cmd_hdr *cmd;
2271 struct l2cap_hdr *lh;
2272 int len, count;
2273
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002274 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d",
2275 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002276
2277 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2278 count = min_t(unsigned int, conn->mtu, len);
2279
2280 skb = bt_skb_alloc(count, GFP_ATOMIC);
2281 if (!skb)
2282 return NULL;
2283
2284 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002285 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03002286 lh->cid = cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002287
2288 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2289 cmd->code = code;
2290 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002291 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002292
2293 if (dlen) {
2294 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2295 memcpy(skb_put(skb, count), data, count);
2296 data += count;
2297 }
2298
2299 len -= skb->len;
2300
2301 /* Continuation fragments (no L2CAP header) */
2302 frag = &skb_shinfo(skb)->frag_list;
2303 while (len) {
2304 count = min_t(unsigned int, conn->mtu, len);
2305
2306 *frag = bt_skb_alloc(count, GFP_ATOMIC);
2307 if (!*frag)
2308 goto fail;
2309
2310 memcpy(skb_put(*frag, count), data, count);
2311
2312 len -= count;
2313 data += count;
2314
2315 frag = &(*frag)->next;
2316 }
2317
2318 return skb;
2319
2320fail:
2321 kfree_skb(skb);
2322 return NULL;
2323}
2324
2325static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned long *val)
2326{
2327 struct l2cap_conf_opt *opt = *ptr;
2328 int len;
2329
2330 len = L2CAP_CONF_OPT_SIZE + opt->len;
2331 *ptr += len;
2332
2333 *type = opt->type;
2334 *olen = opt->len;
2335
2336 switch (opt->len) {
2337 case 1:
2338 *val = *((u8 *) opt->val);
2339 break;
2340
2341 case 2:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002342 *val = __le16_to_cpu(*((__le16 *) opt->val));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002343 break;
2344
2345 case 4:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002346 *val = __le32_to_cpu(*((__le32 *) opt->val));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002347 break;
2348
2349 default:
2350 *val = (unsigned long) opt->val;
2351 break;
2352 }
2353
2354 BT_DBG("type 0x%2.2x len %d val 0x%lx", *type, opt->len, *val);
2355 return len;
2356}
2357
Linus Torvalds1da177e2005-04-16 15:20:36 -07002358static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2359{
2360 struct l2cap_conf_opt *opt = *ptr;
2361
2362 BT_DBG("type 0x%2.2x len %d val 0x%lx", type, len, val);
2363
2364 opt->type = type;
2365 opt->len = len;
2366
2367 switch (len) {
2368 case 1:
2369 *((u8 *) opt->val) = val;
2370 break;
2371
2372 case 2:
Al Viro8e036fc2007-07-29 00:16:36 -07002373 *((__le16 *) opt->val) = cpu_to_le16(val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002374 break;
2375
2376 case 4:
Al Viro8e036fc2007-07-29 00:16:36 -07002377 *((__le32 *) opt->val) = cpu_to_le32(val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002378 break;
2379
2380 default:
2381 memcpy(opt->val, (void *) val, len);
2382 break;
2383 }
2384
2385 *ptr += L2CAP_CONF_OPT_SIZE + len;
2386}
2387
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002388static void l2cap_ack_timeout(unsigned long arg)
2389{
2390 struct sock *sk = (void *) arg;
2391
2392 bh_lock_sock(sk);
2393 l2cap_send_ack(l2cap_pi(sk));
2394 bh_unlock_sock(sk);
2395}
2396
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002397static inline void l2cap_ertm_init(struct sock *sk)
2398{
2399 l2cap_pi(sk)->expected_ack_seq = 0;
2400 l2cap_pi(sk)->unacked_frames = 0;
2401 l2cap_pi(sk)->buffer_seq = 0;
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03002402 l2cap_pi(sk)->num_acked = 0;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03002403 l2cap_pi(sk)->frames_sent = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002404
2405 setup_timer(&l2cap_pi(sk)->retrans_timer,
2406 l2cap_retrans_timeout, (unsigned long) sk);
2407 setup_timer(&l2cap_pi(sk)->monitor_timer,
2408 l2cap_monitor_timeout, (unsigned long) sk);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002409 setup_timer(&l2cap_pi(sk)->ack_timer,
2410 l2cap_ack_timeout, (unsigned long) sk);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002411
2412 __skb_queue_head_init(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002413 __skb_queue_head_init(BUSY_QUEUE(sk));
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03002414 spin_lock_init(&l2cap_pi(sk)->send_lock);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002415
2416 INIT_WORK(&l2cap_pi(sk)->busy_work, l2cap_busy_work);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002417}
2418
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002419static int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
2420{
2421 u32 local_feat_mask = l2cap_feat_mask;
2422 if (enable_ertm)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002423 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002424
2425 switch (mode) {
2426 case L2CAP_MODE_ERTM:
2427 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
2428 case L2CAP_MODE_STREAMING:
2429 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
2430 default:
2431 return 0x00;
2432 }
2433}
2434
2435static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
2436{
2437 switch (mode) {
2438 case L2CAP_MODE_STREAMING:
2439 case L2CAP_MODE_ERTM:
2440 if (l2cap_mode_supported(mode, remote_feat_mask))
2441 return mode;
2442 /* fall through */
2443 default:
2444 return L2CAP_MODE_BASIC;
2445 }
2446}
2447
Linus Torvalds1da177e2005-04-16 15:20:36 -07002448static int l2cap_build_conf_req(struct sock *sk, void *data)
2449{
2450 struct l2cap_pinfo *pi = l2cap_pi(sk);
2451 struct l2cap_conf_req *req = data;
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03002452 struct l2cap_conf_rfc rfc = { .mode = pi->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07002453 void *ptr = req->data;
2454
2455 BT_DBG("sk %p", sk);
2456
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002457 if (pi->num_conf_req || pi->num_conf_rsp)
2458 goto done;
2459
2460 switch (pi->mode) {
2461 case L2CAP_MODE_STREAMING:
2462 case L2CAP_MODE_ERTM:
2463 pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002464 if (!l2cap_mode_supported(pi->mode, pi->conn->feat_mask))
2465 l2cap_send_disconn_req(pi->conn, sk);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002466 break;
2467 default:
2468 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
2469 break;
2470 }
2471
2472done:
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002473 switch (pi->mode) {
2474 case L2CAP_MODE_BASIC:
2475 if (pi->imtu != L2CAP_DEFAULT_MTU)
2476 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
2477 break;
2478
2479 case L2CAP_MODE_ERTM:
2480 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03002481 rfc.txwin_size = pi->tx_win;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03002482 rfc.max_transmit = pi->max_tx;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002483 rfc.retrans_timeout = 0;
2484 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002485 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03002486 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002487 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002488
2489 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2490 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002491
2492 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2493 break;
2494
2495 if (pi->fcs == L2CAP_FCS_NONE ||
2496 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
2497 pi->fcs = L2CAP_FCS_NONE;
2498 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
2499 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002500 break;
2501
2502 case L2CAP_MODE_STREAMING:
2503 rfc.mode = L2CAP_MODE_STREAMING;
2504 rfc.txwin_size = 0;
2505 rfc.max_transmit = 0;
2506 rfc.retrans_timeout = 0;
2507 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002508 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03002509 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002510 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002511
2512 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2513 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002514
2515 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2516 break;
2517
2518 if (pi->fcs == L2CAP_FCS_NONE ||
2519 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
2520 pi->fcs = L2CAP_FCS_NONE;
2521 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
2522 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002523 break;
2524 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002525
2526 /* FIXME: Need actual value of the flush timeout */
2527 //if (flush_to != L2CAP_DEFAULT_FLUSH_TO)
2528 // l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2, pi->flush_to);
2529
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002530 req->dcid = cpu_to_le16(pi->dcid);
2531 req->flags = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002532
2533 return ptr - data;
2534}
2535
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002536static int l2cap_parse_conf_req(struct sock *sk, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002537{
2538 struct l2cap_pinfo *pi = l2cap_pi(sk);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002539 struct l2cap_conf_rsp *rsp = data;
2540 void *ptr = rsp->data;
2541 void *req = pi->conf_req;
2542 int len = pi->conf_len;
2543 int type, hint, olen;
2544 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002545 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Marcel Holtmann861d6882007-10-20 13:37:06 +02002546 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002547 u16 result = L2CAP_CONF_SUCCESS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002548
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002549 BT_DBG("sk %p", sk);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01002550
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002551 while (len >= L2CAP_CONF_OPT_SIZE) {
2552 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002553
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03002554 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07002555 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002556
2557 switch (type) {
2558 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002559 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002560 break;
2561
2562 case L2CAP_CONF_FLUSH_TO:
2563 pi->flush_to = val;
2564 break;
2565
2566 case L2CAP_CONF_QOS:
2567 break;
2568
Marcel Holtmann6464f352007-10-20 13:39:51 +02002569 case L2CAP_CONF_RFC:
2570 if (olen == sizeof(rfc))
2571 memcpy(&rfc, (void *) val, olen);
2572 break;
2573
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002574 case L2CAP_CONF_FCS:
2575 if (val == L2CAP_FCS_NONE)
2576 pi->conf_state |= L2CAP_CONF_NO_FCS_RECV;
2577
2578 break;
2579
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002580 default:
2581 if (hint)
2582 break;
2583
2584 result = L2CAP_CONF_UNKNOWN;
2585 *((u8 *) ptr++) = type;
2586 break;
2587 }
2588 }
2589
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002590 if (pi->num_conf_rsp || pi->num_conf_req)
2591 goto done;
2592
2593 switch (pi->mode) {
2594 case L2CAP_MODE_STREAMING:
2595 case L2CAP_MODE_ERTM:
2596 pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
2597 if (!l2cap_mode_supported(pi->mode, pi->conn->feat_mask))
2598 return -ECONNREFUSED;
2599 break;
2600 default:
2601 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
2602 break;
2603 }
2604
2605done:
2606 if (pi->mode != rfc.mode) {
2607 result = L2CAP_CONF_UNACCEPT;
2608 rfc.mode = pi->mode;
2609
2610 if (pi->num_conf_rsp == 1)
2611 return -ECONNREFUSED;
2612
2613 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2614 sizeof(rfc), (unsigned long) &rfc);
2615 }
2616
2617
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002618 if (result == L2CAP_CONF_SUCCESS) {
2619 /* Configure output options and let the other side know
2620 * which ones we don't like. */
2621
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002622 if (mtu < L2CAP_DEFAULT_MIN_MTU)
2623 result = L2CAP_CONF_UNACCEPT;
2624 else {
2625 pi->omtu = mtu;
2626 pi->conf_state |= L2CAP_CONF_MTU_DONE;
2627 }
2628 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002629
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002630 switch (rfc.mode) {
2631 case L2CAP_MODE_BASIC:
2632 pi->fcs = L2CAP_FCS_NONE;
2633 pi->conf_state |= L2CAP_CONF_MODE_DONE;
2634 break;
2635
2636 case L2CAP_MODE_ERTM:
2637 pi->remote_tx_win = rfc.txwin_size;
2638 pi->remote_max_tx = rfc.max_transmit;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002639 if (rfc.max_pdu_size > pi->conn->mtu - 10)
2640 rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10);
2641
2642 pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002643
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002644 rfc.retrans_timeout =
2645 le16_to_cpu(L2CAP_DEFAULT_RETRANS_TO);
2646 rfc.monitor_timeout =
2647 le16_to_cpu(L2CAP_DEFAULT_MONITOR_TO);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002648
2649 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03002650
2651 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2652 sizeof(rfc), (unsigned long) &rfc);
2653
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002654 break;
2655
2656 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002657 if (rfc.max_pdu_size > pi->conn->mtu - 10)
2658 rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10);
2659
2660 pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002661
2662 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03002663
2664 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2665 sizeof(rfc), (unsigned long) &rfc);
2666
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002667 break;
2668
2669 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02002670 result = L2CAP_CONF_UNACCEPT;
2671
2672 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002673 rfc.mode = pi->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002674 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002675
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002676 if (result == L2CAP_CONF_SUCCESS)
2677 pi->conf_state |= L2CAP_CONF_OUTPUT_DONE;
2678 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002679 rsp->scid = cpu_to_le16(pi->dcid);
2680 rsp->result = cpu_to_le16(result);
2681 rsp->flags = cpu_to_le16(0x0000);
2682
2683 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002684}
2685
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002686static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data, u16 *result)
2687{
2688 struct l2cap_pinfo *pi = l2cap_pi(sk);
2689 struct l2cap_conf_req *req = data;
2690 void *ptr = req->data;
2691 int type, olen;
2692 unsigned long val;
2693 struct l2cap_conf_rfc rfc;
2694
2695 BT_DBG("sk %p, rsp %p, len %d, req %p", sk, rsp, len, data);
2696
2697 while (len >= L2CAP_CONF_OPT_SIZE) {
2698 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
2699
2700 switch (type) {
2701 case L2CAP_CONF_MTU:
2702 if (val < L2CAP_DEFAULT_MIN_MTU) {
2703 *result = L2CAP_CONF_UNACCEPT;
2704 pi->omtu = L2CAP_DEFAULT_MIN_MTU;
2705 } else
2706 pi->omtu = val;
2707 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
2708 break;
2709
2710 case L2CAP_CONF_FLUSH_TO:
2711 pi->flush_to = val;
2712 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
2713 2, pi->flush_to);
2714 break;
2715
2716 case L2CAP_CONF_RFC:
2717 if (olen == sizeof(rfc))
2718 memcpy(&rfc, (void *)val, olen);
2719
2720 if ((pi->conf_state & L2CAP_CONF_STATE2_DEVICE) &&
2721 rfc.mode != pi->mode)
2722 return -ECONNREFUSED;
2723
2724 pi->mode = rfc.mode;
2725 pi->fcs = 0;
2726
2727 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2728 sizeof(rfc), (unsigned long) &rfc);
2729 break;
2730 }
2731 }
2732
2733 if (*result == L2CAP_CONF_SUCCESS) {
2734 switch (rfc.mode) {
2735 case L2CAP_MODE_ERTM:
2736 pi->remote_tx_win = rfc.txwin_size;
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002737 pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
2738 pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002739 pi->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002740 break;
2741 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002742 pi->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002743 }
2744 }
2745
2746 req->dcid = cpu_to_le16(pi->dcid);
2747 req->flags = cpu_to_le16(0x0000);
2748
2749 return ptr - data;
2750}
2751
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002752static int l2cap_build_conf_rsp(struct sock *sk, void *data, u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002753{
2754 struct l2cap_conf_rsp *rsp = data;
2755 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002756
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002757 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002758
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002759 rsp->scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002760 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002761 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002762
2763 return ptr - data;
2764}
2765
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002766static void l2cap_conf_rfc_get(struct sock *sk, void *rsp, int len)
2767{
2768 struct l2cap_pinfo *pi = l2cap_pi(sk);
2769 int type, olen;
2770 unsigned long val;
2771 struct l2cap_conf_rfc rfc;
2772
2773 BT_DBG("sk %p, rsp %p, len %d", sk, rsp, len);
2774
2775 if ((pi->mode != L2CAP_MODE_ERTM) && (pi->mode != L2CAP_MODE_STREAMING))
2776 return;
2777
2778 while (len >= L2CAP_CONF_OPT_SIZE) {
2779 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
2780
2781 switch (type) {
2782 case L2CAP_CONF_RFC:
2783 if (olen == sizeof(rfc))
2784 memcpy(&rfc, (void *)val, olen);
2785 goto done;
2786 }
2787 }
2788
2789done:
2790 switch (rfc.mode) {
2791 case L2CAP_MODE_ERTM:
2792 pi->remote_tx_win = rfc.txwin_size;
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002793 pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
2794 pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002795 pi->mps = le16_to_cpu(rfc.max_pdu_size);
2796 break;
2797 case L2CAP_MODE_STREAMING:
2798 pi->mps = le16_to_cpu(rfc.max_pdu_size);
2799 }
2800}
2801
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002802static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2803{
2804 struct l2cap_cmd_rej *rej = (struct l2cap_cmd_rej *) data;
2805
2806 if (rej->reason != 0x0000)
2807 return 0;
2808
2809 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
2810 cmd->ident == conn->info_ident) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002811 del_timer(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01002812
2813 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002814 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01002815
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002816 l2cap_conn_start(conn);
2817 }
2818
2819 return 0;
2820}
2821
Linus Torvalds1da177e2005-04-16 15:20:36 -07002822static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2823{
2824 struct l2cap_chan_list *list = &conn->chan_list;
2825 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
2826 struct l2cap_conn_rsp rsp;
2827 struct sock *sk, *parent;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002828 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002829
2830 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002831 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002832
2833 BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
2834
2835 /* Check if we have socket listening on psm */
2836 parent = l2cap_get_sock_by_psm(BT_LISTEN, psm, conn->src);
2837 if (!parent) {
2838 result = L2CAP_CR_BAD_PSM;
2839 goto sendresp;
2840 }
2841
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002842 /* Check if the ACL is secure enough (if not SDP) */
2843 if (psm != cpu_to_le16(0x0001) &&
2844 !hci_conn_check_link_mode(conn->hcon)) {
Marcel Holtmann2950f212009-02-12 14:02:50 +01002845 conn->disc_reason = 0x05;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002846 result = L2CAP_CR_SEC_BLOCK;
2847 goto response;
2848 }
2849
Linus Torvalds1da177e2005-04-16 15:20:36 -07002850 result = L2CAP_CR_NO_MEM;
2851
2852 /* Check for backlog size */
2853 if (sk_acceptq_is_full(parent)) {
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09002854 BT_DBG("backlog full %d", parent->sk_ack_backlog);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002855 goto response;
2856 }
2857
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09002858 sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002859 if (!sk)
2860 goto response;
2861
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002862 write_lock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002863
2864 /* Check if we already have channel with that dcid */
2865 if (__l2cap_get_chan_by_dcid(list, scid)) {
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002866 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002867 sock_set_flag(sk, SOCK_ZAPPED);
2868 l2cap_sock_kill(sk);
2869 goto response;
2870 }
2871
2872 hci_conn_hold(conn->hcon);
2873
2874 l2cap_sock_init(sk, parent);
2875 bacpy(&bt_sk(sk)->src, conn->src);
2876 bacpy(&bt_sk(sk)->dst, conn->dst);
2877 l2cap_pi(sk)->psm = psm;
2878 l2cap_pi(sk)->dcid = scid;
2879
2880 __l2cap_chan_add(conn, sk, parent);
2881 dcid = l2cap_pi(sk)->scid;
2882
2883 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
2884
Linus Torvalds1da177e2005-04-16 15:20:36 -07002885 l2cap_pi(sk)->ident = cmd->ident;
2886
Marcel Holtmann984947d2009-02-06 23:35:19 +01002887 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002888 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002889 if (bt_sk(sk)->defer_setup) {
2890 sk->sk_state = BT_CONNECT2;
2891 result = L2CAP_CR_PEND;
2892 status = L2CAP_CS_AUTHOR_PEND;
2893 parent->sk_data_ready(parent, 0);
2894 } else {
2895 sk->sk_state = BT_CONFIG;
2896 result = L2CAP_CR_SUCCESS;
2897 status = L2CAP_CS_NO_INFO;
2898 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002899 } else {
2900 sk->sk_state = BT_CONNECT2;
2901 result = L2CAP_CR_PEND;
2902 status = L2CAP_CS_AUTHEN_PEND;
2903 }
2904 } else {
2905 sk->sk_state = BT_CONNECT2;
2906 result = L2CAP_CR_PEND;
2907 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002908 }
2909
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002910 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002911
2912response:
2913 bh_unlock_sock(parent);
2914
2915sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002916 rsp.scid = cpu_to_le16(scid);
2917 rsp.dcid = cpu_to_le16(dcid);
2918 rsp.result = cpu_to_le16(result);
2919 rsp.status = cpu_to_le16(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002920 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002921
2922 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
2923 struct l2cap_info_req info;
2924 info.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
2925
2926 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
2927 conn->info_ident = l2cap_get_ident(conn);
2928
2929 mod_timer(&conn->info_timer, jiffies +
2930 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
2931
2932 l2cap_send_cmd(conn, conn->info_ident,
2933 L2CAP_INFO_REQ, sizeof(info), &info);
2934 }
2935
Linus Torvalds1da177e2005-04-16 15:20:36 -07002936 return 0;
2937}
2938
2939static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2940{
2941 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
2942 u16 scid, dcid, result, status;
2943 struct sock *sk;
2944 u8 req[128];
2945
2946 scid = __le16_to_cpu(rsp->scid);
2947 dcid = __le16_to_cpu(rsp->dcid);
2948 result = __le16_to_cpu(rsp->result);
2949 status = __le16_to_cpu(rsp->status);
2950
2951 BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
2952
2953 if (scid) {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002954 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2955 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002956 return 0;
2957 } else {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002958 sk = l2cap_get_chan_by_ident(&conn->chan_list, cmd->ident);
2959 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002960 return 0;
2961 }
2962
2963 switch (result) {
2964 case L2CAP_CR_SUCCESS:
2965 sk->sk_state = BT_CONFIG;
2966 l2cap_pi(sk)->ident = 0;
2967 l2cap_pi(sk)->dcid = dcid;
2968 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002969 l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_CONNECT_PEND;
2970
Linus Torvalds1da177e2005-04-16 15:20:36 -07002971 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
2972 l2cap_build_conf_req(sk, req), req);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002973 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002974 break;
2975
2976 case L2CAP_CR_PEND:
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002977 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002978 break;
2979
2980 default:
2981 l2cap_chan_del(sk, ECONNREFUSED);
2982 break;
2983 }
2984
2985 bh_unlock_sock(sk);
2986 return 0;
2987}
2988
Al Viro88219a02007-07-29 00:17:25 -07002989static 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 -07002990{
2991 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
2992 u16 dcid, flags;
2993 u8 rsp[64];
2994 struct sock *sk;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002995 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002996
2997 dcid = __le16_to_cpu(req->dcid);
2998 flags = __le16_to_cpu(req->flags);
2999
3000 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
3001
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003002 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
3003 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003004 return -ENOENT;
3005
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003006 if (sk->sk_state == BT_DISCONN)
3007 goto unlock;
3008
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003009 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07003010 len = cmd_len - sizeof(*req);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003011 if (l2cap_pi(sk)->conf_len + len > sizeof(l2cap_pi(sk)->conf_req)) {
3012 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
3013 l2cap_build_conf_rsp(sk, rsp,
3014 L2CAP_CONF_REJECT, flags), rsp);
3015 goto unlock;
3016 }
3017
3018 /* Store config. */
3019 memcpy(l2cap_pi(sk)->conf_req + l2cap_pi(sk)->conf_len, req->data, len);
3020 l2cap_pi(sk)->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003021
3022 if (flags & 0x0001) {
3023 /* Incomplete config. Send empty response. */
3024 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003025 l2cap_build_conf_rsp(sk, rsp,
3026 L2CAP_CONF_SUCCESS, 0x0001), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003027 goto unlock;
3028 }
3029
3030 /* Complete config. */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003031 len = l2cap_parse_conf_req(sk, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003032 if (len < 0) {
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03003033 l2cap_send_disconn_req(conn, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003034 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003035 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003036
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003037 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003038 l2cap_pi(sk)->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003039
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003040 /* Reset config buffer. */
3041 l2cap_pi(sk)->conf_len = 0;
3042
Marcel Holtmann876d9482007-10-20 13:35:42 +02003043 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE))
3044 goto unlock;
3045
Linus Torvalds1da177e2005-04-16 15:20:36 -07003046 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) {
Joe Perchesf64f9e72009-11-29 16:55:45 -08003047 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) ||
3048 l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003049 l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
3050
Linus Torvalds1da177e2005-04-16 15:20:36 -07003051 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003052
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03003053 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003054 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03003055 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003056 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
3057 l2cap_ertm_init(sk);
3058
Linus Torvalds1da177e2005-04-16 15:20:36 -07003059 l2cap_chan_ready(sk);
Marcel Holtmann876d9482007-10-20 13:35:42 +02003060 goto unlock;
3061 }
3062
3063 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003064 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003065 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003066 l2cap_build_conf_req(sk, buf), buf);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003067 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003068 }
3069
3070unlock:
3071 bh_unlock_sock(sk);
3072 return 0;
3073}
3074
3075static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3076{
3077 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
3078 u16 scid, flags, result;
3079 struct sock *sk;
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003080 int len = cmd->len - sizeof(*rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003081
3082 scid = __le16_to_cpu(rsp->scid);
3083 flags = __le16_to_cpu(rsp->flags);
3084 result = __le16_to_cpu(rsp->result);
3085
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003086 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x",
3087 scid, flags, result);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003088
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003089 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
3090 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003091 return 0;
3092
3093 switch (result) {
3094 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003095 l2cap_conf_rfc_get(sk, rsp->data, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003096 break;
3097
3098 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003099 if (l2cap_pi(sk)->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003100 char req[64];
3101
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02003102 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
3103 l2cap_send_disconn_req(conn, sk);
3104 goto done;
3105 }
3106
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003107 /* throw out any old stored conf requests */
3108 result = L2CAP_CONF_SUCCESS;
3109 len = l2cap_parse_conf_rsp(sk, rsp->data,
3110 len, req, &result);
3111 if (len < 0) {
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03003112 l2cap_send_disconn_req(conn, sk);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003113 goto done;
3114 }
3115
3116 l2cap_send_cmd(conn, l2cap_get_ident(conn),
3117 L2CAP_CONF_REQ, len, req);
3118 l2cap_pi(sk)->num_conf_req++;
3119 if (result != L2CAP_CONF_SUCCESS)
3120 goto done;
3121 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003122 }
3123
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09003124 default:
Marcel Holtmannb1235d7962008-07-14 20:13:54 +02003125 sk->sk_err = ECONNRESET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003126 l2cap_sock_set_timer(sk, HZ * 5);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03003127 l2cap_send_disconn_req(conn, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003128 goto done;
3129 }
3130
3131 if (flags & 0x01)
3132 goto done;
3133
Linus Torvalds1da177e2005-04-16 15:20:36 -07003134 l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE;
3135
3136 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) {
Joe Perchesf64f9e72009-11-29 16:55:45 -08003137 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) ||
3138 l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003139 l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
3140
Linus Torvalds1da177e2005-04-16 15:20:36 -07003141 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003142 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03003143 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03003144 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003145 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
3146 l2cap_ertm_init(sk);
3147
Linus Torvalds1da177e2005-04-16 15:20:36 -07003148 l2cap_chan_ready(sk);
3149 }
3150
3151done:
3152 bh_unlock_sock(sk);
3153 return 0;
3154}
3155
3156static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3157{
3158 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
3159 struct l2cap_disconn_rsp rsp;
3160 u16 dcid, scid;
3161 struct sock *sk;
3162
3163 scid = __le16_to_cpu(req->scid);
3164 dcid = __le16_to_cpu(req->dcid);
3165
3166 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
3167
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003168 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
3169 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003170 return 0;
3171
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003172 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
3173 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003174 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
3175
3176 sk->sk_shutdown = SHUTDOWN_MASK;
3177
3178 l2cap_chan_del(sk, ECONNRESET);
3179 bh_unlock_sock(sk);
3180
3181 l2cap_sock_kill(sk);
3182 return 0;
3183}
3184
3185static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3186{
3187 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
3188 u16 dcid, scid;
3189 struct sock *sk;
3190
3191 scid = __le16_to_cpu(rsp->scid);
3192 dcid = __le16_to_cpu(rsp->dcid);
3193
3194 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
3195
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003196 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
3197 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003198 return 0;
3199
3200 l2cap_chan_del(sk, 0);
3201 bh_unlock_sock(sk);
3202
3203 l2cap_sock_kill(sk);
3204 return 0;
3205}
3206
3207static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3208{
3209 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003210 u16 type;
3211
3212 type = __le16_to_cpu(req->type);
3213
3214 BT_DBG("type 0x%4.4x", type);
3215
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003216 if (type == L2CAP_IT_FEAT_MASK) {
3217 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003218 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003219 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
3220 rsp->type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
3221 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003222 if (enable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003223 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
3224 | L2CAP_FEAT_FCS;
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03003225 put_unaligned_le32(feat_mask, rsp->data);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003226 l2cap_send_cmd(conn, cmd->ident,
3227 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003228 } else if (type == L2CAP_IT_FIXED_CHAN) {
3229 u8 buf[12];
3230 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
3231 rsp->type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3232 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
3233 memcpy(buf + 4, l2cap_fixed_chan, 8);
3234 l2cap_send_cmd(conn, cmd->ident,
3235 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003236 } else {
3237 struct l2cap_info_rsp rsp;
3238 rsp.type = cpu_to_le16(type);
3239 rsp.result = cpu_to_le16(L2CAP_IR_NOTSUPP);
3240 l2cap_send_cmd(conn, cmd->ident,
3241 L2CAP_INFO_RSP, sizeof(rsp), &rsp);
3242 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003243
3244 return 0;
3245}
3246
3247static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3248{
3249 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
3250 u16 type, result;
3251
3252 type = __le16_to_cpu(rsp->type);
3253 result = __le16_to_cpu(rsp->result);
3254
3255 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
3256
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003257 del_timer(&conn->info_timer);
3258
Marcel Holtmann984947d2009-02-06 23:35:19 +01003259 if (type == L2CAP_IT_FEAT_MASK) {
Harvey Harrison83985312008-05-02 16:25:46 -07003260 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003261
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003262 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003263 struct l2cap_info_req req;
3264 req.type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3265
3266 conn->info_ident = l2cap_get_ident(conn);
3267
3268 l2cap_send_cmd(conn, conn->info_ident,
3269 L2CAP_INFO_REQ, sizeof(req), &req);
3270 } else {
3271 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
3272 conn->info_ident = 0;
3273
3274 l2cap_conn_start(conn);
3275 }
3276 } else if (type == L2CAP_IT_FIXED_CHAN) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01003277 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003278 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003279
3280 l2cap_conn_start(conn);
3281 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003282
Linus Torvalds1da177e2005-04-16 15:20:36 -07003283 return 0;
3284}
3285
3286static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
3287{
3288 u8 *data = skb->data;
3289 int len = skb->len;
3290 struct l2cap_cmd_hdr cmd;
3291 int err = 0;
3292
3293 l2cap_raw_recv(conn, skb);
3294
3295 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07003296 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003297 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
3298 data += L2CAP_CMD_HDR_SIZE;
3299 len -= L2CAP_CMD_HDR_SIZE;
3300
Al Viro88219a02007-07-29 00:17:25 -07003301 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003302
Al Viro88219a02007-07-29 00:17:25 -07003303 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 -07003304
Al Viro88219a02007-07-29 00:17:25 -07003305 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003306 BT_DBG("corrupted command");
3307 break;
3308 }
3309
3310 switch (cmd.code) {
3311 case L2CAP_COMMAND_REJ:
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003312 l2cap_command_rej(conn, &cmd, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003313 break;
3314
3315 case L2CAP_CONN_REQ:
3316 err = l2cap_connect_req(conn, &cmd, data);
3317 break;
3318
3319 case L2CAP_CONN_RSP:
3320 err = l2cap_connect_rsp(conn, &cmd, data);
3321 break;
3322
3323 case L2CAP_CONF_REQ:
Al Viro88219a02007-07-29 00:17:25 -07003324 err = l2cap_config_req(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003325 break;
3326
3327 case L2CAP_CONF_RSP:
3328 err = l2cap_config_rsp(conn, &cmd, data);
3329 break;
3330
3331 case L2CAP_DISCONN_REQ:
3332 err = l2cap_disconnect_req(conn, &cmd, data);
3333 break;
3334
3335 case L2CAP_DISCONN_RSP:
3336 err = l2cap_disconnect_rsp(conn, &cmd, data);
3337 break;
3338
3339 case L2CAP_ECHO_REQ:
Al Viro88219a02007-07-29 00:17:25 -07003340 l2cap_send_cmd(conn, cmd.ident, L2CAP_ECHO_RSP, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003341 break;
3342
3343 case L2CAP_ECHO_RSP:
3344 break;
3345
3346 case L2CAP_INFO_REQ:
3347 err = l2cap_information_req(conn, &cmd, data);
3348 break;
3349
3350 case L2CAP_INFO_RSP:
3351 err = l2cap_information_rsp(conn, &cmd, data);
3352 break;
3353
3354 default:
3355 BT_ERR("Unknown signaling command 0x%2.2x", cmd.code);
3356 err = -EINVAL;
3357 break;
3358 }
3359
3360 if (err) {
3361 struct l2cap_cmd_rej rej;
3362 BT_DBG("error %d", err);
3363
3364 /* FIXME: Map err to a valid reason */
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003365 rej.reason = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003366 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
3367 }
3368
Al Viro88219a02007-07-29 00:17:25 -07003369 data += cmd_len;
3370 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003371 }
3372
3373 kfree_skb(skb);
3374}
3375
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003376static int l2cap_check_fcs(struct l2cap_pinfo *pi, struct sk_buff *skb)
3377{
3378 u16 our_fcs, rcv_fcs;
3379 int hdr_size = L2CAP_HDR_SIZE + 2;
3380
3381 if (pi->fcs == L2CAP_FCS_CRC16) {
3382 skb_trim(skb, skb->len - 2);
3383 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
3384 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
3385
3386 if (our_fcs != rcv_fcs)
3387 return -EINVAL;
3388 }
3389 return 0;
3390}
3391
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003392static inline void l2cap_send_i_or_rr_or_rnr(struct sock *sk)
3393{
3394 struct l2cap_pinfo *pi = l2cap_pi(sk);
3395 u16 control = 0;
3396
3397 pi->frames_sent = 0;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003398
3399 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3400
3401 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
3402 control |= L2CAP_SUPER_RCV_NOT_READY | L2CAP_CTRL_FINAL;
3403 l2cap_send_sframe(pi, control);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003404 pi->conn_state |= L2CAP_CONN_RNR_SENT;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003405 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
3406 }
3407
Gustavo F. Padovan4ea727e2010-06-03 16:34:20 -03003408 if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY)
3409 l2cap_retransmit_frames(sk);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003410
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003411 spin_lock_bh(&pi->send_lock);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003412 l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003413 spin_unlock_bh(&pi->send_lock);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003414
3415 if (!(pi->conn_state & L2CAP_CONN_LOCAL_BUSY) &&
3416 pi->frames_sent == 0) {
3417 control |= L2CAP_SUPER_RCV_READY;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003418 l2cap_send_sframe(pi, control);
3419 }
3420}
3421
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003422static 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 -03003423{
3424 struct sk_buff *next_skb;
João Paulo Rechi Vitabfbacc12010-05-31 18:35:44 -03003425 struct l2cap_pinfo *pi = l2cap_pi(sk);
3426 int tx_seq_offset, next_tx_seq_offset;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003427
3428 bt_cb(skb)->tx_seq = tx_seq;
3429 bt_cb(skb)->sar = sar;
3430
3431 next_skb = skb_peek(SREJ_QUEUE(sk));
3432 if (!next_skb) {
3433 __skb_queue_tail(SREJ_QUEUE(sk), skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003434 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003435 }
3436
João Paulo Rechi Vitabfbacc12010-05-31 18:35:44 -03003437 tx_seq_offset = (tx_seq - pi->buffer_seq) % 64;
3438 if (tx_seq_offset < 0)
3439 tx_seq_offset += 64;
3440
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003441 do {
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003442 if (bt_cb(next_skb)->tx_seq == tx_seq)
3443 return -EINVAL;
3444
João Paulo Rechi Vitabfbacc12010-05-31 18:35:44 -03003445 next_tx_seq_offset = (bt_cb(next_skb)->tx_seq -
3446 pi->buffer_seq) % 64;
3447 if (next_tx_seq_offset < 0)
3448 next_tx_seq_offset += 64;
3449
3450 if (next_tx_seq_offset > tx_seq_offset) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003451 __skb_queue_before(SREJ_QUEUE(sk), next_skb, skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003452 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003453 }
3454
3455 if (skb_queue_is_last(SREJ_QUEUE(sk), next_skb))
3456 break;
3457
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003458 } while ((next_skb = skb_queue_next(SREJ_QUEUE(sk), next_skb)));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003459
3460 __skb_queue_tail(SREJ_QUEUE(sk), skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003461
3462 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003463}
3464
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003465static int l2cap_ertm_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
3466{
3467 struct l2cap_pinfo *pi = l2cap_pi(sk);
3468 struct sk_buff *_skb;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003469 int err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003470
3471 switch (control & L2CAP_CTRL_SAR) {
3472 case L2CAP_SDU_UNSEGMENTED:
3473 if (pi->conn_state & L2CAP_CONN_SAR_SDU)
3474 goto drop;
3475
3476 err = sock_queue_rcv_skb(sk, skb);
3477 if (!err)
3478 return err;
3479
3480 break;
3481
3482 case L2CAP_SDU_START:
3483 if (pi->conn_state & L2CAP_CONN_SAR_SDU)
3484 goto drop;
3485
3486 pi->sdu_len = get_unaligned_le16(skb->data);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003487
3488 if (pi->sdu_len > pi->imtu)
3489 goto disconnect;
3490
3491 pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003492 if (!pi->sdu)
3493 return -ENOMEM;
3494
3495 /* pull sdu_len bytes only after alloc, because of Local Busy
3496 * condition we have to be sure that this will be executed
3497 * only once, i.e., when alloc does not fail */
3498 skb_pull(skb, 2);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003499
3500 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3501
3502 pi->conn_state |= L2CAP_CONN_SAR_SDU;
3503 pi->partial_sdu_len = skb->len;
3504 break;
3505
3506 case L2CAP_SDU_CONTINUE:
3507 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3508 goto disconnect;
3509
3510 if (!pi->sdu)
3511 goto disconnect;
3512
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003513 pi->partial_sdu_len += skb->len;
3514 if (pi->partial_sdu_len > pi->sdu_len)
3515 goto drop;
3516
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03003517 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3518
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003519 break;
3520
3521 case L2CAP_SDU_END:
3522 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3523 goto disconnect;
3524
3525 if (!pi->sdu)
3526 goto disconnect;
3527
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003528 if (!(pi->conn_state & L2CAP_CONN_SAR_RETRY)) {
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003529 pi->partial_sdu_len += skb->len;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003530
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003531 if (pi->partial_sdu_len > pi->imtu)
3532 goto drop;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003533
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003534 if (pi->partial_sdu_len != pi->sdu_len)
3535 goto drop;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03003536
3537 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003538 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003539
3540 _skb = skb_clone(pi->sdu, GFP_ATOMIC);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003541 if (!_skb) {
3542 pi->conn_state |= L2CAP_CONN_SAR_RETRY;
3543 return -ENOMEM;
3544 }
3545
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003546 err = sock_queue_rcv_skb(sk, _skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003547 if (err < 0) {
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003548 kfree_skb(_skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003549 pi->conn_state |= L2CAP_CONN_SAR_RETRY;
3550 return err;
3551 }
3552
3553 pi->conn_state &= ~L2CAP_CONN_SAR_RETRY;
3554 pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003555
3556 kfree_skb(pi->sdu);
3557 break;
3558 }
3559
3560 kfree_skb(skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003561 return 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003562
3563drop:
3564 kfree_skb(pi->sdu);
3565 pi->sdu = NULL;
3566
3567disconnect:
3568 l2cap_send_disconn_req(pi->conn, sk);
3569 kfree_skb(skb);
3570 return 0;
3571}
3572
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003573static void l2cap_busy_work(struct work_struct *work)
3574{
3575 DECLARE_WAITQUEUE(wait, current);
3576 struct l2cap_pinfo *pi =
3577 container_of(work, struct l2cap_pinfo, busy_work);
3578 struct sock *sk = (struct sock *)pi;
3579 int n_tries = 0, timeo = HZ/5, err;
3580 struct sk_buff *skb;
3581 u16 control;
3582
3583 lock_sock(sk);
3584
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02003585 add_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003586 while ((skb = skb_peek(BUSY_QUEUE(sk)))) {
3587 set_current_state(TASK_INTERRUPTIBLE);
3588
3589 if (n_tries++ > L2CAP_LOCAL_BUSY_TRIES) {
3590 err = -EBUSY;
3591 l2cap_send_disconn_req(pi->conn, sk);
3592 goto done;
3593 }
3594
3595 if (!timeo)
3596 timeo = HZ/5;
3597
3598 if (signal_pending(current)) {
3599 err = sock_intr_errno(timeo);
3600 goto done;
3601 }
3602
3603 release_sock(sk);
3604 timeo = schedule_timeout(timeo);
3605 lock_sock(sk);
3606
3607 err = sock_error(sk);
3608 if (err)
3609 goto done;
3610
3611 while ((skb = skb_dequeue(BUSY_QUEUE(sk)))) {
3612 control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
3613 err = l2cap_ertm_reassembly_sdu(sk, skb, control);
3614 if (err < 0) {
3615 skb_queue_head(BUSY_QUEUE(sk), skb);
3616 break;
3617 }
3618
3619 pi->buffer_seq = (pi->buffer_seq + 1) % 64;
3620 }
3621
3622 if (!skb)
3623 break;
3624 }
3625
3626 if (!(pi->conn_state & L2CAP_CONN_RNR_SENT))
3627 goto done;
3628
3629 control = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3630 control |= L2CAP_SUPER_RCV_READY | L2CAP_CTRL_POLL;
3631 l2cap_send_sframe(pi, control);
3632 l2cap_pi(sk)->retry_count = 1;
3633
3634 del_timer(&pi->retrans_timer);
3635 __mod_monitor_timer();
3636
3637 l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
3638
3639done:
3640 pi->conn_state &= ~L2CAP_CONN_LOCAL_BUSY;
3641 pi->conn_state &= ~L2CAP_CONN_RNR_SENT;
3642
3643 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02003644 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003645
3646 release_sock(sk);
3647}
3648
3649static int l2cap_push_rx_skb(struct sock *sk, struct sk_buff *skb, u16 control)
3650{
3651 struct l2cap_pinfo *pi = l2cap_pi(sk);
3652 int sctrl, err;
3653
3654 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
3655 bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT;
3656 __skb_queue_tail(BUSY_QUEUE(sk), skb);
3657 return -EBUSY;
3658 }
3659
3660 err = l2cap_ertm_reassembly_sdu(sk, skb, control);
3661 if (err >= 0) {
3662 pi->buffer_seq = (pi->buffer_seq + 1) % 64;
3663 return err;
3664 }
3665
3666 /* Busy Condition */
3667 pi->conn_state |= L2CAP_CONN_LOCAL_BUSY;
3668 bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT;
3669 __skb_queue_tail(BUSY_QUEUE(sk), skb);
3670
3671 sctrl = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3672 sctrl |= L2CAP_SUPER_RCV_NOT_READY;
3673 l2cap_send_sframe(pi, sctrl);
3674
3675 pi->conn_state |= L2CAP_CONN_RNR_SENT;
3676
Gustavo F. Padovan7fe9b292010-05-12 18:32:04 -03003677 del_timer(&pi->ack_timer);
3678
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003679 queue_work(_busy_wq, &pi->busy_work);
3680
3681 return err;
3682}
3683
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003684static int l2cap_streaming_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003685{
3686 struct l2cap_pinfo *pi = l2cap_pi(sk);
3687 struct sk_buff *_skb;
3688 int err = -EINVAL;
3689
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003690 /*
3691 * TODO: We have to notify the userland if some data is lost with the
3692 * Streaming Mode.
3693 */
3694
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003695 switch (control & L2CAP_CTRL_SAR) {
3696 case L2CAP_SDU_UNSEGMENTED:
3697 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3698 kfree_skb(pi->sdu);
3699 break;
3700 }
3701
3702 err = sock_queue_rcv_skb(sk, skb);
3703 if (!err)
3704 return 0;
3705
3706 break;
3707
3708 case L2CAP_SDU_START:
3709 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3710 kfree_skb(pi->sdu);
3711 break;
3712 }
3713
3714 pi->sdu_len = get_unaligned_le16(skb->data);
3715 skb_pull(skb, 2);
3716
Gustavo F. Padovan052897c2010-05-01 16:15:40 -03003717 if (pi->sdu_len > pi->imtu) {
3718 err = -EMSGSIZE;
3719 break;
3720 }
3721
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003722 pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
3723 if (!pi->sdu) {
3724 err = -ENOMEM;
3725 break;
3726 }
3727
3728 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3729
3730 pi->conn_state |= L2CAP_CONN_SAR_SDU;
3731 pi->partial_sdu_len = skb->len;
3732 err = 0;
3733 break;
3734
3735 case L2CAP_SDU_CONTINUE:
3736 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3737 break;
3738
3739 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3740
3741 pi->partial_sdu_len += skb->len;
3742 if (pi->partial_sdu_len > pi->sdu_len)
3743 kfree_skb(pi->sdu);
3744 else
3745 err = 0;
3746
3747 break;
3748
3749 case L2CAP_SDU_END:
3750 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3751 break;
3752
3753 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3754
3755 pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
3756 pi->partial_sdu_len += skb->len;
3757
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003758 if (pi->partial_sdu_len > pi->imtu)
3759 goto drop;
3760
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003761 if (pi->partial_sdu_len == pi->sdu_len) {
3762 _skb = skb_clone(pi->sdu, GFP_ATOMIC);
3763 err = sock_queue_rcv_skb(sk, _skb);
3764 if (err < 0)
3765 kfree_skb(_skb);
3766 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003767 err = 0;
3768
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003769drop:
3770 kfree_skb(pi->sdu);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003771 break;
3772 }
3773
3774 kfree_skb(skb);
3775 return err;
3776}
3777
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003778static void l2cap_check_srej_gap(struct sock *sk, u8 tx_seq)
3779{
3780 struct sk_buff *skb;
Gustavo F. Padovanafefdbc2010-05-01 16:15:43 -03003781 u16 control;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003782
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003783 while ((skb = skb_peek(SREJ_QUEUE(sk)))) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003784 if (bt_cb(skb)->tx_seq != tx_seq)
3785 break;
3786
3787 skb = skb_dequeue(SREJ_QUEUE(sk));
Gustavo F. Padovanafefdbc2010-05-01 16:15:43 -03003788 control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003789 l2cap_ertm_reassembly_sdu(sk, skb, control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003790 l2cap_pi(sk)->buffer_seq_srej =
3791 (l2cap_pi(sk)->buffer_seq_srej + 1) % 64;
Gustavo F. Padovan8ff50ec2010-05-10 19:34:11 -03003792 tx_seq = (tx_seq + 1) % 64;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003793 }
3794}
3795
3796static void l2cap_resend_srejframe(struct sock *sk, u8 tx_seq)
3797{
3798 struct l2cap_pinfo *pi = l2cap_pi(sk);
3799 struct srej_list *l, *tmp;
3800 u16 control;
3801
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003802 list_for_each_entry_safe(l, tmp, SREJ_LIST(sk), list) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003803 if (l->tx_seq == tx_seq) {
3804 list_del(&l->list);
3805 kfree(l);
3806 return;
3807 }
3808 control = L2CAP_SUPER_SELECT_REJECT;
3809 control |= l->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3810 l2cap_send_sframe(pi, control);
3811 list_del(&l->list);
3812 list_add_tail(&l->list, SREJ_LIST(sk));
3813 }
3814}
3815
3816static void l2cap_send_srejframe(struct sock *sk, u8 tx_seq)
3817{
3818 struct l2cap_pinfo *pi = l2cap_pi(sk);
3819 struct srej_list *new;
3820 u16 control;
3821
3822 while (tx_seq != pi->expected_tx_seq) {
3823 control = L2CAP_SUPER_SELECT_REJECT;
3824 control |= pi->expected_tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3825 l2cap_send_sframe(pi, control);
3826
3827 new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC);
Gustavo F. Padovan8ff50ec2010-05-10 19:34:11 -03003828 new->tx_seq = pi->expected_tx_seq;
3829 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003830 list_add_tail(&new->list, SREJ_LIST(sk));
3831 }
Gustavo F. Padovan8ff50ec2010-05-10 19:34:11 -03003832 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003833}
3834
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03003835static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
3836{
3837 struct l2cap_pinfo *pi = l2cap_pi(sk);
3838 u8 tx_seq = __get_txseq(rx_control);
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003839 u8 req_seq = __get_reqseq(rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003840 u8 sar = rx_control >> L2CAP_CTRL_SAR_SHIFT;
Gustavo F. Padovanf6337c72010-05-10 18:32:04 -03003841 int tx_seq_offset, expected_tx_seq_offset;
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03003842 int num_to_ack = (pi->tx_win/6) + 1;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03003843 int err = 0;
3844
3845 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
3846
Gustavo F. Padovan9b16dc62010-05-05 20:05:57 -03003847 if (L2CAP_CTRL_FINAL & rx_control &&
3848 l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) {
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003849 del_timer(&pi->monitor_timer);
3850 if (pi->unacked_frames > 0)
3851 __mod_retrans_timer();
3852 pi->conn_state &= ~L2CAP_CONN_WAIT_F;
3853 }
3854
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003855 pi->expected_ack_seq = req_seq;
3856 l2cap_drop_acked_frames(sk);
3857
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003858 if (tx_seq == pi->expected_tx_seq)
3859 goto expected;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03003860
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003861 tx_seq_offset = (tx_seq - pi->buffer_seq) % 64;
3862 if (tx_seq_offset < 0)
3863 tx_seq_offset += 64;
3864
3865 /* invalid tx_seq */
3866 if (tx_seq_offset >= pi->tx_win) {
3867 l2cap_send_disconn_req(pi->conn, sk);
3868 goto drop;
3869 }
3870
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003871 if (pi->conn_state == L2CAP_CONN_LOCAL_BUSY)
3872 goto drop;
3873
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003874 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3875 struct srej_list *first;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03003876
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003877 first = list_first_entry(SREJ_LIST(sk),
3878 struct srej_list, list);
3879 if (tx_seq == first->tx_seq) {
3880 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3881 l2cap_check_srej_gap(sk, tx_seq);
3882
3883 list_del(&first->list);
3884 kfree(first);
3885
3886 if (list_empty(SREJ_LIST(sk))) {
3887 pi->buffer_seq = pi->buffer_seq_srej;
3888 pi->conn_state &= ~L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan855666cc2010-05-01 16:15:40 -03003889 l2cap_send_ack(pi);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003890 }
3891 } else {
3892 struct srej_list *l;
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003893
3894 /* duplicated tx_seq */
3895 if (l2cap_add_to_srej_queue(sk, skb, tx_seq, sar) < 0)
3896 goto drop;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003897
3898 list_for_each_entry(l, SREJ_LIST(sk), list) {
3899 if (l->tx_seq == tx_seq) {
3900 l2cap_resend_srejframe(sk, tx_seq);
3901 return 0;
3902 }
3903 }
3904 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003905 }
3906 } else {
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003907 expected_tx_seq_offset =
3908 (pi->expected_tx_seq - pi->buffer_seq) % 64;
3909 if (expected_tx_seq_offset < 0)
3910 expected_tx_seq_offset += 64;
3911
3912 /* duplicated tx_seq */
3913 if (tx_seq_offset < expected_tx_seq_offset)
3914 goto drop;
3915
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003916 pi->conn_state |= L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003917
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003918 INIT_LIST_HEAD(SREJ_LIST(sk));
3919 pi->buffer_seq_srej = pi->buffer_seq;
3920
3921 __skb_queue_head_init(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003922 __skb_queue_head_init(BUSY_QUEUE(sk));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003923 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3924
Gustavo F. Padovanef54fd92009-08-20 22:26:04 -03003925 pi->conn_state |= L2CAP_CONN_SEND_PBIT;
3926
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003927 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan7fe9b292010-05-12 18:32:04 -03003928
3929 del_timer(&pi->ack_timer);
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03003930 }
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003931 return 0;
3932
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003933expected:
3934 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
3935
3936 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
Gustavo F. Padovan3b1a9f32010-05-01 16:15:42 -03003937 bt_cb(skb)->tx_seq = tx_seq;
3938 bt_cb(skb)->sar = sar;
3939 __skb_queue_tail(SREJ_QUEUE(sk), skb);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003940 return 0;
3941 }
3942
Gustavo F. Padovan2ece3682010-06-16 17:21:44 -03003943 err = l2cap_push_rx_skb(sk, skb, rx_control);
3944 if (err < 0)
3945 return 0;
3946
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03003947 if (rx_control & L2CAP_CTRL_FINAL) {
3948 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3949 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003950 else
3951 l2cap_retransmit_frames(sk);
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03003952 }
3953
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003954 __mod_ack_timer();
3955
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03003956 pi->num_acked = (pi->num_acked + 1) % num_to_ack;
3957 if (pi->num_acked == num_to_ack - 1)
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03003958 l2cap_send_ack(pi);
3959
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003960 return 0;
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003961
3962drop:
3963 kfree_skb(skb);
3964 return 0;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03003965}
3966
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003967static inline void l2cap_data_channel_rrframe(struct sock *sk, u16 rx_control)
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03003968{
3969 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan6e3a5982010-05-01 16:15:38 -03003970
3971 pi->expected_ack_seq = __get_reqseq(rx_control);
3972 l2cap_drop_acked_frames(sk);
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03003973
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003974 if (rx_control & L2CAP_CTRL_POLL) {
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03003975 pi->conn_state |= L2CAP_CONN_SEND_FBIT;
Gustavo F. Padovan05fbd892010-05-01 16:15:39 -03003976 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3977 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
3978 (pi->unacked_frames > 0))
3979 __mod_retrans_timer();
3980
3981 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3982 l2cap_send_srejtail(sk);
3983 } else {
3984 l2cap_send_i_or_rr_or_rnr(sk);
Gustavo F. Padovan05fbd892010-05-01 16:15:39 -03003985 }
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003986
3987 } else if (rx_control & L2CAP_CTRL_FINAL) {
3988 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003989
3990 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3991 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003992 else
3993 l2cap_retransmit_frames(sk);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003994
3995 } else {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003996 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;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004001 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004002 l2cap_send_ack(pi);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004003 } else {
4004 spin_lock_bh(&pi->send_lock);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004005 l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004006 spin_unlock_bh(&pi->send_lock);
4007 }
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004008 }
4009}
4010
4011static inline void l2cap_data_channel_rejframe(struct sock *sk, u16 rx_control)
4012{
4013 struct l2cap_pinfo *pi = l2cap_pi(sk);
4014 u8 tx_seq = __get_reqseq(rx_control);
4015
4016 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
4017
Gustavo F. Padovan8abb52e2010-05-01 16:15:38 -03004018 pi->expected_ack_seq = tx_seq;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004019 l2cap_drop_acked_frames(sk);
4020
4021 if (rx_control & L2CAP_CTRL_FINAL) {
4022 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
4023 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004024 else
4025 l2cap_retransmit_frames(sk);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004026 } else {
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004027 l2cap_retransmit_frames(sk);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004028
Gustavo F. Padovan0301ef02010-05-05 20:56:43 -03004029 if (pi->conn_state & L2CAP_CONN_WAIT_F)
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004030 pi->conn_state |= L2CAP_CONN_REJ_ACT;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004031 }
4032}
4033static inline void l2cap_data_channel_srejframe(struct sock *sk, u16 rx_control)
4034{
4035 struct l2cap_pinfo *pi = l2cap_pi(sk);
4036 u8 tx_seq = __get_reqseq(rx_control);
4037
4038 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
4039
4040 if (rx_control & L2CAP_CTRL_POLL) {
4041 pi->expected_ack_seq = tx_seq;
4042 l2cap_drop_acked_frames(sk);
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03004043
4044 pi->conn_state |= L2CAP_CONN_SEND_FBIT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004045 l2cap_retransmit_one_frame(sk, tx_seq);
4046
4047 spin_lock_bh(&pi->send_lock);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004048 l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004049 spin_unlock_bh(&pi->send_lock);
4050
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004051 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
4052 pi->srej_save_reqseq = tx_seq;
4053 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
4054 }
4055 } else if (rx_control & L2CAP_CTRL_FINAL) {
4056 if ((pi->conn_state & L2CAP_CONN_SREJ_ACT) &&
4057 pi->srej_save_reqseq == tx_seq)
4058 pi->conn_state &= ~L2CAP_CONN_SREJ_ACT;
4059 else
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004060 l2cap_retransmit_one_frame(sk, tx_seq);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004061 } else {
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004062 l2cap_retransmit_one_frame(sk, tx_seq);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004063 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
4064 pi->srej_save_reqseq = tx_seq;
4065 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
4066 }
4067 }
4068}
4069
4070static inline void l2cap_data_channel_rnrframe(struct sock *sk, u16 rx_control)
4071{
4072 struct l2cap_pinfo *pi = l2cap_pi(sk);
4073 u8 tx_seq = __get_reqseq(rx_control);
4074
4075 pi->conn_state |= L2CAP_CONN_REMOTE_BUSY;
4076 pi->expected_ack_seq = tx_seq;
4077 l2cap_drop_acked_frames(sk);
4078
Gustavo F. Padovan3cb123d2010-05-29 02:24:35 -03004079 if (rx_control & L2CAP_CTRL_POLL)
4080 pi->conn_state |= L2CAP_CONN_SEND_FBIT;
4081
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03004082 if (!(pi->conn_state & L2CAP_CONN_SREJ_SENT)) {
4083 del_timer(&pi->retrans_timer);
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -03004084 if (rx_control & L2CAP_CTRL_POLL)
4085 l2cap_send_rr_or_rnr(pi, L2CAP_CTRL_FINAL);
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03004086 return;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004087 }
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03004088
4089 if (rx_control & L2CAP_CTRL_POLL)
4090 l2cap_send_srejtail(sk);
4091 else
4092 l2cap_send_sframe(pi, L2CAP_SUPER_RCV_READY);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004093}
4094
4095static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
4096{
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03004097 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
4098
Gustavo F. Padovan9b16dc62010-05-05 20:05:57 -03004099 if (L2CAP_CTRL_FINAL & rx_control &&
4100 l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004101 del_timer(&l2cap_pi(sk)->monitor_timer);
4102 if (l2cap_pi(sk)->unacked_frames > 0)
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03004103 __mod_retrans_timer();
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004104 l2cap_pi(sk)->conn_state &= ~L2CAP_CONN_WAIT_F;
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03004105 }
4106
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03004107 switch (rx_control & L2CAP_CTRL_SUPERVISE) {
4108 case L2CAP_SUPER_RCV_READY:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004109 l2cap_data_channel_rrframe(sk, rx_control);
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03004110 break;
4111
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03004112 case L2CAP_SUPER_REJECT:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004113 l2cap_data_channel_rejframe(sk, rx_control);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03004114 break;
4115
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03004116 case L2CAP_SUPER_SELECT_REJECT:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004117 l2cap_data_channel_srejframe(sk, rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004118 break;
4119
4120 case L2CAP_SUPER_RCV_NOT_READY:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004121 l2cap_data_channel_rnrframe(sk, rx_control);
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03004122 break;
4123 }
4124
Gustavo F. Padovanfaaebd12010-05-01 16:15:35 -03004125 kfree_skb(skb);
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03004126 return 0;
4127}
4128
Linus Torvalds1da177e2005-04-16 15:20:36 -07004129static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk_buff *skb)
4130{
4131 struct sock *sk;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004132 struct l2cap_pinfo *pi;
Nathan Holstein51893f82010-06-09 15:46:25 -04004133 u16 control;
Gustavo F. Padovanf6337c72010-05-10 18:32:04 -03004134 u8 tx_seq, req_seq;
Nathan Holstein51893f82010-06-09 15:46:25 -04004135 int len, next_tx_seq_offset, req_seq_offset;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004136
4137 sk = l2cap_get_chan_by_scid(&conn->chan_list, cid);
4138 if (!sk) {
4139 BT_DBG("unknown cid 0x%4.4x", cid);
4140 goto drop;
4141 }
4142
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004143 pi = l2cap_pi(sk);
4144
Linus Torvalds1da177e2005-04-16 15:20:36 -07004145 BT_DBG("sk %p, len %d", sk, skb->len);
4146
4147 if (sk->sk_state != BT_CONNECTED)
4148 goto drop;
4149
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004150 switch (pi->mode) {
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03004151 case L2CAP_MODE_BASIC:
4152 /* If socket recv buffers overflows we drop data here
4153 * which is *bad* because L2CAP has to be reliable.
4154 * But we don't have any other choice. L2CAP doesn't
4155 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07004156
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004157 if (pi->imtu < skb->len)
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03004158 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004159
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03004160 if (!sock_queue_rcv_skb(sk, skb))
4161 goto done;
4162 break;
4163
4164 case L2CAP_MODE_ERTM:
4165 control = get_unaligned_le16(skb->data);
4166 skb_pull(skb, 2);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03004167 len = skb->len;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03004168
Gustavo F. Padovan26000082010-05-11 22:02:00 -03004169 /*
4170 * We can just drop the corrupted I-frame here.
4171 * Receiver will miss it and start proper recovery
4172 * procedures and ask retransmission.
4173 */
4174 if (l2cap_check_fcs(pi, skb))
4175 goto drop;
4176
Gustavo F. Padovanbc1b1f82010-05-11 22:14:00 -03004177 if (__is_sar_start(control) && __is_iframe(control))
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03004178 len -= 2;
4179
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004180 if (pi->fcs == L2CAP_FCS_CRC16)
4181 len -= 2;
4182
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004183 if (len > pi->mps) {
4184 l2cap_send_disconn_req(pi->conn, sk);
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03004185 goto drop;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004186 }
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03004187
João Paulo Rechi Vita01760bd2010-05-01 16:15:43 -03004188 req_seq = __get_reqseq(control);
4189 req_seq_offset = (req_seq - pi->expected_ack_seq) % 64;
4190 if (req_seq_offset < 0)
4191 req_seq_offset += 64;
4192
4193 next_tx_seq_offset =
4194 (pi->next_tx_seq - pi->expected_ack_seq) % 64;
4195 if (next_tx_seq_offset < 0)
4196 next_tx_seq_offset += 64;
4197
4198 /* check for invalid req-seq */
4199 if (req_seq_offset > next_tx_seq_offset) {
4200 l2cap_send_disconn_req(pi->conn, sk);
4201 goto drop;
4202 }
4203
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004204 if (__is_iframe(control)) {
Nathan Holstein51893f82010-06-09 15:46:25 -04004205 if (len < 0) {
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004206 l2cap_send_disconn_req(pi->conn, sk);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004207 goto drop;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004208 }
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004209
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02004210 l2cap_data_channel_iframe(sk, control, skb);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004211 } else {
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004212 if (len != 0) {
4213 l2cap_send_disconn_req(pi->conn, sk);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004214 goto drop;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004215 }
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004216
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02004217 l2cap_data_channel_sframe(sk, control, skb);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004218 }
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03004219
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02004220 goto done;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03004221
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004222 case L2CAP_MODE_STREAMING:
4223 control = get_unaligned_le16(skb->data);
4224 skb_pull(skb, 2);
4225 len = skb->len;
4226
Gustavo F. Padovan26000082010-05-11 22:02:00 -03004227 if (l2cap_check_fcs(pi, skb))
4228 goto drop;
4229
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004230 if (__is_sar_start(control))
4231 len -= 2;
4232
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004233 if (pi->fcs == L2CAP_FCS_CRC16)
4234 len -= 2;
4235
Nathan Holstein51893f82010-06-09 15:46:25 -04004236 if (len > pi->mps || len < 0 || __is_sframe(control))
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004237 goto drop;
4238
4239 tx_seq = __get_txseq(control);
4240
4241 if (pi->expected_tx_seq == tx_seq)
4242 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
4243 else
Gustavo F. Padovan7dffe422010-05-01 16:15:36 -03004244 pi->expected_tx_seq = (tx_seq + 1) % 64;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004245
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004246 l2cap_streaming_reassembly_sdu(sk, skb, control);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004247
4248 goto done;
4249
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03004250 default:
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03004251 BT_DBG("sk %p: bad mode 0x%2.2x", sk, pi->mode);
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03004252 break;
4253 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004254
4255drop:
4256 kfree_skb(skb);
4257
4258done:
Marcel Holtmann01394182006-07-03 10:02:46 +02004259 if (sk)
4260 bh_unlock_sock(sk);
4261
Linus Torvalds1da177e2005-04-16 15:20:36 -07004262 return 0;
4263}
4264
Al Viro8e036fc2007-07-29 00:16:36 -07004265static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004266{
4267 struct sock *sk;
4268
4269 sk = l2cap_get_sock_by_psm(0, psm, conn->src);
4270 if (!sk)
4271 goto drop;
4272
4273 BT_DBG("sk %p, len %d", sk, skb->len);
4274
4275 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_CONNECTED)
4276 goto drop;
4277
4278 if (l2cap_pi(sk)->imtu < skb->len)
4279 goto drop;
4280
4281 if (!sock_queue_rcv_skb(sk, skb))
4282 goto done;
4283
4284drop:
4285 kfree_skb(skb);
4286
4287done:
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03004288 if (sk)
4289 bh_unlock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004290 return 0;
4291}
4292
4293static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
4294{
4295 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07004296 u16 cid, len;
4297 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004298
4299 skb_pull(skb, L2CAP_HDR_SIZE);
4300 cid = __le16_to_cpu(lh->cid);
4301 len = __le16_to_cpu(lh->len);
4302
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03004303 if (len != skb->len) {
4304 kfree_skb(skb);
4305 return;
4306 }
4307
Linus Torvalds1da177e2005-04-16 15:20:36 -07004308 BT_DBG("len %d, cid 0x%4.4x", len, cid);
4309
4310 switch (cid) {
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03004311 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07004312 l2cap_sig_channel(conn, skb);
4313 break;
4314
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03004315 case L2CAP_CID_CONN_LESS:
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03004316 psm = get_unaligned_le16(skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004317 skb_pull(skb, 2);
4318 l2cap_conless_channel(conn, psm, skb);
4319 break;
4320
4321 default:
4322 l2cap_data_channel(conn, cid, skb);
4323 break;
4324 }
4325}
4326
4327/* ---- L2CAP interface with lower layer (HCI) ---- */
4328
4329static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
4330{
4331 int exact = 0, lm1 = 0, lm2 = 0;
4332 register struct sock *sk;
4333 struct hlist_node *node;
4334
4335 if (type != ACL_LINK)
4336 return 0;
4337
4338 BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
4339
4340 /* Find listening sockets and check their link_mode */
4341 read_lock(&l2cap_sk_list.lock);
4342 sk_for_each(sk, node, &l2cap_sk_list.head) {
4343 if (sk->sk_state != BT_LISTEN)
4344 continue;
4345
4346 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01004347 lm1 |= HCI_LM_ACCEPT;
4348 if (l2cap_pi(sk)->role_switch)
4349 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004350 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01004351 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
4352 lm2 |= HCI_LM_ACCEPT;
4353 if (l2cap_pi(sk)->role_switch)
4354 lm2 |= HCI_LM_MASTER;
4355 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004356 }
4357 read_unlock(&l2cap_sk_list.lock);
4358
4359 return exact ? lm1 : lm2;
4360}
4361
4362static int l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
4363{
Marcel Holtmann01394182006-07-03 10:02:46 +02004364 struct l2cap_conn *conn;
4365
Linus Torvalds1da177e2005-04-16 15:20:36 -07004366 BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
4367
4368 if (hcon->type != ACL_LINK)
4369 return 0;
4370
4371 if (!status) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004372 conn = l2cap_conn_add(hcon, status);
4373 if (conn)
4374 l2cap_conn_ready(conn);
Marcel Holtmann01394182006-07-03 10:02:46 +02004375 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -07004376 l2cap_conn_del(hcon, bt_err(status));
4377
4378 return 0;
4379}
4380
Marcel Holtmann2950f212009-02-12 14:02:50 +01004381static int l2cap_disconn_ind(struct hci_conn *hcon)
4382{
4383 struct l2cap_conn *conn = hcon->l2cap_data;
4384
4385 BT_DBG("hcon %p", hcon);
4386
4387 if (hcon->type != ACL_LINK || !conn)
4388 return 0x13;
4389
4390 return conn->disc_reason;
4391}
4392
4393static int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004394{
4395 BT_DBG("hcon %p reason %d", hcon, reason);
4396
4397 if (hcon->type != ACL_LINK)
4398 return 0;
4399
4400 l2cap_conn_del(hcon, bt_err(reason));
Marcel Holtmann01394182006-07-03 10:02:46 +02004401
Linus Torvalds1da177e2005-04-16 15:20:36 -07004402 return 0;
4403}
4404
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004405static inline void l2cap_check_encryption(struct sock *sk, u8 encrypt)
4406{
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03004407 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM)
Marcel Holtmann255c7602009-02-04 21:07:19 +01004408 return;
4409
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004410 if (encrypt == 0x00) {
4411 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM) {
4412 l2cap_sock_clear_timer(sk);
4413 l2cap_sock_set_timer(sk, HZ * 5);
4414 } else if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
4415 __l2cap_sock_close(sk, ECONNREFUSED);
4416 } else {
4417 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM)
4418 l2cap_sock_clear_timer(sk);
4419 }
4420}
4421
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004422static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004423{
4424 struct l2cap_chan_list *l;
Marcel Holtmann40be4922008-07-14 20:13:50 +02004425 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004426 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004427
Marcel Holtmann01394182006-07-03 10:02:46 +02004428 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004429 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02004430
Linus Torvalds1da177e2005-04-16 15:20:36 -07004431 l = &conn->chan_list;
4432
4433 BT_DBG("conn %p", conn);
4434
4435 read_lock(&l->lock);
4436
4437 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
4438 bh_lock_sock(sk);
4439
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01004440 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND) {
4441 bh_unlock_sock(sk);
4442 continue;
4443 }
4444
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004445 if (!status && (sk->sk_state == BT_CONNECTED ||
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004446 sk->sk_state == BT_CONFIG)) {
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004447 l2cap_check_encryption(sk, encrypt);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02004448 bh_unlock_sock(sk);
4449 continue;
4450 }
4451
Marcel Holtmannb1235d7962008-07-14 20:13:54 +02004452 if (sk->sk_state == BT_CONNECT) {
4453 if (!status) {
4454 struct l2cap_conn_req req;
4455 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
4456 req.psm = l2cap_pi(sk)->psm;
4457
4458 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03004459 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Marcel Holtmannb1235d7962008-07-14 20:13:54 +02004460
4461 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
4462 L2CAP_CONN_REQ, sizeof(req), &req);
4463 } else {
4464 l2cap_sock_clear_timer(sk);
4465 l2cap_sock_set_timer(sk, HZ / 10);
4466 }
4467 } else if (sk->sk_state == BT_CONNECT2) {
4468 struct l2cap_conn_rsp rsp;
4469 __u16 result;
4470
4471 if (!status) {
4472 sk->sk_state = BT_CONFIG;
4473 result = L2CAP_CR_SUCCESS;
4474 } else {
4475 sk->sk_state = BT_DISCONN;
4476 l2cap_sock_set_timer(sk, HZ / 10);
4477 result = L2CAP_CR_SEC_BLOCK;
4478 }
4479
4480 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
4481 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
4482 rsp.result = cpu_to_le16(result);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02004483 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannb1235d7962008-07-14 20:13:54 +02004484 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
4485 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004486 }
4487
Linus Torvalds1da177e2005-04-16 15:20:36 -07004488 bh_unlock_sock(sk);
4489 }
4490
4491 read_unlock(&l->lock);
Marcel Holtmannb1235d7962008-07-14 20:13:54 +02004492
Linus Torvalds1da177e2005-04-16 15:20:36 -07004493 return 0;
4494}
4495
4496static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
4497{
4498 struct l2cap_conn *conn = hcon->l2cap_data;
4499
4500 if (!conn && !(conn = l2cap_conn_add(hcon, 0)))
4501 goto drop;
4502
4503 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
4504
4505 if (flags & ACL_START) {
4506 struct l2cap_hdr *hdr;
4507 int len;
4508
4509 if (conn->rx_len) {
4510 BT_ERR("Unexpected start frame (len %d)", skb->len);
4511 kfree_skb(conn->rx_skb);
4512 conn->rx_skb = NULL;
4513 conn->rx_len = 0;
4514 l2cap_conn_unreliable(conn, ECOMM);
4515 }
4516
4517 if (skb->len < 2) {
4518 BT_ERR("Frame is too short (len %d)", skb->len);
4519 l2cap_conn_unreliable(conn, ECOMM);
4520 goto drop;
4521 }
4522
4523 hdr = (struct l2cap_hdr *) skb->data;
4524 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
4525
4526 if (len == skb->len) {
4527 /* Complete frame received */
4528 l2cap_recv_frame(conn, skb);
4529 return 0;
4530 }
4531
4532 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
4533
4534 if (skb->len > len) {
4535 BT_ERR("Frame is too long (len %d, expected len %d)",
4536 skb->len, len);
4537 l2cap_conn_unreliable(conn, ECOMM);
4538 goto drop;
4539 }
4540
4541 /* Allocate skb for the complete frame (with header) */
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03004542 conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC);
4543 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004544 goto drop;
4545
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03004546 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004547 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004548 conn->rx_len = len - skb->len;
4549 } else {
4550 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
4551
4552 if (!conn->rx_len) {
4553 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
4554 l2cap_conn_unreliable(conn, ECOMM);
4555 goto drop;
4556 }
4557
4558 if (skb->len > conn->rx_len) {
4559 BT_ERR("Fragment is too long (len %d, expected %d)",
4560 skb->len, conn->rx_len);
4561 kfree_skb(conn->rx_skb);
4562 conn->rx_skb = NULL;
4563 conn->rx_len = 0;
4564 l2cap_conn_unreliable(conn, ECOMM);
4565 goto drop;
4566 }
4567
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03004568 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004569 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004570 conn->rx_len -= skb->len;
4571
4572 if (!conn->rx_len) {
4573 /* Complete frame received */
4574 l2cap_recv_frame(conn, conn->rx_skb);
4575 conn->rx_skb = NULL;
4576 }
4577 }
4578
4579drop:
4580 kfree_skb(skb);
4581 return 0;
4582}
4583
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004584static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004585{
4586 struct sock *sk;
4587 struct hlist_node *node;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004588
4589 read_lock_bh(&l2cap_sk_list.lock);
4590
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004591 sk_for_each(sk, node, &l2cap_sk_list.head) {
4592 struct l2cap_pinfo *pi = l2cap_pi(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004593
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004594 seq_printf(f, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d\n",
4595 batostr(&bt_sk(sk)->src),
4596 batostr(&bt_sk(sk)->dst),
4597 sk->sk_state, __le16_to_cpu(pi->psm),
4598 pi->scid, pi->dcid,
4599 pi->imtu, pi->omtu, pi->sec_level);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004600 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004601
Linus Torvalds1da177e2005-04-16 15:20:36 -07004602 read_unlock_bh(&l2cap_sk_list.lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004603
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004604 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004605}
4606
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004607static int l2cap_debugfs_open(struct inode *inode, struct file *file)
4608{
4609 return single_open(file, l2cap_debugfs_show, inode->i_private);
4610}
4611
4612static const struct file_operations l2cap_debugfs_fops = {
4613 .open = l2cap_debugfs_open,
4614 .read = seq_read,
4615 .llseek = seq_lseek,
4616 .release = single_release,
4617};
4618
4619static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004620
Eric Dumazet90ddc4f2005-12-22 12:49:22 -08004621static const struct proto_ops l2cap_sock_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004622 .family = PF_BLUETOOTH,
4623 .owner = THIS_MODULE,
4624 .release = l2cap_sock_release,
4625 .bind = l2cap_sock_bind,
4626 .connect = l2cap_sock_connect,
4627 .listen = l2cap_sock_listen,
4628 .accept = l2cap_sock_accept,
4629 .getname = l2cap_sock_getname,
4630 .sendmsg = l2cap_sock_sendmsg,
Marcel Holtmannf66dc812009-01-15 21:57:00 +01004631 .recvmsg = l2cap_sock_recvmsg,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004632 .poll = bt_sock_poll,
Marcel Holtmann3241ad82008-07-14 20:13:50 +02004633 .ioctl = bt_sock_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004634 .mmap = sock_no_mmap,
4635 .socketpair = sock_no_socketpair,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004636 .shutdown = l2cap_sock_shutdown,
4637 .setsockopt = l2cap_sock_setsockopt,
4638 .getsockopt = l2cap_sock_getsockopt
4639};
4640
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +00004641static const struct net_proto_family l2cap_sock_family_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004642 .family = PF_BLUETOOTH,
4643 .owner = THIS_MODULE,
4644 .create = l2cap_sock_create,
4645};
4646
4647static struct hci_proto l2cap_hci_proto = {
4648 .name = "L2CAP",
4649 .id = HCI_PROTO_L2CAP,
4650 .connect_ind = l2cap_connect_ind,
4651 .connect_cfm = l2cap_connect_cfm,
4652 .disconn_ind = l2cap_disconn_ind,
Marcel Holtmann2950f212009-02-12 14:02:50 +01004653 .disconn_cfm = l2cap_disconn_cfm,
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004654 .security_cfm = l2cap_security_cfm,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004655 .recv_acldata = l2cap_recv_acldata
4656};
4657
4658static int __init l2cap_init(void)
4659{
4660 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004661
Linus Torvalds1da177e2005-04-16 15:20:36 -07004662 err = proto_register(&l2cap_proto, 0);
4663 if (err < 0)
4664 return err;
4665
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004666 _busy_wq = create_singlethread_workqueue("l2cap");
4667 if (!_busy_wq)
4668 goto error;
4669
Linus Torvalds1da177e2005-04-16 15:20:36 -07004670 err = bt_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops);
4671 if (err < 0) {
4672 BT_ERR("L2CAP socket registration failed");
4673 goto error;
4674 }
4675
4676 err = hci_register_proto(&l2cap_hci_proto);
4677 if (err < 0) {
4678 BT_ERR("L2CAP protocol registration failed");
4679 bt_sock_unregister(BTPROTO_L2CAP);
4680 goto error;
4681 }
4682
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004683 if (bt_debugfs) {
4684 l2cap_debugfs = debugfs_create_file("l2cap", 0444,
4685 bt_debugfs, NULL, &l2cap_debugfs_fops);
4686 if (!l2cap_debugfs)
4687 BT_ERR("Failed to create L2CAP debug file");
4688 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004689
4690 BT_INFO("L2CAP ver %s", VERSION);
4691 BT_INFO("L2CAP socket layer initialized");
4692
4693 return 0;
4694
4695error:
4696 proto_unregister(&l2cap_proto);
4697 return err;
4698}
4699
4700static void __exit l2cap_exit(void)
4701{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004702 debugfs_remove(l2cap_debugfs);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004703
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004704 flush_workqueue(_busy_wq);
4705 destroy_workqueue(_busy_wq);
4706
Linus Torvalds1da177e2005-04-16 15:20:36 -07004707 if (bt_sock_unregister(BTPROTO_L2CAP) < 0)
4708 BT_ERR("L2CAP socket unregistration failed");
4709
4710 if (hci_unregister_proto(&l2cap_hci_proto) < 0)
4711 BT_ERR("L2CAP protocol unregistration failed");
4712
4713 proto_unregister(&l2cap_proto);
4714}
4715
4716void l2cap_load(void)
4717{
4718 /* Dummy function to trigger automatic L2CAP module loading by
4719 * other modules that use L2CAP sockets but don't use any other
4720 * symbols from it. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07004721}
4722EXPORT_SYMBOL(l2cap_load);
4723
4724module_init(l2cap_init);
4725module_exit(l2cap_exit);
4726
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07004727module_param(enable_ertm, bool, 0644);
4728MODULE_PARM_DESC(enable_ertm, "Enable enhanced retransmission mode");
4729
Marcel Holtmann63fbd242008-08-18 13:23:53 +02004730MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004731MODULE_DESCRIPTION("Bluetooth L2CAP ver " VERSION);
4732MODULE_VERSION(VERSION);
4733MODULE_LICENSE("GPL");
4734MODULE_ALIAS("bt-proto-0");