blob: 103e4b54a86a2c94f816c7a9519742f625936d1b [file] [log] [blame]
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 BlueZ - Bluetooth protocol stack for Linux
3 Copyright (C) 2000-2001 Qualcomm Incorporated
4
5 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License version 2 as
9 published by the Free Software Foundation;
10
11 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
12 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
14 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090015 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
16 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Linus Torvalds1da177e2005-04-16 15:20:36 -070018 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090020 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
21 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
Linus Torvalds1da177e2005-04-16 15:20:36 -070022 SOFTWARE IS DISCLAIMED.
23*/
24
25/* Bluetooth L2CAP core and sockets. */
26
Linus Torvalds1da177e2005-04-16 15:20:36 -070027#include <linux/module.h>
28
29#include <linux/types.h>
Randy Dunlap4fc268d2006-01-11 12:17:47 -080030#include <linux/capability.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070031#include <linux/errno.h>
32#include <linux/kernel.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070033#include <linux/sched.h>
34#include <linux/slab.h>
35#include <linux/poll.h>
36#include <linux/fcntl.h>
37#include <linux/init.h>
38#include <linux/interrupt.h>
39#include <linux/socket.h>
40#include <linux/skbuff.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070041#include <linux/list.h>
Marcel Holtmannbe9d1222005-11-08 09:57:38 -080042#include <linux/device.h>
Marcel Holtmannaef7d972010-03-21 05:27:45 +010043#include <linux/debugfs.h>
44#include <linux/seq_file.h>
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -030045#include <linux/uaccess.h>
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -030046#include <linux/crc16.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070047#include <net/sock.h>
48
49#include <asm/system.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070050#include <asm/unaligned.h>
51
52#include <net/bluetooth/bluetooth.h>
53#include <net/bluetooth/hci_core.h>
54#include <net/bluetooth/l2cap.h>
55
Marcel Holtmann44dd46d2009-05-02 19:09:01 -070056#define VERSION "2.14"
57
Gustavo F. Padovan84fb0a62010-05-01 16:15:42 -030058#ifdef CONFIG_BT_L2CAP_EXT_FEATURES
59static int enable_ertm = 1;
60#else
Marcel Holtmann44dd46d2009-05-02 19:09:01 -070061static int enable_ertm = 0;
Gustavo F. Padovan84fb0a62010-05-01 16:15:42 -030062#endif
Marcel Holtmann5fbcd3d2009-10-05 11:35:43 +020063static int max_transmit = L2CAP_DEFAULT_MAX_TX;
Gustavo F. Padovan369ba302010-05-01 16:15:41 -030064static int tx_window = L2CAP_DEFAULT_TX_WINDOW;
Marcel Holtmannf0709e02007-10-20 13:38:51 +020065
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -070066static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN;
Marcel Holtmanne1027a72009-02-09 09:18:02 +010067static u8 l2cap_fixed_chan[8] = { 0x02, };
Linus Torvalds1da177e2005-04-16 15:20:36 -070068
Eric Dumazet90ddc4f2005-12-22 12:49:22 -080069static const struct proto_ops l2cap_sock_ops;
Linus Torvalds1da177e2005-04-16 15:20:36 -070070
Gustavo F. Padovan1890d362010-05-01 16:15:44 -030071static struct workqueue_struct *_busy_wq;
72
Linus Torvalds1da177e2005-04-16 15:20:36 -070073static struct bt_sock_list l2cap_sk_list = {
Robert P. J. Dayd5fb2962008-03-28 16:17:38 -070074 .lock = __RW_LOCK_UNLOCKED(l2cap_sk_list.lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -070075};
76
Gustavo F. Padovan1890d362010-05-01 16:15:44 -030077static void l2cap_busy_work(struct work_struct *work);
78
Linus Torvalds1da177e2005-04-16 15:20:36 -070079static void __l2cap_sock_close(struct sock *sk, int reason);
80static void l2cap_sock_close(struct sock *sk);
81static void l2cap_sock_kill(struct sock *sk);
82
83static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
84 u8 code, u8 ident, u16 dlen, void *data);
85
86/* ---- L2CAP timers ---- */
87static void l2cap_sock_timeout(unsigned long arg)
88{
89 struct sock *sk = (struct sock *) arg;
Marcel Holtmannb1235d72008-07-14 20:13:54 +020090 int reason;
Linus Torvalds1da177e2005-04-16 15:20:36 -070091
92 BT_DBG("sock %p state %d", sk, sk->sk_state);
93
94 bh_lock_sock(sk);
Marcel Holtmannb1235d72008-07-14 20:13:54 +020095
Marcel Holtmannf62e4322009-01-15 21:58:44 +010096 if (sk->sk_state == BT_CONNECTED || sk->sk_state == BT_CONFIG)
97 reason = ECONNREFUSED;
98 else if (sk->sk_state == BT_CONNECT &&
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +010099 l2cap_pi(sk)->sec_level != BT_SECURITY_SDP)
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200100 reason = ECONNREFUSED;
101 else
102 reason = ETIMEDOUT;
103
104 __l2cap_sock_close(sk, reason);
105
Linus Torvalds1da177e2005-04-16 15:20:36 -0700106 bh_unlock_sock(sk);
107
108 l2cap_sock_kill(sk);
109 sock_put(sk);
110}
111
112static void l2cap_sock_set_timer(struct sock *sk, long timeout)
113{
114 BT_DBG("sk %p state %d timeout %ld", sk, sk->sk_state, timeout);
115 sk_reset_timer(sk, &sk->sk_timer, jiffies + timeout);
116}
117
118static void l2cap_sock_clear_timer(struct sock *sk)
119{
120 BT_DBG("sock %p state %d", sk, sk->sk_state);
121 sk_stop_timer(sk, &sk->sk_timer);
122}
123
Marcel Holtmann01394182006-07-03 10:02:46 +0200124/* ---- L2CAP channels ---- */
125static struct sock *__l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, u16 cid)
126{
127 struct sock *s;
128 for (s = l->head; s; s = l2cap_pi(s)->next_c) {
129 if (l2cap_pi(s)->dcid == cid)
130 break;
131 }
132 return s;
133}
134
135static struct sock *__l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid)
136{
137 struct sock *s;
138 for (s = l->head; s; s = l2cap_pi(s)->next_c) {
139 if (l2cap_pi(s)->scid == cid)
140 break;
141 }
142 return s;
143}
144
145/* Find channel with given SCID.
146 * Returns locked socket */
147static inline struct sock *l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid)
148{
149 struct sock *s;
150 read_lock(&l->lock);
151 s = __l2cap_get_chan_by_scid(l, cid);
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -0300152 if (s)
153 bh_lock_sock(s);
Marcel Holtmann01394182006-07-03 10:02:46 +0200154 read_unlock(&l->lock);
155 return s;
156}
157
158static struct sock *__l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 ident)
159{
160 struct sock *s;
161 for (s = l->head; s; s = l2cap_pi(s)->next_c) {
162 if (l2cap_pi(s)->ident == ident)
163 break;
164 }
165 return s;
166}
167
168static inline struct sock *l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 ident)
169{
170 struct sock *s;
171 read_lock(&l->lock);
172 s = __l2cap_get_chan_by_ident(l, ident);
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -0300173 if (s)
174 bh_lock_sock(s);
Marcel Holtmann01394182006-07-03 10:02:46 +0200175 read_unlock(&l->lock);
176 return s;
177}
178
179static u16 l2cap_alloc_cid(struct l2cap_chan_list *l)
180{
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300181 u16 cid = L2CAP_CID_DYN_START;
Marcel Holtmann01394182006-07-03 10:02:46 +0200182
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300183 for (; cid < L2CAP_CID_DYN_END; cid++) {
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -0300184 if (!__l2cap_get_chan_by_scid(l, cid))
Marcel Holtmann01394182006-07-03 10:02:46 +0200185 return cid;
186 }
187
188 return 0;
189}
190
191static inline void __l2cap_chan_link(struct l2cap_chan_list *l, struct sock *sk)
192{
193 sock_hold(sk);
194
195 if (l->head)
196 l2cap_pi(l->head)->prev_c = sk;
197
198 l2cap_pi(sk)->next_c = l->head;
199 l2cap_pi(sk)->prev_c = NULL;
200 l->head = sk;
201}
202
203static inline void l2cap_chan_unlink(struct l2cap_chan_list *l, struct sock *sk)
204{
205 struct sock *next = l2cap_pi(sk)->next_c, *prev = l2cap_pi(sk)->prev_c;
206
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200207 write_lock_bh(&l->lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200208 if (sk == l->head)
209 l->head = next;
210
211 if (next)
212 l2cap_pi(next)->prev_c = prev;
213 if (prev)
214 l2cap_pi(prev)->next_c = next;
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200215 write_unlock_bh(&l->lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200216
217 __sock_put(sk);
218}
219
220static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
221{
222 struct l2cap_chan_list *l = &conn->chan_list;
223
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -0300224 BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
225 l2cap_pi(sk)->psm, l2cap_pi(sk)->dcid);
Marcel Holtmann01394182006-07-03 10:02:46 +0200226
Marcel Holtmann2950f212009-02-12 14:02:50 +0100227 conn->disc_reason = 0x13;
228
Marcel Holtmann01394182006-07-03 10:02:46 +0200229 l2cap_pi(sk)->conn = conn;
230
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300231 if (sk->sk_type == SOCK_SEQPACKET || sk->sk_type == SOCK_STREAM) {
Marcel Holtmann01394182006-07-03 10:02:46 +0200232 /* Alloc CID for connection-oriented socket */
233 l2cap_pi(sk)->scid = l2cap_alloc_cid(l);
234 } else if (sk->sk_type == SOCK_DGRAM) {
235 /* Connectionless socket */
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300236 l2cap_pi(sk)->scid = L2CAP_CID_CONN_LESS;
237 l2cap_pi(sk)->dcid = L2CAP_CID_CONN_LESS;
Marcel Holtmann01394182006-07-03 10:02:46 +0200238 l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
239 } else {
240 /* Raw socket can send/recv signalling messages only */
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300241 l2cap_pi(sk)->scid = L2CAP_CID_SIGNALING;
242 l2cap_pi(sk)->dcid = L2CAP_CID_SIGNALING;
Marcel Holtmann01394182006-07-03 10:02:46 +0200243 l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
244 }
245
246 __l2cap_chan_link(l, sk);
247
248 if (parent)
249 bt_accept_enqueue(parent, sk);
250}
251
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900252/* Delete channel.
Marcel Holtmann01394182006-07-03 10:02:46 +0200253 * Must be called on the locked socket. */
254static void l2cap_chan_del(struct sock *sk, int err)
255{
256 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
257 struct sock *parent = bt_sk(sk)->parent;
258
259 l2cap_sock_clear_timer(sk);
260
261 BT_DBG("sk %p, conn %p, err %d", sk, conn, err);
262
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900263 if (conn) {
Marcel Holtmann01394182006-07-03 10:02:46 +0200264 /* Unlink from channel list */
265 l2cap_chan_unlink(&conn->chan_list, sk);
266 l2cap_pi(sk)->conn = NULL;
267 hci_conn_put(conn->hcon);
268 }
269
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200270 sk->sk_state = BT_CLOSED;
Marcel Holtmann01394182006-07-03 10:02:46 +0200271 sock_set_flag(sk, SOCK_ZAPPED);
272
273 if (err)
274 sk->sk_err = err;
275
276 if (parent) {
277 bt_accept_unlink(sk);
278 parent->sk_data_ready(parent, 0);
279 } else
280 sk->sk_state_change(sk);
281}
282
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200283/* Service level security */
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100284static inline int l2cap_check_security(struct sock *sk)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200285{
286 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100287 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200288
Marcel Holtmann00ae4af2009-02-12 16:19:45 +0100289 if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) {
290 if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
291 auth_type = HCI_AT_NO_BONDING_MITM;
292 else
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -0300293 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann00ae4af2009-02-12 16:19:45 +0100294
295 if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW)
296 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
297 } else {
298 switch (l2cap_pi(sk)->sec_level) {
299 case BT_SECURITY_HIGH:
300 auth_type = HCI_AT_GENERAL_BONDING_MITM;
301 break;
302 case BT_SECURITY_MEDIUM:
303 auth_type = HCI_AT_GENERAL_BONDING;
304 break;
305 default:
306 auth_type = HCI_AT_NO_BONDING;
307 break;
308 }
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100309 }
310
311 return hci_conn_security(conn->hcon, l2cap_pi(sk)->sec_level,
312 auth_type);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200313}
314
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200315static inline u8 l2cap_get_ident(struct l2cap_conn *conn)
316{
317 u8 id;
318
319 /* Get next available identificator.
320 * 1 - 128 are used by kernel.
321 * 129 - 199 are reserved.
322 * 200 - 254 are used by utilities like l2ping, etc.
323 */
324
325 spin_lock_bh(&conn->lock);
326
327 if (++conn->tx_ident > 128)
328 conn->tx_ident = 1;
329
330 id = conn->tx_ident;
331
332 spin_unlock_bh(&conn->lock);
333
334 return id;
335}
336
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300337static inline void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200338{
339 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
340
341 BT_DBG("code 0x%2.2x", code);
342
343 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300344 return;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200345
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300346 hci_send_acl(conn->hcon, skb, 0);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200347}
348
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300349static inline void l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300350{
351 struct sk_buff *skb;
352 struct l2cap_hdr *lh;
353 struct l2cap_conn *conn = pi->conn;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300354 int count, hlen = L2CAP_HDR_SIZE + 2;
355
356 if (pi->fcs == L2CAP_FCS_CRC16)
357 hlen += 2;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300358
359 BT_DBG("pi %p, control 0x%2.2x", pi, control);
360
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300361 count = min_t(unsigned int, conn->mtu, hlen);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300362 control |= L2CAP_CTRL_FRAME_TYPE;
363
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -0300364 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
365 control |= L2CAP_CTRL_FINAL;
366 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
367 }
368
Gustavo F. Padovanf0946cc2010-05-01 16:15:37 -0300369 if (pi->conn_state & L2CAP_CONN_SEND_PBIT) {
370 control |= L2CAP_CTRL_POLL;
371 pi->conn_state &= ~L2CAP_CONN_SEND_PBIT;
372 }
373
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300374 skb = bt_skb_alloc(count, GFP_ATOMIC);
375 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300376 return;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300377
378 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300379 lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300380 lh->cid = cpu_to_le16(pi->dcid);
381 put_unaligned_le16(control, skb_put(skb, 2));
382
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300383 if (pi->fcs == L2CAP_FCS_CRC16) {
384 u16 fcs = crc16(0, (u8 *)lh, count - 2);
385 put_unaligned_le16(fcs, skb_put(skb, 2));
386 }
387
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300388 hci_send_acl(pi->conn->hcon, skb, 0);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300389}
390
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300391static inline void l2cap_send_rr_or_rnr(struct l2cap_pinfo *pi, u16 control)
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300392{
Gustavo F. Padovan1890d362010-05-01 16:15:44 -0300393 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300394 control |= L2CAP_SUPER_RCV_NOT_READY;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -0300395 pi->conn_state |= L2CAP_CONN_RNR_SENT;
396 } else
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300397 control |= L2CAP_SUPER_RCV_READY;
398
Gustavo F. Padovan2ab25cd2009-10-03 02:34:40 -0300399 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
400
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300401 l2cap_send_sframe(pi, control);
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300402}
403
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200404static void l2cap_do_start(struct sock *sk)
405{
406 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
407
408 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +0100409 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
410 return;
411
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100412 if (l2cap_check_security(sk)) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200413 struct l2cap_conn_req req;
414 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
415 req.psm = l2cap_pi(sk)->psm;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200416
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200417 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200418
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200419 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200420 L2CAP_CONN_REQ, sizeof(req), &req);
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200421 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200422 } else {
423 struct l2cap_info_req req;
424 req.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
425
426 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
427 conn->info_ident = l2cap_get_ident(conn);
428
429 mod_timer(&conn->info_timer, jiffies +
430 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
431
432 l2cap_send_cmd(conn, conn->info_ident,
433 L2CAP_INFO_REQ, sizeof(req), &req);
434 }
435}
436
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300437static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct sock *sk)
438{
439 struct l2cap_disconn_req req;
440
441 req.dcid = cpu_to_le16(l2cap_pi(sk)->dcid);
442 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
443 l2cap_send_cmd(conn, l2cap_get_ident(conn),
444 L2CAP_DISCONN_REQ, sizeof(req), &req);
445}
446
Linus Torvalds1da177e2005-04-16 15:20:36 -0700447/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200448static void l2cap_conn_start(struct l2cap_conn *conn)
449{
450 struct l2cap_chan_list *l = &conn->chan_list;
451 struct sock *sk;
452
453 BT_DBG("conn %p", conn);
454
455 read_lock(&l->lock);
456
457 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
458 bh_lock_sock(sk);
459
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300460 if (sk->sk_type != SOCK_SEQPACKET &&
461 sk->sk_type != SOCK_STREAM) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200462 bh_unlock_sock(sk);
463 continue;
464 }
465
466 if (sk->sk_state == BT_CONNECT) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100467 if (l2cap_check_security(sk)) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200468 struct l2cap_conn_req req;
469 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
470 req.psm = l2cap_pi(sk)->psm;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200471
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200472 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200473
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200474 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200475 L2CAP_CONN_REQ, sizeof(req), &req);
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200476 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200477 } else if (sk->sk_state == BT_CONNECT2) {
478 struct l2cap_conn_rsp rsp;
479 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
480 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
481
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100482 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100483 if (bt_sk(sk)->defer_setup) {
484 struct sock *parent = bt_sk(sk)->parent;
485 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
486 rsp.status = cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
487 parent->sk_data_ready(parent, 0);
488
489 } else {
490 sk->sk_state = BT_CONFIG;
491 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
492 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
493 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200494 } else {
495 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
496 rsp.status = cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
497 }
498
499 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
500 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
501 }
502
503 bh_unlock_sock(sk);
504 }
505
506 read_unlock(&l->lock);
507}
508
509static void l2cap_conn_ready(struct l2cap_conn *conn)
510{
511 struct l2cap_chan_list *l = &conn->chan_list;
512 struct sock *sk;
513
514 BT_DBG("conn %p", conn);
515
516 read_lock(&l->lock);
517
518 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
519 bh_lock_sock(sk);
520
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300521 if (sk->sk_type != SOCK_SEQPACKET &&
522 sk->sk_type != SOCK_STREAM) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200523 l2cap_sock_clear_timer(sk);
524 sk->sk_state = BT_CONNECTED;
525 sk->sk_state_change(sk);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200526 } else if (sk->sk_state == BT_CONNECT)
527 l2cap_do_start(sk);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200528
529 bh_unlock_sock(sk);
530 }
531
532 read_unlock(&l->lock);
533}
534
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200535/* Notify sockets that we cannot guaranty reliability anymore */
536static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
537{
538 struct l2cap_chan_list *l = &conn->chan_list;
539 struct sock *sk;
540
541 BT_DBG("conn %p", conn);
542
543 read_lock(&l->lock);
544
545 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100546 if (l2cap_pi(sk)->force_reliable)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200547 sk->sk_err = err;
548 }
549
550 read_unlock(&l->lock);
551}
552
553static void l2cap_info_timeout(unsigned long arg)
554{
555 struct l2cap_conn *conn = (void *) arg;
556
Marcel Holtmann984947d2009-02-06 23:35:19 +0100557 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +0100558 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +0100559
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200560 l2cap_conn_start(conn);
561}
562
Linus Torvalds1da177e2005-04-16 15:20:36 -0700563static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
564{
Marcel Holtmann01394182006-07-03 10:02:46 +0200565 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700566
Marcel Holtmann01394182006-07-03 10:02:46 +0200567 if (conn || status)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700568 return conn;
569
Marcel Holtmann01394182006-07-03 10:02:46 +0200570 conn = kzalloc(sizeof(struct l2cap_conn), GFP_ATOMIC);
571 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700572 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700573
574 hcon->l2cap_data = conn;
575 conn->hcon = hcon;
576
Marcel Holtmann01394182006-07-03 10:02:46 +0200577 BT_DBG("hcon %p conn %p", hcon, conn);
578
Linus Torvalds1da177e2005-04-16 15:20:36 -0700579 conn->mtu = hcon->hdev->acl_mtu;
580 conn->src = &hcon->hdev->bdaddr;
581 conn->dst = &hcon->dst;
582
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200583 conn->feat_mask = 0;
584
Linus Torvalds1da177e2005-04-16 15:20:36 -0700585 spin_lock_init(&conn->lock);
586 rwlock_init(&conn->chan_list.lock);
587
Dave Young45054dc2009-10-18 20:28:30 +0000588 setup_timer(&conn->info_timer, l2cap_info_timeout,
589 (unsigned long) conn);
590
Marcel Holtmann2950f212009-02-12 14:02:50 +0100591 conn->disc_reason = 0x13;
592
Linus Torvalds1da177e2005-04-16 15:20:36 -0700593 return conn;
594}
595
Marcel Holtmann01394182006-07-03 10:02:46 +0200596static void l2cap_conn_del(struct hci_conn *hcon, int err)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700597{
Marcel Holtmann01394182006-07-03 10:02:46 +0200598 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700599 struct sock *sk;
600
Marcel Holtmann01394182006-07-03 10:02:46 +0200601 if (!conn)
602 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700603
604 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
605
Wei Yongjun7585b972009-02-25 18:29:52 +0800606 kfree_skb(conn->rx_skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700607
608 /* Kill channels */
609 while ((sk = conn->chan_list.head)) {
610 bh_lock_sock(sk);
611 l2cap_chan_del(sk, err);
612 bh_unlock_sock(sk);
613 l2cap_sock_kill(sk);
614 }
615
Dave Young8e8440f2008-03-03 12:18:55 -0800616 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
617 del_timer_sync(&conn->info_timer);
Thomas Gleixner3ab22732008-02-26 17:42:56 -0800618
Linus Torvalds1da177e2005-04-16 15:20:36 -0700619 hcon->l2cap_data = NULL;
620 kfree(conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700621}
622
623static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
624{
625 struct l2cap_chan_list *l = &conn->chan_list;
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200626 write_lock_bh(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700627 __l2cap_chan_add(conn, sk, parent);
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200628 write_unlock_bh(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700629}
630
Linus Torvalds1da177e2005-04-16 15:20:36 -0700631/* ---- Socket interface ---- */
Al Viro8e036fc2007-07-29 00:16:36 -0700632static struct sock *__l2cap_get_sock_by_addr(__le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700633{
634 struct sock *sk;
635 struct hlist_node *node;
636 sk_for_each(sk, node, &l2cap_sk_list.head)
637 if (l2cap_pi(sk)->sport == psm && !bacmp(&bt_sk(sk)->src, src))
638 goto found;
639 sk = NULL;
640found:
641 return sk;
642}
643
644/* Find socket with psm and source bdaddr.
645 * Returns closest match.
646 */
Al Viro8e036fc2007-07-29 00:16:36 -0700647static struct sock *__l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700648{
649 struct sock *sk = NULL, *sk1 = NULL;
650 struct hlist_node *node;
651
652 sk_for_each(sk, node, &l2cap_sk_list.head) {
653 if (state && sk->sk_state != state)
654 continue;
655
656 if (l2cap_pi(sk)->psm == psm) {
657 /* Exact match. */
658 if (!bacmp(&bt_sk(sk)->src, src))
659 break;
660
661 /* Closest match */
662 if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY))
663 sk1 = sk;
664 }
665 }
666 return node ? sk : sk1;
667}
668
669/* Find socket with given address (psm, src).
670 * Returns locked socket */
Al Viro8e036fc2007-07-29 00:16:36 -0700671static inline struct sock *l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700672{
673 struct sock *s;
674 read_lock(&l2cap_sk_list.lock);
675 s = __l2cap_get_sock_by_psm(state, psm, src);
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -0300676 if (s)
677 bh_lock_sock(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700678 read_unlock(&l2cap_sk_list.lock);
679 return s;
680}
681
682static void l2cap_sock_destruct(struct sock *sk)
683{
684 BT_DBG("sk %p", sk);
685
686 skb_queue_purge(&sk->sk_receive_queue);
687 skb_queue_purge(&sk->sk_write_queue);
688}
689
690static void l2cap_sock_cleanup_listen(struct sock *parent)
691{
692 struct sock *sk;
693
694 BT_DBG("parent %p", parent);
695
696 /* Close not yet accepted channels */
697 while ((sk = bt_accept_dequeue(parent, NULL)))
698 l2cap_sock_close(sk);
699
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200700 parent->sk_state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700701 sock_set_flag(parent, SOCK_ZAPPED);
702}
703
704/* Kill socket (only if zapped and orphan)
705 * Must be called on unlocked socket.
706 */
707static void l2cap_sock_kill(struct sock *sk)
708{
709 if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket)
710 return;
711
712 BT_DBG("sk %p state %d", sk, sk->sk_state);
713
714 /* Kill poor orphan */
715 bt_sock_unlink(&l2cap_sk_list, sk);
716 sock_set_flag(sk, SOCK_DEAD);
717 sock_put(sk);
718}
719
720static void __l2cap_sock_close(struct sock *sk, int reason)
721{
722 BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket);
723
724 switch (sk->sk_state) {
725 case BT_LISTEN:
726 l2cap_sock_cleanup_listen(sk);
727 break;
728
729 case BT_CONNECTED:
730 case BT_CONFIG:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300731 if (sk->sk_type == SOCK_SEQPACKET ||
732 sk->sk_type == SOCK_STREAM) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700733 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700734
735 sk->sk_state = BT_DISCONN;
736 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300737 l2cap_send_disconn_req(conn, sk);
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200738 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -0700739 l2cap_chan_del(sk, reason);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700740 break;
741
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100742 case BT_CONNECT2:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300743 if (sk->sk_type == SOCK_SEQPACKET ||
744 sk->sk_type == SOCK_STREAM) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100745 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
746 struct l2cap_conn_rsp rsp;
747 __u16 result;
748
749 if (bt_sk(sk)->defer_setup)
750 result = L2CAP_CR_SEC_BLOCK;
751 else
752 result = L2CAP_CR_BAD_PSM;
753
754 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
755 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
756 rsp.result = cpu_to_le16(result);
757 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
758 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
759 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
760 } else
761 l2cap_chan_del(sk, reason);
762 break;
763
Linus Torvalds1da177e2005-04-16 15:20:36 -0700764 case BT_CONNECT:
765 case BT_DISCONN:
766 l2cap_chan_del(sk, reason);
767 break;
768
769 default:
770 sock_set_flag(sk, SOCK_ZAPPED);
771 break;
772 }
773}
774
775/* Must be called on unlocked socket. */
776static void l2cap_sock_close(struct sock *sk)
777{
778 l2cap_sock_clear_timer(sk);
779 lock_sock(sk);
780 __l2cap_sock_close(sk, ECONNRESET);
781 release_sock(sk);
782 l2cap_sock_kill(sk);
783}
784
785static void l2cap_sock_init(struct sock *sk, struct sock *parent)
786{
787 struct l2cap_pinfo *pi = l2cap_pi(sk);
788
789 BT_DBG("sk %p", sk);
790
791 if (parent) {
792 sk->sk_type = parent->sk_type;
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100793 bt_sk(sk)->defer_setup = bt_sk(parent)->defer_setup;
794
Linus Torvalds1da177e2005-04-16 15:20:36 -0700795 pi->imtu = l2cap_pi(parent)->imtu;
796 pi->omtu = l2cap_pi(parent)->omtu;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -0700797 pi->mode = l2cap_pi(parent)->mode;
798 pi->fcs = l2cap_pi(parent)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -0300799 pi->max_tx = l2cap_pi(parent)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -0300800 pi->tx_win = l2cap_pi(parent)->tx_win;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100801 pi->sec_level = l2cap_pi(parent)->sec_level;
802 pi->role_switch = l2cap_pi(parent)->role_switch;
803 pi->force_reliable = l2cap_pi(parent)->force_reliable;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700804 } else {
805 pi->imtu = L2CAP_DEFAULT_MTU;
806 pi->omtu = 0;
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300807 if (enable_ertm && sk->sk_type == SOCK_STREAM)
808 pi->mode = L2CAP_MODE_ERTM;
809 else
810 pi->mode = L2CAP_MODE_BASIC;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -0300811 pi->max_tx = max_transmit;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -0700812 pi->fcs = L2CAP_FCS_CRC16;
Gustavo F. Padovan369ba302010-05-01 16:15:41 -0300813 pi->tx_win = tx_window;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100814 pi->sec_level = BT_SECURITY_LOW;
815 pi->role_switch = 0;
816 pi->force_reliable = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700817 }
818
819 /* Default config options */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +0200820 pi->conf_len = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700821 pi->flush_to = L2CAP_DEFAULT_FLUSH_TO;
Dave Young45054dc2009-10-18 20:28:30 +0000822 skb_queue_head_init(TX_QUEUE(sk));
823 skb_queue_head_init(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -0300824 skb_queue_head_init(BUSY_QUEUE(sk));
Dave Young45054dc2009-10-18 20:28:30 +0000825 INIT_LIST_HEAD(SREJ_LIST(sk));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700826}
827
828static struct proto l2cap_proto = {
829 .name = "L2CAP",
830 .owner = THIS_MODULE,
831 .obj_size = sizeof(struct l2cap_pinfo)
832};
833
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700834static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700835{
836 struct sock *sk;
837
Pavel Emelyanov6257ff22007-11-01 00:39:31 -0700838 sk = sk_alloc(net, PF_BLUETOOTH, prio, &l2cap_proto);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700839 if (!sk)
840 return NULL;
841
842 sock_init_data(sock, sk);
843 INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
844
845 sk->sk_destruct = l2cap_sock_destruct;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200846 sk->sk_sndtimeo = msecs_to_jiffies(L2CAP_CONN_TIMEOUT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700847
848 sock_reset_flag(sk, SOCK_ZAPPED);
849
850 sk->sk_protocol = proto;
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200851 sk->sk_state = BT_OPEN;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700852
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200853 setup_timer(&sk->sk_timer, l2cap_sock_timeout, (unsigned long) sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700854
855 bt_sock_link(&l2cap_sk_list, sk);
856 return sk;
857}
858
Eric Paris3f378b62009-11-05 22:18:14 -0800859static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol,
860 int kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700861{
862 struct sock *sk;
863
864 BT_DBG("sock %p", sock);
865
866 sock->state = SS_UNCONNECTED;
867
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300868 if (sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM &&
Linus Torvalds1da177e2005-04-16 15:20:36 -0700869 sock->type != SOCK_DGRAM && sock->type != SOCK_RAW)
870 return -ESOCKTNOSUPPORT;
871
Eric Parisc84b3262009-11-05 20:45:52 -0800872 if (sock->type == SOCK_RAW && !kern && !capable(CAP_NET_RAW))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700873 return -EPERM;
874
875 sock->ops = &l2cap_sock_ops;
876
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700877 sk = l2cap_sock_alloc(net, sock, protocol, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700878 if (!sk)
879 return -ENOMEM;
880
881 l2cap_sock_init(sk, NULL);
882 return 0;
883}
884
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100885static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700886{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700887 struct sock *sk = sock->sk;
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100888 struct sockaddr_l2 la;
889 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700890
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100891 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700892
893 if (!addr || addr->sa_family != AF_BLUETOOTH)
894 return -EINVAL;
895
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100896 memset(&la, 0, sizeof(la));
897 len = min_t(unsigned int, sizeof(la), alen);
898 memcpy(&la, addr, len);
899
Marcel Holtmann2a517ca2009-02-16 03:20:31 +0100900 if (la.l2_cid)
901 return -EINVAL;
902
Linus Torvalds1da177e2005-04-16 15:20:36 -0700903 lock_sock(sk);
904
905 if (sk->sk_state != BT_OPEN) {
906 err = -EBADFD;
907 goto done;
908 }
909
Marcel Holtmannb4324b52009-06-07 18:06:51 +0200910 if (la.l2_psm && __le16_to_cpu(la.l2_psm) < 0x1001 &&
Marcel Holtmann847641d2007-01-22 22:00:45 +0100911 !capable(CAP_NET_BIND_SERVICE)) {
912 err = -EACCES;
913 goto done;
914 }
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900915
Linus Torvalds1da177e2005-04-16 15:20:36 -0700916 write_lock_bh(&l2cap_sk_list.lock);
917
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100918 if (la.l2_psm && __l2cap_get_sock_by_addr(la.l2_psm, &la.l2_bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700919 err = -EADDRINUSE;
920 } else {
921 /* Save source address */
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100922 bacpy(&bt_sk(sk)->src, &la.l2_bdaddr);
923 l2cap_pi(sk)->psm = la.l2_psm;
924 l2cap_pi(sk)->sport = la.l2_psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700925 sk->sk_state = BT_BOUND;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100926
Marcel Holtmannb4324b52009-06-07 18:06:51 +0200927 if (__le16_to_cpu(la.l2_psm) == 0x0001 ||
928 __le16_to_cpu(la.l2_psm) == 0x0003)
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100929 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700930 }
931
932 write_unlock_bh(&l2cap_sk_list.lock);
933
934done:
935 release_sock(sk);
936 return err;
937}
938
939static int l2cap_do_connect(struct sock *sk)
940{
941 bdaddr_t *src = &bt_sk(sk)->src;
942 bdaddr_t *dst = &bt_sk(sk)->dst;
943 struct l2cap_conn *conn;
944 struct hci_conn *hcon;
945 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200946 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +0200947 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700948
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100949 BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst),
950 l2cap_pi(sk)->psm);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700951
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -0300952 hdev = hci_get_route(dst, src);
953 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700954 return -EHOSTUNREACH;
955
956 hci_dev_lock_bh(hdev);
957
958 err = -ENOMEM;
959
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100960 if (sk->sk_type == SOCK_RAW) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100961 switch (l2cap_pi(sk)->sec_level) {
962 case BT_SECURITY_HIGH:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100963 auth_type = HCI_AT_DEDICATED_BONDING_MITM;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100964 break;
965 case BT_SECURITY_MEDIUM:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100966 auth_type = HCI_AT_DEDICATED_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100967 break;
968 default:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100969 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100970 break;
971 }
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100972 } else if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100973 if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200974 auth_type = HCI_AT_NO_BONDING_MITM;
975 else
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200976 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann435fef22009-02-09 03:55:28 +0100977
978 if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW)
979 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100980 } else {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100981 switch (l2cap_pi(sk)->sec_level) {
982 case BT_SECURITY_HIGH:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100983 auth_type = HCI_AT_GENERAL_BONDING_MITM;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100984 break;
985 case BT_SECURITY_MEDIUM:
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200986 auth_type = HCI_AT_GENERAL_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100987 break;
988 default:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100989 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100990 break;
991 }
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200992 }
993
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100994 hcon = hci_connect(hdev, ACL_LINK, dst,
995 l2cap_pi(sk)->sec_level, auth_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700996 if (!hcon)
997 goto done;
998
999 conn = l2cap_conn_add(hcon, 0);
1000 if (!conn) {
1001 hci_conn_put(hcon);
1002 goto done;
1003 }
1004
1005 err = 0;
1006
1007 /* Update source addr of the socket */
1008 bacpy(src, conn->src);
1009
1010 l2cap_chan_add(conn, sk, NULL);
1011
1012 sk->sk_state = BT_CONNECT;
1013 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
1014
1015 if (hcon->state == BT_CONNECTED) {
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001016 if (sk->sk_type != SOCK_SEQPACKET &&
1017 sk->sk_type != SOCK_STREAM) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001018 l2cap_sock_clear_timer(sk);
1019 sk->sk_state = BT_CONNECTED;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001020 } else
1021 l2cap_do_start(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001022 }
1023
1024done:
1025 hci_dev_unlock_bh(hdev);
1026 hci_dev_put(hdev);
1027 return err;
1028}
1029
1030static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
1031{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001032 struct sock *sk = sock->sk;
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001033 struct sockaddr_l2 la;
1034 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001035
Linus Torvalds1da177e2005-04-16 15:20:36 -07001036 BT_DBG("sk %p", sk);
1037
Changli Gao6503d962010-03-31 22:58:26 +00001038 if (!addr || alen < sizeof(addr->sa_family) ||
1039 addr->sa_family != AF_BLUETOOTH)
Marcel Holtmann2a517ca2009-02-16 03:20:31 +01001040 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001041
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001042 memset(&la, 0, sizeof(la));
1043 len = min_t(unsigned int, sizeof(la), alen);
1044 memcpy(&la, addr, len);
1045
Marcel Holtmann2a517ca2009-02-16 03:20:31 +01001046 if (la.l2_cid)
1047 return -EINVAL;
1048
1049 lock_sock(sk);
1050
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001051 if ((sk->sk_type == SOCK_SEQPACKET || sk->sk_type == SOCK_STREAM)
1052 && !la.l2_psm) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001053 err = -EINVAL;
1054 goto done;
1055 }
1056
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001057 switch (l2cap_pi(sk)->mode) {
1058 case L2CAP_MODE_BASIC:
1059 break;
1060 case L2CAP_MODE_ERTM:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001061 case L2CAP_MODE_STREAMING:
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001062 if (enable_ertm)
1063 break;
1064 /* fall through */
1065 default:
1066 err = -ENOTSUPP;
1067 goto done;
1068 }
1069
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03001070 switch (sk->sk_state) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001071 case BT_CONNECT:
1072 case BT_CONNECT2:
1073 case BT_CONFIG:
1074 /* Already connecting */
1075 goto wait;
1076
1077 case BT_CONNECTED:
1078 /* Already connected */
1079 goto done;
1080
1081 case BT_OPEN:
1082 case BT_BOUND:
1083 /* Can connect */
1084 break;
1085
1086 default:
1087 err = -EBADFD;
1088 goto done;
1089 }
1090
1091 /* Set destination address and psm */
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001092 bacpy(&bt_sk(sk)->dst, &la.l2_bdaddr);
1093 l2cap_pi(sk)->psm = la.l2_psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001094
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03001095 err = l2cap_do_connect(sk);
1096 if (err)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001097 goto done;
1098
1099wait:
1100 err = bt_sock_wait_state(sk, BT_CONNECTED,
1101 sock_sndtimeo(sk, flags & O_NONBLOCK));
1102done:
1103 release_sock(sk);
1104 return err;
1105}
1106
1107static int l2cap_sock_listen(struct socket *sock, int backlog)
1108{
1109 struct sock *sk = sock->sk;
1110 int err = 0;
1111
1112 BT_DBG("sk %p backlog %d", sk, backlog);
1113
1114 lock_sock(sk);
1115
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001116 if ((sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM)
1117 || sk->sk_state != BT_BOUND) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001118 err = -EBADFD;
1119 goto done;
1120 }
1121
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001122 switch (l2cap_pi(sk)->mode) {
1123 case L2CAP_MODE_BASIC:
1124 break;
1125 case L2CAP_MODE_ERTM:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001126 case L2CAP_MODE_STREAMING:
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001127 if (enable_ertm)
1128 break;
1129 /* fall through */
1130 default:
1131 err = -ENOTSUPP;
1132 goto done;
1133 }
1134
Linus Torvalds1da177e2005-04-16 15:20:36 -07001135 if (!l2cap_pi(sk)->psm) {
1136 bdaddr_t *src = &bt_sk(sk)->src;
1137 u16 psm;
1138
1139 err = -EINVAL;
1140
1141 write_lock_bh(&l2cap_sk_list.lock);
1142
1143 for (psm = 0x1001; psm < 0x1100; psm += 2)
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001144 if (!__l2cap_get_sock_by_addr(cpu_to_le16(psm), src)) {
1145 l2cap_pi(sk)->psm = cpu_to_le16(psm);
1146 l2cap_pi(sk)->sport = cpu_to_le16(psm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001147 err = 0;
1148 break;
1149 }
1150
1151 write_unlock_bh(&l2cap_sk_list.lock);
1152
1153 if (err < 0)
1154 goto done;
1155 }
1156
1157 sk->sk_max_ack_backlog = backlog;
1158 sk->sk_ack_backlog = 0;
1159 sk->sk_state = BT_LISTEN;
1160
1161done:
1162 release_sock(sk);
1163 return err;
1164}
1165
1166static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int flags)
1167{
1168 DECLARE_WAITQUEUE(wait, current);
1169 struct sock *sk = sock->sk, *nsk;
1170 long timeo;
1171 int err = 0;
1172
Peter Zijlstrafcc70d52006-11-08 22:44:35 -08001173 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001174
1175 if (sk->sk_state != BT_LISTEN) {
1176 err = -EBADFD;
1177 goto done;
1178 }
1179
1180 timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
1181
1182 BT_DBG("sk %p timeo %ld", sk, timeo);
1183
1184 /* Wait for an incoming connection. (wake-one). */
Eric Dumazetaa395142010-04-20 13:03:51 +00001185 add_wait_queue_exclusive(sk_sleep(sk), &wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001186 while (!(nsk = bt_accept_dequeue(sk, newsock))) {
1187 set_current_state(TASK_INTERRUPTIBLE);
1188 if (!timeo) {
1189 err = -EAGAIN;
1190 break;
1191 }
1192
1193 release_sock(sk);
1194 timeo = schedule_timeout(timeo);
Peter Zijlstrafcc70d52006-11-08 22:44:35 -08001195 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001196
1197 if (sk->sk_state != BT_LISTEN) {
1198 err = -EBADFD;
1199 break;
1200 }
1201
1202 if (signal_pending(current)) {
1203 err = sock_intr_errno(timeo);
1204 break;
1205 }
1206 }
1207 set_current_state(TASK_RUNNING);
Eric Dumazetaa395142010-04-20 13:03:51 +00001208 remove_wait_queue(sk_sleep(sk), &wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001209
1210 if (err)
1211 goto done;
1212
1213 newsock->state = SS_CONNECTED;
1214
1215 BT_DBG("new socket %p", nsk);
1216
1217done:
1218 release_sock(sk);
1219 return err;
1220}
1221
1222static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
1223{
1224 struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
1225 struct sock *sk = sock->sk;
1226
1227 BT_DBG("sock %p, sk %p", sock, sk);
1228
1229 addr->sa_family = AF_BLUETOOTH;
1230 *len = sizeof(struct sockaddr_l2);
1231
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001232 if (peer) {
1233 la->l2_psm = l2cap_pi(sk)->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001234 bacpy(&la->l2_bdaddr, &bt_sk(sk)->dst);
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001235 la->l2_cid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001236 } else {
1237 la->l2_psm = l2cap_pi(sk)->sport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001238 bacpy(&la->l2_bdaddr, &bt_sk(sk)->src);
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001239 la->l2_cid = cpu_to_le16(l2cap_pi(sk)->scid);
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001240 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001241
Linus Torvalds1da177e2005-04-16 15:20:36 -07001242 return 0;
1243}
1244
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001245static void l2cap_monitor_timeout(unsigned long arg)
1246{
1247 struct sock *sk = (void *) arg;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001248
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001249 bh_lock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001250 if (l2cap_pi(sk)->retry_count >= l2cap_pi(sk)->remote_max_tx) {
1251 l2cap_send_disconn_req(l2cap_pi(sk)->conn, sk);
Andrei Emeltchenkob13f5862009-12-15 11:38:04 +02001252 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001253 return;
1254 }
1255
1256 l2cap_pi(sk)->retry_count++;
1257 __mod_monitor_timer();
1258
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -03001259 l2cap_send_rr_or_rnr(l2cap_pi(sk), L2CAP_CTRL_POLL);
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001260 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001261}
1262
1263static void l2cap_retrans_timeout(unsigned long arg)
1264{
1265 struct sock *sk = (void *) arg;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001266
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001267 bh_lock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001268 l2cap_pi(sk)->retry_count = 1;
1269 __mod_monitor_timer();
1270
1271 l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
1272
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -03001273 l2cap_send_rr_or_rnr(l2cap_pi(sk), L2CAP_CTRL_POLL);
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001274 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001275}
1276
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001277static void l2cap_drop_acked_frames(struct sock *sk)
1278{
1279 struct sk_buff *skb;
1280
Gustavo F. Padovan812e7372010-05-01 16:15:42 -03001281 while ((skb = skb_peek(TX_QUEUE(sk))) &&
1282 l2cap_pi(sk)->unacked_frames) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001283 if (bt_cb(skb)->tx_seq == l2cap_pi(sk)->expected_ack_seq)
1284 break;
1285
1286 skb = skb_dequeue(TX_QUEUE(sk));
1287 kfree_skb(skb);
1288
1289 l2cap_pi(sk)->unacked_frames--;
1290 }
1291
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001292 if (!l2cap_pi(sk)->unacked_frames)
1293 del_timer(&l2cap_pi(sk)->retrans_timer);
1294
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001295 return;
1296}
1297
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001298static inline void l2cap_do_send(struct sock *sk, struct sk_buff *skb)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001299{
1300 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001301
1302 BT_DBG("sk %p, skb %p len %d", sk, skb, skb->len);
1303
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001304 hci_send_acl(pi->conn->hcon, skb, 0);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001305}
1306
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001307static int l2cap_streaming_send(struct sock *sk)
1308{
1309 struct sk_buff *skb, *tx_skb;
1310 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001311 u16 control, fcs;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001312
1313 while ((skb = sk->sk_send_head)) {
1314 tx_skb = skb_clone(skb, GFP_ATOMIC);
1315
1316 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
1317 control |= pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT;
1318 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1319
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001320 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001321 fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
1322 put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
1323 }
1324
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001325 l2cap_do_send(sk, tx_skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001326
1327 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
1328
1329 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1330 sk->sk_send_head = NULL;
1331 else
1332 sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
1333
1334 skb = skb_dequeue(TX_QUEUE(sk));
1335 kfree_skb(skb);
1336 }
1337 return 0;
1338}
1339
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001340static void l2cap_retransmit_frame(struct sock *sk, u8 tx_seq)
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001341{
1342 struct l2cap_pinfo *pi = l2cap_pi(sk);
1343 struct sk_buff *skb, *tx_skb;
1344 u16 control, fcs;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001345
1346 skb = skb_peek(TX_QUEUE(sk));
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001347 if (!skb)
1348 return;
1349
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001350 do {
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001351 if (bt_cb(skb)->tx_seq == tx_seq)
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001352 break;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001353
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001354 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1355 return;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001356
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001357 } while ((skb = skb_queue_next(TX_QUEUE(sk), skb)));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001358
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001359 if (pi->remote_max_tx &&
1360 bt_cb(skb)->retries == pi->remote_max_tx) {
1361 l2cap_send_disconn_req(pi->conn, sk);
1362 return;
1363 }
1364
1365 tx_skb = skb_clone(skb, GFP_ATOMIC);
1366 bt_cb(skb)->retries++;
1367 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
1368 control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
1369 | (tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
1370 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1371
1372 if (pi->fcs == L2CAP_FCS_CRC16) {
1373 fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
1374 put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
1375 }
1376
1377 l2cap_do_send(sk, tx_skb);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001378}
1379
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001380static int l2cap_ertm_send(struct sock *sk)
1381{
1382 struct sk_buff *skb, *tx_skb;
1383 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001384 u16 control, fcs;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001385 int nsent = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001386
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001387 if (pi->conn_state & L2CAP_CONN_WAIT_F)
1388 return 0;
1389
Joe Perchesf64f9e72009-11-29 16:55:45 -08001390 while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(sk)) &&
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03001391 !(pi->conn_state & L2CAP_CONN_REMOTE_BUSY)) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001392
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001393 if (pi->remote_max_tx &&
1394 bt_cb(skb)->retries == pi->remote_max_tx) {
1395 l2cap_send_disconn_req(pi->conn, sk);
1396 break;
1397 }
1398
Andrei Emeltchenkoe420aba2009-12-23 13:07:14 +02001399 tx_skb = skb_clone(skb, GFP_ATOMIC);
1400
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001401 bt_cb(skb)->retries++;
1402
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001403 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001404 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
1405 control |= L2CAP_CTRL_FINAL;
1406 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
1407 }
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03001408 control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001409 | (pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
1410 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1411
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001412
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001413 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001414 fcs = crc16(0, (u8 *)skb->data, tx_skb->len - 2);
1415 put_unaligned_le16(fcs, skb->data + tx_skb->len - 2);
1416 }
1417
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001418 l2cap_do_send(sk, tx_skb);
1419
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001420 __mod_retrans_timer();
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001421
1422 bt_cb(skb)->tx_seq = pi->next_tx_seq;
1423 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
1424
1425 pi->unacked_frames++;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001426 pi->frames_sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001427
1428 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1429 sk->sk_send_head = NULL;
1430 else
1431 sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001432
1433 nsent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001434 }
1435
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001436 return nsent;
1437}
1438
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001439static void l2cap_send_ack(struct l2cap_pinfo *pi)
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001440{
1441 struct sock *sk = (struct sock *)pi;
1442 u16 control = 0;
1443
1444 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1445
1446 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
1447 control |= L2CAP_SUPER_RCV_NOT_READY;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03001448 pi->conn_state |= L2CAP_CONN_RNR_SENT;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001449 l2cap_send_sframe(pi, control);
1450 return;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001451 } else if (l2cap_ertm_send(sk) == 0) {
1452 control |= L2CAP_SUPER_RCV_READY;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001453 l2cap_send_sframe(pi, control);
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001454 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001455}
1456
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001457static void l2cap_send_srejtail(struct sock *sk)
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03001458{
1459 struct srej_list *tail;
1460 u16 control;
1461
1462 control = L2CAP_SUPER_SELECT_REJECT;
1463 control |= L2CAP_CTRL_FINAL;
1464
1465 tail = list_entry(SREJ_LIST(sk)->prev, struct srej_list, list);
1466 control |= tail->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1467
1468 l2cap_send_sframe(l2cap_pi(sk), control);
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03001469}
1470
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001471static 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 -07001472{
1473 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001474 struct sk_buff **frag;
1475 int err, sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001476
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03001477 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001478 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001479
1480 sent += count;
1481 len -= count;
1482
1483 /* Continuation fragments (no L2CAP header) */
1484 frag = &skb_shinfo(skb)->frag_list;
1485 while (len) {
1486 count = min_t(unsigned int, conn->mtu, len);
1487
1488 *frag = bt_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err);
1489 if (!*frag)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001490 return -EFAULT;
1491 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
1492 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001493
1494 sent += count;
1495 len -= count;
1496
1497 frag = &(*frag)->next;
1498 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001499
1500 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001501}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001502
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001503static struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, size_t len)
1504{
1505 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1506 struct sk_buff *skb;
1507 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1508 struct l2cap_hdr *lh;
1509
1510 BT_DBG("sk %p len %d", sk, (int)len);
1511
1512 count = min_t(unsigned int, (conn->mtu - hlen), len);
1513 skb = bt_skb_send_alloc(sk, count + hlen,
1514 msg->msg_flags & MSG_DONTWAIT, &err);
1515 if (!skb)
1516 return ERR_PTR(-ENOMEM);
1517
1518 /* Create L2CAP header */
1519 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1520 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1521 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1522 put_unaligned_le16(l2cap_pi(sk)->psm, skb_put(skb, 2));
1523
1524 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1525 if (unlikely(err < 0)) {
1526 kfree_skb(skb);
1527 return ERR_PTR(err);
1528 }
1529 return skb;
1530}
1531
1532static struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *msg, size_t len)
1533{
1534 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1535 struct sk_buff *skb;
1536 int err, count, hlen = L2CAP_HDR_SIZE;
1537 struct l2cap_hdr *lh;
1538
1539 BT_DBG("sk %p len %d", sk, (int)len);
1540
1541 count = min_t(unsigned int, (conn->mtu - hlen), len);
1542 skb = bt_skb_send_alloc(sk, count + hlen,
1543 msg->msg_flags & MSG_DONTWAIT, &err);
1544 if (!skb)
1545 return ERR_PTR(-ENOMEM);
1546
1547 /* Create L2CAP header */
1548 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1549 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1550 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1551
1552 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1553 if (unlikely(err < 0)) {
1554 kfree_skb(skb);
1555 return ERR_PTR(err);
1556 }
1557 return skb;
1558}
1559
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001560static struct sk_buff *l2cap_create_iframe_pdu(struct sock *sk, struct msghdr *msg, size_t len, u16 control, u16 sdulen)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001561{
1562 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1563 struct sk_buff *skb;
1564 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1565 struct l2cap_hdr *lh;
1566
1567 BT_DBG("sk %p len %d", sk, (int)len);
1568
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03001569 if (!conn)
1570 return ERR_PTR(-ENOTCONN);
1571
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001572 if (sdulen)
1573 hlen += 2;
1574
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001575 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1576 hlen += 2;
1577
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001578 count = min_t(unsigned int, (conn->mtu - hlen), len);
1579 skb = bt_skb_send_alloc(sk, count + hlen,
1580 msg->msg_flags & MSG_DONTWAIT, &err);
1581 if (!skb)
1582 return ERR_PTR(-ENOMEM);
1583
1584 /* Create L2CAP header */
1585 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1586 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1587 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1588 put_unaligned_le16(control, skb_put(skb, 2));
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001589 if (sdulen)
1590 put_unaligned_le16(sdulen, skb_put(skb, 2));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001591
1592 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1593 if (unlikely(err < 0)) {
1594 kfree_skb(skb);
1595 return ERR_PTR(err);
1596 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001597
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001598 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1599 put_unaligned_le16(0, skb_put(skb, 2));
1600
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001601 bt_cb(skb)->retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001602 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001603}
1604
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001605static inline int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len)
1606{
1607 struct l2cap_pinfo *pi = l2cap_pi(sk);
1608 struct sk_buff *skb;
1609 struct sk_buff_head sar_queue;
1610 u16 control;
1611 size_t size = 0;
1612
Gustavo F. Padovanff12fd62010-05-05 22:09:15 -03001613 skb_queue_head_init(&sar_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001614 control = L2CAP_SDU_START;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001615 skb = l2cap_create_iframe_pdu(sk, msg, pi->remote_mps, control, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001616 if (IS_ERR(skb))
1617 return PTR_ERR(skb);
1618
1619 __skb_queue_tail(&sar_queue, skb);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001620 len -= pi->remote_mps;
1621 size += pi->remote_mps;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001622
1623 while (len > 0) {
1624 size_t buflen;
1625
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001626 if (len > pi->remote_mps) {
Gustavo F. Padovan44651b82010-05-01 16:15:43 -03001627 control = L2CAP_SDU_CONTINUE;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001628 buflen = pi->remote_mps;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001629 } else {
Gustavo F. Padovan44651b82010-05-01 16:15:43 -03001630 control = L2CAP_SDU_END;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001631 buflen = len;
1632 }
1633
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001634 skb = l2cap_create_iframe_pdu(sk, msg, buflen, control, 0);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001635 if (IS_ERR(skb)) {
1636 skb_queue_purge(&sar_queue);
1637 return PTR_ERR(skb);
1638 }
1639
1640 __skb_queue_tail(&sar_queue, skb);
1641 len -= buflen;
1642 size += buflen;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001643 }
1644 skb_queue_splice_tail(&sar_queue, TX_QUEUE(sk));
1645 if (sk->sk_send_head == NULL)
1646 sk->sk_send_head = sar_queue.next;
1647
1648 return size;
1649}
1650
Linus Torvalds1da177e2005-04-16 15:20:36 -07001651static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len)
1652{
1653 struct sock *sk = sock->sk;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001654 struct l2cap_pinfo *pi = l2cap_pi(sk);
1655 struct sk_buff *skb;
1656 u16 control;
1657 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001658
1659 BT_DBG("sock %p, sk %p", sock, sk);
1660
Benjamin LaHaisec1cbe4b2005-12-13 23:22:19 -08001661 err = sock_error(sk);
1662 if (err)
1663 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001664
1665 if (msg->msg_flags & MSG_OOB)
1666 return -EOPNOTSUPP;
1667
Linus Torvalds1da177e2005-04-16 15:20:36 -07001668 lock_sock(sk);
1669
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001670 if (sk->sk_state != BT_CONNECTED) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001671 err = -ENOTCONN;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001672 goto done;
1673 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001674
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001675 /* Connectionless channel */
1676 if (sk->sk_type == SOCK_DGRAM) {
1677 skb = l2cap_create_connless_pdu(sk, msg, len);
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001678 if (IS_ERR(skb)) {
Dan Carpenter477fffb2010-04-21 23:52:01 +00001679 err = PTR_ERR(skb);
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001680 } else {
1681 l2cap_do_send(sk, skb);
1682 err = len;
1683 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001684 goto done;
1685 }
1686
1687 switch (pi->mode) {
1688 case L2CAP_MODE_BASIC:
Gustavo F. Padovanc69163e2010-05-01 16:15:35 -03001689 /* Check outgoing MTU */
1690 if (len > pi->omtu) {
1691 err = -EINVAL;
1692 goto done;
1693 }
1694
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001695 /* Create a basic PDU */
1696 skb = l2cap_create_basic_pdu(sk, msg, len);
1697 if (IS_ERR(skb)) {
1698 err = PTR_ERR(skb);
1699 goto done;
1700 }
1701
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001702 l2cap_do_send(sk, skb);
1703 err = len;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001704 break;
1705
1706 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001707 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001708 /* Entire SDU fits into one PDU */
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001709 if (len <= pi->remote_mps) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001710 control = L2CAP_SDU_UNSEGMENTED;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001711 skb = l2cap_create_iframe_pdu(sk, msg, len, control, 0);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001712 if (IS_ERR(skb)) {
1713 err = PTR_ERR(skb);
1714 goto done;
1715 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001716 __skb_queue_tail(TX_QUEUE(sk), skb);
1717 if (sk->sk_send_head == NULL)
1718 sk->sk_send_head = skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001719 } else {
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001720 /* Segment SDU into multiples PDUs */
1721 err = l2cap_sar_segment_sdu(sk, msg, len);
1722 if (err < 0)
1723 goto done;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001724 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001725
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001726 if (pi->mode == L2CAP_MODE_STREAMING)
1727 err = l2cap_streaming_send(sk);
1728 else
1729 err = l2cap_ertm_send(sk);
1730
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001731 if (err >= 0)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001732 err = len;
1733 break;
1734
1735 default:
1736 BT_DBG("bad state %1.1x", pi->mode);
1737 err = -EINVAL;
1738 }
1739
1740done:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001741 release_sock(sk);
1742 return err;
1743}
1744
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001745static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags)
1746{
1747 struct sock *sk = sock->sk;
1748
1749 lock_sock(sk);
1750
1751 if (sk->sk_state == BT_CONNECT2 && bt_sk(sk)->defer_setup) {
1752 struct l2cap_conn_rsp rsp;
1753
1754 sk->sk_state = BT_CONFIG;
1755
1756 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
1757 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
1758 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
1759 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
1760 l2cap_send_cmd(l2cap_pi(sk)->conn, l2cap_pi(sk)->ident,
1761 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
1762
1763 release_sock(sk);
1764 return 0;
1765 }
1766
1767 release_sock(sk);
1768
1769 return bt_sock_recvmsg(iocb, sock, msg, len, flags);
1770}
1771
David S. Millerb7058842009-09-30 16:12:20 -07001772static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001773{
1774 struct sock *sk = sock->sk;
1775 struct l2cap_options opts;
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001776 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001777 u32 opt;
1778
1779 BT_DBG("sk %p", sk);
1780
1781 lock_sock(sk);
1782
1783 switch (optname) {
1784 case L2CAP_OPTIONS:
Marcel Holtmann0878b662007-05-05 00:35:59 +02001785 opts.imtu = l2cap_pi(sk)->imtu;
1786 opts.omtu = l2cap_pi(sk)->omtu;
1787 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001788 opts.mode = l2cap_pi(sk)->mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001789 opts.fcs = l2cap_pi(sk)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03001790 opts.max_tx = l2cap_pi(sk)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03001791 opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
Marcel Holtmann0878b662007-05-05 00:35:59 +02001792
Linus Torvalds1da177e2005-04-16 15:20:36 -07001793 len = min_t(unsigned int, sizeof(opts), optlen);
1794 if (copy_from_user((char *) &opts, optval, len)) {
1795 err = -EFAULT;
1796 break;
1797 }
Marcel Holtmann0878b662007-05-05 00:35:59 +02001798
João Paulo Rechi Vita0041ecf2010-05-01 16:15:42 -03001799 l2cap_pi(sk)->mode = opts.mode;
1800 switch (l2cap_pi(sk)->mode) {
1801 case L2CAP_MODE_BASIC:
1802 break;
1803 case L2CAP_MODE_ERTM:
1804 case L2CAP_MODE_STREAMING:
1805 if (enable_ertm)
1806 break;
1807 /* fall through */
1808 default:
1809 err = -EINVAL;
1810 break;
1811 }
1812
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001813 l2cap_pi(sk)->imtu = opts.imtu;
1814 l2cap_pi(sk)->omtu = opts.omtu;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001815 l2cap_pi(sk)->fcs = opts.fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03001816 l2cap_pi(sk)->max_tx = opts.max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03001817 l2cap_pi(sk)->tx_win = (__u8)opts.txwin_size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001818 break;
1819
1820 case L2CAP_LM:
1821 if (get_user(opt, (u32 __user *) optval)) {
1822 err = -EFAULT;
1823 break;
1824 }
1825
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001826 if (opt & L2CAP_LM_AUTH)
1827 l2cap_pi(sk)->sec_level = BT_SECURITY_LOW;
1828 if (opt & L2CAP_LM_ENCRYPT)
1829 l2cap_pi(sk)->sec_level = BT_SECURITY_MEDIUM;
1830 if (opt & L2CAP_LM_SECURE)
1831 l2cap_pi(sk)->sec_level = BT_SECURITY_HIGH;
1832
1833 l2cap_pi(sk)->role_switch = (opt & L2CAP_LM_MASTER);
1834 l2cap_pi(sk)->force_reliable = (opt & L2CAP_LM_RELIABLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001835 break;
1836
1837 default:
1838 err = -ENOPROTOOPT;
1839 break;
1840 }
1841
1842 release_sock(sk);
1843 return err;
1844}
1845
David S. Millerb7058842009-09-30 16:12:20 -07001846static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001847{
1848 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001849 struct bt_security sec;
1850 int len, err = 0;
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001851 u32 opt;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001852
1853 BT_DBG("sk %p", sk);
1854
1855 if (level == SOL_L2CAP)
1856 return l2cap_sock_setsockopt_old(sock, optname, optval, optlen);
1857
Marcel Holtmann0588d942009-01-16 10:06:13 +01001858 if (level != SOL_BLUETOOTH)
1859 return -ENOPROTOOPT;
1860
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001861 lock_sock(sk);
1862
1863 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001864 case BT_SECURITY:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001865 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
1866 && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01001867 err = -EINVAL;
1868 break;
1869 }
1870
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001871 sec.level = BT_SECURITY_LOW;
1872
1873 len = min_t(unsigned int, sizeof(sec), optlen);
1874 if (copy_from_user((char *) &sec, optval, len)) {
1875 err = -EFAULT;
1876 break;
1877 }
1878
1879 if (sec.level < BT_SECURITY_LOW ||
1880 sec.level > BT_SECURITY_HIGH) {
1881 err = -EINVAL;
1882 break;
1883 }
1884
1885 l2cap_pi(sk)->sec_level = sec.level;
1886 break;
1887
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001888 case BT_DEFER_SETUP:
1889 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
1890 err = -EINVAL;
1891 break;
1892 }
1893
1894 if (get_user(opt, (u32 __user *) optval)) {
1895 err = -EFAULT;
1896 break;
1897 }
1898
1899 bt_sk(sk)->defer_setup = opt;
1900 break;
1901
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001902 default:
1903 err = -ENOPROTOOPT;
1904 break;
1905 }
1906
1907 release_sock(sk);
1908 return err;
1909}
1910
1911static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001912{
1913 struct sock *sk = sock->sk;
1914 struct l2cap_options opts;
1915 struct l2cap_conninfo cinfo;
1916 int len, err = 0;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001917 u32 opt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001918
1919 BT_DBG("sk %p", sk);
1920
1921 if (get_user(len, optlen))
1922 return -EFAULT;
1923
1924 lock_sock(sk);
1925
1926 switch (optname) {
1927 case L2CAP_OPTIONS:
1928 opts.imtu = l2cap_pi(sk)->imtu;
1929 opts.omtu = l2cap_pi(sk)->omtu;
1930 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001931 opts.mode = l2cap_pi(sk)->mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001932 opts.fcs = l2cap_pi(sk)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03001933 opts.max_tx = l2cap_pi(sk)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03001934 opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001935
1936 len = min_t(unsigned int, len, sizeof(opts));
1937 if (copy_to_user(optval, (char *) &opts, len))
1938 err = -EFAULT;
1939
1940 break;
1941
1942 case L2CAP_LM:
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001943 switch (l2cap_pi(sk)->sec_level) {
1944 case BT_SECURITY_LOW:
1945 opt = L2CAP_LM_AUTH;
1946 break;
1947 case BT_SECURITY_MEDIUM:
1948 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT;
1949 break;
1950 case BT_SECURITY_HIGH:
1951 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT |
1952 L2CAP_LM_SECURE;
1953 break;
1954 default:
1955 opt = 0;
1956 break;
1957 }
1958
1959 if (l2cap_pi(sk)->role_switch)
1960 opt |= L2CAP_LM_MASTER;
1961
1962 if (l2cap_pi(sk)->force_reliable)
1963 opt |= L2CAP_LM_RELIABLE;
1964
1965 if (put_user(opt, (u32 __user *) optval))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001966 err = -EFAULT;
1967 break;
1968
1969 case L2CAP_CONNINFO:
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001970 if (sk->sk_state != BT_CONNECTED &&
1971 !(sk->sk_state == BT_CONNECT2 &&
1972 bt_sk(sk)->defer_setup)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001973 err = -ENOTCONN;
1974 break;
1975 }
1976
1977 cinfo.hci_handle = l2cap_pi(sk)->conn->hcon->handle;
1978 memcpy(cinfo.dev_class, l2cap_pi(sk)->conn->hcon->dev_class, 3);
1979
1980 len = min_t(unsigned int, len, sizeof(cinfo));
1981 if (copy_to_user(optval, (char *) &cinfo, len))
1982 err = -EFAULT;
1983
1984 break;
1985
1986 default:
1987 err = -ENOPROTOOPT;
1988 break;
1989 }
1990
1991 release_sock(sk);
1992 return err;
1993}
1994
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001995static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
1996{
1997 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001998 struct bt_security sec;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001999 int len, err = 0;
2000
2001 BT_DBG("sk %p", sk);
2002
2003 if (level == SOL_L2CAP)
2004 return l2cap_sock_getsockopt_old(sock, optname, optval, optlen);
2005
Marcel Holtmann0588d942009-01-16 10:06:13 +01002006 if (level != SOL_BLUETOOTH)
2007 return -ENOPROTOOPT;
2008
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002009 if (get_user(len, optlen))
2010 return -EFAULT;
2011
2012 lock_sock(sk);
2013
2014 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002015 case BT_SECURITY:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03002016 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
2017 && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01002018 err = -EINVAL;
2019 break;
2020 }
2021
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002022 sec.level = l2cap_pi(sk)->sec_level;
2023
2024 len = min_t(unsigned int, len, sizeof(sec));
2025 if (copy_to_user(optval, (char *) &sec, len))
2026 err = -EFAULT;
2027
2028 break;
2029
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002030 case BT_DEFER_SETUP:
2031 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
2032 err = -EINVAL;
2033 break;
2034 }
2035
2036 if (put_user(bt_sk(sk)->defer_setup, (u32 __user *) optval))
2037 err = -EFAULT;
2038
2039 break;
2040
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002041 default:
2042 err = -ENOPROTOOPT;
2043 break;
2044 }
2045
2046 release_sock(sk);
2047 return err;
2048}
2049
Linus Torvalds1da177e2005-04-16 15:20:36 -07002050static int l2cap_sock_shutdown(struct socket *sock, int how)
2051{
2052 struct sock *sk = sock->sk;
2053 int err = 0;
2054
2055 BT_DBG("sock %p, sk %p", sock, sk);
2056
2057 if (!sk)
2058 return 0;
2059
2060 lock_sock(sk);
2061 if (!sk->sk_shutdown) {
2062 sk->sk_shutdown = SHUTDOWN_MASK;
2063 l2cap_sock_clear_timer(sk);
2064 __l2cap_sock_close(sk, 0);
2065
2066 if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
Marcel Holtmannb1235d72008-07-14 20:13:54 +02002067 err = bt_sock_wait_state(sk, BT_CLOSED,
2068 sk->sk_lingertime);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002069 }
2070 release_sock(sk);
2071 return err;
2072}
2073
2074static int l2cap_sock_release(struct socket *sock)
2075{
2076 struct sock *sk = sock->sk;
2077 int err;
2078
2079 BT_DBG("sock %p, sk %p", sock, sk);
2080
2081 if (!sk)
2082 return 0;
2083
2084 err = l2cap_sock_shutdown(sock, 2);
2085
2086 sock_orphan(sk);
2087 l2cap_sock_kill(sk);
2088 return err;
2089}
2090
Linus Torvalds1da177e2005-04-16 15:20:36 -07002091static void l2cap_chan_ready(struct sock *sk)
2092{
2093 struct sock *parent = bt_sk(sk)->parent;
2094
2095 BT_DBG("sk %p, parent %p", sk, parent);
2096
2097 l2cap_pi(sk)->conf_state = 0;
2098 l2cap_sock_clear_timer(sk);
2099
2100 if (!parent) {
2101 /* Outgoing channel.
2102 * Wake up socket sleeping on connect.
2103 */
2104 sk->sk_state = BT_CONNECTED;
2105 sk->sk_state_change(sk);
2106 } else {
2107 /* Incoming channel.
2108 * Wake up socket sleeping on accept.
2109 */
2110 parent->sk_data_ready(parent, 0);
2111 }
2112}
2113
2114/* Copy frame to all raw sockets on that connection */
2115static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2116{
2117 struct l2cap_chan_list *l = &conn->chan_list;
2118 struct sk_buff *nskb;
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002119 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002120
2121 BT_DBG("conn %p", conn);
2122
2123 read_lock(&l->lock);
2124 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
2125 if (sk->sk_type != SOCK_RAW)
2126 continue;
2127
2128 /* Don't send frame to the socket it came from */
2129 if (skb->sk == sk)
2130 continue;
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002131 nskb = skb_clone(skb, GFP_ATOMIC);
2132 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002133 continue;
2134
2135 if (sock_queue_rcv_skb(sk, nskb))
2136 kfree_skb(nskb);
2137 }
2138 read_unlock(&l->lock);
2139}
2140
2141/* ---- L2CAP signalling commands ---- */
2142static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
2143 u8 code, u8 ident, u16 dlen, void *data)
2144{
2145 struct sk_buff *skb, **frag;
2146 struct l2cap_cmd_hdr *cmd;
2147 struct l2cap_hdr *lh;
2148 int len, count;
2149
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002150 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d",
2151 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002152
2153 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2154 count = min_t(unsigned int, conn->mtu, len);
2155
2156 skb = bt_skb_alloc(count, GFP_ATOMIC);
2157 if (!skb)
2158 return NULL;
2159
2160 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002161 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03002162 lh->cid = cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002163
2164 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2165 cmd->code = code;
2166 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002167 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002168
2169 if (dlen) {
2170 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2171 memcpy(skb_put(skb, count), data, count);
2172 data += count;
2173 }
2174
2175 len -= skb->len;
2176
2177 /* Continuation fragments (no L2CAP header) */
2178 frag = &skb_shinfo(skb)->frag_list;
2179 while (len) {
2180 count = min_t(unsigned int, conn->mtu, len);
2181
2182 *frag = bt_skb_alloc(count, GFP_ATOMIC);
2183 if (!*frag)
2184 goto fail;
2185
2186 memcpy(skb_put(*frag, count), data, count);
2187
2188 len -= count;
2189 data += count;
2190
2191 frag = &(*frag)->next;
2192 }
2193
2194 return skb;
2195
2196fail:
2197 kfree_skb(skb);
2198 return NULL;
2199}
2200
2201static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned long *val)
2202{
2203 struct l2cap_conf_opt *opt = *ptr;
2204 int len;
2205
2206 len = L2CAP_CONF_OPT_SIZE + opt->len;
2207 *ptr += len;
2208
2209 *type = opt->type;
2210 *olen = opt->len;
2211
2212 switch (opt->len) {
2213 case 1:
2214 *val = *((u8 *) opt->val);
2215 break;
2216
2217 case 2:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002218 *val = __le16_to_cpu(*((__le16 *) opt->val));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002219 break;
2220
2221 case 4:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002222 *val = __le32_to_cpu(*((__le32 *) opt->val));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002223 break;
2224
2225 default:
2226 *val = (unsigned long) opt->val;
2227 break;
2228 }
2229
2230 BT_DBG("type 0x%2.2x len %d val 0x%lx", *type, opt->len, *val);
2231 return len;
2232}
2233
Linus Torvalds1da177e2005-04-16 15:20:36 -07002234static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2235{
2236 struct l2cap_conf_opt *opt = *ptr;
2237
2238 BT_DBG("type 0x%2.2x len %d val 0x%lx", type, len, val);
2239
2240 opt->type = type;
2241 opt->len = len;
2242
2243 switch (len) {
2244 case 1:
2245 *((u8 *) opt->val) = val;
2246 break;
2247
2248 case 2:
Al Viro8e036fc2007-07-29 00:16:36 -07002249 *((__le16 *) opt->val) = cpu_to_le16(val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002250 break;
2251
2252 case 4:
Al Viro8e036fc2007-07-29 00:16:36 -07002253 *((__le32 *) opt->val) = cpu_to_le32(val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002254 break;
2255
2256 default:
2257 memcpy(opt->val, (void *) val, len);
2258 break;
2259 }
2260
2261 *ptr += L2CAP_CONF_OPT_SIZE + len;
2262}
2263
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002264static void l2cap_ack_timeout(unsigned long arg)
2265{
2266 struct sock *sk = (void *) arg;
2267
2268 bh_lock_sock(sk);
2269 l2cap_send_ack(l2cap_pi(sk));
2270 bh_unlock_sock(sk);
2271}
2272
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002273static inline void l2cap_ertm_init(struct sock *sk)
2274{
2275 l2cap_pi(sk)->expected_ack_seq = 0;
2276 l2cap_pi(sk)->unacked_frames = 0;
2277 l2cap_pi(sk)->buffer_seq = 0;
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03002278 l2cap_pi(sk)->num_acked = 0;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03002279 l2cap_pi(sk)->frames_sent = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002280
2281 setup_timer(&l2cap_pi(sk)->retrans_timer,
2282 l2cap_retrans_timeout, (unsigned long) sk);
2283 setup_timer(&l2cap_pi(sk)->monitor_timer,
2284 l2cap_monitor_timeout, (unsigned long) sk);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002285 setup_timer(&l2cap_pi(sk)->ack_timer,
2286 l2cap_ack_timeout, (unsigned long) sk);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002287
2288 __skb_queue_head_init(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002289 __skb_queue_head_init(BUSY_QUEUE(sk));
2290
2291 INIT_WORK(&l2cap_pi(sk)->busy_work, l2cap_busy_work);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002292}
2293
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002294static int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
2295{
2296 u32 local_feat_mask = l2cap_feat_mask;
2297 if (enable_ertm)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002298 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002299
2300 switch (mode) {
2301 case L2CAP_MODE_ERTM:
2302 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
2303 case L2CAP_MODE_STREAMING:
2304 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
2305 default:
2306 return 0x00;
2307 }
2308}
2309
2310static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
2311{
2312 switch (mode) {
2313 case L2CAP_MODE_STREAMING:
2314 case L2CAP_MODE_ERTM:
2315 if (l2cap_mode_supported(mode, remote_feat_mask))
2316 return mode;
2317 /* fall through */
2318 default:
2319 return L2CAP_MODE_BASIC;
2320 }
2321}
2322
Linus Torvalds1da177e2005-04-16 15:20:36 -07002323static int l2cap_build_conf_req(struct sock *sk, void *data)
2324{
2325 struct l2cap_pinfo *pi = l2cap_pi(sk);
2326 struct l2cap_conf_req *req = data;
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03002327 struct l2cap_conf_rfc rfc = { .mode = pi->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07002328 void *ptr = req->data;
2329
2330 BT_DBG("sk %p", sk);
2331
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002332 if (pi->num_conf_req || pi->num_conf_rsp)
2333 goto done;
2334
2335 switch (pi->mode) {
2336 case L2CAP_MODE_STREAMING:
2337 case L2CAP_MODE_ERTM:
2338 pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002339 if (!l2cap_mode_supported(pi->mode, pi->conn->feat_mask))
2340 l2cap_send_disconn_req(pi->conn, sk);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002341 break;
2342 default:
2343 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
2344 break;
2345 }
2346
2347done:
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002348 switch (pi->mode) {
2349 case L2CAP_MODE_BASIC:
2350 if (pi->imtu != L2CAP_DEFAULT_MTU)
2351 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
2352 break;
2353
2354 case L2CAP_MODE_ERTM:
2355 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03002356 rfc.txwin_size = pi->tx_win;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03002357 rfc.max_transmit = pi->max_tx;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002358 rfc.retrans_timeout = 0;
2359 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002360 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03002361 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002362 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002363
2364 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2365 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002366
2367 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2368 break;
2369
2370 if (pi->fcs == L2CAP_FCS_NONE ||
2371 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
2372 pi->fcs = L2CAP_FCS_NONE;
2373 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
2374 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002375 break;
2376
2377 case L2CAP_MODE_STREAMING:
2378 rfc.mode = L2CAP_MODE_STREAMING;
2379 rfc.txwin_size = 0;
2380 rfc.max_transmit = 0;
2381 rfc.retrans_timeout = 0;
2382 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002383 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03002384 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002385 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002386
2387 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2388 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002389
2390 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2391 break;
2392
2393 if (pi->fcs == L2CAP_FCS_NONE ||
2394 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
2395 pi->fcs = L2CAP_FCS_NONE;
2396 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
2397 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002398 break;
2399 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002400
2401 /* FIXME: Need actual value of the flush timeout */
2402 //if (flush_to != L2CAP_DEFAULT_FLUSH_TO)
2403 // l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2, pi->flush_to);
2404
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002405 req->dcid = cpu_to_le16(pi->dcid);
2406 req->flags = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002407
2408 return ptr - data;
2409}
2410
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002411static int l2cap_parse_conf_req(struct sock *sk, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002412{
2413 struct l2cap_pinfo *pi = l2cap_pi(sk);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002414 struct l2cap_conf_rsp *rsp = data;
2415 void *ptr = rsp->data;
2416 void *req = pi->conf_req;
2417 int len = pi->conf_len;
2418 int type, hint, olen;
2419 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002420 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Marcel Holtmann861d6882007-10-20 13:37:06 +02002421 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002422 u16 result = L2CAP_CONF_SUCCESS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002423
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002424 BT_DBG("sk %p", sk);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01002425
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002426 while (len >= L2CAP_CONF_OPT_SIZE) {
2427 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002428
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03002429 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07002430 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002431
2432 switch (type) {
2433 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002434 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002435 break;
2436
2437 case L2CAP_CONF_FLUSH_TO:
2438 pi->flush_to = val;
2439 break;
2440
2441 case L2CAP_CONF_QOS:
2442 break;
2443
Marcel Holtmann6464f352007-10-20 13:39:51 +02002444 case L2CAP_CONF_RFC:
2445 if (olen == sizeof(rfc))
2446 memcpy(&rfc, (void *) val, olen);
2447 break;
2448
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002449 case L2CAP_CONF_FCS:
2450 if (val == L2CAP_FCS_NONE)
2451 pi->conf_state |= L2CAP_CONF_NO_FCS_RECV;
2452
2453 break;
2454
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002455 default:
2456 if (hint)
2457 break;
2458
2459 result = L2CAP_CONF_UNKNOWN;
2460 *((u8 *) ptr++) = type;
2461 break;
2462 }
2463 }
2464
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002465 if (pi->num_conf_rsp || pi->num_conf_req)
2466 goto done;
2467
2468 switch (pi->mode) {
2469 case L2CAP_MODE_STREAMING:
2470 case L2CAP_MODE_ERTM:
2471 pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
2472 if (!l2cap_mode_supported(pi->mode, pi->conn->feat_mask))
2473 return -ECONNREFUSED;
2474 break;
2475 default:
2476 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
2477 break;
2478 }
2479
2480done:
2481 if (pi->mode != rfc.mode) {
2482 result = L2CAP_CONF_UNACCEPT;
2483 rfc.mode = pi->mode;
2484
2485 if (pi->num_conf_rsp == 1)
2486 return -ECONNREFUSED;
2487
2488 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2489 sizeof(rfc), (unsigned long) &rfc);
2490 }
2491
2492
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002493 if (result == L2CAP_CONF_SUCCESS) {
2494 /* Configure output options and let the other side know
2495 * which ones we don't like. */
2496
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002497 if (mtu < L2CAP_DEFAULT_MIN_MTU)
2498 result = L2CAP_CONF_UNACCEPT;
2499 else {
2500 pi->omtu = mtu;
2501 pi->conf_state |= L2CAP_CONF_MTU_DONE;
2502 }
2503 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002504
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002505 switch (rfc.mode) {
2506 case L2CAP_MODE_BASIC:
2507 pi->fcs = L2CAP_FCS_NONE;
2508 pi->conf_state |= L2CAP_CONF_MODE_DONE;
2509 break;
2510
2511 case L2CAP_MODE_ERTM:
2512 pi->remote_tx_win = rfc.txwin_size;
2513 pi->remote_max_tx = rfc.max_transmit;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002514 if (rfc.max_pdu_size > pi->conn->mtu - 10)
2515 rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10);
2516
2517 pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002518
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002519 rfc.retrans_timeout =
2520 le16_to_cpu(L2CAP_DEFAULT_RETRANS_TO);
2521 rfc.monitor_timeout =
2522 le16_to_cpu(L2CAP_DEFAULT_MONITOR_TO);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002523
2524 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03002525
2526 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2527 sizeof(rfc), (unsigned long) &rfc);
2528
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002529 break;
2530
2531 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002532 if (rfc.max_pdu_size > pi->conn->mtu - 10)
2533 rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10);
2534
2535 pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002536
2537 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03002538
2539 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2540 sizeof(rfc), (unsigned long) &rfc);
2541
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002542 break;
2543
2544 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02002545 result = L2CAP_CONF_UNACCEPT;
2546
2547 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002548 rfc.mode = pi->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002549 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002550
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002551 if (result == L2CAP_CONF_SUCCESS)
2552 pi->conf_state |= L2CAP_CONF_OUTPUT_DONE;
2553 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002554 rsp->scid = cpu_to_le16(pi->dcid);
2555 rsp->result = cpu_to_le16(result);
2556 rsp->flags = cpu_to_le16(0x0000);
2557
2558 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002559}
2560
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002561static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data, u16 *result)
2562{
2563 struct l2cap_pinfo *pi = l2cap_pi(sk);
2564 struct l2cap_conf_req *req = data;
2565 void *ptr = req->data;
2566 int type, olen;
2567 unsigned long val;
2568 struct l2cap_conf_rfc rfc;
2569
2570 BT_DBG("sk %p, rsp %p, len %d, req %p", sk, rsp, len, data);
2571
2572 while (len >= L2CAP_CONF_OPT_SIZE) {
2573 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
2574
2575 switch (type) {
2576 case L2CAP_CONF_MTU:
2577 if (val < L2CAP_DEFAULT_MIN_MTU) {
2578 *result = L2CAP_CONF_UNACCEPT;
2579 pi->omtu = L2CAP_DEFAULT_MIN_MTU;
2580 } else
2581 pi->omtu = val;
2582 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
2583 break;
2584
2585 case L2CAP_CONF_FLUSH_TO:
2586 pi->flush_to = val;
2587 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
2588 2, pi->flush_to);
2589 break;
2590
2591 case L2CAP_CONF_RFC:
2592 if (olen == sizeof(rfc))
2593 memcpy(&rfc, (void *)val, olen);
2594
2595 if ((pi->conf_state & L2CAP_CONF_STATE2_DEVICE) &&
2596 rfc.mode != pi->mode)
2597 return -ECONNREFUSED;
2598
2599 pi->mode = rfc.mode;
2600 pi->fcs = 0;
2601
2602 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2603 sizeof(rfc), (unsigned long) &rfc);
2604 break;
2605 }
2606 }
2607
2608 if (*result == L2CAP_CONF_SUCCESS) {
2609 switch (rfc.mode) {
2610 case L2CAP_MODE_ERTM:
2611 pi->remote_tx_win = rfc.txwin_size;
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002612 pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
2613 pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002614 pi->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002615 break;
2616 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002617 pi->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002618 }
2619 }
2620
2621 req->dcid = cpu_to_le16(pi->dcid);
2622 req->flags = cpu_to_le16(0x0000);
2623
2624 return ptr - data;
2625}
2626
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002627static int l2cap_build_conf_rsp(struct sock *sk, void *data, u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002628{
2629 struct l2cap_conf_rsp *rsp = data;
2630 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002631
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002632 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002633
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002634 rsp->scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002635 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002636 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002637
2638 return ptr - data;
2639}
2640
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002641static void l2cap_conf_rfc_get(struct sock *sk, void *rsp, int len)
2642{
2643 struct l2cap_pinfo *pi = l2cap_pi(sk);
2644 int type, olen;
2645 unsigned long val;
2646 struct l2cap_conf_rfc rfc;
2647
2648 BT_DBG("sk %p, rsp %p, len %d", sk, rsp, len);
2649
2650 if ((pi->mode != L2CAP_MODE_ERTM) && (pi->mode != L2CAP_MODE_STREAMING))
2651 return;
2652
2653 while (len >= L2CAP_CONF_OPT_SIZE) {
2654 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
2655
2656 switch (type) {
2657 case L2CAP_CONF_RFC:
2658 if (olen == sizeof(rfc))
2659 memcpy(&rfc, (void *)val, olen);
2660 goto done;
2661 }
2662 }
2663
2664done:
2665 switch (rfc.mode) {
2666 case L2CAP_MODE_ERTM:
2667 pi->remote_tx_win = rfc.txwin_size;
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002668 pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
2669 pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002670 pi->mps = le16_to_cpu(rfc.max_pdu_size);
2671 break;
2672 case L2CAP_MODE_STREAMING:
2673 pi->mps = le16_to_cpu(rfc.max_pdu_size);
2674 }
2675}
2676
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002677static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2678{
2679 struct l2cap_cmd_rej *rej = (struct l2cap_cmd_rej *) data;
2680
2681 if (rej->reason != 0x0000)
2682 return 0;
2683
2684 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
2685 cmd->ident == conn->info_ident) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002686 del_timer(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01002687
2688 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002689 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01002690
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002691 l2cap_conn_start(conn);
2692 }
2693
2694 return 0;
2695}
2696
Linus Torvalds1da177e2005-04-16 15:20:36 -07002697static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2698{
2699 struct l2cap_chan_list *list = &conn->chan_list;
2700 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
2701 struct l2cap_conn_rsp rsp;
2702 struct sock *sk, *parent;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002703 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002704
2705 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002706 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002707
2708 BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
2709
2710 /* Check if we have socket listening on psm */
2711 parent = l2cap_get_sock_by_psm(BT_LISTEN, psm, conn->src);
2712 if (!parent) {
2713 result = L2CAP_CR_BAD_PSM;
2714 goto sendresp;
2715 }
2716
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002717 /* Check if the ACL is secure enough (if not SDP) */
2718 if (psm != cpu_to_le16(0x0001) &&
2719 !hci_conn_check_link_mode(conn->hcon)) {
Marcel Holtmann2950f212009-02-12 14:02:50 +01002720 conn->disc_reason = 0x05;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002721 result = L2CAP_CR_SEC_BLOCK;
2722 goto response;
2723 }
2724
Linus Torvalds1da177e2005-04-16 15:20:36 -07002725 result = L2CAP_CR_NO_MEM;
2726
2727 /* Check for backlog size */
2728 if (sk_acceptq_is_full(parent)) {
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09002729 BT_DBG("backlog full %d", parent->sk_ack_backlog);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002730 goto response;
2731 }
2732
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09002733 sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002734 if (!sk)
2735 goto response;
2736
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002737 write_lock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002738
2739 /* Check if we already have channel with that dcid */
2740 if (__l2cap_get_chan_by_dcid(list, scid)) {
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002741 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002742 sock_set_flag(sk, SOCK_ZAPPED);
2743 l2cap_sock_kill(sk);
2744 goto response;
2745 }
2746
2747 hci_conn_hold(conn->hcon);
2748
2749 l2cap_sock_init(sk, parent);
2750 bacpy(&bt_sk(sk)->src, conn->src);
2751 bacpy(&bt_sk(sk)->dst, conn->dst);
2752 l2cap_pi(sk)->psm = psm;
2753 l2cap_pi(sk)->dcid = scid;
2754
2755 __l2cap_chan_add(conn, sk, parent);
2756 dcid = l2cap_pi(sk)->scid;
2757
2758 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
2759
Linus Torvalds1da177e2005-04-16 15:20:36 -07002760 l2cap_pi(sk)->ident = cmd->ident;
2761
Marcel Holtmann984947d2009-02-06 23:35:19 +01002762 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002763 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002764 if (bt_sk(sk)->defer_setup) {
2765 sk->sk_state = BT_CONNECT2;
2766 result = L2CAP_CR_PEND;
2767 status = L2CAP_CS_AUTHOR_PEND;
2768 parent->sk_data_ready(parent, 0);
2769 } else {
2770 sk->sk_state = BT_CONFIG;
2771 result = L2CAP_CR_SUCCESS;
2772 status = L2CAP_CS_NO_INFO;
2773 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002774 } else {
2775 sk->sk_state = BT_CONNECT2;
2776 result = L2CAP_CR_PEND;
2777 status = L2CAP_CS_AUTHEN_PEND;
2778 }
2779 } else {
2780 sk->sk_state = BT_CONNECT2;
2781 result = L2CAP_CR_PEND;
2782 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002783 }
2784
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002785 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002786
2787response:
2788 bh_unlock_sock(parent);
2789
2790sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002791 rsp.scid = cpu_to_le16(scid);
2792 rsp.dcid = cpu_to_le16(dcid);
2793 rsp.result = cpu_to_le16(result);
2794 rsp.status = cpu_to_le16(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002795 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002796
2797 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
2798 struct l2cap_info_req info;
2799 info.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
2800
2801 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
2802 conn->info_ident = l2cap_get_ident(conn);
2803
2804 mod_timer(&conn->info_timer, jiffies +
2805 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
2806
2807 l2cap_send_cmd(conn, conn->info_ident,
2808 L2CAP_INFO_REQ, sizeof(info), &info);
2809 }
2810
Linus Torvalds1da177e2005-04-16 15:20:36 -07002811 return 0;
2812}
2813
2814static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2815{
2816 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
2817 u16 scid, dcid, result, status;
2818 struct sock *sk;
2819 u8 req[128];
2820
2821 scid = __le16_to_cpu(rsp->scid);
2822 dcid = __le16_to_cpu(rsp->dcid);
2823 result = __le16_to_cpu(rsp->result);
2824 status = __le16_to_cpu(rsp->status);
2825
2826 BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
2827
2828 if (scid) {
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002829 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2830 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002831 return 0;
2832 } else {
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002833 sk = l2cap_get_chan_by_ident(&conn->chan_list, cmd->ident);
2834 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002835 return 0;
2836 }
2837
2838 switch (result) {
2839 case L2CAP_CR_SUCCESS:
2840 sk->sk_state = BT_CONFIG;
2841 l2cap_pi(sk)->ident = 0;
2842 l2cap_pi(sk)->dcid = dcid;
2843 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
2844
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002845 l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_CONNECT_PEND;
2846
Linus Torvalds1da177e2005-04-16 15:20:36 -07002847 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
2848 l2cap_build_conf_req(sk, req), req);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002849 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002850 break;
2851
2852 case L2CAP_CR_PEND:
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002853 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002854 break;
2855
2856 default:
2857 l2cap_chan_del(sk, ECONNREFUSED);
2858 break;
2859 }
2860
2861 bh_unlock_sock(sk);
2862 return 0;
2863}
2864
Al Viro88219a02007-07-29 00:17:25 -07002865static 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 -07002866{
2867 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
2868 u16 dcid, flags;
2869 u8 rsp[64];
2870 struct sock *sk;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002871 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002872
2873 dcid = __le16_to_cpu(req->dcid);
2874 flags = __le16_to_cpu(req->flags);
2875
2876 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
2877
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002878 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
2879 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002880 return -ENOENT;
2881
Marcel Holtmann354f60a2006-11-18 22:15:20 +01002882 if (sk->sk_state == BT_DISCONN)
2883 goto unlock;
2884
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002885 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07002886 len = cmd_len - sizeof(*req);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002887 if (l2cap_pi(sk)->conf_len + len > sizeof(l2cap_pi(sk)->conf_req)) {
2888 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
2889 l2cap_build_conf_rsp(sk, rsp,
2890 L2CAP_CONF_REJECT, flags), rsp);
2891 goto unlock;
2892 }
2893
2894 /* Store config. */
2895 memcpy(l2cap_pi(sk)->conf_req + l2cap_pi(sk)->conf_len, req->data, len);
2896 l2cap_pi(sk)->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002897
2898 if (flags & 0x0001) {
2899 /* Incomplete config. Send empty response. */
2900 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002901 l2cap_build_conf_rsp(sk, rsp,
2902 L2CAP_CONF_SUCCESS, 0x0001), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002903 goto unlock;
2904 }
2905
2906 /* Complete config. */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002907 len = l2cap_parse_conf_req(sk, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002908 if (len < 0) {
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002909 l2cap_send_disconn_req(conn, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002910 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002911 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002912
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002913 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002914 l2cap_pi(sk)->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002915
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002916 /* Reset config buffer. */
2917 l2cap_pi(sk)->conf_len = 0;
2918
Marcel Holtmann876d9482007-10-20 13:35:42 +02002919 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE))
2920 goto unlock;
2921
Linus Torvalds1da177e2005-04-16 15:20:36 -07002922 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) {
Joe Perchesf64f9e72009-11-29 16:55:45 -08002923 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) ||
2924 l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002925 l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
2926
Linus Torvalds1da177e2005-04-16 15:20:36 -07002927 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002928
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002929 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002930 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002931 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002932 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
2933 l2cap_ertm_init(sk);
2934
Linus Torvalds1da177e2005-04-16 15:20:36 -07002935 l2cap_chan_ready(sk);
Marcel Holtmann876d9482007-10-20 13:35:42 +02002936 goto unlock;
2937 }
2938
2939 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002940 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002941 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002942 l2cap_build_conf_req(sk, buf), buf);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002943 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002944 }
2945
2946unlock:
2947 bh_unlock_sock(sk);
2948 return 0;
2949}
2950
2951static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2952{
2953 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
2954 u16 scid, flags, result;
2955 struct sock *sk;
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002956 int len = cmd->len - sizeof(*rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002957
2958 scid = __le16_to_cpu(rsp->scid);
2959 flags = __le16_to_cpu(rsp->flags);
2960 result = __le16_to_cpu(rsp->result);
2961
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002962 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x",
2963 scid, flags, result);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002964
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002965 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2966 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002967 return 0;
2968
2969 switch (result) {
2970 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002971 l2cap_conf_rfc_get(sk, rsp->data, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002972 break;
2973
2974 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002975 if (l2cap_pi(sk)->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002976 char req[64];
2977
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02002978 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
2979 l2cap_send_disconn_req(conn, sk);
2980 goto done;
2981 }
2982
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002983 /* throw out any old stored conf requests */
2984 result = L2CAP_CONF_SUCCESS;
2985 len = l2cap_parse_conf_rsp(sk, rsp->data,
2986 len, req, &result);
2987 if (len < 0) {
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002988 l2cap_send_disconn_req(conn, sk);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002989 goto done;
2990 }
2991
2992 l2cap_send_cmd(conn, l2cap_get_ident(conn),
2993 L2CAP_CONF_REQ, len, req);
2994 l2cap_pi(sk)->num_conf_req++;
2995 if (result != L2CAP_CONF_SUCCESS)
2996 goto done;
2997 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002998 }
2999
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09003000 default:
Linus Torvalds1da177e2005-04-16 15:20:36 -07003001 sk->sk_state = BT_DISCONN;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02003002 sk->sk_err = ECONNRESET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003003 l2cap_sock_set_timer(sk, HZ * 5);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03003004 l2cap_send_disconn_req(conn, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003005 goto done;
3006 }
3007
3008 if (flags & 0x01)
3009 goto done;
3010
Linus Torvalds1da177e2005-04-16 15:20:36 -07003011 l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE;
3012
3013 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) {
Joe Perchesf64f9e72009-11-29 16:55:45 -08003014 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) ||
3015 l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003016 l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
3017
Linus Torvalds1da177e2005-04-16 15:20:36 -07003018 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003019 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003020 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003021 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003022 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
3023 l2cap_ertm_init(sk);
3024
Linus Torvalds1da177e2005-04-16 15:20:36 -07003025 l2cap_chan_ready(sk);
3026 }
3027
3028done:
3029 bh_unlock_sock(sk);
3030 return 0;
3031}
3032
3033static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3034{
3035 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
3036 struct l2cap_disconn_rsp rsp;
3037 u16 dcid, scid;
3038 struct sock *sk;
3039
3040 scid = __le16_to_cpu(req->scid);
3041 dcid = __le16_to_cpu(req->dcid);
3042
3043 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
3044
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03003045 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
3046 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003047 return 0;
3048
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003049 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
3050 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003051 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
3052
3053 sk->sk_shutdown = SHUTDOWN_MASK;
3054
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003055 skb_queue_purge(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003056
3057 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
3058 skb_queue_purge(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003059 skb_queue_purge(BUSY_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003060 del_timer(&l2cap_pi(sk)->retrans_timer);
3061 del_timer(&l2cap_pi(sk)->monitor_timer);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003062 del_timer(&l2cap_pi(sk)->ack_timer);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003063 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003064
Linus Torvalds1da177e2005-04-16 15:20:36 -07003065 l2cap_chan_del(sk, ECONNRESET);
3066 bh_unlock_sock(sk);
3067
3068 l2cap_sock_kill(sk);
3069 return 0;
3070}
3071
3072static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3073{
3074 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
3075 u16 dcid, scid;
3076 struct sock *sk;
3077
3078 scid = __le16_to_cpu(rsp->scid);
3079 dcid = __le16_to_cpu(rsp->dcid);
3080
3081 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
3082
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03003083 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
3084 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003085 return 0;
3086
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003087 skb_queue_purge(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003088
3089 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
3090 skb_queue_purge(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003091 skb_queue_purge(BUSY_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003092 del_timer(&l2cap_pi(sk)->retrans_timer);
3093 del_timer(&l2cap_pi(sk)->monitor_timer);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003094 del_timer(&l2cap_pi(sk)->ack_timer);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003095 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003096
Linus Torvalds1da177e2005-04-16 15:20:36 -07003097 l2cap_chan_del(sk, 0);
3098 bh_unlock_sock(sk);
3099
3100 l2cap_sock_kill(sk);
3101 return 0;
3102}
3103
3104static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3105{
3106 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003107 u16 type;
3108
3109 type = __le16_to_cpu(req->type);
3110
3111 BT_DBG("type 0x%4.4x", type);
3112
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003113 if (type == L2CAP_IT_FEAT_MASK) {
3114 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003115 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003116 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
3117 rsp->type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
3118 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003119 if (enable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003120 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
3121 | L2CAP_FEAT_FCS;
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03003122 put_unaligned_le32(feat_mask, rsp->data);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003123 l2cap_send_cmd(conn, cmd->ident,
3124 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003125 } else if (type == L2CAP_IT_FIXED_CHAN) {
3126 u8 buf[12];
3127 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
3128 rsp->type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3129 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
3130 memcpy(buf + 4, l2cap_fixed_chan, 8);
3131 l2cap_send_cmd(conn, cmd->ident,
3132 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003133 } else {
3134 struct l2cap_info_rsp rsp;
3135 rsp.type = cpu_to_le16(type);
3136 rsp.result = cpu_to_le16(L2CAP_IR_NOTSUPP);
3137 l2cap_send_cmd(conn, cmd->ident,
3138 L2CAP_INFO_RSP, sizeof(rsp), &rsp);
3139 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003140
3141 return 0;
3142}
3143
3144static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3145{
3146 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
3147 u16 type, result;
3148
3149 type = __le16_to_cpu(rsp->type);
3150 result = __le16_to_cpu(rsp->result);
3151
3152 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
3153
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003154 del_timer(&conn->info_timer);
3155
Marcel Holtmann984947d2009-02-06 23:35:19 +01003156 if (type == L2CAP_IT_FEAT_MASK) {
Harvey Harrison83985312008-05-02 16:25:46 -07003157 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003158
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003159 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003160 struct l2cap_info_req req;
3161 req.type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3162
3163 conn->info_ident = l2cap_get_ident(conn);
3164
3165 l2cap_send_cmd(conn, conn->info_ident,
3166 L2CAP_INFO_REQ, sizeof(req), &req);
3167 } else {
3168 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
3169 conn->info_ident = 0;
3170
3171 l2cap_conn_start(conn);
3172 }
3173 } else if (type == L2CAP_IT_FIXED_CHAN) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01003174 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003175 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003176
3177 l2cap_conn_start(conn);
3178 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003179
Linus Torvalds1da177e2005-04-16 15:20:36 -07003180 return 0;
3181}
3182
3183static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
3184{
3185 u8 *data = skb->data;
3186 int len = skb->len;
3187 struct l2cap_cmd_hdr cmd;
3188 int err = 0;
3189
3190 l2cap_raw_recv(conn, skb);
3191
3192 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07003193 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003194 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
3195 data += L2CAP_CMD_HDR_SIZE;
3196 len -= L2CAP_CMD_HDR_SIZE;
3197
Al Viro88219a02007-07-29 00:17:25 -07003198 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003199
Al Viro88219a02007-07-29 00:17:25 -07003200 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 -07003201
Al Viro88219a02007-07-29 00:17:25 -07003202 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003203 BT_DBG("corrupted command");
3204 break;
3205 }
3206
3207 switch (cmd.code) {
3208 case L2CAP_COMMAND_REJ:
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003209 l2cap_command_rej(conn, &cmd, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003210 break;
3211
3212 case L2CAP_CONN_REQ:
3213 err = l2cap_connect_req(conn, &cmd, data);
3214 break;
3215
3216 case L2CAP_CONN_RSP:
3217 err = l2cap_connect_rsp(conn, &cmd, data);
3218 break;
3219
3220 case L2CAP_CONF_REQ:
Al Viro88219a02007-07-29 00:17:25 -07003221 err = l2cap_config_req(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003222 break;
3223
3224 case L2CAP_CONF_RSP:
3225 err = l2cap_config_rsp(conn, &cmd, data);
3226 break;
3227
3228 case L2CAP_DISCONN_REQ:
3229 err = l2cap_disconnect_req(conn, &cmd, data);
3230 break;
3231
3232 case L2CAP_DISCONN_RSP:
3233 err = l2cap_disconnect_rsp(conn, &cmd, data);
3234 break;
3235
3236 case L2CAP_ECHO_REQ:
Al Viro88219a02007-07-29 00:17:25 -07003237 l2cap_send_cmd(conn, cmd.ident, L2CAP_ECHO_RSP, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003238 break;
3239
3240 case L2CAP_ECHO_RSP:
3241 break;
3242
3243 case L2CAP_INFO_REQ:
3244 err = l2cap_information_req(conn, &cmd, data);
3245 break;
3246
3247 case L2CAP_INFO_RSP:
3248 err = l2cap_information_rsp(conn, &cmd, data);
3249 break;
3250
3251 default:
3252 BT_ERR("Unknown signaling command 0x%2.2x", cmd.code);
3253 err = -EINVAL;
3254 break;
3255 }
3256
3257 if (err) {
3258 struct l2cap_cmd_rej rej;
3259 BT_DBG("error %d", err);
3260
3261 /* FIXME: Map err to a valid reason */
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003262 rej.reason = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003263 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
3264 }
3265
Al Viro88219a02007-07-29 00:17:25 -07003266 data += cmd_len;
3267 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003268 }
3269
3270 kfree_skb(skb);
3271}
3272
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003273static int l2cap_check_fcs(struct l2cap_pinfo *pi, struct sk_buff *skb)
3274{
3275 u16 our_fcs, rcv_fcs;
3276 int hdr_size = L2CAP_HDR_SIZE + 2;
3277
3278 if (pi->fcs == L2CAP_FCS_CRC16) {
3279 skb_trim(skb, skb->len - 2);
3280 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
3281 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
3282
3283 if (our_fcs != rcv_fcs)
3284 return -EINVAL;
3285 }
3286 return 0;
3287}
3288
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003289static inline void l2cap_send_i_or_rr_or_rnr(struct sock *sk)
3290{
3291 struct l2cap_pinfo *pi = l2cap_pi(sk);
3292 u16 control = 0;
3293
3294 pi->frames_sent = 0;
3295 pi->conn_state |= L2CAP_CONN_SEND_FBIT;
3296
3297 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3298
3299 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
3300 control |= L2CAP_SUPER_RCV_NOT_READY | L2CAP_CTRL_FINAL;
3301 l2cap_send_sframe(pi, control);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003302 pi->conn_state |= L2CAP_CONN_RNR_SENT;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003303 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
3304 }
3305
3306 if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY && pi->unacked_frames > 0)
3307 __mod_retrans_timer();
3308
3309 l2cap_ertm_send(sk);
3310
3311 if (!(pi->conn_state & L2CAP_CONN_LOCAL_BUSY) &&
3312 pi->frames_sent == 0) {
3313 control |= L2CAP_SUPER_RCV_READY;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003314 l2cap_send_sframe(pi, control);
3315 }
3316}
3317
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003318static 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 -03003319{
3320 struct sk_buff *next_skb;
3321
3322 bt_cb(skb)->tx_seq = tx_seq;
3323 bt_cb(skb)->sar = sar;
3324
3325 next_skb = skb_peek(SREJ_QUEUE(sk));
3326 if (!next_skb) {
3327 __skb_queue_tail(SREJ_QUEUE(sk), skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003328 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003329 }
3330
3331 do {
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003332 if (bt_cb(next_skb)->tx_seq == tx_seq)
3333 return -EINVAL;
3334
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003335 if (bt_cb(next_skb)->tx_seq > tx_seq) {
3336 __skb_queue_before(SREJ_QUEUE(sk), next_skb, skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003337 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003338 }
3339
3340 if (skb_queue_is_last(SREJ_QUEUE(sk), next_skb))
3341 break;
3342
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003343 } while ((next_skb = skb_queue_next(SREJ_QUEUE(sk), next_skb)));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003344
3345 __skb_queue_tail(SREJ_QUEUE(sk), skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003346
3347 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003348}
3349
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003350static int l2cap_ertm_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
3351{
3352 struct l2cap_pinfo *pi = l2cap_pi(sk);
3353 struct sk_buff *_skb;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003354 int err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003355
3356 switch (control & L2CAP_CTRL_SAR) {
3357 case L2CAP_SDU_UNSEGMENTED:
3358 if (pi->conn_state & L2CAP_CONN_SAR_SDU)
3359 goto drop;
3360
3361 err = sock_queue_rcv_skb(sk, skb);
3362 if (!err)
3363 return err;
3364
3365 break;
3366
3367 case L2CAP_SDU_START:
3368 if (pi->conn_state & L2CAP_CONN_SAR_SDU)
3369 goto drop;
3370
3371 pi->sdu_len = get_unaligned_le16(skb->data);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003372
3373 if (pi->sdu_len > pi->imtu)
3374 goto disconnect;
3375
3376 pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003377 if (!pi->sdu)
3378 return -ENOMEM;
3379
3380 /* pull sdu_len bytes only after alloc, because of Local Busy
3381 * condition we have to be sure that this will be executed
3382 * only once, i.e., when alloc does not fail */
3383 skb_pull(skb, 2);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003384
3385 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3386
3387 pi->conn_state |= L2CAP_CONN_SAR_SDU;
3388 pi->partial_sdu_len = skb->len;
3389 break;
3390
3391 case L2CAP_SDU_CONTINUE:
3392 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3393 goto disconnect;
3394
3395 if (!pi->sdu)
3396 goto disconnect;
3397
3398 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3399
3400 pi->partial_sdu_len += skb->len;
3401 if (pi->partial_sdu_len > pi->sdu_len)
3402 goto drop;
3403
3404 break;
3405
3406 case L2CAP_SDU_END:
3407 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3408 goto disconnect;
3409
3410 if (!pi->sdu)
3411 goto disconnect;
3412
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003413 if (!(pi->conn_state & L2CAP_CONN_SAR_RETRY)) {
3414 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003415
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003416 pi->partial_sdu_len += skb->len;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003417
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003418 if (pi->partial_sdu_len > pi->imtu)
3419 goto drop;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003420
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003421 if (pi->partial_sdu_len != pi->sdu_len)
3422 goto drop;
3423 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003424
3425 _skb = skb_clone(pi->sdu, GFP_ATOMIC);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003426 if (!_skb) {
3427 pi->conn_state |= L2CAP_CONN_SAR_RETRY;
3428 return -ENOMEM;
3429 }
3430
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003431 err = sock_queue_rcv_skb(sk, _skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003432 if (err < 0) {
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003433 kfree_skb(_skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003434 pi->conn_state |= L2CAP_CONN_SAR_RETRY;
3435 return err;
3436 }
3437
3438 pi->conn_state &= ~L2CAP_CONN_SAR_RETRY;
3439 pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003440
3441 kfree_skb(pi->sdu);
3442 break;
3443 }
3444
3445 kfree_skb(skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003446 return 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003447
3448drop:
3449 kfree_skb(pi->sdu);
3450 pi->sdu = NULL;
3451
3452disconnect:
3453 l2cap_send_disconn_req(pi->conn, sk);
3454 kfree_skb(skb);
3455 return 0;
3456}
3457
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003458static void l2cap_busy_work(struct work_struct *work)
3459{
3460 DECLARE_WAITQUEUE(wait, current);
3461 struct l2cap_pinfo *pi =
3462 container_of(work, struct l2cap_pinfo, busy_work);
3463 struct sock *sk = (struct sock *)pi;
3464 int n_tries = 0, timeo = HZ/5, err;
3465 struct sk_buff *skb;
3466 u16 control;
3467
3468 lock_sock(sk);
3469
3470 add_wait_queue(sk->sk_sleep, &wait);
3471 while ((skb = skb_peek(BUSY_QUEUE(sk)))) {
3472 set_current_state(TASK_INTERRUPTIBLE);
3473
3474 if (n_tries++ > L2CAP_LOCAL_BUSY_TRIES) {
3475 err = -EBUSY;
3476 l2cap_send_disconn_req(pi->conn, sk);
3477 goto done;
3478 }
3479
3480 if (!timeo)
3481 timeo = HZ/5;
3482
3483 if (signal_pending(current)) {
3484 err = sock_intr_errno(timeo);
3485 goto done;
3486 }
3487
3488 release_sock(sk);
3489 timeo = schedule_timeout(timeo);
3490 lock_sock(sk);
3491
3492 err = sock_error(sk);
3493 if (err)
3494 goto done;
3495
3496 while ((skb = skb_dequeue(BUSY_QUEUE(sk)))) {
3497 control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
3498 err = l2cap_ertm_reassembly_sdu(sk, skb, control);
3499 if (err < 0) {
3500 skb_queue_head(BUSY_QUEUE(sk), skb);
3501 break;
3502 }
3503
3504 pi->buffer_seq = (pi->buffer_seq + 1) % 64;
3505 }
3506
3507 if (!skb)
3508 break;
3509 }
3510
3511 if (!(pi->conn_state & L2CAP_CONN_RNR_SENT))
3512 goto done;
3513
3514 control = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3515 control |= L2CAP_SUPER_RCV_READY | L2CAP_CTRL_POLL;
3516 l2cap_send_sframe(pi, control);
3517 l2cap_pi(sk)->retry_count = 1;
3518
3519 del_timer(&pi->retrans_timer);
3520 __mod_monitor_timer();
3521
3522 l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
3523
3524done:
3525 pi->conn_state &= ~L2CAP_CONN_LOCAL_BUSY;
3526 pi->conn_state &= ~L2CAP_CONN_RNR_SENT;
3527
3528 set_current_state(TASK_RUNNING);
3529 remove_wait_queue(sk->sk_sleep, &wait);
3530
3531 release_sock(sk);
3532}
3533
3534static int l2cap_push_rx_skb(struct sock *sk, struct sk_buff *skb, u16 control)
3535{
3536 struct l2cap_pinfo *pi = l2cap_pi(sk);
3537 int sctrl, err;
3538
3539 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
3540 bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT;
3541 __skb_queue_tail(BUSY_QUEUE(sk), skb);
3542 return -EBUSY;
3543 }
3544
3545 err = l2cap_ertm_reassembly_sdu(sk, skb, control);
3546 if (err >= 0) {
3547 pi->buffer_seq = (pi->buffer_seq + 1) % 64;
3548 return err;
3549 }
3550
3551 /* Busy Condition */
3552 pi->conn_state |= L2CAP_CONN_LOCAL_BUSY;
3553 bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT;
3554 __skb_queue_tail(BUSY_QUEUE(sk), skb);
3555
3556 sctrl = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3557 sctrl |= L2CAP_SUPER_RCV_NOT_READY;
3558 l2cap_send_sframe(pi, sctrl);
3559
3560 pi->conn_state |= L2CAP_CONN_RNR_SENT;
3561
3562 queue_work(_busy_wq, &pi->busy_work);
3563
3564 return err;
3565}
3566
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003567static int l2cap_streaming_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003568{
3569 struct l2cap_pinfo *pi = l2cap_pi(sk);
3570 struct sk_buff *_skb;
3571 int err = -EINVAL;
3572
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003573 /*
3574 * TODO: We have to notify the userland if some data is lost with the
3575 * Streaming Mode.
3576 */
3577
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003578 switch (control & L2CAP_CTRL_SAR) {
3579 case L2CAP_SDU_UNSEGMENTED:
3580 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3581 kfree_skb(pi->sdu);
3582 break;
3583 }
3584
3585 err = sock_queue_rcv_skb(sk, skb);
3586 if (!err)
3587 return 0;
3588
3589 break;
3590
3591 case L2CAP_SDU_START:
3592 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3593 kfree_skb(pi->sdu);
3594 break;
3595 }
3596
3597 pi->sdu_len = get_unaligned_le16(skb->data);
3598 skb_pull(skb, 2);
3599
Gustavo F. Padovan052897c2010-05-01 16:15:40 -03003600 if (pi->sdu_len > pi->imtu) {
3601 err = -EMSGSIZE;
3602 break;
3603 }
3604
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003605 pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
3606 if (!pi->sdu) {
3607 err = -ENOMEM;
3608 break;
3609 }
3610
3611 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3612
3613 pi->conn_state |= L2CAP_CONN_SAR_SDU;
3614 pi->partial_sdu_len = skb->len;
3615 err = 0;
3616 break;
3617
3618 case L2CAP_SDU_CONTINUE:
3619 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3620 break;
3621
3622 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3623
3624 pi->partial_sdu_len += skb->len;
3625 if (pi->partial_sdu_len > pi->sdu_len)
3626 kfree_skb(pi->sdu);
3627 else
3628 err = 0;
3629
3630 break;
3631
3632 case L2CAP_SDU_END:
3633 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3634 break;
3635
3636 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3637
3638 pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
3639 pi->partial_sdu_len += skb->len;
3640
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003641 if (pi->partial_sdu_len > pi->imtu)
3642 goto drop;
3643
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003644 if (pi->partial_sdu_len == pi->sdu_len) {
3645 _skb = skb_clone(pi->sdu, GFP_ATOMIC);
3646 err = sock_queue_rcv_skb(sk, _skb);
3647 if (err < 0)
3648 kfree_skb(_skb);
3649 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003650 err = 0;
3651
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003652drop:
3653 kfree_skb(pi->sdu);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003654 break;
3655 }
3656
3657 kfree_skb(skb);
3658 return err;
3659}
3660
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003661static void l2cap_check_srej_gap(struct sock *sk, u8 tx_seq)
3662{
3663 struct sk_buff *skb;
Gustavo F. Padovanafefdbc2010-05-01 16:15:43 -03003664 u16 control;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003665
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003666 while ((skb = skb_peek(SREJ_QUEUE(sk)))) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003667 if (bt_cb(skb)->tx_seq != tx_seq)
3668 break;
3669
3670 skb = skb_dequeue(SREJ_QUEUE(sk));
Gustavo F. Padovanafefdbc2010-05-01 16:15:43 -03003671 control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003672 l2cap_ertm_reassembly_sdu(sk, skb, control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003673 l2cap_pi(sk)->buffer_seq_srej =
3674 (l2cap_pi(sk)->buffer_seq_srej + 1) % 64;
3675 tx_seq++;
3676 }
3677}
3678
3679static void l2cap_resend_srejframe(struct sock *sk, u8 tx_seq)
3680{
3681 struct l2cap_pinfo *pi = l2cap_pi(sk);
3682 struct srej_list *l, *tmp;
3683 u16 control;
3684
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003685 list_for_each_entry_safe(l, tmp, SREJ_LIST(sk), list) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003686 if (l->tx_seq == tx_seq) {
3687 list_del(&l->list);
3688 kfree(l);
3689 return;
3690 }
3691 control = L2CAP_SUPER_SELECT_REJECT;
3692 control |= l->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3693 l2cap_send_sframe(pi, control);
3694 list_del(&l->list);
3695 list_add_tail(&l->list, SREJ_LIST(sk));
3696 }
3697}
3698
3699static void l2cap_send_srejframe(struct sock *sk, u8 tx_seq)
3700{
3701 struct l2cap_pinfo *pi = l2cap_pi(sk);
3702 struct srej_list *new;
3703 u16 control;
3704
3705 while (tx_seq != pi->expected_tx_seq) {
3706 control = L2CAP_SUPER_SELECT_REJECT;
3707 control |= pi->expected_tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3708 l2cap_send_sframe(pi, control);
3709
3710 new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC);
3711 new->tx_seq = pi->expected_tx_seq++;
3712 list_add_tail(&new->list, SREJ_LIST(sk));
3713 }
3714 pi->expected_tx_seq++;
3715}
3716
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003717static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
3718{
3719 struct l2cap_pinfo *pi = l2cap_pi(sk);
3720 u8 tx_seq = __get_txseq(rx_control);
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003721 u8 req_seq = __get_reqseq(rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003722 u8 sar = rx_control >> L2CAP_CTRL_SAR_SHIFT;
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003723 u8 tx_seq_offset, expected_tx_seq_offset;
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03003724 int num_to_ack = (pi->tx_win/6) + 1;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003725 int err = 0;
3726
3727 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
3728
Gustavo F. Padovan9b16dc62010-05-05 20:05:57 -03003729 if (L2CAP_CTRL_FINAL & rx_control &&
3730 l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) {
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003731 del_timer(&pi->monitor_timer);
3732 if (pi->unacked_frames > 0)
3733 __mod_retrans_timer();
3734 pi->conn_state &= ~L2CAP_CONN_WAIT_F;
3735 }
3736
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003737 pi->expected_ack_seq = req_seq;
3738 l2cap_drop_acked_frames(sk);
3739
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003740 if (tx_seq == pi->expected_tx_seq)
3741 goto expected;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003742
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003743 tx_seq_offset = (tx_seq - pi->buffer_seq) % 64;
3744 if (tx_seq_offset < 0)
3745 tx_seq_offset += 64;
3746
3747 /* invalid tx_seq */
3748 if (tx_seq_offset >= pi->tx_win) {
3749 l2cap_send_disconn_req(pi->conn, sk);
3750 goto drop;
3751 }
3752
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003753 if (pi->conn_state == L2CAP_CONN_LOCAL_BUSY)
3754 goto drop;
3755
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003756 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3757 struct srej_list *first;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003758
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003759 first = list_first_entry(SREJ_LIST(sk),
3760 struct srej_list, list);
3761 if (tx_seq == first->tx_seq) {
3762 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3763 l2cap_check_srej_gap(sk, tx_seq);
3764
3765 list_del(&first->list);
3766 kfree(first);
3767
3768 if (list_empty(SREJ_LIST(sk))) {
3769 pi->buffer_seq = pi->buffer_seq_srej;
3770 pi->conn_state &= ~L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan855666c2010-05-01 16:15:40 -03003771 l2cap_send_ack(pi);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003772 }
3773 } else {
3774 struct srej_list *l;
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003775
3776 /* duplicated tx_seq */
3777 if (l2cap_add_to_srej_queue(sk, skb, tx_seq, sar) < 0)
3778 goto drop;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003779
3780 list_for_each_entry(l, SREJ_LIST(sk), list) {
3781 if (l->tx_seq == tx_seq) {
3782 l2cap_resend_srejframe(sk, tx_seq);
3783 return 0;
3784 }
3785 }
3786 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003787 }
3788 } else {
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003789 expected_tx_seq_offset =
3790 (pi->expected_tx_seq - pi->buffer_seq) % 64;
3791 if (expected_tx_seq_offset < 0)
3792 expected_tx_seq_offset += 64;
3793
3794 /* duplicated tx_seq */
3795 if (tx_seq_offset < expected_tx_seq_offset)
3796 goto drop;
3797
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003798 pi->conn_state |= L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003799
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003800 INIT_LIST_HEAD(SREJ_LIST(sk));
3801 pi->buffer_seq_srej = pi->buffer_seq;
3802
3803 __skb_queue_head_init(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003804 __skb_queue_head_init(BUSY_QUEUE(sk));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003805 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3806
Gustavo F. Padovanef54fd92009-08-20 22:26:04 -03003807 pi->conn_state |= L2CAP_CONN_SEND_PBIT;
3808
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003809 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003810 }
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003811 return 0;
3812
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003813expected:
3814 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
3815
3816 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
Gustavo F. Padovan3b1a9f32010-05-01 16:15:42 -03003817 bt_cb(skb)->tx_seq = tx_seq;
3818 bt_cb(skb)->sar = sar;
3819 __skb_queue_tail(SREJ_QUEUE(sk), skb);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003820 return 0;
3821 }
3822
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03003823 if (rx_control & L2CAP_CTRL_FINAL) {
3824 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3825 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
3826 else {
Gustavo F. Padovanf6e6b162010-05-01 16:15:41 -03003827 if (!skb_queue_empty(TX_QUEUE(sk)))
3828 sk->sk_send_head = TX_QUEUE(sk)->next;
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03003829 pi->next_tx_seq = pi->expected_ack_seq;
3830 l2cap_ertm_send(sk);
3831 }
3832 }
3833
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003834 err = l2cap_push_rx_skb(sk, skb, rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003835 if (err < 0)
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003836 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003837
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003838 __mod_ack_timer();
3839
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03003840 pi->num_acked = (pi->num_acked + 1) % num_to_ack;
3841 if (pi->num_acked == num_to_ack - 1)
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03003842 l2cap_send_ack(pi);
3843
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003844 return 0;
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003845
3846drop:
3847 kfree_skb(skb);
3848 return 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003849}
3850
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003851static inline void l2cap_data_channel_rrframe(struct sock *sk, u16 rx_control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003852{
3853 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan6e3a5982010-05-01 16:15:38 -03003854
3855 pi->expected_ack_seq = __get_reqseq(rx_control);
3856 l2cap_drop_acked_frames(sk);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003857
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003858 if (rx_control & L2CAP_CTRL_POLL) {
Gustavo F. Padovan05fbd892010-05-01 16:15:39 -03003859 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3860 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
3861 (pi->unacked_frames > 0))
3862 __mod_retrans_timer();
3863
3864 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3865 l2cap_send_srejtail(sk);
3866 } else {
3867 l2cap_send_i_or_rr_or_rnr(sk);
3868 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3869 }
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003870
3871 } else if (rx_control & L2CAP_CTRL_FINAL) {
3872 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003873
3874 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3875 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
3876 else {
Gustavo F. Padovanf6e6b162010-05-01 16:15:41 -03003877 if (!skb_queue_empty(TX_QUEUE(sk)))
3878 sk->sk_send_head = TX_QUEUE(sk)->next;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003879 pi->next_tx_seq = pi->expected_ack_seq;
3880 l2cap_ertm_send(sk);
3881 }
3882
3883 } else {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003884 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
3885 (pi->unacked_frames > 0))
3886 __mod_retrans_timer();
3887
3888 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3889 if (pi->conn_state & L2CAP_CONN_SREJ_SENT)
3890 l2cap_send_ack(pi);
3891 else
3892 l2cap_ertm_send(sk);
3893 }
3894}
3895
3896static inline void l2cap_data_channel_rejframe(struct sock *sk, u16 rx_control)
3897{
3898 struct l2cap_pinfo *pi = l2cap_pi(sk);
3899 u8 tx_seq = __get_reqseq(rx_control);
3900
3901 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3902
Gustavo F. Padovan8abb52e2010-05-01 16:15:38 -03003903 pi->expected_ack_seq = tx_seq;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003904 l2cap_drop_acked_frames(sk);
3905
3906 if (rx_control & L2CAP_CTRL_FINAL) {
3907 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3908 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
3909 else {
Gustavo F. Padovanf6e6b162010-05-01 16:15:41 -03003910 if (!skb_queue_empty(TX_QUEUE(sk)))
3911 sk->sk_send_head = TX_QUEUE(sk)->next;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003912 pi->next_tx_seq = pi->expected_ack_seq;
3913 l2cap_ertm_send(sk);
3914 }
3915 } else {
Gustavo F. Padovanf6e6b162010-05-01 16:15:41 -03003916 if (!skb_queue_empty(TX_QUEUE(sk)))
3917 sk->sk_send_head = TX_QUEUE(sk)->next;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003918 pi->next_tx_seq = pi->expected_ack_seq;
3919 l2cap_ertm_send(sk);
3920
Gustavo F. Padovan0301ef02010-05-05 20:56:43 -03003921 if (pi->conn_state & L2CAP_CONN_WAIT_F)
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003922 pi->conn_state |= L2CAP_CONN_REJ_ACT;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003923 }
3924}
3925static inline void l2cap_data_channel_srejframe(struct sock *sk, u16 rx_control)
3926{
3927 struct l2cap_pinfo *pi = l2cap_pi(sk);
3928 u8 tx_seq = __get_reqseq(rx_control);
3929
3930 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3931
3932 if (rx_control & L2CAP_CTRL_POLL) {
3933 pi->expected_ack_seq = tx_seq;
3934 l2cap_drop_acked_frames(sk);
3935 l2cap_retransmit_frame(sk, tx_seq);
3936 l2cap_ertm_send(sk);
3937 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
3938 pi->srej_save_reqseq = tx_seq;
3939 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
3940 }
3941 } else if (rx_control & L2CAP_CTRL_FINAL) {
3942 if ((pi->conn_state & L2CAP_CONN_SREJ_ACT) &&
3943 pi->srej_save_reqseq == tx_seq)
3944 pi->conn_state &= ~L2CAP_CONN_SREJ_ACT;
3945 else
3946 l2cap_retransmit_frame(sk, tx_seq);
3947 } else {
3948 l2cap_retransmit_frame(sk, tx_seq);
3949 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
3950 pi->srej_save_reqseq = tx_seq;
3951 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
3952 }
3953 }
3954}
3955
3956static inline void l2cap_data_channel_rnrframe(struct sock *sk, u16 rx_control)
3957{
3958 struct l2cap_pinfo *pi = l2cap_pi(sk);
3959 u8 tx_seq = __get_reqseq(rx_control);
3960
3961 pi->conn_state |= L2CAP_CONN_REMOTE_BUSY;
3962 pi->expected_ack_seq = tx_seq;
3963 l2cap_drop_acked_frames(sk);
3964
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03003965 if (!(pi->conn_state & L2CAP_CONN_SREJ_SENT)) {
3966 del_timer(&pi->retrans_timer);
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -03003967 if (rx_control & L2CAP_CTRL_POLL)
3968 l2cap_send_rr_or_rnr(pi, L2CAP_CTRL_FINAL);
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03003969 return;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003970 }
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03003971
3972 if (rx_control & L2CAP_CTRL_POLL)
3973 l2cap_send_srejtail(sk);
3974 else
3975 l2cap_send_sframe(pi, L2CAP_SUPER_RCV_READY);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003976}
3977
3978static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
3979{
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003980 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
3981
Gustavo F. Padovan9b16dc62010-05-05 20:05:57 -03003982 if (L2CAP_CTRL_FINAL & rx_control &&
3983 l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003984 del_timer(&l2cap_pi(sk)->monitor_timer);
3985 if (l2cap_pi(sk)->unacked_frames > 0)
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003986 __mod_retrans_timer();
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003987 l2cap_pi(sk)->conn_state &= ~L2CAP_CONN_WAIT_F;
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003988 }
3989
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003990 switch (rx_control & L2CAP_CTRL_SUPERVISE) {
3991 case L2CAP_SUPER_RCV_READY:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003992 l2cap_data_channel_rrframe(sk, rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003993 break;
3994
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003995 case L2CAP_SUPER_REJECT:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003996 l2cap_data_channel_rejframe(sk, rx_control);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003997 break;
3998
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003999 case L2CAP_SUPER_SELECT_REJECT:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004000 l2cap_data_channel_srejframe(sk, rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004001 break;
4002
4003 case L2CAP_SUPER_RCV_NOT_READY:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004004 l2cap_data_channel_rnrframe(sk, rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004005 break;
4006 }
4007
Gustavo F. Padovanfaaebd12010-05-01 16:15:35 -03004008 kfree_skb(skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004009 return 0;
4010}
4011
Linus Torvalds1da177e2005-04-16 15:20:36 -07004012static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk_buff *skb)
4013{
4014 struct sock *sk;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004015 struct l2cap_pinfo *pi;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03004016 u16 control, len;
João Paulo Rechi Vita01760bd2010-05-01 16:15:43 -03004017 u8 tx_seq, req_seq, next_tx_seq_offset, req_seq_offset;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004018
4019 sk = l2cap_get_chan_by_scid(&conn->chan_list, cid);
4020 if (!sk) {
4021 BT_DBG("unknown cid 0x%4.4x", cid);
4022 goto drop;
4023 }
4024
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004025 pi = l2cap_pi(sk);
4026
Linus Torvalds1da177e2005-04-16 15:20:36 -07004027 BT_DBG("sk %p, len %d", sk, skb->len);
4028
4029 if (sk->sk_state != BT_CONNECTED)
4030 goto drop;
4031
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004032 switch (pi->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004033 case L2CAP_MODE_BASIC:
4034 /* If socket recv buffers overflows we drop data here
4035 * which is *bad* because L2CAP has to be reliable.
4036 * But we don't have any other choice. L2CAP doesn't
4037 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07004038
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004039 if (pi->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004040 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004041
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004042 if (!sock_queue_rcv_skb(sk, skb))
4043 goto done;
4044 break;
4045
4046 case L2CAP_MODE_ERTM:
4047 control = get_unaligned_le16(skb->data);
4048 skb_pull(skb, 2);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03004049 len = skb->len;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004050
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03004051 if (__is_sar_start(control))
4052 len -= 2;
4053
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004054 if (pi->fcs == L2CAP_FCS_CRC16)
4055 len -= 2;
4056
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03004057 /*
4058 * We can just drop the corrupted I-frame here.
4059 * Receiver will miss it and start proper recovery
4060 * procedures and ask retransmission.
4061 */
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004062 if (len > pi->mps) {
4063 l2cap_send_disconn_req(pi->conn, sk);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004064 goto drop;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004065 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004066
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004067 if (l2cap_check_fcs(pi, skb))
4068 goto drop;
4069
João Paulo Rechi Vita01760bd2010-05-01 16:15:43 -03004070 req_seq = __get_reqseq(control);
4071 req_seq_offset = (req_seq - pi->expected_ack_seq) % 64;
4072 if (req_seq_offset < 0)
4073 req_seq_offset += 64;
4074
4075 next_tx_seq_offset =
4076 (pi->next_tx_seq - pi->expected_ack_seq) % 64;
4077 if (next_tx_seq_offset < 0)
4078 next_tx_seq_offset += 64;
4079
4080 /* check for invalid req-seq */
4081 if (req_seq_offset > next_tx_seq_offset) {
4082 l2cap_send_disconn_req(pi->conn, sk);
4083 goto drop;
4084 }
4085
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004086 if (__is_iframe(control)) {
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004087 if (len < 4) {
4088 l2cap_send_disconn_req(pi->conn, sk);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004089 goto drop;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004090 }
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004091
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02004092 l2cap_data_channel_iframe(sk, control, skb);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004093 } else {
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004094 if (len != 0) {
4095 l2cap_send_disconn_req(pi->conn, sk);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004096 goto drop;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004097 }
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004098
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02004099 l2cap_data_channel_sframe(sk, control, skb);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004100 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004101
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02004102 goto done;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004103
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004104 case L2CAP_MODE_STREAMING:
4105 control = get_unaligned_le16(skb->data);
4106 skb_pull(skb, 2);
4107 len = skb->len;
4108
4109 if (__is_sar_start(control))
4110 len -= 2;
4111
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004112 if (pi->fcs == L2CAP_FCS_CRC16)
4113 len -= 2;
4114
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03004115 if (len > pi->mps || len < 4 || __is_sframe(control))
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004116 goto drop;
4117
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004118 if (l2cap_check_fcs(pi, skb))
4119 goto drop;
4120
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004121 tx_seq = __get_txseq(control);
4122
4123 if (pi->expected_tx_seq == tx_seq)
4124 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
4125 else
Gustavo F. Padovan7dffe422010-05-01 16:15:36 -03004126 pi->expected_tx_seq = (tx_seq + 1) % 64;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004127
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004128 l2cap_streaming_reassembly_sdu(sk, skb, control);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004129
4130 goto done;
4131
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004132 default:
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03004133 BT_DBG("sk %p: bad mode 0x%2.2x", sk, pi->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004134 break;
4135 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004136
4137drop:
4138 kfree_skb(skb);
4139
4140done:
Marcel Holtmann01394182006-07-03 10:02:46 +02004141 if (sk)
4142 bh_unlock_sock(sk);
4143
Linus Torvalds1da177e2005-04-16 15:20:36 -07004144 return 0;
4145}
4146
Al Viro8e036fc2007-07-29 00:16:36 -07004147static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004148{
4149 struct sock *sk;
4150
4151 sk = l2cap_get_sock_by_psm(0, psm, conn->src);
4152 if (!sk)
4153 goto drop;
4154
4155 BT_DBG("sk %p, len %d", sk, skb->len);
4156
4157 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_CONNECTED)
4158 goto drop;
4159
4160 if (l2cap_pi(sk)->imtu < skb->len)
4161 goto drop;
4162
4163 if (!sock_queue_rcv_skb(sk, skb))
4164 goto done;
4165
4166drop:
4167 kfree_skb(skb);
4168
4169done:
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03004170 if (sk)
4171 bh_unlock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004172 return 0;
4173}
4174
4175static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
4176{
4177 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07004178 u16 cid, len;
4179 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004180
4181 skb_pull(skb, L2CAP_HDR_SIZE);
4182 cid = __le16_to_cpu(lh->cid);
4183 len = __le16_to_cpu(lh->len);
4184
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004185 if (len != skb->len) {
4186 kfree_skb(skb);
4187 return;
4188 }
4189
Linus Torvalds1da177e2005-04-16 15:20:36 -07004190 BT_DBG("len %d, cid 0x%4.4x", len, cid);
4191
4192 switch (cid) {
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03004193 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07004194 l2cap_sig_channel(conn, skb);
4195 break;
4196
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03004197 case L2CAP_CID_CONN_LESS:
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03004198 psm = get_unaligned_le16(skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004199 skb_pull(skb, 2);
4200 l2cap_conless_channel(conn, psm, skb);
4201 break;
4202
4203 default:
4204 l2cap_data_channel(conn, cid, skb);
4205 break;
4206 }
4207}
4208
4209/* ---- L2CAP interface with lower layer (HCI) ---- */
4210
4211static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
4212{
4213 int exact = 0, lm1 = 0, lm2 = 0;
4214 register struct sock *sk;
4215 struct hlist_node *node;
4216
4217 if (type != ACL_LINK)
4218 return 0;
4219
4220 BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
4221
4222 /* Find listening sockets and check their link_mode */
4223 read_lock(&l2cap_sk_list.lock);
4224 sk_for_each(sk, node, &l2cap_sk_list.head) {
4225 if (sk->sk_state != BT_LISTEN)
4226 continue;
4227
4228 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01004229 lm1 |= HCI_LM_ACCEPT;
4230 if (l2cap_pi(sk)->role_switch)
4231 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004232 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01004233 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
4234 lm2 |= HCI_LM_ACCEPT;
4235 if (l2cap_pi(sk)->role_switch)
4236 lm2 |= HCI_LM_MASTER;
4237 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004238 }
4239 read_unlock(&l2cap_sk_list.lock);
4240
4241 return exact ? lm1 : lm2;
4242}
4243
4244static int l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
4245{
Marcel Holtmann01394182006-07-03 10:02:46 +02004246 struct l2cap_conn *conn;
4247
Linus Torvalds1da177e2005-04-16 15:20:36 -07004248 BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
4249
4250 if (hcon->type != ACL_LINK)
4251 return 0;
4252
4253 if (!status) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004254 conn = l2cap_conn_add(hcon, status);
4255 if (conn)
4256 l2cap_conn_ready(conn);
Marcel Holtmann01394182006-07-03 10:02:46 +02004257 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -07004258 l2cap_conn_del(hcon, bt_err(status));
4259
4260 return 0;
4261}
4262
Marcel Holtmann2950f212009-02-12 14:02:50 +01004263static int l2cap_disconn_ind(struct hci_conn *hcon)
4264{
4265 struct l2cap_conn *conn = hcon->l2cap_data;
4266
4267 BT_DBG("hcon %p", hcon);
4268
4269 if (hcon->type != ACL_LINK || !conn)
4270 return 0x13;
4271
4272 return conn->disc_reason;
4273}
4274
4275static int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004276{
4277 BT_DBG("hcon %p reason %d", hcon, reason);
4278
4279 if (hcon->type != ACL_LINK)
4280 return 0;
4281
4282 l2cap_conn_del(hcon, bt_err(reason));
Marcel Holtmann01394182006-07-03 10:02:46 +02004283
Linus Torvalds1da177e2005-04-16 15:20:36 -07004284 return 0;
4285}
4286
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004287static inline void l2cap_check_encryption(struct sock *sk, u8 encrypt)
4288{
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03004289 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM)
Marcel Holtmann255c7602009-02-04 21:07:19 +01004290 return;
4291
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004292 if (encrypt == 0x00) {
4293 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM) {
4294 l2cap_sock_clear_timer(sk);
4295 l2cap_sock_set_timer(sk, HZ * 5);
4296 } else if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
4297 __l2cap_sock_close(sk, ECONNREFUSED);
4298 } else {
4299 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM)
4300 l2cap_sock_clear_timer(sk);
4301 }
4302}
4303
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004304static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004305{
4306 struct l2cap_chan_list *l;
Marcel Holtmann40be4922008-07-14 20:13:50 +02004307 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004308 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004309
Marcel Holtmann01394182006-07-03 10:02:46 +02004310 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004311 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02004312
Linus Torvalds1da177e2005-04-16 15:20:36 -07004313 l = &conn->chan_list;
4314
4315 BT_DBG("conn %p", conn);
4316
4317 read_lock(&l->lock);
4318
4319 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
4320 bh_lock_sock(sk);
4321
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01004322 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND) {
4323 bh_unlock_sock(sk);
4324 continue;
4325 }
4326
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004327 if (!status && (sk->sk_state == BT_CONNECTED ||
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004328 sk->sk_state == BT_CONFIG)) {
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004329 l2cap_check_encryption(sk, encrypt);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02004330 bh_unlock_sock(sk);
4331 continue;
4332 }
4333
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004334 if (sk->sk_state == BT_CONNECT) {
4335 if (!status) {
4336 struct l2cap_conn_req req;
4337 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
4338 req.psm = l2cap_pi(sk)->psm;
4339
4340 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
4341
4342 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
4343 L2CAP_CONN_REQ, sizeof(req), &req);
4344 } else {
4345 l2cap_sock_clear_timer(sk);
4346 l2cap_sock_set_timer(sk, HZ / 10);
4347 }
4348 } else if (sk->sk_state == BT_CONNECT2) {
4349 struct l2cap_conn_rsp rsp;
4350 __u16 result;
4351
4352 if (!status) {
4353 sk->sk_state = BT_CONFIG;
4354 result = L2CAP_CR_SUCCESS;
4355 } else {
4356 sk->sk_state = BT_DISCONN;
4357 l2cap_sock_set_timer(sk, HZ / 10);
4358 result = L2CAP_CR_SEC_BLOCK;
4359 }
4360
4361 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
4362 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
4363 rsp.result = cpu_to_le16(result);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02004364 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004365 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
4366 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004367 }
4368
Linus Torvalds1da177e2005-04-16 15:20:36 -07004369 bh_unlock_sock(sk);
4370 }
4371
4372 read_unlock(&l->lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004373
Linus Torvalds1da177e2005-04-16 15:20:36 -07004374 return 0;
4375}
4376
4377static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
4378{
4379 struct l2cap_conn *conn = hcon->l2cap_data;
4380
4381 if (!conn && !(conn = l2cap_conn_add(hcon, 0)))
4382 goto drop;
4383
4384 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
4385
4386 if (flags & ACL_START) {
4387 struct l2cap_hdr *hdr;
4388 int len;
4389
4390 if (conn->rx_len) {
4391 BT_ERR("Unexpected start frame (len %d)", skb->len);
4392 kfree_skb(conn->rx_skb);
4393 conn->rx_skb = NULL;
4394 conn->rx_len = 0;
4395 l2cap_conn_unreliable(conn, ECOMM);
4396 }
4397
4398 if (skb->len < 2) {
4399 BT_ERR("Frame is too short (len %d)", skb->len);
4400 l2cap_conn_unreliable(conn, ECOMM);
4401 goto drop;
4402 }
4403
4404 hdr = (struct l2cap_hdr *) skb->data;
4405 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
4406
4407 if (len == skb->len) {
4408 /* Complete frame received */
4409 l2cap_recv_frame(conn, skb);
4410 return 0;
4411 }
4412
4413 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
4414
4415 if (skb->len > len) {
4416 BT_ERR("Frame is too long (len %d, expected len %d)",
4417 skb->len, len);
4418 l2cap_conn_unreliable(conn, ECOMM);
4419 goto drop;
4420 }
4421
4422 /* Allocate skb for the complete frame (with header) */
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03004423 conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC);
4424 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004425 goto drop;
4426
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03004427 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004428 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004429 conn->rx_len = len - skb->len;
4430 } else {
4431 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
4432
4433 if (!conn->rx_len) {
4434 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
4435 l2cap_conn_unreliable(conn, ECOMM);
4436 goto drop;
4437 }
4438
4439 if (skb->len > conn->rx_len) {
4440 BT_ERR("Fragment is too long (len %d, expected %d)",
4441 skb->len, conn->rx_len);
4442 kfree_skb(conn->rx_skb);
4443 conn->rx_skb = NULL;
4444 conn->rx_len = 0;
4445 l2cap_conn_unreliable(conn, ECOMM);
4446 goto drop;
4447 }
4448
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03004449 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004450 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004451 conn->rx_len -= skb->len;
4452
4453 if (!conn->rx_len) {
4454 /* Complete frame received */
4455 l2cap_recv_frame(conn, conn->rx_skb);
4456 conn->rx_skb = NULL;
4457 }
4458 }
4459
4460drop:
4461 kfree_skb(skb);
4462 return 0;
4463}
4464
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004465static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004466{
4467 struct sock *sk;
4468 struct hlist_node *node;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004469
4470 read_lock_bh(&l2cap_sk_list.lock);
4471
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004472 sk_for_each(sk, node, &l2cap_sk_list.head) {
4473 struct l2cap_pinfo *pi = l2cap_pi(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004474
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004475 seq_printf(f, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d\n",
4476 batostr(&bt_sk(sk)->src),
4477 batostr(&bt_sk(sk)->dst),
4478 sk->sk_state, __le16_to_cpu(pi->psm),
4479 pi->scid, pi->dcid,
4480 pi->imtu, pi->omtu, pi->sec_level);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004481 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004482
Linus Torvalds1da177e2005-04-16 15:20:36 -07004483 read_unlock_bh(&l2cap_sk_list.lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004484
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004485 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004486}
4487
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004488static int l2cap_debugfs_open(struct inode *inode, struct file *file)
4489{
4490 return single_open(file, l2cap_debugfs_show, inode->i_private);
4491}
4492
4493static const struct file_operations l2cap_debugfs_fops = {
4494 .open = l2cap_debugfs_open,
4495 .read = seq_read,
4496 .llseek = seq_lseek,
4497 .release = single_release,
4498};
4499
4500static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004501
Eric Dumazet90ddc4f2005-12-22 12:49:22 -08004502static const struct proto_ops l2cap_sock_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004503 .family = PF_BLUETOOTH,
4504 .owner = THIS_MODULE,
4505 .release = l2cap_sock_release,
4506 .bind = l2cap_sock_bind,
4507 .connect = l2cap_sock_connect,
4508 .listen = l2cap_sock_listen,
4509 .accept = l2cap_sock_accept,
4510 .getname = l2cap_sock_getname,
4511 .sendmsg = l2cap_sock_sendmsg,
Marcel Holtmannf66dc812009-01-15 21:57:00 +01004512 .recvmsg = l2cap_sock_recvmsg,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004513 .poll = bt_sock_poll,
Marcel Holtmann3241ad82008-07-14 20:13:50 +02004514 .ioctl = bt_sock_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004515 .mmap = sock_no_mmap,
4516 .socketpair = sock_no_socketpair,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004517 .shutdown = l2cap_sock_shutdown,
4518 .setsockopt = l2cap_sock_setsockopt,
4519 .getsockopt = l2cap_sock_getsockopt
4520};
4521
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +00004522static const struct net_proto_family l2cap_sock_family_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004523 .family = PF_BLUETOOTH,
4524 .owner = THIS_MODULE,
4525 .create = l2cap_sock_create,
4526};
4527
4528static struct hci_proto l2cap_hci_proto = {
4529 .name = "L2CAP",
4530 .id = HCI_PROTO_L2CAP,
4531 .connect_ind = l2cap_connect_ind,
4532 .connect_cfm = l2cap_connect_cfm,
4533 .disconn_ind = l2cap_disconn_ind,
Marcel Holtmann2950f212009-02-12 14:02:50 +01004534 .disconn_cfm = l2cap_disconn_cfm,
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004535 .security_cfm = l2cap_security_cfm,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004536 .recv_acldata = l2cap_recv_acldata
4537};
4538
4539static int __init l2cap_init(void)
4540{
4541 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004542
Linus Torvalds1da177e2005-04-16 15:20:36 -07004543 err = proto_register(&l2cap_proto, 0);
4544 if (err < 0)
4545 return err;
4546
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004547 _busy_wq = create_singlethread_workqueue("l2cap");
4548 if (!_busy_wq)
4549 goto error;
4550
Linus Torvalds1da177e2005-04-16 15:20:36 -07004551 err = bt_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops);
4552 if (err < 0) {
4553 BT_ERR("L2CAP socket registration failed");
4554 goto error;
4555 }
4556
4557 err = hci_register_proto(&l2cap_hci_proto);
4558 if (err < 0) {
4559 BT_ERR("L2CAP protocol registration failed");
4560 bt_sock_unregister(BTPROTO_L2CAP);
4561 goto error;
4562 }
4563
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004564 if (bt_debugfs) {
4565 l2cap_debugfs = debugfs_create_file("l2cap", 0444,
4566 bt_debugfs, NULL, &l2cap_debugfs_fops);
4567 if (!l2cap_debugfs)
4568 BT_ERR("Failed to create L2CAP debug file");
4569 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004570
4571 BT_INFO("L2CAP ver %s", VERSION);
4572 BT_INFO("L2CAP socket layer initialized");
4573
4574 return 0;
4575
4576error:
4577 proto_unregister(&l2cap_proto);
4578 return err;
4579}
4580
4581static void __exit l2cap_exit(void)
4582{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004583 debugfs_remove(l2cap_debugfs);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004584
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004585 flush_workqueue(_busy_wq);
4586 destroy_workqueue(_busy_wq);
4587
Linus Torvalds1da177e2005-04-16 15:20:36 -07004588 if (bt_sock_unregister(BTPROTO_L2CAP) < 0)
4589 BT_ERR("L2CAP socket unregistration failed");
4590
4591 if (hci_unregister_proto(&l2cap_hci_proto) < 0)
4592 BT_ERR("L2CAP protocol unregistration failed");
4593
4594 proto_unregister(&l2cap_proto);
4595}
4596
4597void l2cap_load(void)
4598{
4599 /* Dummy function to trigger automatic L2CAP module loading by
4600 * other modules that use L2CAP sockets but don't use any other
4601 * symbols from it. */
4602 return;
4603}
4604EXPORT_SYMBOL(l2cap_load);
4605
4606module_init(l2cap_init);
4607module_exit(l2cap_exit);
4608
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07004609module_param(enable_ertm, bool, 0644);
4610MODULE_PARM_DESC(enable_ertm, "Enable enhanced retransmission mode");
4611
Marcel Holtmann5fbcd3d2009-10-05 11:35:43 +02004612module_param(max_transmit, uint, 0644);
4613MODULE_PARM_DESC(max_transmit, "Max transmit value (default = 3)");
4614
Gustavo F. Padovan369ba302010-05-01 16:15:41 -03004615module_param(tx_window, uint, 0644);
4616MODULE_PARM_DESC(tx_window, "Transmission window size value (default = 63)");
4617
Marcel Holtmann63fbd242008-08-18 13:23:53 +02004618MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004619MODULE_DESCRIPTION("Bluetooth L2CAP ver " VERSION);
4620MODULE_VERSION(VERSION);
4621MODULE_LICENSE("GPL");
4622MODULE_ALIAS("bt-proto-0");