blob: 9d514f9dbc0f643f5e7c93ef791b1471b655a556 [file] [log] [blame]
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 BlueZ - Bluetooth protocol stack for Linux
3 Copyright (C) 2000-2001 Qualcomm Incorporated
4
5 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License version 2 as
9 published by the Free Software Foundation;
10
11 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
12 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
14 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090015 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
16 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Linus Torvalds1da177e2005-04-16 15:20:36 -070018 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090020 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
21 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
Linus Torvalds1da177e2005-04-16 15:20:36 -070022 SOFTWARE IS DISCLAIMED.
23*/
24
25/* Bluetooth L2CAP core and sockets. */
26
Linus Torvalds1da177e2005-04-16 15:20:36 -070027#include <linux/module.h>
28
29#include <linux/types.h>
Randy Dunlap4fc268d2006-01-11 12:17:47 -080030#include <linux/capability.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070031#include <linux/errno.h>
32#include <linux/kernel.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070033#include <linux/sched.h>
34#include <linux/slab.h>
35#include <linux/poll.h>
36#include <linux/fcntl.h>
37#include <linux/init.h>
38#include <linux/interrupt.h>
39#include <linux/socket.h>
40#include <linux/skbuff.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070041#include <linux/list.h>
Marcel Holtmannbe9d1222005-11-08 09:57:38 -080042#include <linux/device.h>
Marcel Holtmannaef7d972010-03-21 05:27:45 +010043#include <linux/debugfs.h>
44#include <linux/seq_file.h>
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -030045#include <linux/uaccess.h>
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -030046#include <linux/crc16.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070047#include <net/sock.h>
48
49#include <asm/system.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070050#include <asm/unaligned.h>
51
52#include <net/bluetooth/bluetooth.h>
53#include <net/bluetooth/hci_core.h>
54#include <net/bluetooth/l2cap.h>
55
Marcel Holtmann44dd46d2009-05-02 19:09:01 -070056#define VERSION "2.14"
57
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. Padovanaf05b30b2009-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. Padovanaf05b30b2009-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. Padovanaf05b30b2009-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. Padovanaf05b30b2009-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. Padovanaf05b30b2009-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. Padovanaf05b30b2009-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. Padovanaf05b30b2009-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. Padovanaf05b30b2009-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. Padovanaf05b30b2009-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. Padovan6161c032010-05-01 16:15:44 -03001245static int __l2cap_wait_ack(struct sock *sk)
1246{
1247 DECLARE_WAITQUEUE(wait, current);
1248 int err = 0;
1249 int timeo = HZ/5;
1250
1251 add_wait_queue(sk->sk_sleep, &wait);
1252 while ((l2cap_pi(sk)->unacked_frames > 0 && l2cap_pi(sk)->conn)) {
1253 set_current_state(TASK_INTERRUPTIBLE);
1254
1255 if (!timeo)
1256 timeo = HZ/5;
1257
1258 if (signal_pending(current)) {
1259 err = sock_intr_errno(timeo);
1260 break;
1261 }
1262
1263 release_sock(sk);
1264 timeo = schedule_timeout(timeo);
1265 lock_sock(sk);
1266
1267 err = sock_error(sk);
1268 if (err)
1269 break;
1270 }
1271 set_current_state(TASK_RUNNING);
1272 remove_wait_queue(sk->sk_sleep, &wait);
1273 return err;
1274}
1275
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001276static void l2cap_monitor_timeout(unsigned long arg)
1277{
1278 struct sock *sk = (void *) arg;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001279
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001280 bh_lock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001281 if (l2cap_pi(sk)->retry_count >= l2cap_pi(sk)->remote_max_tx) {
1282 l2cap_send_disconn_req(l2cap_pi(sk)->conn, sk);
Andrei Emeltchenkob13f5862009-12-15 11:38:04 +02001283 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001284 return;
1285 }
1286
1287 l2cap_pi(sk)->retry_count++;
1288 __mod_monitor_timer();
1289
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -03001290 l2cap_send_rr_or_rnr(l2cap_pi(sk), L2CAP_CTRL_POLL);
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001291 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001292}
1293
1294static void l2cap_retrans_timeout(unsigned long arg)
1295{
1296 struct sock *sk = (void *) arg;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001297
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001298 bh_lock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001299 l2cap_pi(sk)->retry_count = 1;
1300 __mod_monitor_timer();
1301
1302 l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
1303
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -03001304 l2cap_send_rr_or_rnr(l2cap_pi(sk), L2CAP_CTRL_POLL);
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001305 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001306}
1307
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001308static void l2cap_drop_acked_frames(struct sock *sk)
1309{
1310 struct sk_buff *skb;
1311
Gustavo F. Padovan812e7372010-05-01 16:15:42 -03001312 while ((skb = skb_peek(TX_QUEUE(sk))) &&
1313 l2cap_pi(sk)->unacked_frames) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001314 if (bt_cb(skb)->tx_seq == l2cap_pi(sk)->expected_ack_seq)
1315 break;
1316
1317 skb = skb_dequeue(TX_QUEUE(sk));
1318 kfree_skb(skb);
1319
1320 l2cap_pi(sk)->unacked_frames--;
1321 }
1322
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001323 if (!l2cap_pi(sk)->unacked_frames)
1324 del_timer(&l2cap_pi(sk)->retrans_timer);
1325
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001326 return;
1327}
1328
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001329static inline void l2cap_do_send(struct sock *sk, struct sk_buff *skb)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001330{
1331 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001332
1333 BT_DBG("sk %p, skb %p len %d", sk, skb, skb->len);
1334
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001335 hci_send_acl(pi->conn->hcon, skb, 0);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001336}
1337
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001338static int l2cap_streaming_send(struct sock *sk)
1339{
1340 struct sk_buff *skb, *tx_skb;
1341 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001342 u16 control, fcs;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001343
1344 while ((skb = sk->sk_send_head)) {
1345 tx_skb = skb_clone(skb, GFP_ATOMIC);
1346
1347 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
1348 control |= pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT;
1349 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1350
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001351 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001352 fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
1353 put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
1354 }
1355
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001356 l2cap_do_send(sk, tx_skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001357
1358 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
1359
1360 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1361 sk->sk_send_head = NULL;
1362 else
1363 sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
1364
1365 skb = skb_dequeue(TX_QUEUE(sk));
1366 kfree_skb(skb);
1367 }
1368 return 0;
1369}
1370
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001371static void l2cap_retransmit_frame(struct sock *sk, u8 tx_seq)
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001372{
1373 struct l2cap_pinfo *pi = l2cap_pi(sk);
1374 struct sk_buff *skb, *tx_skb;
1375 u16 control, fcs;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001376
1377 skb = skb_peek(TX_QUEUE(sk));
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001378 if (!skb)
1379 return;
1380
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001381 do {
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001382 if (bt_cb(skb)->tx_seq == tx_seq)
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001383 break;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001384
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001385 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1386 return;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001387
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001388 } while ((skb = skb_queue_next(TX_QUEUE(sk), skb)));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001389
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001390 if (pi->remote_max_tx &&
1391 bt_cb(skb)->retries == pi->remote_max_tx) {
1392 l2cap_send_disconn_req(pi->conn, sk);
1393 return;
1394 }
1395
1396 tx_skb = skb_clone(skb, GFP_ATOMIC);
1397 bt_cb(skb)->retries++;
1398 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
1399 control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
1400 | (tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
1401 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1402
1403 if (pi->fcs == L2CAP_FCS_CRC16) {
1404 fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
1405 put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
1406 }
1407
1408 l2cap_do_send(sk, tx_skb);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001409}
1410
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001411static int l2cap_ertm_send(struct sock *sk)
1412{
1413 struct sk_buff *skb, *tx_skb;
1414 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001415 u16 control, fcs;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001416 int nsent = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001417
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001418 if (pi->conn_state & L2CAP_CONN_WAIT_F)
1419 return 0;
1420
Joe Perchesf64f9e72009-11-29 16:55:45 -08001421 while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(sk)) &&
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03001422 !(pi->conn_state & L2CAP_CONN_REMOTE_BUSY)) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001423
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001424 if (pi->remote_max_tx &&
1425 bt_cb(skb)->retries == pi->remote_max_tx) {
1426 l2cap_send_disconn_req(pi->conn, sk);
1427 break;
1428 }
1429
Andrei Emeltchenkoe420aba2009-12-23 13:07:14 +02001430 tx_skb = skb_clone(skb, GFP_ATOMIC);
1431
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001432 bt_cb(skb)->retries++;
1433
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001434 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001435 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
1436 control |= L2CAP_CTRL_FINAL;
1437 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
1438 }
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03001439 control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001440 | (pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
1441 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1442
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001443
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001444 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001445 fcs = crc16(0, (u8 *)skb->data, tx_skb->len - 2);
1446 put_unaligned_le16(fcs, skb->data + tx_skb->len - 2);
1447 }
1448
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001449 l2cap_do_send(sk, tx_skb);
1450
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001451 __mod_retrans_timer();
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001452
1453 bt_cb(skb)->tx_seq = pi->next_tx_seq;
1454 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
1455
1456 pi->unacked_frames++;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001457 pi->frames_sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001458
1459 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1460 sk->sk_send_head = NULL;
1461 else
1462 sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001463
1464 nsent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001465 }
1466
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001467 return nsent;
1468}
1469
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001470static void l2cap_send_ack(struct l2cap_pinfo *pi)
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001471{
1472 struct sock *sk = (struct sock *)pi;
1473 u16 control = 0;
1474
1475 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1476
1477 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
1478 control |= L2CAP_SUPER_RCV_NOT_READY;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03001479 pi->conn_state |= L2CAP_CONN_RNR_SENT;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001480 l2cap_send_sframe(pi, control);
1481 return;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001482 } else if (l2cap_ertm_send(sk) == 0) {
1483 control |= L2CAP_SUPER_RCV_READY;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001484 l2cap_send_sframe(pi, control);
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001485 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001486}
1487
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001488static void l2cap_send_srejtail(struct sock *sk)
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03001489{
1490 struct srej_list *tail;
1491 u16 control;
1492
1493 control = L2CAP_SUPER_SELECT_REJECT;
1494 control |= L2CAP_CTRL_FINAL;
1495
1496 tail = list_entry(SREJ_LIST(sk)->prev, struct srej_list, list);
1497 control |= tail->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1498
1499 l2cap_send_sframe(l2cap_pi(sk), control);
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03001500}
1501
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001502static 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 -07001503{
1504 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001505 struct sk_buff **frag;
1506 int err, sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001507
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03001508 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001509 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001510
1511 sent += count;
1512 len -= count;
1513
1514 /* Continuation fragments (no L2CAP header) */
1515 frag = &skb_shinfo(skb)->frag_list;
1516 while (len) {
1517 count = min_t(unsigned int, conn->mtu, len);
1518
1519 *frag = bt_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err);
1520 if (!*frag)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001521 return -EFAULT;
1522 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
1523 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001524
1525 sent += count;
1526 len -= count;
1527
1528 frag = &(*frag)->next;
1529 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001530
1531 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001532}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001533
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001534static struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, size_t len)
1535{
1536 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1537 struct sk_buff *skb;
1538 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1539 struct l2cap_hdr *lh;
1540
1541 BT_DBG("sk %p len %d", sk, (int)len);
1542
1543 count = min_t(unsigned int, (conn->mtu - hlen), len);
1544 skb = bt_skb_send_alloc(sk, count + hlen,
1545 msg->msg_flags & MSG_DONTWAIT, &err);
1546 if (!skb)
1547 return ERR_PTR(-ENOMEM);
1548
1549 /* Create L2CAP header */
1550 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1551 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1552 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1553 put_unaligned_le16(l2cap_pi(sk)->psm, skb_put(skb, 2));
1554
1555 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1556 if (unlikely(err < 0)) {
1557 kfree_skb(skb);
1558 return ERR_PTR(err);
1559 }
1560 return skb;
1561}
1562
1563static struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *msg, size_t len)
1564{
1565 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1566 struct sk_buff *skb;
1567 int err, count, hlen = L2CAP_HDR_SIZE;
1568 struct l2cap_hdr *lh;
1569
1570 BT_DBG("sk %p len %d", sk, (int)len);
1571
1572 count = min_t(unsigned int, (conn->mtu - hlen), len);
1573 skb = bt_skb_send_alloc(sk, count + hlen,
1574 msg->msg_flags & MSG_DONTWAIT, &err);
1575 if (!skb)
1576 return ERR_PTR(-ENOMEM);
1577
1578 /* Create L2CAP header */
1579 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1580 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1581 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1582
1583 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1584 if (unlikely(err < 0)) {
1585 kfree_skb(skb);
1586 return ERR_PTR(err);
1587 }
1588 return skb;
1589}
1590
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001591static 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 -03001592{
1593 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1594 struct sk_buff *skb;
1595 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1596 struct l2cap_hdr *lh;
1597
1598 BT_DBG("sk %p len %d", sk, (int)len);
1599
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03001600 if (!conn)
1601 return ERR_PTR(-ENOTCONN);
1602
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001603 if (sdulen)
1604 hlen += 2;
1605
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001606 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1607 hlen += 2;
1608
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001609 count = min_t(unsigned int, (conn->mtu - hlen), len);
1610 skb = bt_skb_send_alloc(sk, count + hlen,
1611 msg->msg_flags & MSG_DONTWAIT, &err);
1612 if (!skb)
1613 return ERR_PTR(-ENOMEM);
1614
1615 /* Create L2CAP header */
1616 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1617 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1618 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1619 put_unaligned_le16(control, skb_put(skb, 2));
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001620 if (sdulen)
1621 put_unaligned_le16(sdulen, skb_put(skb, 2));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001622
1623 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1624 if (unlikely(err < 0)) {
1625 kfree_skb(skb);
1626 return ERR_PTR(err);
1627 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001628
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001629 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1630 put_unaligned_le16(0, skb_put(skb, 2));
1631
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001632 bt_cb(skb)->retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001633 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001634}
1635
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001636static inline int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len)
1637{
1638 struct l2cap_pinfo *pi = l2cap_pi(sk);
1639 struct sk_buff *skb;
1640 struct sk_buff_head sar_queue;
1641 u16 control;
1642 size_t size = 0;
1643
Gustavo F. Padovanff12fd62010-05-05 22:09:15 -03001644 skb_queue_head_init(&sar_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001645 control = L2CAP_SDU_START;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001646 skb = l2cap_create_iframe_pdu(sk, msg, pi->remote_mps, control, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001647 if (IS_ERR(skb))
1648 return PTR_ERR(skb);
1649
1650 __skb_queue_tail(&sar_queue, skb);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001651 len -= pi->remote_mps;
1652 size += pi->remote_mps;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001653
1654 while (len > 0) {
1655 size_t buflen;
1656
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001657 if (len > pi->remote_mps) {
Gustavo F. Padovan44651b82010-05-01 16:15:43 -03001658 control = L2CAP_SDU_CONTINUE;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001659 buflen = pi->remote_mps;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001660 } else {
Gustavo F. Padovan44651b82010-05-01 16:15:43 -03001661 control = L2CAP_SDU_END;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001662 buflen = len;
1663 }
1664
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001665 skb = l2cap_create_iframe_pdu(sk, msg, buflen, control, 0);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001666 if (IS_ERR(skb)) {
1667 skb_queue_purge(&sar_queue);
1668 return PTR_ERR(skb);
1669 }
1670
1671 __skb_queue_tail(&sar_queue, skb);
1672 len -= buflen;
1673 size += buflen;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001674 }
1675 skb_queue_splice_tail(&sar_queue, TX_QUEUE(sk));
1676 if (sk->sk_send_head == NULL)
1677 sk->sk_send_head = sar_queue.next;
1678
1679 return size;
1680}
1681
Linus Torvalds1da177e2005-04-16 15:20:36 -07001682static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len)
1683{
1684 struct sock *sk = sock->sk;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001685 struct l2cap_pinfo *pi = l2cap_pi(sk);
1686 struct sk_buff *skb;
1687 u16 control;
1688 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001689
1690 BT_DBG("sock %p, sk %p", sock, sk);
1691
Benjamin LaHaisec1cbe4b2005-12-13 23:22:19 -08001692 err = sock_error(sk);
1693 if (err)
1694 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001695
1696 if (msg->msg_flags & MSG_OOB)
1697 return -EOPNOTSUPP;
1698
Linus Torvalds1da177e2005-04-16 15:20:36 -07001699 lock_sock(sk);
1700
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001701 if (sk->sk_state != BT_CONNECTED) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001702 err = -ENOTCONN;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001703 goto done;
1704 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001705
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001706 /* Connectionless channel */
1707 if (sk->sk_type == SOCK_DGRAM) {
1708 skb = l2cap_create_connless_pdu(sk, msg, len);
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001709 if (IS_ERR(skb)) {
Dan Carpenter477fffb2010-04-21 23:52:01 +00001710 err = PTR_ERR(skb);
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001711 } else {
1712 l2cap_do_send(sk, skb);
1713 err = len;
1714 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001715 goto done;
1716 }
1717
1718 switch (pi->mode) {
1719 case L2CAP_MODE_BASIC:
Gustavo F. Padovanc69163e2010-05-01 16:15:35 -03001720 /* Check outgoing MTU */
1721 if (len > pi->omtu) {
1722 err = -EINVAL;
1723 goto done;
1724 }
1725
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001726 /* Create a basic PDU */
1727 skb = l2cap_create_basic_pdu(sk, msg, len);
1728 if (IS_ERR(skb)) {
1729 err = PTR_ERR(skb);
1730 goto done;
1731 }
1732
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001733 l2cap_do_send(sk, skb);
1734 err = len;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001735 break;
1736
1737 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001738 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001739 /* Entire SDU fits into one PDU */
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001740 if (len <= pi->remote_mps) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001741 control = L2CAP_SDU_UNSEGMENTED;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001742 skb = l2cap_create_iframe_pdu(sk, msg, len, control, 0);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001743 if (IS_ERR(skb)) {
1744 err = PTR_ERR(skb);
1745 goto done;
1746 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001747 __skb_queue_tail(TX_QUEUE(sk), skb);
1748 if (sk->sk_send_head == NULL)
1749 sk->sk_send_head = skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001750 } else {
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001751 /* Segment SDU into multiples PDUs */
1752 err = l2cap_sar_segment_sdu(sk, msg, len);
1753 if (err < 0)
1754 goto done;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001755 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001756
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001757 if (pi->mode == L2CAP_MODE_STREAMING)
1758 err = l2cap_streaming_send(sk);
1759 else
1760 err = l2cap_ertm_send(sk);
1761
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001762 if (err >= 0)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001763 err = len;
1764 break;
1765
1766 default:
1767 BT_DBG("bad state %1.1x", pi->mode);
1768 err = -EINVAL;
1769 }
1770
1771done:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001772 release_sock(sk);
1773 return err;
1774}
1775
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001776static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags)
1777{
1778 struct sock *sk = sock->sk;
1779
1780 lock_sock(sk);
1781
1782 if (sk->sk_state == BT_CONNECT2 && bt_sk(sk)->defer_setup) {
1783 struct l2cap_conn_rsp rsp;
1784
1785 sk->sk_state = BT_CONFIG;
1786
1787 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
1788 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
1789 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
1790 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
1791 l2cap_send_cmd(l2cap_pi(sk)->conn, l2cap_pi(sk)->ident,
1792 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
1793
1794 release_sock(sk);
1795 return 0;
1796 }
1797
1798 release_sock(sk);
1799
1800 return bt_sock_recvmsg(iocb, sock, msg, len, flags);
1801}
1802
David S. Millerb7058842009-09-30 16:12:20 -07001803static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001804{
1805 struct sock *sk = sock->sk;
1806 struct l2cap_options opts;
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001807 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001808 u32 opt;
1809
1810 BT_DBG("sk %p", sk);
1811
1812 lock_sock(sk);
1813
1814 switch (optname) {
1815 case L2CAP_OPTIONS:
Marcel Holtmann0878b662007-05-05 00:35:59 +02001816 opts.imtu = l2cap_pi(sk)->imtu;
1817 opts.omtu = l2cap_pi(sk)->omtu;
1818 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001819 opts.mode = l2cap_pi(sk)->mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001820 opts.fcs = l2cap_pi(sk)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03001821 opts.max_tx = l2cap_pi(sk)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03001822 opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
Marcel Holtmann0878b662007-05-05 00:35:59 +02001823
Linus Torvalds1da177e2005-04-16 15:20:36 -07001824 len = min_t(unsigned int, sizeof(opts), optlen);
1825 if (copy_from_user((char *) &opts, optval, len)) {
1826 err = -EFAULT;
1827 break;
1828 }
Marcel Holtmann0878b662007-05-05 00:35:59 +02001829
João Paulo Rechi Vita0041ecf2010-05-01 16:15:42 -03001830 l2cap_pi(sk)->mode = opts.mode;
1831 switch (l2cap_pi(sk)->mode) {
1832 case L2CAP_MODE_BASIC:
1833 break;
1834 case L2CAP_MODE_ERTM:
1835 case L2CAP_MODE_STREAMING:
1836 if (enable_ertm)
1837 break;
1838 /* fall through */
1839 default:
1840 err = -EINVAL;
1841 break;
1842 }
1843
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001844 l2cap_pi(sk)->imtu = opts.imtu;
1845 l2cap_pi(sk)->omtu = opts.omtu;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001846 l2cap_pi(sk)->fcs = opts.fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03001847 l2cap_pi(sk)->max_tx = opts.max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03001848 l2cap_pi(sk)->tx_win = (__u8)opts.txwin_size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001849 break;
1850
1851 case L2CAP_LM:
1852 if (get_user(opt, (u32 __user *) optval)) {
1853 err = -EFAULT;
1854 break;
1855 }
1856
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001857 if (opt & L2CAP_LM_AUTH)
1858 l2cap_pi(sk)->sec_level = BT_SECURITY_LOW;
1859 if (opt & L2CAP_LM_ENCRYPT)
1860 l2cap_pi(sk)->sec_level = BT_SECURITY_MEDIUM;
1861 if (opt & L2CAP_LM_SECURE)
1862 l2cap_pi(sk)->sec_level = BT_SECURITY_HIGH;
1863
1864 l2cap_pi(sk)->role_switch = (opt & L2CAP_LM_MASTER);
1865 l2cap_pi(sk)->force_reliable = (opt & L2CAP_LM_RELIABLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001866 break;
1867
1868 default:
1869 err = -ENOPROTOOPT;
1870 break;
1871 }
1872
1873 release_sock(sk);
1874 return err;
1875}
1876
David S. Millerb7058842009-09-30 16:12:20 -07001877static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001878{
1879 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001880 struct bt_security sec;
1881 int len, err = 0;
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001882 u32 opt;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001883
1884 BT_DBG("sk %p", sk);
1885
1886 if (level == SOL_L2CAP)
1887 return l2cap_sock_setsockopt_old(sock, optname, optval, optlen);
1888
Marcel Holtmann0588d942009-01-16 10:06:13 +01001889 if (level != SOL_BLUETOOTH)
1890 return -ENOPROTOOPT;
1891
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001892 lock_sock(sk);
1893
1894 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001895 case BT_SECURITY:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001896 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
1897 && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01001898 err = -EINVAL;
1899 break;
1900 }
1901
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001902 sec.level = BT_SECURITY_LOW;
1903
1904 len = min_t(unsigned int, sizeof(sec), optlen);
1905 if (copy_from_user((char *) &sec, optval, len)) {
1906 err = -EFAULT;
1907 break;
1908 }
1909
1910 if (sec.level < BT_SECURITY_LOW ||
1911 sec.level > BT_SECURITY_HIGH) {
1912 err = -EINVAL;
1913 break;
1914 }
1915
1916 l2cap_pi(sk)->sec_level = sec.level;
1917 break;
1918
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001919 case BT_DEFER_SETUP:
1920 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
1921 err = -EINVAL;
1922 break;
1923 }
1924
1925 if (get_user(opt, (u32 __user *) optval)) {
1926 err = -EFAULT;
1927 break;
1928 }
1929
1930 bt_sk(sk)->defer_setup = opt;
1931 break;
1932
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001933 default:
1934 err = -ENOPROTOOPT;
1935 break;
1936 }
1937
1938 release_sock(sk);
1939 return err;
1940}
1941
1942static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001943{
1944 struct sock *sk = sock->sk;
1945 struct l2cap_options opts;
1946 struct l2cap_conninfo cinfo;
1947 int len, err = 0;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001948 u32 opt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001949
1950 BT_DBG("sk %p", sk);
1951
1952 if (get_user(len, optlen))
1953 return -EFAULT;
1954
1955 lock_sock(sk);
1956
1957 switch (optname) {
1958 case L2CAP_OPTIONS:
1959 opts.imtu = l2cap_pi(sk)->imtu;
1960 opts.omtu = l2cap_pi(sk)->omtu;
1961 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001962 opts.mode = l2cap_pi(sk)->mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001963 opts.fcs = l2cap_pi(sk)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03001964 opts.max_tx = l2cap_pi(sk)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03001965 opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001966
1967 len = min_t(unsigned int, len, sizeof(opts));
1968 if (copy_to_user(optval, (char *) &opts, len))
1969 err = -EFAULT;
1970
1971 break;
1972
1973 case L2CAP_LM:
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001974 switch (l2cap_pi(sk)->sec_level) {
1975 case BT_SECURITY_LOW:
1976 opt = L2CAP_LM_AUTH;
1977 break;
1978 case BT_SECURITY_MEDIUM:
1979 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT;
1980 break;
1981 case BT_SECURITY_HIGH:
1982 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT |
1983 L2CAP_LM_SECURE;
1984 break;
1985 default:
1986 opt = 0;
1987 break;
1988 }
1989
1990 if (l2cap_pi(sk)->role_switch)
1991 opt |= L2CAP_LM_MASTER;
1992
1993 if (l2cap_pi(sk)->force_reliable)
1994 opt |= L2CAP_LM_RELIABLE;
1995
1996 if (put_user(opt, (u32 __user *) optval))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001997 err = -EFAULT;
1998 break;
1999
2000 case L2CAP_CONNINFO:
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002001 if (sk->sk_state != BT_CONNECTED &&
2002 !(sk->sk_state == BT_CONNECT2 &&
2003 bt_sk(sk)->defer_setup)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002004 err = -ENOTCONN;
2005 break;
2006 }
2007
2008 cinfo.hci_handle = l2cap_pi(sk)->conn->hcon->handle;
2009 memcpy(cinfo.dev_class, l2cap_pi(sk)->conn->hcon->dev_class, 3);
2010
2011 len = min_t(unsigned int, len, sizeof(cinfo));
2012 if (copy_to_user(optval, (char *) &cinfo, len))
2013 err = -EFAULT;
2014
2015 break;
2016
2017 default:
2018 err = -ENOPROTOOPT;
2019 break;
2020 }
2021
2022 release_sock(sk);
2023 return err;
2024}
2025
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002026static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
2027{
2028 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002029 struct bt_security sec;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002030 int len, err = 0;
2031
2032 BT_DBG("sk %p", sk);
2033
2034 if (level == SOL_L2CAP)
2035 return l2cap_sock_getsockopt_old(sock, optname, optval, optlen);
2036
Marcel Holtmann0588d942009-01-16 10:06:13 +01002037 if (level != SOL_BLUETOOTH)
2038 return -ENOPROTOOPT;
2039
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002040 if (get_user(len, optlen))
2041 return -EFAULT;
2042
2043 lock_sock(sk);
2044
2045 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002046 case BT_SECURITY:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03002047 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
2048 && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01002049 err = -EINVAL;
2050 break;
2051 }
2052
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002053 sec.level = l2cap_pi(sk)->sec_level;
2054
2055 len = min_t(unsigned int, len, sizeof(sec));
2056 if (copy_to_user(optval, (char *) &sec, len))
2057 err = -EFAULT;
2058
2059 break;
2060
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002061 case BT_DEFER_SETUP:
2062 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
2063 err = -EINVAL;
2064 break;
2065 }
2066
2067 if (put_user(bt_sk(sk)->defer_setup, (u32 __user *) optval))
2068 err = -EFAULT;
2069
2070 break;
2071
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002072 default:
2073 err = -ENOPROTOOPT;
2074 break;
2075 }
2076
2077 release_sock(sk);
2078 return err;
2079}
2080
Linus Torvalds1da177e2005-04-16 15:20:36 -07002081static int l2cap_sock_shutdown(struct socket *sock, int how)
2082{
2083 struct sock *sk = sock->sk;
2084 int err = 0;
2085
2086 BT_DBG("sock %p, sk %p", sock, sk);
2087
2088 if (!sk)
2089 return 0;
2090
2091 lock_sock(sk);
2092 if (!sk->sk_shutdown) {
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03002093 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
2094 err = __l2cap_wait_ack(sk);
2095
Linus Torvalds1da177e2005-04-16 15:20:36 -07002096 sk->sk_shutdown = SHUTDOWN_MASK;
2097 l2cap_sock_clear_timer(sk);
2098 __l2cap_sock_close(sk, 0);
2099
2100 if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
Marcel Holtmannb1235d72008-07-14 20:13:54 +02002101 err = bt_sock_wait_state(sk, BT_CLOSED,
2102 sk->sk_lingertime);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002103 }
2104 release_sock(sk);
2105 return err;
2106}
2107
2108static int l2cap_sock_release(struct socket *sock)
2109{
2110 struct sock *sk = sock->sk;
2111 int err;
2112
2113 BT_DBG("sock %p, sk %p", sock, sk);
2114
2115 if (!sk)
2116 return 0;
2117
2118 err = l2cap_sock_shutdown(sock, 2);
2119
2120 sock_orphan(sk);
2121 l2cap_sock_kill(sk);
2122 return err;
2123}
2124
Linus Torvalds1da177e2005-04-16 15:20:36 -07002125static void l2cap_chan_ready(struct sock *sk)
2126{
2127 struct sock *parent = bt_sk(sk)->parent;
2128
2129 BT_DBG("sk %p, parent %p", sk, parent);
2130
2131 l2cap_pi(sk)->conf_state = 0;
2132 l2cap_sock_clear_timer(sk);
2133
2134 if (!parent) {
2135 /* Outgoing channel.
2136 * Wake up socket sleeping on connect.
2137 */
2138 sk->sk_state = BT_CONNECTED;
2139 sk->sk_state_change(sk);
2140 } else {
2141 /* Incoming channel.
2142 * Wake up socket sleeping on accept.
2143 */
2144 parent->sk_data_ready(parent, 0);
2145 }
2146}
2147
2148/* Copy frame to all raw sockets on that connection */
2149static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2150{
2151 struct l2cap_chan_list *l = &conn->chan_list;
2152 struct sk_buff *nskb;
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002153 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002154
2155 BT_DBG("conn %p", conn);
2156
2157 read_lock(&l->lock);
2158 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
2159 if (sk->sk_type != SOCK_RAW)
2160 continue;
2161
2162 /* Don't send frame to the socket it came from */
2163 if (skb->sk == sk)
2164 continue;
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002165 nskb = skb_clone(skb, GFP_ATOMIC);
2166 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002167 continue;
2168
2169 if (sock_queue_rcv_skb(sk, nskb))
2170 kfree_skb(nskb);
2171 }
2172 read_unlock(&l->lock);
2173}
2174
2175/* ---- L2CAP signalling commands ---- */
2176static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
2177 u8 code, u8 ident, u16 dlen, void *data)
2178{
2179 struct sk_buff *skb, **frag;
2180 struct l2cap_cmd_hdr *cmd;
2181 struct l2cap_hdr *lh;
2182 int len, count;
2183
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002184 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d",
2185 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002186
2187 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2188 count = min_t(unsigned int, conn->mtu, len);
2189
2190 skb = bt_skb_alloc(count, GFP_ATOMIC);
2191 if (!skb)
2192 return NULL;
2193
2194 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002195 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03002196 lh->cid = cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002197
2198 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2199 cmd->code = code;
2200 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002201 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002202
2203 if (dlen) {
2204 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2205 memcpy(skb_put(skb, count), data, count);
2206 data += count;
2207 }
2208
2209 len -= skb->len;
2210
2211 /* Continuation fragments (no L2CAP header) */
2212 frag = &skb_shinfo(skb)->frag_list;
2213 while (len) {
2214 count = min_t(unsigned int, conn->mtu, len);
2215
2216 *frag = bt_skb_alloc(count, GFP_ATOMIC);
2217 if (!*frag)
2218 goto fail;
2219
2220 memcpy(skb_put(*frag, count), data, count);
2221
2222 len -= count;
2223 data += count;
2224
2225 frag = &(*frag)->next;
2226 }
2227
2228 return skb;
2229
2230fail:
2231 kfree_skb(skb);
2232 return NULL;
2233}
2234
2235static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned long *val)
2236{
2237 struct l2cap_conf_opt *opt = *ptr;
2238 int len;
2239
2240 len = L2CAP_CONF_OPT_SIZE + opt->len;
2241 *ptr += len;
2242
2243 *type = opt->type;
2244 *olen = opt->len;
2245
2246 switch (opt->len) {
2247 case 1:
2248 *val = *((u8 *) opt->val);
2249 break;
2250
2251 case 2:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002252 *val = __le16_to_cpu(*((__le16 *) opt->val));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002253 break;
2254
2255 case 4:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002256 *val = __le32_to_cpu(*((__le32 *) opt->val));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002257 break;
2258
2259 default:
2260 *val = (unsigned long) opt->val;
2261 break;
2262 }
2263
2264 BT_DBG("type 0x%2.2x len %d val 0x%lx", *type, opt->len, *val);
2265 return len;
2266}
2267
Linus Torvalds1da177e2005-04-16 15:20:36 -07002268static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2269{
2270 struct l2cap_conf_opt *opt = *ptr;
2271
2272 BT_DBG("type 0x%2.2x len %d val 0x%lx", type, len, val);
2273
2274 opt->type = type;
2275 opt->len = len;
2276
2277 switch (len) {
2278 case 1:
2279 *((u8 *) opt->val) = val;
2280 break;
2281
2282 case 2:
Al Viro8e036fc2007-07-29 00:16:36 -07002283 *((__le16 *) opt->val) = cpu_to_le16(val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002284 break;
2285
2286 case 4:
Al Viro8e036fc2007-07-29 00:16:36 -07002287 *((__le32 *) opt->val) = cpu_to_le32(val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002288 break;
2289
2290 default:
2291 memcpy(opt->val, (void *) val, len);
2292 break;
2293 }
2294
2295 *ptr += L2CAP_CONF_OPT_SIZE + len;
2296}
2297
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002298static void l2cap_ack_timeout(unsigned long arg)
2299{
2300 struct sock *sk = (void *) arg;
2301
2302 bh_lock_sock(sk);
2303 l2cap_send_ack(l2cap_pi(sk));
2304 bh_unlock_sock(sk);
2305}
2306
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002307static inline void l2cap_ertm_init(struct sock *sk)
2308{
2309 l2cap_pi(sk)->expected_ack_seq = 0;
2310 l2cap_pi(sk)->unacked_frames = 0;
2311 l2cap_pi(sk)->buffer_seq = 0;
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03002312 l2cap_pi(sk)->num_acked = 0;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03002313 l2cap_pi(sk)->frames_sent = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002314
2315 setup_timer(&l2cap_pi(sk)->retrans_timer,
2316 l2cap_retrans_timeout, (unsigned long) sk);
2317 setup_timer(&l2cap_pi(sk)->monitor_timer,
2318 l2cap_monitor_timeout, (unsigned long) sk);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002319 setup_timer(&l2cap_pi(sk)->ack_timer,
2320 l2cap_ack_timeout, (unsigned long) sk);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002321
2322 __skb_queue_head_init(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002323 __skb_queue_head_init(BUSY_QUEUE(sk));
2324
2325 INIT_WORK(&l2cap_pi(sk)->busy_work, l2cap_busy_work);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002326}
2327
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002328static int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
2329{
2330 u32 local_feat_mask = l2cap_feat_mask;
2331 if (enable_ertm)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002332 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002333
2334 switch (mode) {
2335 case L2CAP_MODE_ERTM:
2336 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
2337 case L2CAP_MODE_STREAMING:
2338 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
2339 default:
2340 return 0x00;
2341 }
2342}
2343
2344static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
2345{
2346 switch (mode) {
2347 case L2CAP_MODE_STREAMING:
2348 case L2CAP_MODE_ERTM:
2349 if (l2cap_mode_supported(mode, remote_feat_mask))
2350 return mode;
2351 /* fall through */
2352 default:
2353 return L2CAP_MODE_BASIC;
2354 }
2355}
2356
Linus Torvalds1da177e2005-04-16 15:20:36 -07002357static int l2cap_build_conf_req(struct sock *sk, void *data)
2358{
2359 struct l2cap_pinfo *pi = l2cap_pi(sk);
2360 struct l2cap_conf_req *req = data;
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03002361 struct l2cap_conf_rfc rfc = { .mode = pi->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07002362 void *ptr = req->data;
2363
2364 BT_DBG("sk %p", sk);
2365
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002366 if (pi->num_conf_req || pi->num_conf_rsp)
2367 goto done;
2368
2369 switch (pi->mode) {
2370 case L2CAP_MODE_STREAMING:
2371 case L2CAP_MODE_ERTM:
2372 pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002373 if (!l2cap_mode_supported(pi->mode, pi->conn->feat_mask))
2374 l2cap_send_disconn_req(pi->conn, sk);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002375 break;
2376 default:
2377 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
2378 break;
2379 }
2380
2381done:
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002382 switch (pi->mode) {
2383 case L2CAP_MODE_BASIC:
2384 if (pi->imtu != L2CAP_DEFAULT_MTU)
2385 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
2386 break;
2387
2388 case L2CAP_MODE_ERTM:
2389 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03002390 rfc.txwin_size = pi->tx_win;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03002391 rfc.max_transmit = pi->max_tx;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002392 rfc.retrans_timeout = 0;
2393 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002394 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03002395 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002396 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002397
2398 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2399 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002400
2401 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2402 break;
2403
2404 if (pi->fcs == L2CAP_FCS_NONE ||
2405 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
2406 pi->fcs = L2CAP_FCS_NONE;
2407 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
2408 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002409 break;
2410
2411 case L2CAP_MODE_STREAMING:
2412 rfc.mode = L2CAP_MODE_STREAMING;
2413 rfc.txwin_size = 0;
2414 rfc.max_transmit = 0;
2415 rfc.retrans_timeout = 0;
2416 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002417 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03002418 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002419 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002420
2421 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2422 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002423
2424 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2425 break;
2426
2427 if (pi->fcs == L2CAP_FCS_NONE ||
2428 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
2429 pi->fcs = L2CAP_FCS_NONE;
2430 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
2431 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002432 break;
2433 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002434
2435 /* FIXME: Need actual value of the flush timeout */
2436 //if (flush_to != L2CAP_DEFAULT_FLUSH_TO)
2437 // l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2, pi->flush_to);
2438
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002439 req->dcid = cpu_to_le16(pi->dcid);
2440 req->flags = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002441
2442 return ptr - data;
2443}
2444
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002445static int l2cap_parse_conf_req(struct sock *sk, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002446{
2447 struct l2cap_pinfo *pi = l2cap_pi(sk);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002448 struct l2cap_conf_rsp *rsp = data;
2449 void *ptr = rsp->data;
2450 void *req = pi->conf_req;
2451 int len = pi->conf_len;
2452 int type, hint, olen;
2453 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002454 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Marcel Holtmann861d6882007-10-20 13:37:06 +02002455 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002456 u16 result = L2CAP_CONF_SUCCESS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002457
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002458 BT_DBG("sk %p", sk);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01002459
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002460 while (len >= L2CAP_CONF_OPT_SIZE) {
2461 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002462
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03002463 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07002464 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002465
2466 switch (type) {
2467 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002468 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002469 break;
2470
2471 case L2CAP_CONF_FLUSH_TO:
2472 pi->flush_to = val;
2473 break;
2474
2475 case L2CAP_CONF_QOS:
2476 break;
2477
Marcel Holtmann6464f352007-10-20 13:39:51 +02002478 case L2CAP_CONF_RFC:
2479 if (olen == sizeof(rfc))
2480 memcpy(&rfc, (void *) val, olen);
2481 break;
2482
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002483 case L2CAP_CONF_FCS:
2484 if (val == L2CAP_FCS_NONE)
2485 pi->conf_state |= L2CAP_CONF_NO_FCS_RECV;
2486
2487 break;
2488
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002489 default:
2490 if (hint)
2491 break;
2492
2493 result = L2CAP_CONF_UNKNOWN;
2494 *((u8 *) ptr++) = type;
2495 break;
2496 }
2497 }
2498
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002499 if (pi->num_conf_rsp || pi->num_conf_req)
2500 goto done;
2501
2502 switch (pi->mode) {
2503 case L2CAP_MODE_STREAMING:
2504 case L2CAP_MODE_ERTM:
2505 pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
2506 if (!l2cap_mode_supported(pi->mode, pi->conn->feat_mask))
2507 return -ECONNREFUSED;
2508 break;
2509 default:
2510 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
2511 break;
2512 }
2513
2514done:
2515 if (pi->mode != rfc.mode) {
2516 result = L2CAP_CONF_UNACCEPT;
2517 rfc.mode = pi->mode;
2518
2519 if (pi->num_conf_rsp == 1)
2520 return -ECONNREFUSED;
2521
2522 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2523 sizeof(rfc), (unsigned long) &rfc);
2524 }
2525
2526
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002527 if (result == L2CAP_CONF_SUCCESS) {
2528 /* Configure output options and let the other side know
2529 * which ones we don't like. */
2530
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002531 if (mtu < L2CAP_DEFAULT_MIN_MTU)
2532 result = L2CAP_CONF_UNACCEPT;
2533 else {
2534 pi->omtu = mtu;
2535 pi->conf_state |= L2CAP_CONF_MTU_DONE;
2536 }
2537 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002538
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002539 switch (rfc.mode) {
2540 case L2CAP_MODE_BASIC:
2541 pi->fcs = L2CAP_FCS_NONE;
2542 pi->conf_state |= L2CAP_CONF_MODE_DONE;
2543 break;
2544
2545 case L2CAP_MODE_ERTM:
2546 pi->remote_tx_win = rfc.txwin_size;
2547 pi->remote_max_tx = rfc.max_transmit;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002548 if (rfc.max_pdu_size > pi->conn->mtu - 10)
2549 rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10);
2550
2551 pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002552
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002553 rfc.retrans_timeout =
2554 le16_to_cpu(L2CAP_DEFAULT_RETRANS_TO);
2555 rfc.monitor_timeout =
2556 le16_to_cpu(L2CAP_DEFAULT_MONITOR_TO);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002557
2558 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03002559
2560 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2561 sizeof(rfc), (unsigned long) &rfc);
2562
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002563 break;
2564
2565 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002566 if (rfc.max_pdu_size > pi->conn->mtu - 10)
2567 rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10);
2568
2569 pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002570
2571 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03002572
2573 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2574 sizeof(rfc), (unsigned long) &rfc);
2575
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002576 break;
2577
2578 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02002579 result = L2CAP_CONF_UNACCEPT;
2580
2581 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002582 rfc.mode = pi->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002583 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002584
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002585 if (result == L2CAP_CONF_SUCCESS)
2586 pi->conf_state |= L2CAP_CONF_OUTPUT_DONE;
2587 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002588 rsp->scid = cpu_to_le16(pi->dcid);
2589 rsp->result = cpu_to_le16(result);
2590 rsp->flags = cpu_to_le16(0x0000);
2591
2592 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002593}
2594
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002595static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data, u16 *result)
2596{
2597 struct l2cap_pinfo *pi = l2cap_pi(sk);
2598 struct l2cap_conf_req *req = data;
2599 void *ptr = req->data;
2600 int type, olen;
2601 unsigned long val;
2602 struct l2cap_conf_rfc rfc;
2603
2604 BT_DBG("sk %p, rsp %p, len %d, req %p", sk, rsp, len, data);
2605
2606 while (len >= L2CAP_CONF_OPT_SIZE) {
2607 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
2608
2609 switch (type) {
2610 case L2CAP_CONF_MTU:
2611 if (val < L2CAP_DEFAULT_MIN_MTU) {
2612 *result = L2CAP_CONF_UNACCEPT;
2613 pi->omtu = L2CAP_DEFAULT_MIN_MTU;
2614 } else
2615 pi->omtu = val;
2616 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
2617 break;
2618
2619 case L2CAP_CONF_FLUSH_TO:
2620 pi->flush_to = val;
2621 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
2622 2, pi->flush_to);
2623 break;
2624
2625 case L2CAP_CONF_RFC:
2626 if (olen == sizeof(rfc))
2627 memcpy(&rfc, (void *)val, olen);
2628
2629 if ((pi->conf_state & L2CAP_CONF_STATE2_DEVICE) &&
2630 rfc.mode != pi->mode)
2631 return -ECONNREFUSED;
2632
2633 pi->mode = rfc.mode;
2634 pi->fcs = 0;
2635
2636 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2637 sizeof(rfc), (unsigned long) &rfc);
2638 break;
2639 }
2640 }
2641
2642 if (*result == L2CAP_CONF_SUCCESS) {
2643 switch (rfc.mode) {
2644 case L2CAP_MODE_ERTM:
2645 pi->remote_tx_win = rfc.txwin_size;
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002646 pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
2647 pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002648 pi->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002649 break;
2650 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002651 pi->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002652 }
2653 }
2654
2655 req->dcid = cpu_to_le16(pi->dcid);
2656 req->flags = cpu_to_le16(0x0000);
2657
2658 return ptr - data;
2659}
2660
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002661static int l2cap_build_conf_rsp(struct sock *sk, void *data, u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002662{
2663 struct l2cap_conf_rsp *rsp = data;
2664 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002665
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002666 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002667
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002668 rsp->scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002669 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002670 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002671
2672 return ptr - data;
2673}
2674
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002675static void l2cap_conf_rfc_get(struct sock *sk, void *rsp, int len)
2676{
2677 struct l2cap_pinfo *pi = l2cap_pi(sk);
2678 int type, olen;
2679 unsigned long val;
2680 struct l2cap_conf_rfc rfc;
2681
2682 BT_DBG("sk %p, rsp %p, len %d", sk, rsp, len);
2683
2684 if ((pi->mode != L2CAP_MODE_ERTM) && (pi->mode != L2CAP_MODE_STREAMING))
2685 return;
2686
2687 while (len >= L2CAP_CONF_OPT_SIZE) {
2688 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
2689
2690 switch (type) {
2691 case L2CAP_CONF_RFC:
2692 if (olen == sizeof(rfc))
2693 memcpy(&rfc, (void *)val, olen);
2694 goto done;
2695 }
2696 }
2697
2698done:
2699 switch (rfc.mode) {
2700 case L2CAP_MODE_ERTM:
2701 pi->remote_tx_win = rfc.txwin_size;
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002702 pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
2703 pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002704 pi->mps = le16_to_cpu(rfc.max_pdu_size);
2705 break;
2706 case L2CAP_MODE_STREAMING:
2707 pi->mps = le16_to_cpu(rfc.max_pdu_size);
2708 }
2709}
2710
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002711static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2712{
2713 struct l2cap_cmd_rej *rej = (struct l2cap_cmd_rej *) data;
2714
2715 if (rej->reason != 0x0000)
2716 return 0;
2717
2718 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
2719 cmd->ident == conn->info_ident) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002720 del_timer(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01002721
2722 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002723 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01002724
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002725 l2cap_conn_start(conn);
2726 }
2727
2728 return 0;
2729}
2730
Linus Torvalds1da177e2005-04-16 15:20:36 -07002731static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2732{
2733 struct l2cap_chan_list *list = &conn->chan_list;
2734 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
2735 struct l2cap_conn_rsp rsp;
2736 struct sock *sk, *parent;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002737 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002738
2739 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002740 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002741
2742 BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
2743
2744 /* Check if we have socket listening on psm */
2745 parent = l2cap_get_sock_by_psm(BT_LISTEN, psm, conn->src);
2746 if (!parent) {
2747 result = L2CAP_CR_BAD_PSM;
2748 goto sendresp;
2749 }
2750
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002751 /* Check if the ACL is secure enough (if not SDP) */
2752 if (psm != cpu_to_le16(0x0001) &&
2753 !hci_conn_check_link_mode(conn->hcon)) {
Marcel Holtmann2950f212009-02-12 14:02:50 +01002754 conn->disc_reason = 0x05;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002755 result = L2CAP_CR_SEC_BLOCK;
2756 goto response;
2757 }
2758
Linus Torvalds1da177e2005-04-16 15:20:36 -07002759 result = L2CAP_CR_NO_MEM;
2760
2761 /* Check for backlog size */
2762 if (sk_acceptq_is_full(parent)) {
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09002763 BT_DBG("backlog full %d", parent->sk_ack_backlog);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002764 goto response;
2765 }
2766
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09002767 sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002768 if (!sk)
2769 goto response;
2770
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002771 write_lock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002772
2773 /* Check if we already have channel with that dcid */
2774 if (__l2cap_get_chan_by_dcid(list, scid)) {
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002775 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002776 sock_set_flag(sk, SOCK_ZAPPED);
2777 l2cap_sock_kill(sk);
2778 goto response;
2779 }
2780
2781 hci_conn_hold(conn->hcon);
2782
2783 l2cap_sock_init(sk, parent);
2784 bacpy(&bt_sk(sk)->src, conn->src);
2785 bacpy(&bt_sk(sk)->dst, conn->dst);
2786 l2cap_pi(sk)->psm = psm;
2787 l2cap_pi(sk)->dcid = scid;
2788
2789 __l2cap_chan_add(conn, sk, parent);
2790 dcid = l2cap_pi(sk)->scid;
2791
2792 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
2793
Linus Torvalds1da177e2005-04-16 15:20:36 -07002794 l2cap_pi(sk)->ident = cmd->ident;
2795
Marcel Holtmann984947d2009-02-06 23:35:19 +01002796 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002797 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002798 if (bt_sk(sk)->defer_setup) {
2799 sk->sk_state = BT_CONNECT2;
2800 result = L2CAP_CR_PEND;
2801 status = L2CAP_CS_AUTHOR_PEND;
2802 parent->sk_data_ready(parent, 0);
2803 } else {
2804 sk->sk_state = BT_CONFIG;
2805 result = L2CAP_CR_SUCCESS;
2806 status = L2CAP_CS_NO_INFO;
2807 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002808 } else {
2809 sk->sk_state = BT_CONNECT2;
2810 result = L2CAP_CR_PEND;
2811 status = L2CAP_CS_AUTHEN_PEND;
2812 }
2813 } else {
2814 sk->sk_state = BT_CONNECT2;
2815 result = L2CAP_CR_PEND;
2816 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002817 }
2818
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002819 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002820
2821response:
2822 bh_unlock_sock(parent);
2823
2824sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002825 rsp.scid = cpu_to_le16(scid);
2826 rsp.dcid = cpu_to_le16(dcid);
2827 rsp.result = cpu_to_le16(result);
2828 rsp.status = cpu_to_le16(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002829 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002830
2831 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
2832 struct l2cap_info_req info;
2833 info.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
2834
2835 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
2836 conn->info_ident = l2cap_get_ident(conn);
2837
2838 mod_timer(&conn->info_timer, jiffies +
2839 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
2840
2841 l2cap_send_cmd(conn, conn->info_ident,
2842 L2CAP_INFO_REQ, sizeof(info), &info);
2843 }
2844
Linus Torvalds1da177e2005-04-16 15:20:36 -07002845 return 0;
2846}
2847
2848static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2849{
2850 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
2851 u16 scid, dcid, result, status;
2852 struct sock *sk;
2853 u8 req[128];
2854
2855 scid = __le16_to_cpu(rsp->scid);
2856 dcid = __le16_to_cpu(rsp->dcid);
2857 result = __le16_to_cpu(rsp->result);
2858 status = __le16_to_cpu(rsp->status);
2859
2860 BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
2861
2862 if (scid) {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002863 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2864 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002865 return 0;
2866 } else {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002867 sk = l2cap_get_chan_by_ident(&conn->chan_list, cmd->ident);
2868 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002869 return 0;
2870 }
2871
2872 switch (result) {
2873 case L2CAP_CR_SUCCESS:
2874 sk->sk_state = BT_CONFIG;
2875 l2cap_pi(sk)->ident = 0;
2876 l2cap_pi(sk)->dcid = dcid;
2877 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
2878
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002879 l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_CONNECT_PEND;
2880
Linus Torvalds1da177e2005-04-16 15:20:36 -07002881 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
2882 l2cap_build_conf_req(sk, req), req);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002883 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002884 break;
2885
2886 case L2CAP_CR_PEND:
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002887 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002888 break;
2889
2890 default:
2891 l2cap_chan_del(sk, ECONNREFUSED);
2892 break;
2893 }
2894
2895 bh_unlock_sock(sk);
2896 return 0;
2897}
2898
Al Viro88219a02007-07-29 00:17:25 -07002899static 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 -07002900{
2901 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
2902 u16 dcid, flags;
2903 u8 rsp[64];
2904 struct sock *sk;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002905 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002906
2907 dcid = __le16_to_cpu(req->dcid);
2908 flags = __le16_to_cpu(req->flags);
2909
2910 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
2911
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002912 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
2913 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002914 return -ENOENT;
2915
Marcel Holtmann354f60a2006-11-18 22:15:20 +01002916 if (sk->sk_state == BT_DISCONN)
2917 goto unlock;
2918
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002919 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07002920 len = cmd_len - sizeof(*req);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002921 if (l2cap_pi(sk)->conf_len + len > sizeof(l2cap_pi(sk)->conf_req)) {
2922 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
2923 l2cap_build_conf_rsp(sk, rsp,
2924 L2CAP_CONF_REJECT, flags), rsp);
2925 goto unlock;
2926 }
2927
2928 /* Store config. */
2929 memcpy(l2cap_pi(sk)->conf_req + l2cap_pi(sk)->conf_len, req->data, len);
2930 l2cap_pi(sk)->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002931
2932 if (flags & 0x0001) {
2933 /* Incomplete config. Send empty response. */
2934 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002935 l2cap_build_conf_rsp(sk, rsp,
2936 L2CAP_CONF_SUCCESS, 0x0001), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002937 goto unlock;
2938 }
2939
2940 /* Complete config. */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002941 len = l2cap_parse_conf_req(sk, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002942 if (len < 0) {
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002943 l2cap_send_disconn_req(conn, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002944 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002945 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002946
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002947 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002948 l2cap_pi(sk)->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002949
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002950 /* Reset config buffer. */
2951 l2cap_pi(sk)->conf_len = 0;
2952
Marcel Holtmann876d9482007-10-20 13:35:42 +02002953 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE))
2954 goto unlock;
2955
Linus Torvalds1da177e2005-04-16 15:20:36 -07002956 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) {
Joe Perchesf64f9e72009-11-29 16:55:45 -08002957 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) ||
2958 l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002959 l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
2960
Linus Torvalds1da177e2005-04-16 15:20:36 -07002961 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002962
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002963 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002964 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002965 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002966 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
2967 l2cap_ertm_init(sk);
2968
Linus Torvalds1da177e2005-04-16 15:20:36 -07002969 l2cap_chan_ready(sk);
Marcel Holtmann876d9482007-10-20 13:35:42 +02002970 goto unlock;
2971 }
2972
2973 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002974 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002975 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002976 l2cap_build_conf_req(sk, buf), buf);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002977 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002978 }
2979
2980unlock:
2981 bh_unlock_sock(sk);
2982 return 0;
2983}
2984
2985static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2986{
2987 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
2988 u16 scid, flags, result;
2989 struct sock *sk;
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002990 int len = cmd->len - sizeof(*rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002991
2992 scid = __le16_to_cpu(rsp->scid);
2993 flags = __le16_to_cpu(rsp->flags);
2994 result = __le16_to_cpu(rsp->result);
2995
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002996 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x",
2997 scid, flags, result);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002998
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002999 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
3000 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003001 return 0;
3002
3003 switch (result) {
3004 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003005 l2cap_conf_rfc_get(sk, rsp->data, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003006 break;
3007
3008 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003009 if (l2cap_pi(sk)->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003010 char req[64];
3011
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02003012 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
3013 l2cap_send_disconn_req(conn, sk);
3014 goto done;
3015 }
3016
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003017 /* throw out any old stored conf requests */
3018 result = L2CAP_CONF_SUCCESS;
3019 len = l2cap_parse_conf_rsp(sk, rsp->data,
3020 len, req, &result);
3021 if (len < 0) {
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03003022 l2cap_send_disconn_req(conn, sk);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003023 goto done;
3024 }
3025
3026 l2cap_send_cmd(conn, l2cap_get_ident(conn),
3027 L2CAP_CONF_REQ, len, req);
3028 l2cap_pi(sk)->num_conf_req++;
3029 if (result != L2CAP_CONF_SUCCESS)
3030 goto done;
3031 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003032 }
3033
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09003034 default:
Linus Torvalds1da177e2005-04-16 15:20:36 -07003035 sk->sk_state = BT_DISCONN;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02003036 sk->sk_err = ECONNRESET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003037 l2cap_sock_set_timer(sk, HZ * 5);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03003038 l2cap_send_disconn_req(conn, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003039 goto done;
3040 }
3041
3042 if (flags & 0x01)
3043 goto done;
3044
Linus Torvalds1da177e2005-04-16 15:20:36 -07003045 l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE;
3046
3047 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) {
Joe Perchesf64f9e72009-11-29 16:55:45 -08003048 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) ||
3049 l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003050 l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
3051
Linus Torvalds1da177e2005-04-16 15:20:36 -07003052 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003053 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003054 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003055 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003056 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
3057 l2cap_ertm_init(sk);
3058
Linus Torvalds1da177e2005-04-16 15:20:36 -07003059 l2cap_chan_ready(sk);
3060 }
3061
3062done:
3063 bh_unlock_sock(sk);
3064 return 0;
3065}
3066
3067static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3068{
3069 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
3070 struct l2cap_disconn_rsp rsp;
3071 u16 dcid, scid;
3072 struct sock *sk;
3073
3074 scid = __le16_to_cpu(req->scid);
3075 dcid = __le16_to_cpu(req->dcid);
3076
3077 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
3078
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003079 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
3080 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003081 return 0;
3082
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003083 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
3084 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003085 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
3086
3087 sk->sk_shutdown = SHUTDOWN_MASK;
3088
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003089 skb_queue_purge(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003090
3091 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
3092 skb_queue_purge(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003093 skb_queue_purge(BUSY_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003094 del_timer(&l2cap_pi(sk)->retrans_timer);
3095 del_timer(&l2cap_pi(sk)->monitor_timer);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003096 del_timer(&l2cap_pi(sk)->ack_timer);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003097 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003098
Linus Torvalds1da177e2005-04-16 15:20:36 -07003099 l2cap_chan_del(sk, ECONNRESET);
3100 bh_unlock_sock(sk);
3101
3102 l2cap_sock_kill(sk);
3103 return 0;
3104}
3105
3106static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3107{
3108 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
3109 u16 dcid, scid;
3110 struct sock *sk;
3111
3112 scid = __le16_to_cpu(rsp->scid);
3113 dcid = __le16_to_cpu(rsp->dcid);
3114
3115 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
3116
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003117 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
3118 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003119 return 0;
3120
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003121 skb_queue_purge(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003122
3123 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
3124 skb_queue_purge(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003125 skb_queue_purge(BUSY_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003126 del_timer(&l2cap_pi(sk)->retrans_timer);
3127 del_timer(&l2cap_pi(sk)->monitor_timer);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003128 del_timer(&l2cap_pi(sk)->ack_timer);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003129 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003130
Linus Torvalds1da177e2005-04-16 15:20:36 -07003131 l2cap_chan_del(sk, 0);
3132 bh_unlock_sock(sk);
3133
3134 l2cap_sock_kill(sk);
3135 return 0;
3136}
3137
3138static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3139{
3140 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003141 u16 type;
3142
3143 type = __le16_to_cpu(req->type);
3144
3145 BT_DBG("type 0x%4.4x", type);
3146
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003147 if (type == L2CAP_IT_FEAT_MASK) {
3148 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003149 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003150 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
3151 rsp->type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
3152 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003153 if (enable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003154 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
3155 | L2CAP_FEAT_FCS;
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03003156 put_unaligned_le32(feat_mask, rsp->data);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003157 l2cap_send_cmd(conn, cmd->ident,
3158 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003159 } else if (type == L2CAP_IT_FIXED_CHAN) {
3160 u8 buf[12];
3161 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
3162 rsp->type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3163 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
3164 memcpy(buf + 4, l2cap_fixed_chan, 8);
3165 l2cap_send_cmd(conn, cmd->ident,
3166 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003167 } else {
3168 struct l2cap_info_rsp rsp;
3169 rsp.type = cpu_to_le16(type);
3170 rsp.result = cpu_to_le16(L2CAP_IR_NOTSUPP);
3171 l2cap_send_cmd(conn, cmd->ident,
3172 L2CAP_INFO_RSP, sizeof(rsp), &rsp);
3173 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003174
3175 return 0;
3176}
3177
3178static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3179{
3180 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
3181 u16 type, result;
3182
3183 type = __le16_to_cpu(rsp->type);
3184 result = __le16_to_cpu(rsp->result);
3185
3186 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
3187
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003188 del_timer(&conn->info_timer);
3189
Marcel Holtmann984947d2009-02-06 23:35:19 +01003190 if (type == L2CAP_IT_FEAT_MASK) {
Harvey Harrison83985312008-05-02 16:25:46 -07003191 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003192
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003193 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003194 struct l2cap_info_req req;
3195 req.type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3196
3197 conn->info_ident = l2cap_get_ident(conn);
3198
3199 l2cap_send_cmd(conn, conn->info_ident,
3200 L2CAP_INFO_REQ, sizeof(req), &req);
3201 } else {
3202 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
3203 conn->info_ident = 0;
3204
3205 l2cap_conn_start(conn);
3206 }
3207 } else if (type == L2CAP_IT_FIXED_CHAN) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01003208 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003209 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003210
3211 l2cap_conn_start(conn);
3212 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003213
Linus Torvalds1da177e2005-04-16 15:20:36 -07003214 return 0;
3215}
3216
3217static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
3218{
3219 u8 *data = skb->data;
3220 int len = skb->len;
3221 struct l2cap_cmd_hdr cmd;
3222 int err = 0;
3223
3224 l2cap_raw_recv(conn, skb);
3225
3226 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07003227 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003228 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
3229 data += L2CAP_CMD_HDR_SIZE;
3230 len -= L2CAP_CMD_HDR_SIZE;
3231
Al Viro88219a02007-07-29 00:17:25 -07003232 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003233
Al Viro88219a02007-07-29 00:17:25 -07003234 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 -07003235
Al Viro88219a02007-07-29 00:17:25 -07003236 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003237 BT_DBG("corrupted command");
3238 break;
3239 }
3240
3241 switch (cmd.code) {
3242 case L2CAP_COMMAND_REJ:
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003243 l2cap_command_rej(conn, &cmd, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003244 break;
3245
3246 case L2CAP_CONN_REQ:
3247 err = l2cap_connect_req(conn, &cmd, data);
3248 break;
3249
3250 case L2CAP_CONN_RSP:
3251 err = l2cap_connect_rsp(conn, &cmd, data);
3252 break;
3253
3254 case L2CAP_CONF_REQ:
Al Viro88219a02007-07-29 00:17:25 -07003255 err = l2cap_config_req(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003256 break;
3257
3258 case L2CAP_CONF_RSP:
3259 err = l2cap_config_rsp(conn, &cmd, data);
3260 break;
3261
3262 case L2CAP_DISCONN_REQ:
3263 err = l2cap_disconnect_req(conn, &cmd, data);
3264 break;
3265
3266 case L2CAP_DISCONN_RSP:
3267 err = l2cap_disconnect_rsp(conn, &cmd, data);
3268 break;
3269
3270 case L2CAP_ECHO_REQ:
Al Viro88219a02007-07-29 00:17:25 -07003271 l2cap_send_cmd(conn, cmd.ident, L2CAP_ECHO_RSP, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003272 break;
3273
3274 case L2CAP_ECHO_RSP:
3275 break;
3276
3277 case L2CAP_INFO_REQ:
3278 err = l2cap_information_req(conn, &cmd, data);
3279 break;
3280
3281 case L2CAP_INFO_RSP:
3282 err = l2cap_information_rsp(conn, &cmd, data);
3283 break;
3284
3285 default:
3286 BT_ERR("Unknown signaling command 0x%2.2x", cmd.code);
3287 err = -EINVAL;
3288 break;
3289 }
3290
3291 if (err) {
3292 struct l2cap_cmd_rej rej;
3293 BT_DBG("error %d", err);
3294
3295 /* FIXME: Map err to a valid reason */
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003296 rej.reason = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003297 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
3298 }
3299
Al Viro88219a02007-07-29 00:17:25 -07003300 data += cmd_len;
3301 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003302 }
3303
3304 kfree_skb(skb);
3305}
3306
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003307static int l2cap_check_fcs(struct l2cap_pinfo *pi, struct sk_buff *skb)
3308{
3309 u16 our_fcs, rcv_fcs;
3310 int hdr_size = L2CAP_HDR_SIZE + 2;
3311
3312 if (pi->fcs == L2CAP_FCS_CRC16) {
3313 skb_trim(skb, skb->len - 2);
3314 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
3315 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
3316
3317 if (our_fcs != rcv_fcs)
3318 return -EINVAL;
3319 }
3320 return 0;
3321}
3322
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003323static inline void l2cap_send_i_or_rr_or_rnr(struct sock *sk)
3324{
3325 struct l2cap_pinfo *pi = l2cap_pi(sk);
3326 u16 control = 0;
3327
3328 pi->frames_sent = 0;
3329 pi->conn_state |= L2CAP_CONN_SEND_FBIT;
3330
3331 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3332
3333 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
3334 control |= L2CAP_SUPER_RCV_NOT_READY | L2CAP_CTRL_FINAL;
3335 l2cap_send_sframe(pi, control);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003336 pi->conn_state |= L2CAP_CONN_RNR_SENT;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003337 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
3338 }
3339
3340 if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY && pi->unacked_frames > 0)
3341 __mod_retrans_timer();
3342
3343 l2cap_ertm_send(sk);
3344
3345 if (!(pi->conn_state & L2CAP_CONN_LOCAL_BUSY) &&
3346 pi->frames_sent == 0) {
3347 control |= L2CAP_SUPER_RCV_READY;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003348 l2cap_send_sframe(pi, control);
3349 }
3350}
3351
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003352static 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 -03003353{
3354 struct sk_buff *next_skb;
3355
3356 bt_cb(skb)->tx_seq = tx_seq;
3357 bt_cb(skb)->sar = sar;
3358
3359 next_skb = skb_peek(SREJ_QUEUE(sk));
3360 if (!next_skb) {
3361 __skb_queue_tail(SREJ_QUEUE(sk), skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003362 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003363 }
3364
3365 do {
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003366 if (bt_cb(next_skb)->tx_seq == tx_seq)
3367 return -EINVAL;
3368
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003369 if (bt_cb(next_skb)->tx_seq > tx_seq) {
3370 __skb_queue_before(SREJ_QUEUE(sk), next_skb, skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003371 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003372 }
3373
3374 if (skb_queue_is_last(SREJ_QUEUE(sk), next_skb))
3375 break;
3376
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003377 } while ((next_skb = skb_queue_next(SREJ_QUEUE(sk), next_skb)));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003378
3379 __skb_queue_tail(SREJ_QUEUE(sk), skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003380
3381 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003382}
3383
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003384static int l2cap_ertm_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
3385{
3386 struct l2cap_pinfo *pi = l2cap_pi(sk);
3387 struct sk_buff *_skb;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003388 int err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003389
3390 switch (control & L2CAP_CTRL_SAR) {
3391 case L2CAP_SDU_UNSEGMENTED:
3392 if (pi->conn_state & L2CAP_CONN_SAR_SDU)
3393 goto drop;
3394
3395 err = sock_queue_rcv_skb(sk, skb);
3396 if (!err)
3397 return err;
3398
3399 break;
3400
3401 case L2CAP_SDU_START:
3402 if (pi->conn_state & L2CAP_CONN_SAR_SDU)
3403 goto drop;
3404
3405 pi->sdu_len = get_unaligned_le16(skb->data);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003406
3407 if (pi->sdu_len > pi->imtu)
3408 goto disconnect;
3409
3410 pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003411 if (!pi->sdu)
3412 return -ENOMEM;
3413
3414 /* pull sdu_len bytes only after alloc, because of Local Busy
3415 * condition we have to be sure that this will be executed
3416 * only once, i.e., when alloc does not fail */
3417 skb_pull(skb, 2);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003418
3419 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3420
3421 pi->conn_state |= L2CAP_CONN_SAR_SDU;
3422 pi->partial_sdu_len = skb->len;
3423 break;
3424
3425 case L2CAP_SDU_CONTINUE:
3426 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3427 goto disconnect;
3428
3429 if (!pi->sdu)
3430 goto disconnect;
3431
3432 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3433
3434 pi->partial_sdu_len += skb->len;
3435 if (pi->partial_sdu_len > pi->sdu_len)
3436 goto drop;
3437
3438 break;
3439
3440 case L2CAP_SDU_END:
3441 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3442 goto disconnect;
3443
3444 if (!pi->sdu)
3445 goto disconnect;
3446
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003447 if (!(pi->conn_state & L2CAP_CONN_SAR_RETRY)) {
3448 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003449
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003450 pi->partial_sdu_len += skb->len;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003451
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003452 if (pi->partial_sdu_len > pi->imtu)
3453 goto drop;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003454
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003455 if (pi->partial_sdu_len != pi->sdu_len)
3456 goto drop;
3457 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003458
3459 _skb = skb_clone(pi->sdu, GFP_ATOMIC);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003460 if (!_skb) {
3461 pi->conn_state |= L2CAP_CONN_SAR_RETRY;
3462 return -ENOMEM;
3463 }
3464
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003465 err = sock_queue_rcv_skb(sk, _skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003466 if (err < 0) {
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003467 kfree_skb(_skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003468 pi->conn_state |= L2CAP_CONN_SAR_RETRY;
3469 return err;
3470 }
3471
3472 pi->conn_state &= ~L2CAP_CONN_SAR_RETRY;
3473 pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003474
3475 kfree_skb(pi->sdu);
3476 break;
3477 }
3478
3479 kfree_skb(skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003480 return 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003481
3482drop:
3483 kfree_skb(pi->sdu);
3484 pi->sdu = NULL;
3485
3486disconnect:
3487 l2cap_send_disconn_req(pi->conn, sk);
3488 kfree_skb(skb);
3489 return 0;
3490}
3491
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003492static void l2cap_busy_work(struct work_struct *work)
3493{
3494 DECLARE_WAITQUEUE(wait, current);
3495 struct l2cap_pinfo *pi =
3496 container_of(work, struct l2cap_pinfo, busy_work);
3497 struct sock *sk = (struct sock *)pi;
3498 int n_tries = 0, timeo = HZ/5, err;
3499 struct sk_buff *skb;
3500 u16 control;
3501
3502 lock_sock(sk);
3503
3504 add_wait_queue(sk->sk_sleep, &wait);
3505 while ((skb = skb_peek(BUSY_QUEUE(sk)))) {
3506 set_current_state(TASK_INTERRUPTIBLE);
3507
3508 if (n_tries++ > L2CAP_LOCAL_BUSY_TRIES) {
3509 err = -EBUSY;
3510 l2cap_send_disconn_req(pi->conn, sk);
3511 goto done;
3512 }
3513
3514 if (!timeo)
3515 timeo = HZ/5;
3516
3517 if (signal_pending(current)) {
3518 err = sock_intr_errno(timeo);
3519 goto done;
3520 }
3521
3522 release_sock(sk);
3523 timeo = schedule_timeout(timeo);
3524 lock_sock(sk);
3525
3526 err = sock_error(sk);
3527 if (err)
3528 goto done;
3529
3530 while ((skb = skb_dequeue(BUSY_QUEUE(sk)))) {
3531 control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
3532 err = l2cap_ertm_reassembly_sdu(sk, skb, control);
3533 if (err < 0) {
3534 skb_queue_head(BUSY_QUEUE(sk), skb);
3535 break;
3536 }
3537
3538 pi->buffer_seq = (pi->buffer_seq + 1) % 64;
3539 }
3540
3541 if (!skb)
3542 break;
3543 }
3544
3545 if (!(pi->conn_state & L2CAP_CONN_RNR_SENT))
3546 goto done;
3547
3548 control = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3549 control |= L2CAP_SUPER_RCV_READY | L2CAP_CTRL_POLL;
3550 l2cap_send_sframe(pi, control);
3551 l2cap_pi(sk)->retry_count = 1;
3552
3553 del_timer(&pi->retrans_timer);
3554 __mod_monitor_timer();
3555
3556 l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
3557
3558done:
3559 pi->conn_state &= ~L2CAP_CONN_LOCAL_BUSY;
3560 pi->conn_state &= ~L2CAP_CONN_RNR_SENT;
3561
3562 set_current_state(TASK_RUNNING);
3563 remove_wait_queue(sk->sk_sleep, &wait);
3564
3565 release_sock(sk);
3566}
3567
3568static int l2cap_push_rx_skb(struct sock *sk, struct sk_buff *skb, u16 control)
3569{
3570 struct l2cap_pinfo *pi = l2cap_pi(sk);
3571 int sctrl, err;
3572
3573 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
3574 bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT;
3575 __skb_queue_tail(BUSY_QUEUE(sk), skb);
3576 return -EBUSY;
3577 }
3578
3579 err = l2cap_ertm_reassembly_sdu(sk, skb, control);
3580 if (err >= 0) {
3581 pi->buffer_seq = (pi->buffer_seq + 1) % 64;
3582 return err;
3583 }
3584
3585 /* Busy Condition */
3586 pi->conn_state |= L2CAP_CONN_LOCAL_BUSY;
3587 bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT;
3588 __skb_queue_tail(BUSY_QUEUE(sk), skb);
3589
3590 sctrl = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3591 sctrl |= L2CAP_SUPER_RCV_NOT_READY;
3592 l2cap_send_sframe(pi, sctrl);
3593
3594 pi->conn_state |= L2CAP_CONN_RNR_SENT;
3595
3596 queue_work(_busy_wq, &pi->busy_work);
3597
3598 return err;
3599}
3600
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003601static int l2cap_streaming_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003602{
3603 struct l2cap_pinfo *pi = l2cap_pi(sk);
3604 struct sk_buff *_skb;
3605 int err = -EINVAL;
3606
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003607 /*
3608 * TODO: We have to notify the userland if some data is lost with the
3609 * Streaming Mode.
3610 */
3611
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003612 switch (control & L2CAP_CTRL_SAR) {
3613 case L2CAP_SDU_UNSEGMENTED:
3614 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3615 kfree_skb(pi->sdu);
3616 break;
3617 }
3618
3619 err = sock_queue_rcv_skb(sk, skb);
3620 if (!err)
3621 return 0;
3622
3623 break;
3624
3625 case L2CAP_SDU_START:
3626 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3627 kfree_skb(pi->sdu);
3628 break;
3629 }
3630
3631 pi->sdu_len = get_unaligned_le16(skb->data);
3632 skb_pull(skb, 2);
3633
Gustavo F. Padovan052897c2010-05-01 16:15:40 -03003634 if (pi->sdu_len > pi->imtu) {
3635 err = -EMSGSIZE;
3636 break;
3637 }
3638
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003639 pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
3640 if (!pi->sdu) {
3641 err = -ENOMEM;
3642 break;
3643 }
3644
3645 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3646
3647 pi->conn_state |= L2CAP_CONN_SAR_SDU;
3648 pi->partial_sdu_len = skb->len;
3649 err = 0;
3650 break;
3651
3652 case L2CAP_SDU_CONTINUE:
3653 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3654 break;
3655
3656 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3657
3658 pi->partial_sdu_len += skb->len;
3659 if (pi->partial_sdu_len > pi->sdu_len)
3660 kfree_skb(pi->sdu);
3661 else
3662 err = 0;
3663
3664 break;
3665
3666 case L2CAP_SDU_END:
3667 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3668 break;
3669
3670 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3671
3672 pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
3673 pi->partial_sdu_len += skb->len;
3674
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003675 if (pi->partial_sdu_len > pi->imtu)
3676 goto drop;
3677
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003678 if (pi->partial_sdu_len == pi->sdu_len) {
3679 _skb = skb_clone(pi->sdu, GFP_ATOMIC);
3680 err = sock_queue_rcv_skb(sk, _skb);
3681 if (err < 0)
3682 kfree_skb(_skb);
3683 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003684 err = 0;
3685
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003686drop:
3687 kfree_skb(pi->sdu);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003688 break;
3689 }
3690
3691 kfree_skb(skb);
3692 return err;
3693}
3694
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003695static void l2cap_check_srej_gap(struct sock *sk, u8 tx_seq)
3696{
3697 struct sk_buff *skb;
Gustavo F. Padovanafefdbc2010-05-01 16:15:43 -03003698 u16 control;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003699
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003700 while ((skb = skb_peek(SREJ_QUEUE(sk)))) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003701 if (bt_cb(skb)->tx_seq != tx_seq)
3702 break;
3703
3704 skb = skb_dequeue(SREJ_QUEUE(sk));
Gustavo F. Padovanafefdbc2010-05-01 16:15:43 -03003705 control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003706 l2cap_ertm_reassembly_sdu(sk, skb, control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003707 l2cap_pi(sk)->buffer_seq_srej =
3708 (l2cap_pi(sk)->buffer_seq_srej + 1) % 64;
3709 tx_seq++;
3710 }
3711}
3712
3713static void l2cap_resend_srejframe(struct sock *sk, u8 tx_seq)
3714{
3715 struct l2cap_pinfo *pi = l2cap_pi(sk);
3716 struct srej_list *l, *tmp;
3717 u16 control;
3718
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003719 list_for_each_entry_safe(l, tmp, SREJ_LIST(sk), list) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003720 if (l->tx_seq == tx_seq) {
3721 list_del(&l->list);
3722 kfree(l);
3723 return;
3724 }
3725 control = L2CAP_SUPER_SELECT_REJECT;
3726 control |= l->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3727 l2cap_send_sframe(pi, control);
3728 list_del(&l->list);
3729 list_add_tail(&l->list, SREJ_LIST(sk));
3730 }
3731}
3732
3733static void l2cap_send_srejframe(struct sock *sk, u8 tx_seq)
3734{
3735 struct l2cap_pinfo *pi = l2cap_pi(sk);
3736 struct srej_list *new;
3737 u16 control;
3738
3739 while (tx_seq != pi->expected_tx_seq) {
3740 control = L2CAP_SUPER_SELECT_REJECT;
3741 control |= pi->expected_tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3742 l2cap_send_sframe(pi, control);
3743
3744 new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC);
3745 new->tx_seq = pi->expected_tx_seq++;
3746 list_add_tail(&new->list, SREJ_LIST(sk));
3747 }
3748 pi->expected_tx_seq++;
3749}
3750
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003751static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
3752{
3753 struct l2cap_pinfo *pi = l2cap_pi(sk);
3754 u8 tx_seq = __get_txseq(rx_control);
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003755 u8 req_seq = __get_reqseq(rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003756 u8 sar = rx_control >> L2CAP_CTRL_SAR_SHIFT;
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003757 u8 tx_seq_offset, expected_tx_seq_offset;
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03003758 int num_to_ack = (pi->tx_win/6) + 1;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003759 int err = 0;
3760
3761 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
3762
Gustavo F. Padovan9b16dc62010-05-05 20:05:57 -03003763 if (L2CAP_CTRL_FINAL & rx_control &&
3764 l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) {
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003765 del_timer(&pi->monitor_timer);
3766 if (pi->unacked_frames > 0)
3767 __mod_retrans_timer();
3768 pi->conn_state &= ~L2CAP_CONN_WAIT_F;
3769 }
3770
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003771 pi->expected_ack_seq = req_seq;
3772 l2cap_drop_acked_frames(sk);
3773
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003774 if (tx_seq == pi->expected_tx_seq)
3775 goto expected;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003776
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003777 tx_seq_offset = (tx_seq - pi->buffer_seq) % 64;
3778 if (tx_seq_offset < 0)
3779 tx_seq_offset += 64;
3780
3781 /* invalid tx_seq */
3782 if (tx_seq_offset >= pi->tx_win) {
3783 l2cap_send_disconn_req(pi->conn, sk);
3784 goto drop;
3785 }
3786
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003787 if (pi->conn_state == L2CAP_CONN_LOCAL_BUSY)
3788 goto drop;
3789
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003790 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3791 struct srej_list *first;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003792
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003793 first = list_first_entry(SREJ_LIST(sk),
3794 struct srej_list, list);
3795 if (tx_seq == first->tx_seq) {
3796 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3797 l2cap_check_srej_gap(sk, tx_seq);
3798
3799 list_del(&first->list);
3800 kfree(first);
3801
3802 if (list_empty(SREJ_LIST(sk))) {
3803 pi->buffer_seq = pi->buffer_seq_srej;
3804 pi->conn_state &= ~L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan855666cc2010-05-01 16:15:40 -03003805 l2cap_send_ack(pi);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003806 }
3807 } else {
3808 struct srej_list *l;
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003809
3810 /* duplicated tx_seq */
3811 if (l2cap_add_to_srej_queue(sk, skb, tx_seq, sar) < 0)
3812 goto drop;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003813
3814 list_for_each_entry(l, SREJ_LIST(sk), list) {
3815 if (l->tx_seq == tx_seq) {
3816 l2cap_resend_srejframe(sk, tx_seq);
3817 return 0;
3818 }
3819 }
3820 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003821 }
3822 } else {
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003823 expected_tx_seq_offset =
3824 (pi->expected_tx_seq - pi->buffer_seq) % 64;
3825 if (expected_tx_seq_offset < 0)
3826 expected_tx_seq_offset += 64;
3827
3828 /* duplicated tx_seq */
3829 if (tx_seq_offset < expected_tx_seq_offset)
3830 goto drop;
3831
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003832 pi->conn_state |= L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003833
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003834 INIT_LIST_HEAD(SREJ_LIST(sk));
3835 pi->buffer_seq_srej = pi->buffer_seq;
3836
3837 __skb_queue_head_init(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003838 __skb_queue_head_init(BUSY_QUEUE(sk));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003839 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3840
Gustavo F. Padovanef54fd92009-08-20 22:26:04 -03003841 pi->conn_state |= L2CAP_CONN_SEND_PBIT;
3842
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003843 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003844 }
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003845 return 0;
3846
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003847expected:
3848 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
3849
3850 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
Gustavo F. Padovan3b1a9f32010-05-01 16:15:42 -03003851 bt_cb(skb)->tx_seq = tx_seq;
3852 bt_cb(skb)->sar = sar;
3853 __skb_queue_tail(SREJ_QUEUE(sk), skb);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003854 return 0;
3855 }
3856
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03003857 if (rx_control & L2CAP_CTRL_FINAL) {
3858 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3859 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
3860 else {
Gustavo F. Padovanf6e6b162010-05-01 16:15:41 -03003861 if (!skb_queue_empty(TX_QUEUE(sk)))
3862 sk->sk_send_head = TX_QUEUE(sk)->next;
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03003863 pi->next_tx_seq = pi->expected_ack_seq;
3864 l2cap_ertm_send(sk);
3865 }
3866 }
3867
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003868 err = l2cap_push_rx_skb(sk, skb, rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003869 if (err < 0)
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003870 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003871
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003872 __mod_ack_timer();
3873
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03003874 pi->num_acked = (pi->num_acked + 1) % num_to_ack;
3875 if (pi->num_acked == num_to_ack - 1)
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03003876 l2cap_send_ack(pi);
3877
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003878 return 0;
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003879
3880drop:
3881 kfree_skb(skb);
3882 return 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003883}
3884
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003885static inline void l2cap_data_channel_rrframe(struct sock *sk, u16 rx_control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003886{
3887 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan6e3a5982010-05-01 16:15:38 -03003888
3889 pi->expected_ack_seq = __get_reqseq(rx_control);
3890 l2cap_drop_acked_frames(sk);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003891
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003892 if (rx_control & L2CAP_CTRL_POLL) {
Gustavo F. Padovan05fbd892010-05-01 16:15:39 -03003893 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3894 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
3895 (pi->unacked_frames > 0))
3896 __mod_retrans_timer();
3897
3898 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3899 l2cap_send_srejtail(sk);
3900 } else {
3901 l2cap_send_i_or_rr_or_rnr(sk);
3902 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3903 }
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003904
3905 } else if (rx_control & L2CAP_CTRL_FINAL) {
3906 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003907
3908 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3909 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
3910 else {
Gustavo F. Padovanf6e6b162010-05-01 16:15:41 -03003911 if (!skb_queue_empty(TX_QUEUE(sk)))
3912 sk->sk_send_head = TX_QUEUE(sk)->next;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003913 pi->next_tx_seq = pi->expected_ack_seq;
3914 l2cap_ertm_send(sk);
3915 }
3916
3917 } else {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003918 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
3919 (pi->unacked_frames > 0))
3920 __mod_retrans_timer();
3921
3922 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3923 if (pi->conn_state & L2CAP_CONN_SREJ_SENT)
3924 l2cap_send_ack(pi);
3925 else
3926 l2cap_ertm_send(sk);
3927 }
3928}
3929
3930static inline void l2cap_data_channel_rejframe(struct sock *sk, u16 rx_control)
3931{
3932 struct l2cap_pinfo *pi = l2cap_pi(sk);
3933 u8 tx_seq = __get_reqseq(rx_control);
3934
3935 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3936
Gustavo F. Padovan8abb52e2010-05-01 16:15:38 -03003937 pi->expected_ack_seq = tx_seq;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003938 l2cap_drop_acked_frames(sk);
3939
3940 if (rx_control & L2CAP_CTRL_FINAL) {
3941 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3942 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
3943 else {
Gustavo F. Padovanf6e6b162010-05-01 16:15:41 -03003944 if (!skb_queue_empty(TX_QUEUE(sk)))
3945 sk->sk_send_head = TX_QUEUE(sk)->next;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003946 pi->next_tx_seq = pi->expected_ack_seq;
3947 l2cap_ertm_send(sk);
3948 }
3949 } else {
Gustavo F. Padovanf6e6b162010-05-01 16:15:41 -03003950 if (!skb_queue_empty(TX_QUEUE(sk)))
3951 sk->sk_send_head = TX_QUEUE(sk)->next;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003952 pi->next_tx_seq = pi->expected_ack_seq;
3953 l2cap_ertm_send(sk);
3954
Gustavo F. Padovan0301ef02010-05-05 20:56:43 -03003955 if (pi->conn_state & L2CAP_CONN_WAIT_F)
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003956 pi->conn_state |= L2CAP_CONN_REJ_ACT;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003957 }
3958}
3959static inline void l2cap_data_channel_srejframe(struct sock *sk, u16 rx_control)
3960{
3961 struct l2cap_pinfo *pi = l2cap_pi(sk);
3962 u8 tx_seq = __get_reqseq(rx_control);
3963
3964 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3965
3966 if (rx_control & L2CAP_CTRL_POLL) {
3967 pi->expected_ack_seq = tx_seq;
3968 l2cap_drop_acked_frames(sk);
3969 l2cap_retransmit_frame(sk, tx_seq);
3970 l2cap_ertm_send(sk);
3971 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
3972 pi->srej_save_reqseq = tx_seq;
3973 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
3974 }
3975 } else if (rx_control & L2CAP_CTRL_FINAL) {
3976 if ((pi->conn_state & L2CAP_CONN_SREJ_ACT) &&
3977 pi->srej_save_reqseq == tx_seq)
3978 pi->conn_state &= ~L2CAP_CONN_SREJ_ACT;
3979 else
3980 l2cap_retransmit_frame(sk, tx_seq);
3981 } else {
3982 l2cap_retransmit_frame(sk, tx_seq);
3983 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
3984 pi->srej_save_reqseq = tx_seq;
3985 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
3986 }
3987 }
3988}
3989
3990static inline void l2cap_data_channel_rnrframe(struct sock *sk, u16 rx_control)
3991{
3992 struct l2cap_pinfo *pi = l2cap_pi(sk);
3993 u8 tx_seq = __get_reqseq(rx_control);
3994
3995 pi->conn_state |= L2CAP_CONN_REMOTE_BUSY;
3996 pi->expected_ack_seq = tx_seq;
3997 l2cap_drop_acked_frames(sk);
3998
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03003999 if (!(pi->conn_state & L2CAP_CONN_SREJ_SENT)) {
4000 del_timer(&pi->retrans_timer);
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -03004001 if (rx_control & L2CAP_CTRL_POLL)
4002 l2cap_send_rr_or_rnr(pi, L2CAP_CTRL_FINAL);
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03004003 return;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004004 }
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03004005
4006 if (rx_control & L2CAP_CTRL_POLL)
4007 l2cap_send_srejtail(sk);
4008 else
4009 l2cap_send_sframe(pi, L2CAP_SUPER_RCV_READY);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004010}
4011
4012static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
4013{
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004014 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
4015
Gustavo F. Padovan9b16dc62010-05-05 20:05:57 -03004016 if (L2CAP_CTRL_FINAL & rx_control &&
4017 l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004018 del_timer(&l2cap_pi(sk)->monitor_timer);
4019 if (l2cap_pi(sk)->unacked_frames > 0)
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03004020 __mod_retrans_timer();
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004021 l2cap_pi(sk)->conn_state &= ~L2CAP_CONN_WAIT_F;
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03004022 }
4023
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004024 switch (rx_control & L2CAP_CTRL_SUPERVISE) {
4025 case L2CAP_SUPER_RCV_READY:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004026 l2cap_data_channel_rrframe(sk, rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004027 break;
4028
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004029 case L2CAP_SUPER_REJECT:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004030 l2cap_data_channel_rejframe(sk, rx_control);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03004031 break;
4032
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004033 case L2CAP_SUPER_SELECT_REJECT:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004034 l2cap_data_channel_srejframe(sk, rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004035 break;
4036
4037 case L2CAP_SUPER_RCV_NOT_READY:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004038 l2cap_data_channel_rnrframe(sk, rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004039 break;
4040 }
4041
Gustavo F. Padovanfaaebd12010-05-01 16:15:35 -03004042 kfree_skb(skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004043 return 0;
4044}
4045
Linus Torvalds1da177e2005-04-16 15:20:36 -07004046static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk_buff *skb)
4047{
4048 struct sock *sk;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004049 struct l2cap_pinfo *pi;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03004050 u16 control, len;
João Paulo Rechi Vita01760bd2010-05-01 16:15:43 -03004051 u8 tx_seq, req_seq, next_tx_seq_offset, req_seq_offset;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004052
4053 sk = l2cap_get_chan_by_scid(&conn->chan_list, cid);
4054 if (!sk) {
4055 BT_DBG("unknown cid 0x%4.4x", cid);
4056 goto drop;
4057 }
4058
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004059 pi = l2cap_pi(sk);
4060
Linus Torvalds1da177e2005-04-16 15:20:36 -07004061 BT_DBG("sk %p, len %d", sk, skb->len);
4062
4063 if (sk->sk_state != BT_CONNECTED)
4064 goto drop;
4065
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004066 switch (pi->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004067 case L2CAP_MODE_BASIC:
4068 /* If socket recv buffers overflows we drop data here
4069 * which is *bad* because L2CAP has to be reliable.
4070 * But we don't have any other choice. L2CAP doesn't
4071 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07004072
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004073 if (pi->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004074 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004075
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004076 if (!sock_queue_rcv_skb(sk, skb))
4077 goto done;
4078 break;
4079
4080 case L2CAP_MODE_ERTM:
4081 control = get_unaligned_le16(skb->data);
4082 skb_pull(skb, 2);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03004083 len = skb->len;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004084
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03004085 if (__is_sar_start(control))
4086 len -= 2;
4087
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004088 if (pi->fcs == L2CAP_FCS_CRC16)
4089 len -= 2;
4090
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03004091 /*
4092 * We can just drop the corrupted I-frame here.
4093 * Receiver will miss it and start proper recovery
4094 * procedures and ask retransmission.
4095 */
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004096 if (len > pi->mps) {
4097 l2cap_send_disconn_req(pi->conn, sk);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004098 goto drop;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004099 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004100
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004101 if (l2cap_check_fcs(pi, skb))
4102 goto drop;
4103
João Paulo Rechi Vita01760bd2010-05-01 16:15:43 -03004104 req_seq = __get_reqseq(control);
4105 req_seq_offset = (req_seq - pi->expected_ack_seq) % 64;
4106 if (req_seq_offset < 0)
4107 req_seq_offset += 64;
4108
4109 next_tx_seq_offset =
4110 (pi->next_tx_seq - pi->expected_ack_seq) % 64;
4111 if (next_tx_seq_offset < 0)
4112 next_tx_seq_offset += 64;
4113
4114 /* check for invalid req-seq */
4115 if (req_seq_offset > next_tx_seq_offset) {
4116 l2cap_send_disconn_req(pi->conn, sk);
4117 goto drop;
4118 }
4119
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004120 if (__is_iframe(control)) {
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004121 if (len < 4) {
4122 l2cap_send_disconn_req(pi->conn, sk);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004123 goto drop;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004124 }
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004125
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02004126 l2cap_data_channel_iframe(sk, control, skb);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004127 } else {
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004128 if (len != 0) {
4129 l2cap_send_disconn_req(pi->conn, sk);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004130 goto drop;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004131 }
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004132
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02004133 l2cap_data_channel_sframe(sk, control, skb);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004134 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004135
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02004136 goto done;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004137
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004138 case L2CAP_MODE_STREAMING:
4139 control = get_unaligned_le16(skb->data);
4140 skb_pull(skb, 2);
4141 len = skb->len;
4142
4143 if (__is_sar_start(control))
4144 len -= 2;
4145
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004146 if (pi->fcs == L2CAP_FCS_CRC16)
4147 len -= 2;
4148
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03004149 if (len > pi->mps || len < 4 || __is_sframe(control))
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004150 goto drop;
4151
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004152 if (l2cap_check_fcs(pi, skb))
4153 goto drop;
4154
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004155 tx_seq = __get_txseq(control);
4156
4157 if (pi->expected_tx_seq == tx_seq)
4158 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
4159 else
Gustavo F. Padovan7dffe422010-05-01 16:15:36 -03004160 pi->expected_tx_seq = (tx_seq + 1) % 64;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004161
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004162 l2cap_streaming_reassembly_sdu(sk, skb, control);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004163
4164 goto done;
4165
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004166 default:
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03004167 BT_DBG("sk %p: bad mode 0x%2.2x", sk, pi->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004168 break;
4169 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004170
4171drop:
4172 kfree_skb(skb);
4173
4174done:
Marcel Holtmann01394182006-07-03 10:02:46 +02004175 if (sk)
4176 bh_unlock_sock(sk);
4177
Linus Torvalds1da177e2005-04-16 15:20:36 -07004178 return 0;
4179}
4180
Al Viro8e036fc2007-07-29 00:16:36 -07004181static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004182{
4183 struct sock *sk;
4184
4185 sk = l2cap_get_sock_by_psm(0, psm, conn->src);
4186 if (!sk)
4187 goto drop;
4188
4189 BT_DBG("sk %p, len %d", sk, skb->len);
4190
4191 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_CONNECTED)
4192 goto drop;
4193
4194 if (l2cap_pi(sk)->imtu < skb->len)
4195 goto drop;
4196
4197 if (!sock_queue_rcv_skb(sk, skb))
4198 goto done;
4199
4200drop:
4201 kfree_skb(skb);
4202
4203done:
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03004204 if (sk)
4205 bh_unlock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004206 return 0;
4207}
4208
4209static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
4210{
4211 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07004212 u16 cid, len;
4213 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004214
4215 skb_pull(skb, L2CAP_HDR_SIZE);
4216 cid = __le16_to_cpu(lh->cid);
4217 len = __le16_to_cpu(lh->len);
4218
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004219 if (len != skb->len) {
4220 kfree_skb(skb);
4221 return;
4222 }
4223
Linus Torvalds1da177e2005-04-16 15:20:36 -07004224 BT_DBG("len %d, cid 0x%4.4x", len, cid);
4225
4226 switch (cid) {
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03004227 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07004228 l2cap_sig_channel(conn, skb);
4229 break;
4230
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03004231 case L2CAP_CID_CONN_LESS:
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03004232 psm = get_unaligned_le16(skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004233 skb_pull(skb, 2);
4234 l2cap_conless_channel(conn, psm, skb);
4235 break;
4236
4237 default:
4238 l2cap_data_channel(conn, cid, skb);
4239 break;
4240 }
4241}
4242
4243/* ---- L2CAP interface with lower layer (HCI) ---- */
4244
4245static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
4246{
4247 int exact = 0, lm1 = 0, lm2 = 0;
4248 register struct sock *sk;
4249 struct hlist_node *node;
4250
4251 if (type != ACL_LINK)
4252 return 0;
4253
4254 BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
4255
4256 /* Find listening sockets and check their link_mode */
4257 read_lock(&l2cap_sk_list.lock);
4258 sk_for_each(sk, node, &l2cap_sk_list.head) {
4259 if (sk->sk_state != BT_LISTEN)
4260 continue;
4261
4262 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01004263 lm1 |= HCI_LM_ACCEPT;
4264 if (l2cap_pi(sk)->role_switch)
4265 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004266 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01004267 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
4268 lm2 |= HCI_LM_ACCEPT;
4269 if (l2cap_pi(sk)->role_switch)
4270 lm2 |= HCI_LM_MASTER;
4271 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004272 }
4273 read_unlock(&l2cap_sk_list.lock);
4274
4275 return exact ? lm1 : lm2;
4276}
4277
4278static int l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
4279{
Marcel Holtmann01394182006-07-03 10:02:46 +02004280 struct l2cap_conn *conn;
4281
Linus Torvalds1da177e2005-04-16 15:20:36 -07004282 BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
4283
4284 if (hcon->type != ACL_LINK)
4285 return 0;
4286
4287 if (!status) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004288 conn = l2cap_conn_add(hcon, status);
4289 if (conn)
4290 l2cap_conn_ready(conn);
Marcel Holtmann01394182006-07-03 10:02:46 +02004291 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -07004292 l2cap_conn_del(hcon, bt_err(status));
4293
4294 return 0;
4295}
4296
Marcel Holtmann2950f212009-02-12 14:02:50 +01004297static int l2cap_disconn_ind(struct hci_conn *hcon)
4298{
4299 struct l2cap_conn *conn = hcon->l2cap_data;
4300
4301 BT_DBG("hcon %p", hcon);
4302
4303 if (hcon->type != ACL_LINK || !conn)
4304 return 0x13;
4305
4306 return conn->disc_reason;
4307}
4308
4309static int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004310{
4311 BT_DBG("hcon %p reason %d", hcon, reason);
4312
4313 if (hcon->type != ACL_LINK)
4314 return 0;
4315
4316 l2cap_conn_del(hcon, bt_err(reason));
Marcel Holtmann01394182006-07-03 10:02:46 +02004317
Linus Torvalds1da177e2005-04-16 15:20:36 -07004318 return 0;
4319}
4320
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004321static inline void l2cap_check_encryption(struct sock *sk, u8 encrypt)
4322{
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03004323 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM)
Marcel Holtmann255c7602009-02-04 21:07:19 +01004324 return;
4325
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004326 if (encrypt == 0x00) {
4327 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM) {
4328 l2cap_sock_clear_timer(sk);
4329 l2cap_sock_set_timer(sk, HZ * 5);
4330 } else if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
4331 __l2cap_sock_close(sk, ECONNREFUSED);
4332 } else {
4333 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM)
4334 l2cap_sock_clear_timer(sk);
4335 }
4336}
4337
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004338static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004339{
4340 struct l2cap_chan_list *l;
Marcel Holtmann40be4922008-07-14 20:13:50 +02004341 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004342 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004343
Marcel Holtmann01394182006-07-03 10:02:46 +02004344 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004345 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02004346
Linus Torvalds1da177e2005-04-16 15:20:36 -07004347 l = &conn->chan_list;
4348
4349 BT_DBG("conn %p", conn);
4350
4351 read_lock(&l->lock);
4352
4353 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
4354 bh_lock_sock(sk);
4355
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01004356 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND) {
4357 bh_unlock_sock(sk);
4358 continue;
4359 }
4360
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004361 if (!status && (sk->sk_state == BT_CONNECTED ||
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004362 sk->sk_state == BT_CONFIG)) {
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004363 l2cap_check_encryption(sk, encrypt);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02004364 bh_unlock_sock(sk);
4365 continue;
4366 }
4367
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004368 if (sk->sk_state == BT_CONNECT) {
4369 if (!status) {
4370 struct l2cap_conn_req req;
4371 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
4372 req.psm = l2cap_pi(sk)->psm;
4373
4374 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
4375
4376 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
4377 L2CAP_CONN_REQ, sizeof(req), &req);
4378 } else {
4379 l2cap_sock_clear_timer(sk);
4380 l2cap_sock_set_timer(sk, HZ / 10);
4381 }
4382 } else if (sk->sk_state == BT_CONNECT2) {
4383 struct l2cap_conn_rsp rsp;
4384 __u16 result;
4385
4386 if (!status) {
4387 sk->sk_state = BT_CONFIG;
4388 result = L2CAP_CR_SUCCESS;
4389 } else {
4390 sk->sk_state = BT_DISCONN;
4391 l2cap_sock_set_timer(sk, HZ / 10);
4392 result = L2CAP_CR_SEC_BLOCK;
4393 }
4394
4395 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
4396 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
4397 rsp.result = cpu_to_le16(result);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02004398 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004399 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
4400 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004401 }
4402
Linus Torvalds1da177e2005-04-16 15:20:36 -07004403 bh_unlock_sock(sk);
4404 }
4405
4406 read_unlock(&l->lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004407
Linus Torvalds1da177e2005-04-16 15:20:36 -07004408 return 0;
4409}
4410
4411static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
4412{
4413 struct l2cap_conn *conn = hcon->l2cap_data;
4414
4415 if (!conn && !(conn = l2cap_conn_add(hcon, 0)))
4416 goto drop;
4417
4418 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
4419
4420 if (flags & ACL_START) {
4421 struct l2cap_hdr *hdr;
4422 int len;
4423
4424 if (conn->rx_len) {
4425 BT_ERR("Unexpected start frame (len %d)", skb->len);
4426 kfree_skb(conn->rx_skb);
4427 conn->rx_skb = NULL;
4428 conn->rx_len = 0;
4429 l2cap_conn_unreliable(conn, ECOMM);
4430 }
4431
4432 if (skb->len < 2) {
4433 BT_ERR("Frame is too short (len %d)", skb->len);
4434 l2cap_conn_unreliable(conn, ECOMM);
4435 goto drop;
4436 }
4437
4438 hdr = (struct l2cap_hdr *) skb->data;
4439 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
4440
4441 if (len == skb->len) {
4442 /* Complete frame received */
4443 l2cap_recv_frame(conn, skb);
4444 return 0;
4445 }
4446
4447 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
4448
4449 if (skb->len > len) {
4450 BT_ERR("Frame is too long (len %d, expected len %d)",
4451 skb->len, len);
4452 l2cap_conn_unreliable(conn, ECOMM);
4453 goto drop;
4454 }
4455
4456 /* Allocate skb for the complete frame (with header) */
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03004457 conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC);
4458 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004459 goto drop;
4460
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03004461 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004462 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004463 conn->rx_len = len - skb->len;
4464 } else {
4465 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
4466
4467 if (!conn->rx_len) {
4468 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
4469 l2cap_conn_unreliable(conn, ECOMM);
4470 goto drop;
4471 }
4472
4473 if (skb->len > conn->rx_len) {
4474 BT_ERR("Fragment is too long (len %d, expected %d)",
4475 skb->len, conn->rx_len);
4476 kfree_skb(conn->rx_skb);
4477 conn->rx_skb = NULL;
4478 conn->rx_len = 0;
4479 l2cap_conn_unreliable(conn, ECOMM);
4480 goto drop;
4481 }
4482
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03004483 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004484 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004485 conn->rx_len -= skb->len;
4486
4487 if (!conn->rx_len) {
4488 /* Complete frame received */
4489 l2cap_recv_frame(conn, conn->rx_skb);
4490 conn->rx_skb = NULL;
4491 }
4492 }
4493
4494drop:
4495 kfree_skb(skb);
4496 return 0;
4497}
4498
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004499static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004500{
4501 struct sock *sk;
4502 struct hlist_node *node;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004503
4504 read_lock_bh(&l2cap_sk_list.lock);
4505
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004506 sk_for_each(sk, node, &l2cap_sk_list.head) {
4507 struct l2cap_pinfo *pi = l2cap_pi(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004508
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004509 seq_printf(f, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d\n",
4510 batostr(&bt_sk(sk)->src),
4511 batostr(&bt_sk(sk)->dst),
4512 sk->sk_state, __le16_to_cpu(pi->psm),
4513 pi->scid, pi->dcid,
4514 pi->imtu, pi->omtu, pi->sec_level);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004515 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004516
Linus Torvalds1da177e2005-04-16 15:20:36 -07004517 read_unlock_bh(&l2cap_sk_list.lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004518
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004519 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004520}
4521
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004522static int l2cap_debugfs_open(struct inode *inode, struct file *file)
4523{
4524 return single_open(file, l2cap_debugfs_show, inode->i_private);
4525}
4526
4527static const struct file_operations l2cap_debugfs_fops = {
4528 .open = l2cap_debugfs_open,
4529 .read = seq_read,
4530 .llseek = seq_lseek,
4531 .release = single_release,
4532};
4533
4534static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004535
Eric Dumazet90ddc4f2005-12-22 12:49:22 -08004536static const struct proto_ops l2cap_sock_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004537 .family = PF_BLUETOOTH,
4538 .owner = THIS_MODULE,
4539 .release = l2cap_sock_release,
4540 .bind = l2cap_sock_bind,
4541 .connect = l2cap_sock_connect,
4542 .listen = l2cap_sock_listen,
4543 .accept = l2cap_sock_accept,
4544 .getname = l2cap_sock_getname,
4545 .sendmsg = l2cap_sock_sendmsg,
Marcel Holtmannf66dc812009-01-15 21:57:00 +01004546 .recvmsg = l2cap_sock_recvmsg,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004547 .poll = bt_sock_poll,
Marcel Holtmann3241ad82008-07-14 20:13:50 +02004548 .ioctl = bt_sock_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004549 .mmap = sock_no_mmap,
4550 .socketpair = sock_no_socketpair,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004551 .shutdown = l2cap_sock_shutdown,
4552 .setsockopt = l2cap_sock_setsockopt,
4553 .getsockopt = l2cap_sock_getsockopt
4554};
4555
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +00004556static const struct net_proto_family l2cap_sock_family_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004557 .family = PF_BLUETOOTH,
4558 .owner = THIS_MODULE,
4559 .create = l2cap_sock_create,
4560};
4561
4562static struct hci_proto l2cap_hci_proto = {
4563 .name = "L2CAP",
4564 .id = HCI_PROTO_L2CAP,
4565 .connect_ind = l2cap_connect_ind,
4566 .connect_cfm = l2cap_connect_cfm,
4567 .disconn_ind = l2cap_disconn_ind,
Marcel Holtmann2950f212009-02-12 14:02:50 +01004568 .disconn_cfm = l2cap_disconn_cfm,
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004569 .security_cfm = l2cap_security_cfm,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004570 .recv_acldata = l2cap_recv_acldata
4571};
4572
4573static int __init l2cap_init(void)
4574{
4575 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004576
Linus Torvalds1da177e2005-04-16 15:20:36 -07004577 err = proto_register(&l2cap_proto, 0);
4578 if (err < 0)
4579 return err;
4580
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004581 _busy_wq = create_singlethread_workqueue("l2cap");
4582 if (!_busy_wq)
4583 goto error;
4584
Linus Torvalds1da177e2005-04-16 15:20:36 -07004585 err = bt_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops);
4586 if (err < 0) {
4587 BT_ERR("L2CAP socket registration failed");
4588 goto error;
4589 }
4590
4591 err = hci_register_proto(&l2cap_hci_proto);
4592 if (err < 0) {
4593 BT_ERR("L2CAP protocol registration failed");
4594 bt_sock_unregister(BTPROTO_L2CAP);
4595 goto error;
4596 }
4597
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004598 if (bt_debugfs) {
4599 l2cap_debugfs = debugfs_create_file("l2cap", 0444,
4600 bt_debugfs, NULL, &l2cap_debugfs_fops);
4601 if (!l2cap_debugfs)
4602 BT_ERR("Failed to create L2CAP debug file");
4603 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004604
4605 BT_INFO("L2CAP ver %s", VERSION);
4606 BT_INFO("L2CAP socket layer initialized");
4607
4608 return 0;
4609
4610error:
4611 proto_unregister(&l2cap_proto);
4612 return err;
4613}
4614
4615static void __exit l2cap_exit(void)
4616{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004617 debugfs_remove(l2cap_debugfs);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004618
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004619 flush_workqueue(_busy_wq);
4620 destroy_workqueue(_busy_wq);
4621
Linus Torvalds1da177e2005-04-16 15:20:36 -07004622 if (bt_sock_unregister(BTPROTO_L2CAP) < 0)
4623 BT_ERR("L2CAP socket unregistration failed");
4624
4625 if (hci_unregister_proto(&l2cap_hci_proto) < 0)
4626 BT_ERR("L2CAP protocol unregistration failed");
4627
4628 proto_unregister(&l2cap_proto);
4629}
4630
4631void l2cap_load(void)
4632{
4633 /* Dummy function to trigger automatic L2CAP module loading by
4634 * other modules that use L2CAP sockets but don't use any other
4635 * symbols from it. */
4636 return;
4637}
4638EXPORT_SYMBOL(l2cap_load);
4639
4640module_init(l2cap_init);
4641module_exit(l2cap_exit);
4642
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07004643module_param(enable_ertm, bool, 0644);
4644MODULE_PARM_DESC(enable_ertm, "Enable enhanced retransmission mode");
4645
Marcel Holtmann5fbcd3d2009-10-05 11:35:43 +02004646module_param(max_transmit, uint, 0644);
4647MODULE_PARM_DESC(max_transmit, "Max transmit value (default = 3)");
4648
Gustavo F. Padovan369ba302010-05-01 16:15:41 -03004649module_param(tx_window, uint, 0644);
4650MODULE_PARM_DESC(tx_window, "Transmission window size value (default = 63)");
4651
Marcel Holtmann63fbd242008-08-18 13:23:53 +02004652MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004653MODULE_DESCRIPTION("Bluetooth L2CAP ver " VERSION);
4654MODULE_VERSION(VERSION);
4655MODULE_LICENSE("GPL");
4656MODULE_ALIAS("bt-proto-0");