blob: 673a36886716fb036c9dda6e24f26a7506f070c4 [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
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001251 add_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001252 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);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001272 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001273 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. Padovandfc909b2010-05-01 16:15:45 -03001371static void l2cap_retransmit_one_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. Padovandfc909b2010-05-01 16:15:45 -03001470static int l2cap_retransmit_frames(struct sock *sk)
1471{
1472 struct l2cap_pinfo *pi = l2cap_pi(sk);
1473 int ret;
1474
1475 spin_lock_bh(&pi->send_lock);
1476
1477 if (!skb_queue_empty(TX_QUEUE(sk)))
1478 sk->sk_send_head = TX_QUEUE(sk)->next;
1479
1480 pi->next_tx_seq = pi->expected_ack_seq;
1481 ret = l2cap_ertm_send(sk);
1482
1483 spin_unlock_bh(&pi->send_lock);
1484
1485 return ret;
1486}
1487
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001488static void l2cap_send_ack(struct l2cap_pinfo *pi)
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001489{
1490 struct sock *sk = (struct sock *)pi;
1491 u16 control = 0;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001492 int nframes;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001493
1494 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1495
1496 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
1497 control |= L2CAP_SUPER_RCV_NOT_READY;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03001498 pi->conn_state |= L2CAP_CONN_RNR_SENT;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001499 l2cap_send_sframe(pi, control);
1500 return;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001501 }
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001502
1503 spin_lock_bh(&pi->send_lock);
1504 nframes = l2cap_ertm_send(sk);
1505 spin_unlock_bh(&pi->send_lock);
1506
1507 if (nframes > 0)
1508 return;
1509
1510 control |= L2CAP_SUPER_RCV_READY;
1511 l2cap_send_sframe(pi, control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001512}
1513
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001514static void l2cap_send_srejtail(struct sock *sk)
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03001515{
1516 struct srej_list *tail;
1517 u16 control;
1518
1519 control = L2CAP_SUPER_SELECT_REJECT;
1520 control |= L2CAP_CTRL_FINAL;
1521
1522 tail = list_entry(SREJ_LIST(sk)->prev, struct srej_list, list);
1523 control |= tail->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1524
1525 l2cap_send_sframe(l2cap_pi(sk), control);
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03001526}
1527
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001528static 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 -07001529{
1530 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001531 struct sk_buff **frag;
1532 int err, sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001533
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03001534 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001535 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001536
1537 sent += count;
1538 len -= count;
1539
1540 /* Continuation fragments (no L2CAP header) */
1541 frag = &skb_shinfo(skb)->frag_list;
1542 while (len) {
1543 count = min_t(unsigned int, conn->mtu, len);
1544
1545 *frag = bt_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err);
1546 if (!*frag)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001547 return -EFAULT;
1548 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
1549 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001550
1551 sent += count;
1552 len -= count;
1553
1554 frag = &(*frag)->next;
1555 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001556
1557 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001558}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001559
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001560static struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, size_t len)
1561{
1562 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1563 struct sk_buff *skb;
1564 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1565 struct l2cap_hdr *lh;
1566
1567 BT_DBG("sk %p len %d", sk, (int)len);
1568
1569 count = min_t(unsigned int, (conn->mtu - hlen), len);
1570 skb = bt_skb_send_alloc(sk, count + hlen,
1571 msg->msg_flags & MSG_DONTWAIT, &err);
1572 if (!skb)
1573 return ERR_PTR(-ENOMEM);
1574
1575 /* Create L2CAP header */
1576 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1577 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1578 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1579 put_unaligned_le16(l2cap_pi(sk)->psm, skb_put(skb, 2));
1580
1581 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1582 if (unlikely(err < 0)) {
1583 kfree_skb(skb);
1584 return ERR_PTR(err);
1585 }
1586 return skb;
1587}
1588
1589static struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *msg, size_t len)
1590{
1591 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1592 struct sk_buff *skb;
1593 int err, count, hlen = L2CAP_HDR_SIZE;
1594 struct l2cap_hdr *lh;
1595
1596 BT_DBG("sk %p len %d", sk, (int)len);
1597
1598 count = min_t(unsigned int, (conn->mtu - hlen), len);
1599 skb = bt_skb_send_alloc(sk, count + hlen,
1600 msg->msg_flags & MSG_DONTWAIT, &err);
1601 if (!skb)
1602 return ERR_PTR(-ENOMEM);
1603
1604 /* Create L2CAP header */
1605 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1606 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1607 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1608
1609 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1610 if (unlikely(err < 0)) {
1611 kfree_skb(skb);
1612 return ERR_PTR(err);
1613 }
1614 return skb;
1615}
1616
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001617static 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 -03001618{
1619 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1620 struct sk_buff *skb;
1621 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1622 struct l2cap_hdr *lh;
1623
1624 BT_DBG("sk %p len %d", sk, (int)len);
1625
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03001626 if (!conn)
1627 return ERR_PTR(-ENOTCONN);
1628
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001629 if (sdulen)
1630 hlen += 2;
1631
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001632 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1633 hlen += 2;
1634
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001635 count = min_t(unsigned int, (conn->mtu - hlen), len);
1636 skb = bt_skb_send_alloc(sk, count + hlen,
1637 msg->msg_flags & MSG_DONTWAIT, &err);
1638 if (!skb)
1639 return ERR_PTR(-ENOMEM);
1640
1641 /* Create L2CAP header */
1642 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1643 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1644 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1645 put_unaligned_le16(control, skb_put(skb, 2));
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001646 if (sdulen)
1647 put_unaligned_le16(sdulen, skb_put(skb, 2));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001648
1649 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1650 if (unlikely(err < 0)) {
1651 kfree_skb(skb);
1652 return ERR_PTR(err);
1653 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001654
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001655 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1656 put_unaligned_le16(0, skb_put(skb, 2));
1657
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001658 bt_cb(skb)->retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001659 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001660}
1661
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001662static inline int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len)
1663{
1664 struct l2cap_pinfo *pi = l2cap_pi(sk);
1665 struct sk_buff *skb;
1666 struct sk_buff_head sar_queue;
1667 u16 control;
1668 size_t size = 0;
1669
Gustavo F. Padovanff12fd62010-05-05 22:09:15 -03001670 skb_queue_head_init(&sar_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001671 control = L2CAP_SDU_START;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001672 skb = l2cap_create_iframe_pdu(sk, msg, pi->remote_mps, control, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001673 if (IS_ERR(skb))
1674 return PTR_ERR(skb);
1675
1676 __skb_queue_tail(&sar_queue, skb);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001677 len -= pi->remote_mps;
1678 size += pi->remote_mps;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001679
1680 while (len > 0) {
1681 size_t buflen;
1682
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001683 if (len > pi->remote_mps) {
Gustavo F. Padovan44651b82010-05-01 16:15:43 -03001684 control = L2CAP_SDU_CONTINUE;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001685 buflen = pi->remote_mps;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001686 } else {
Gustavo F. Padovan44651b82010-05-01 16:15:43 -03001687 control = L2CAP_SDU_END;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001688 buflen = len;
1689 }
1690
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001691 skb = l2cap_create_iframe_pdu(sk, msg, buflen, control, 0);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001692 if (IS_ERR(skb)) {
1693 skb_queue_purge(&sar_queue);
1694 return PTR_ERR(skb);
1695 }
1696
1697 __skb_queue_tail(&sar_queue, skb);
1698 len -= buflen;
1699 size += buflen;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001700 }
1701 skb_queue_splice_tail(&sar_queue, TX_QUEUE(sk));
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001702 spin_lock_bh(&pi->send_lock);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001703 if (sk->sk_send_head == NULL)
1704 sk->sk_send_head = sar_queue.next;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001705 spin_unlock_bh(&pi->send_lock);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001706
1707 return size;
1708}
1709
Linus Torvalds1da177e2005-04-16 15:20:36 -07001710static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len)
1711{
1712 struct sock *sk = sock->sk;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001713 struct l2cap_pinfo *pi = l2cap_pi(sk);
1714 struct sk_buff *skb;
1715 u16 control;
1716 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001717
1718 BT_DBG("sock %p, sk %p", sock, sk);
1719
Benjamin LaHaisec1cbe4b2005-12-13 23:22:19 -08001720 err = sock_error(sk);
1721 if (err)
1722 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001723
1724 if (msg->msg_flags & MSG_OOB)
1725 return -EOPNOTSUPP;
1726
Linus Torvalds1da177e2005-04-16 15:20:36 -07001727 lock_sock(sk);
1728
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001729 if (sk->sk_state != BT_CONNECTED) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001730 err = -ENOTCONN;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001731 goto done;
1732 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001733
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001734 /* Connectionless channel */
1735 if (sk->sk_type == SOCK_DGRAM) {
1736 skb = l2cap_create_connless_pdu(sk, msg, len);
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001737 if (IS_ERR(skb)) {
Dan Carpenter477fffb2010-04-21 23:52:01 +00001738 err = PTR_ERR(skb);
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001739 } else {
1740 l2cap_do_send(sk, skb);
1741 err = len;
1742 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001743 goto done;
1744 }
1745
1746 switch (pi->mode) {
1747 case L2CAP_MODE_BASIC:
Gustavo F. Padovanc69163e2010-05-01 16:15:35 -03001748 /* Check outgoing MTU */
1749 if (len > pi->omtu) {
1750 err = -EINVAL;
1751 goto done;
1752 }
1753
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001754 /* Create a basic PDU */
1755 skb = l2cap_create_basic_pdu(sk, msg, len);
1756 if (IS_ERR(skb)) {
1757 err = PTR_ERR(skb);
1758 goto done;
1759 }
1760
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001761 l2cap_do_send(sk, skb);
1762 err = len;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001763 break;
1764
1765 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001766 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001767 /* Entire SDU fits into one PDU */
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001768 if (len <= pi->remote_mps) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001769 control = L2CAP_SDU_UNSEGMENTED;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001770 skb = l2cap_create_iframe_pdu(sk, msg, len, control, 0);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001771 if (IS_ERR(skb)) {
1772 err = PTR_ERR(skb);
1773 goto done;
1774 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001775 __skb_queue_tail(TX_QUEUE(sk), skb);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001776
1777 if (pi->mode == L2CAP_MODE_ERTM)
1778 spin_lock_bh(&pi->send_lock);
1779
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001780 if (sk->sk_send_head == NULL)
1781 sk->sk_send_head = skb;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001782
1783 if (pi->mode == L2CAP_MODE_ERTM)
1784 spin_unlock_bh(&pi->send_lock);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001785 } else {
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001786 /* Segment SDU into multiples PDUs */
1787 err = l2cap_sar_segment_sdu(sk, msg, len);
1788 if (err < 0)
1789 goto done;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001790 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001791
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001792 if (pi->mode == L2CAP_MODE_STREAMING) {
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001793 err = l2cap_streaming_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001794 } else {
1795 spin_lock_bh(&pi->send_lock);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001796 err = l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001797 spin_unlock_bh(&pi->send_lock);
1798 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001799
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001800 if (err >= 0)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001801 err = len;
1802 break;
1803
1804 default:
1805 BT_DBG("bad state %1.1x", pi->mode);
1806 err = -EINVAL;
1807 }
1808
1809done:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001810 release_sock(sk);
1811 return err;
1812}
1813
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001814static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags)
1815{
1816 struct sock *sk = sock->sk;
1817
1818 lock_sock(sk);
1819
1820 if (sk->sk_state == BT_CONNECT2 && bt_sk(sk)->defer_setup) {
1821 struct l2cap_conn_rsp rsp;
1822
1823 sk->sk_state = BT_CONFIG;
1824
1825 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
1826 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
1827 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
1828 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
1829 l2cap_send_cmd(l2cap_pi(sk)->conn, l2cap_pi(sk)->ident,
1830 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
1831
1832 release_sock(sk);
1833 return 0;
1834 }
1835
1836 release_sock(sk);
1837
1838 return bt_sock_recvmsg(iocb, sock, msg, len, flags);
1839}
1840
David S. Millerb7058842009-09-30 16:12:20 -07001841static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001842{
1843 struct sock *sk = sock->sk;
1844 struct l2cap_options opts;
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001845 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001846 u32 opt;
1847
1848 BT_DBG("sk %p", sk);
1849
1850 lock_sock(sk);
1851
1852 switch (optname) {
1853 case L2CAP_OPTIONS:
Marcel Holtmann0878b662007-05-05 00:35:59 +02001854 opts.imtu = l2cap_pi(sk)->imtu;
1855 opts.omtu = l2cap_pi(sk)->omtu;
1856 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001857 opts.mode = l2cap_pi(sk)->mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001858 opts.fcs = l2cap_pi(sk)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03001859 opts.max_tx = l2cap_pi(sk)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03001860 opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
Marcel Holtmann0878b662007-05-05 00:35:59 +02001861
Linus Torvalds1da177e2005-04-16 15:20:36 -07001862 len = min_t(unsigned int, sizeof(opts), optlen);
1863 if (copy_from_user((char *) &opts, optval, len)) {
1864 err = -EFAULT;
1865 break;
1866 }
Marcel Holtmann0878b662007-05-05 00:35:59 +02001867
João Paulo Rechi Vita0041ecf2010-05-01 16:15:42 -03001868 l2cap_pi(sk)->mode = opts.mode;
1869 switch (l2cap_pi(sk)->mode) {
1870 case L2CAP_MODE_BASIC:
1871 break;
1872 case L2CAP_MODE_ERTM:
1873 case L2CAP_MODE_STREAMING:
1874 if (enable_ertm)
1875 break;
1876 /* fall through */
1877 default:
1878 err = -EINVAL;
1879 break;
1880 }
1881
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001882 l2cap_pi(sk)->imtu = opts.imtu;
1883 l2cap_pi(sk)->omtu = opts.omtu;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001884 l2cap_pi(sk)->fcs = opts.fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03001885 l2cap_pi(sk)->max_tx = opts.max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03001886 l2cap_pi(sk)->tx_win = (__u8)opts.txwin_size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001887 break;
1888
1889 case L2CAP_LM:
1890 if (get_user(opt, (u32 __user *) optval)) {
1891 err = -EFAULT;
1892 break;
1893 }
1894
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001895 if (opt & L2CAP_LM_AUTH)
1896 l2cap_pi(sk)->sec_level = BT_SECURITY_LOW;
1897 if (opt & L2CAP_LM_ENCRYPT)
1898 l2cap_pi(sk)->sec_level = BT_SECURITY_MEDIUM;
1899 if (opt & L2CAP_LM_SECURE)
1900 l2cap_pi(sk)->sec_level = BT_SECURITY_HIGH;
1901
1902 l2cap_pi(sk)->role_switch = (opt & L2CAP_LM_MASTER);
1903 l2cap_pi(sk)->force_reliable = (opt & L2CAP_LM_RELIABLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001904 break;
1905
1906 default:
1907 err = -ENOPROTOOPT;
1908 break;
1909 }
1910
1911 release_sock(sk);
1912 return err;
1913}
1914
David S. Millerb7058842009-09-30 16:12:20 -07001915static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001916{
1917 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001918 struct bt_security sec;
1919 int len, err = 0;
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001920 u32 opt;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001921
1922 BT_DBG("sk %p", sk);
1923
1924 if (level == SOL_L2CAP)
1925 return l2cap_sock_setsockopt_old(sock, optname, optval, optlen);
1926
Marcel Holtmann0588d942009-01-16 10:06:13 +01001927 if (level != SOL_BLUETOOTH)
1928 return -ENOPROTOOPT;
1929
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001930 lock_sock(sk);
1931
1932 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001933 case BT_SECURITY:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001934 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
1935 && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01001936 err = -EINVAL;
1937 break;
1938 }
1939
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001940 sec.level = BT_SECURITY_LOW;
1941
1942 len = min_t(unsigned int, sizeof(sec), optlen);
1943 if (copy_from_user((char *) &sec, optval, len)) {
1944 err = -EFAULT;
1945 break;
1946 }
1947
1948 if (sec.level < BT_SECURITY_LOW ||
1949 sec.level > BT_SECURITY_HIGH) {
1950 err = -EINVAL;
1951 break;
1952 }
1953
1954 l2cap_pi(sk)->sec_level = sec.level;
1955 break;
1956
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001957 case BT_DEFER_SETUP:
1958 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
1959 err = -EINVAL;
1960 break;
1961 }
1962
1963 if (get_user(opt, (u32 __user *) optval)) {
1964 err = -EFAULT;
1965 break;
1966 }
1967
1968 bt_sk(sk)->defer_setup = opt;
1969 break;
1970
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001971 default:
1972 err = -ENOPROTOOPT;
1973 break;
1974 }
1975
1976 release_sock(sk);
1977 return err;
1978}
1979
1980static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001981{
1982 struct sock *sk = sock->sk;
1983 struct l2cap_options opts;
1984 struct l2cap_conninfo cinfo;
1985 int len, err = 0;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001986 u32 opt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001987
1988 BT_DBG("sk %p", sk);
1989
1990 if (get_user(len, optlen))
1991 return -EFAULT;
1992
1993 lock_sock(sk);
1994
1995 switch (optname) {
1996 case L2CAP_OPTIONS:
1997 opts.imtu = l2cap_pi(sk)->imtu;
1998 opts.omtu = l2cap_pi(sk)->omtu;
1999 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07002000 opts.mode = l2cap_pi(sk)->mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002001 opts.fcs = l2cap_pi(sk)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03002002 opts.max_tx = l2cap_pi(sk)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03002003 opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002004
2005 len = min_t(unsigned int, len, sizeof(opts));
2006 if (copy_to_user(optval, (char *) &opts, len))
2007 err = -EFAULT;
2008
2009 break;
2010
2011 case L2CAP_LM:
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002012 switch (l2cap_pi(sk)->sec_level) {
2013 case BT_SECURITY_LOW:
2014 opt = L2CAP_LM_AUTH;
2015 break;
2016 case BT_SECURITY_MEDIUM:
2017 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT;
2018 break;
2019 case BT_SECURITY_HIGH:
2020 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT |
2021 L2CAP_LM_SECURE;
2022 break;
2023 default:
2024 opt = 0;
2025 break;
2026 }
2027
2028 if (l2cap_pi(sk)->role_switch)
2029 opt |= L2CAP_LM_MASTER;
2030
2031 if (l2cap_pi(sk)->force_reliable)
2032 opt |= L2CAP_LM_RELIABLE;
2033
2034 if (put_user(opt, (u32 __user *) optval))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002035 err = -EFAULT;
2036 break;
2037
2038 case L2CAP_CONNINFO:
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002039 if (sk->sk_state != BT_CONNECTED &&
2040 !(sk->sk_state == BT_CONNECT2 &&
2041 bt_sk(sk)->defer_setup)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002042 err = -ENOTCONN;
2043 break;
2044 }
2045
2046 cinfo.hci_handle = l2cap_pi(sk)->conn->hcon->handle;
2047 memcpy(cinfo.dev_class, l2cap_pi(sk)->conn->hcon->dev_class, 3);
2048
2049 len = min_t(unsigned int, len, sizeof(cinfo));
2050 if (copy_to_user(optval, (char *) &cinfo, len))
2051 err = -EFAULT;
2052
2053 break;
2054
2055 default:
2056 err = -ENOPROTOOPT;
2057 break;
2058 }
2059
2060 release_sock(sk);
2061 return err;
2062}
2063
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002064static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
2065{
2066 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002067 struct bt_security sec;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002068 int len, err = 0;
2069
2070 BT_DBG("sk %p", sk);
2071
2072 if (level == SOL_L2CAP)
2073 return l2cap_sock_getsockopt_old(sock, optname, optval, optlen);
2074
Marcel Holtmann0588d942009-01-16 10:06:13 +01002075 if (level != SOL_BLUETOOTH)
2076 return -ENOPROTOOPT;
2077
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002078 if (get_user(len, optlen))
2079 return -EFAULT;
2080
2081 lock_sock(sk);
2082
2083 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002084 case BT_SECURITY:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03002085 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
2086 && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01002087 err = -EINVAL;
2088 break;
2089 }
2090
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002091 sec.level = l2cap_pi(sk)->sec_level;
2092
2093 len = min_t(unsigned int, len, sizeof(sec));
2094 if (copy_to_user(optval, (char *) &sec, len))
2095 err = -EFAULT;
2096
2097 break;
2098
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002099 case BT_DEFER_SETUP:
2100 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
2101 err = -EINVAL;
2102 break;
2103 }
2104
2105 if (put_user(bt_sk(sk)->defer_setup, (u32 __user *) optval))
2106 err = -EFAULT;
2107
2108 break;
2109
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002110 default:
2111 err = -ENOPROTOOPT;
2112 break;
2113 }
2114
2115 release_sock(sk);
2116 return err;
2117}
2118
Linus Torvalds1da177e2005-04-16 15:20:36 -07002119static int l2cap_sock_shutdown(struct socket *sock, int how)
2120{
2121 struct sock *sk = sock->sk;
2122 int err = 0;
2123
2124 BT_DBG("sock %p, sk %p", sock, sk);
2125
2126 if (!sk)
2127 return 0;
2128
2129 lock_sock(sk);
2130 if (!sk->sk_shutdown) {
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03002131 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
2132 err = __l2cap_wait_ack(sk);
2133
Linus Torvalds1da177e2005-04-16 15:20:36 -07002134 sk->sk_shutdown = SHUTDOWN_MASK;
2135 l2cap_sock_clear_timer(sk);
2136 __l2cap_sock_close(sk, 0);
2137
2138 if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
Marcel Holtmannb1235d72008-07-14 20:13:54 +02002139 err = bt_sock_wait_state(sk, BT_CLOSED,
2140 sk->sk_lingertime);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002141 }
2142 release_sock(sk);
2143 return err;
2144}
2145
2146static int l2cap_sock_release(struct socket *sock)
2147{
2148 struct sock *sk = sock->sk;
2149 int err;
2150
2151 BT_DBG("sock %p, sk %p", sock, sk);
2152
2153 if (!sk)
2154 return 0;
2155
2156 err = l2cap_sock_shutdown(sock, 2);
2157
2158 sock_orphan(sk);
2159 l2cap_sock_kill(sk);
2160 return err;
2161}
2162
Linus Torvalds1da177e2005-04-16 15:20:36 -07002163static void l2cap_chan_ready(struct sock *sk)
2164{
2165 struct sock *parent = bt_sk(sk)->parent;
2166
2167 BT_DBG("sk %p, parent %p", sk, parent);
2168
2169 l2cap_pi(sk)->conf_state = 0;
2170 l2cap_sock_clear_timer(sk);
2171
2172 if (!parent) {
2173 /* Outgoing channel.
2174 * Wake up socket sleeping on connect.
2175 */
2176 sk->sk_state = BT_CONNECTED;
2177 sk->sk_state_change(sk);
2178 } else {
2179 /* Incoming channel.
2180 * Wake up socket sleeping on accept.
2181 */
2182 parent->sk_data_ready(parent, 0);
2183 }
2184}
2185
2186/* Copy frame to all raw sockets on that connection */
2187static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2188{
2189 struct l2cap_chan_list *l = &conn->chan_list;
2190 struct sk_buff *nskb;
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002191 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002192
2193 BT_DBG("conn %p", conn);
2194
2195 read_lock(&l->lock);
2196 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
2197 if (sk->sk_type != SOCK_RAW)
2198 continue;
2199
2200 /* Don't send frame to the socket it came from */
2201 if (skb->sk == sk)
2202 continue;
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002203 nskb = skb_clone(skb, GFP_ATOMIC);
2204 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002205 continue;
2206
2207 if (sock_queue_rcv_skb(sk, nskb))
2208 kfree_skb(nskb);
2209 }
2210 read_unlock(&l->lock);
2211}
2212
2213/* ---- L2CAP signalling commands ---- */
2214static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
2215 u8 code, u8 ident, u16 dlen, void *data)
2216{
2217 struct sk_buff *skb, **frag;
2218 struct l2cap_cmd_hdr *cmd;
2219 struct l2cap_hdr *lh;
2220 int len, count;
2221
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002222 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d",
2223 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002224
2225 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2226 count = min_t(unsigned int, conn->mtu, len);
2227
2228 skb = bt_skb_alloc(count, GFP_ATOMIC);
2229 if (!skb)
2230 return NULL;
2231
2232 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002233 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03002234 lh->cid = cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002235
2236 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2237 cmd->code = code;
2238 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002239 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002240
2241 if (dlen) {
2242 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2243 memcpy(skb_put(skb, count), data, count);
2244 data += count;
2245 }
2246
2247 len -= skb->len;
2248
2249 /* Continuation fragments (no L2CAP header) */
2250 frag = &skb_shinfo(skb)->frag_list;
2251 while (len) {
2252 count = min_t(unsigned int, conn->mtu, len);
2253
2254 *frag = bt_skb_alloc(count, GFP_ATOMIC);
2255 if (!*frag)
2256 goto fail;
2257
2258 memcpy(skb_put(*frag, count), data, count);
2259
2260 len -= count;
2261 data += count;
2262
2263 frag = &(*frag)->next;
2264 }
2265
2266 return skb;
2267
2268fail:
2269 kfree_skb(skb);
2270 return NULL;
2271}
2272
2273static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned long *val)
2274{
2275 struct l2cap_conf_opt *opt = *ptr;
2276 int len;
2277
2278 len = L2CAP_CONF_OPT_SIZE + opt->len;
2279 *ptr += len;
2280
2281 *type = opt->type;
2282 *olen = opt->len;
2283
2284 switch (opt->len) {
2285 case 1:
2286 *val = *((u8 *) opt->val);
2287 break;
2288
2289 case 2:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002290 *val = __le16_to_cpu(*((__le16 *) opt->val));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002291 break;
2292
2293 case 4:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002294 *val = __le32_to_cpu(*((__le32 *) opt->val));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002295 break;
2296
2297 default:
2298 *val = (unsigned long) opt->val;
2299 break;
2300 }
2301
2302 BT_DBG("type 0x%2.2x len %d val 0x%lx", *type, opt->len, *val);
2303 return len;
2304}
2305
Linus Torvalds1da177e2005-04-16 15:20:36 -07002306static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2307{
2308 struct l2cap_conf_opt *opt = *ptr;
2309
2310 BT_DBG("type 0x%2.2x len %d val 0x%lx", type, len, val);
2311
2312 opt->type = type;
2313 opt->len = len;
2314
2315 switch (len) {
2316 case 1:
2317 *((u8 *) opt->val) = val;
2318 break;
2319
2320 case 2:
Al Viro8e036fc2007-07-29 00:16:36 -07002321 *((__le16 *) opt->val) = cpu_to_le16(val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002322 break;
2323
2324 case 4:
Al Viro8e036fc2007-07-29 00:16:36 -07002325 *((__le32 *) opt->val) = cpu_to_le32(val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002326 break;
2327
2328 default:
2329 memcpy(opt->val, (void *) val, len);
2330 break;
2331 }
2332
2333 *ptr += L2CAP_CONF_OPT_SIZE + len;
2334}
2335
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002336static void l2cap_ack_timeout(unsigned long arg)
2337{
2338 struct sock *sk = (void *) arg;
2339
2340 bh_lock_sock(sk);
2341 l2cap_send_ack(l2cap_pi(sk));
2342 bh_unlock_sock(sk);
2343}
2344
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002345static inline void l2cap_ertm_init(struct sock *sk)
2346{
2347 l2cap_pi(sk)->expected_ack_seq = 0;
2348 l2cap_pi(sk)->unacked_frames = 0;
2349 l2cap_pi(sk)->buffer_seq = 0;
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03002350 l2cap_pi(sk)->num_acked = 0;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03002351 l2cap_pi(sk)->frames_sent = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002352
2353 setup_timer(&l2cap_pi(sk)->retrans_timer,
2354 l2cap_retrans_timeout, (unsigned long) sk);
2355 setup_timer(&l2cap_pi(sk)->monitor_timer,
2356 l2cap_monitor_timeout, (unsigned long) sk);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002357 setup_timer(&l2cap_pi(sk)->ack_timer,
2358 l2cap_ack_timeout, (unsigned long) sk);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002359
2360 __skb_queue_head_init(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002361 __skb_queue_head_init(BUSY_QUEUE(sk));
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03002362 spin_lock_init(&l2cap_pi(sk)->send_lock);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002363
2364 INIT_WORK(&l2cap_pi(sk)->busy_work, l2cap_busy_work);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002365}
2366
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002367static int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
2368{
2369 u32 local_feat_mask = l2cap_feat_mask;
2370 if (enable_ertm)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002371 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002372
2373 switch (mode) {
2374 case L2CAP_MODE_ERTM:
2375 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
2376 case L2CAP_MODE_STREAMING:
2377 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
2378 default:
2379 return 0x00;
2380 }
2381}
2382
2383static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
2384{
2385 switch (mode) {
2386 case L2CAP_MODE_STREAMING:
2387 case L2CAP_MODE_ERTM:
2388 if (l2cap_mode_supported(mode, remote_feat_mask))
2389 return mode;
2390 /* fall through */
2391 default:
2392 return L2CAP_MODE_BASIC;
2393 }
2394}
2395
Linus Torvalds1da177e2005-04-16 15:20:36 -07002396static int l2cap_build_conf_req(struct sock *sk, void *data)
2397{
2398 struct l2cap_pinfo *pi = l2cap_pi(sk);
2399 struct l2cap_conf_req *req = data;
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03002400 struct l2cap_conf_rfc rfc = { .mode = pi->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07002401 void *ptr = req->data;
2402
2403 BT_DBG("sk %p", sk);
2404
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002405 if (pi->num_conf_req || pi->num_conf_rsp)
2406 goto done;
2407
2408 switch (pi->mode) {
2409 case L2CAP_MODE_STREAMING:
2410 case L2CAP_MODE_ERTM:
2411 pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002412 if (!l2cap_mode_supported(pi->mode, pi->conn->feat_mask))
2413 l2cap_send_disconn_req(pi->conn, sk);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002414 break;
2415 default:
2416 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
2417 break;
2418 }
2419
2420done:
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002421 switch (pi->mode) {
2422 case L2CAP_MODE_BASIC:
2423 if (pi->imtu != L2CAP_DEFAULT_MTU)
2424 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
2425 break;
2426
2427 case L2CAP_MODE_ERTM:
2428 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03002429 rfc.txwin_size = pi->tx_win;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03002430 rfc.max_transmit = pi->max_tx;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002431 rfc.retrans_timeout = 0;
2432 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002433 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03002434 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002435 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002436
2437 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2438 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002439
2440 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2441 break;
2442
2443 if (pi->fcs == L2CAP_FCS_NONE ||
2444 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
2445 pi->fcs = L2CAP_FCS_NONE;
2446 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
2447 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002448 break;
2449
2450 case L2CAP_MODE_STREAMING:
2451 rfc.mode = L2CAP_MODE_STREAMING;
2452 rfc.txwin_size = 0;
2453 rfc.max_transmit = 0;
2454 rfc.retrans_timeout = 0;
2455 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002456 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03002457 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002458 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002459
2460 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2461 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002462
2463 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2464 break;
2465
2466 if (pi->fcs == L2CAP_FCS_NONE ||
2467 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
2468 pi->fcs = L2CAP_FCS_NONE;
2469 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
2470 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002471 break;
2472 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002473
2474 /* FIXME: Need actual value of the flush timeout */
2475 //if (flush_to != L2CAP_DEFAULT_FLUSH_TO)
2476 // l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2, pi->flush_to);
2477
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002478 req->dcid = cpu_to_le16(pi->dcid);
2479 req->flags = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002480
2481 return ptr - data;
2482}
2483
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002484static int l2cap_parse_conf_req(struct sock *sk, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002485{
2486 struct l2cap_pinfo *pi = l2cap_pi(sk);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002487 struct l2cap_conf_rsp *rsp = data;
2488 void *ptr = rsp->data;
2489 void *req = pi->conf_req;
2490 int len = pi->conf_len;
2491 int type, hint, olen;
2492 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002493 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Marcel Holtmann861d6882007-10-20 13:37:06 +02002494 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002495 u16 result = L2CAP_CONF_SUCCESS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002496
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002497 BT_DBG("sk %p", sk);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01002498
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002499 while (len >= L2CAP_CONF_OPT_SIZE) {
2500 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002501
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03002502 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07002503 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002504
2505 switch (type) {
2506 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002507 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002508 break;
2509
2510 case L2CAP_CONF_FLUSH_TO:
2511 pi->flush_to = val;
2512 break;
2513
2514 case L2CAP_CONF_QOS:
2515 break;
2516
Marcel Holtmann6464f352007-10-20 13:39:51 +02002517 case L2CAP_CONF_RFC:
2518 if (olen == sizeof(rfc))
2519 memcpy(&rfc, (void *) val, olen);
2520 break;
2521
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002522 case L2CAP_CONF_FCS:
2523 if (val == L2CAP_FCS_NONE)
2524 pi->conf_state |= L2CAP_CONF_NO_FCS_RECV;
2525
2526 break;
2527
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002528 default:
2529 if (hint)
2530 break;
2531
2532 result = L2CAP_CONF_UNKNOWN;
2533 *((u8 *) ptr++) = type;
2534 break;
2535 }
2536 }
2537
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002538 if (pi->num_conf_rsp || pi->num_conf_req)
2539 goto done;
2540
2541 switch (pi->mode) {
2542 case L2CAP_MODE_STREAMING:
2543 case L2CAP_MODE_ERTM:
2544 pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
2545 if (!l2cap_mode_supported(pi->mode, pi->conn->feat_mask))
2546 return -ECONNREFUSED;
2547 break;
2548 default:
2549 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
2550 break;
2551 }
2552
2553done:
2554 if (pi->mode != rfc.mode) {
2555 result = L2CAP_CONF_UNACCEPT;
2556 rfc.mode = pi->mode;
2557
2558 if (pi->num_conf_rsp == 1)
2559 return -ECONNREFUSED;
2560
2561 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2562 sizeof(rfc), (unsigned long) &rfc);
2563 }
2564
2565
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002566 if (result == L2CAP_CONF_SUCCESS) {
2567 /* Configure output options and let the other side know
2568 * which ones we don't like. */
2569
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002570 if (mtu < L2CAP_DEFAULT_MIN_MTU)
2571 result = L2CAP_CONF_UNACCEPT;
2572 else {
2573 pi->omtu = mtu;
2574 pi->conf_state |= L2CAP_CONF_MTU_DONE;
2575 }
2576 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002577
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002578 switch (rfc.mode) {
2579 case L2CAP_MODE_BASIC:
2580 pi->fcs = L2CAP_FCS_NONE;
2581 pi->conf_state |= L2CAP_CONF_MODE_DONE;
2582 break;
2583
2584 case L2CAP_MODE_ERTM:
2585 pi->remote_tx_win = rfc.txwin_size;
2586 pi->remote_max_tx = rfc.max_transmit;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002587 if (rfc.max_pdu_size > pi->conn->mtu - 10)
2588 rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10);
2589
2590 pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002591
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002592 rfc.retrans_timeout =
2593 le16_to_cpu(L2CAP_DEFAULT_RETRANS_TO);
2594 rfc.monitor_timeout =
2595 le16_to_cpu(L2CAP_DEFAULT_MONITOR_TO);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002596
2597 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03002598
2599 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2600 sizeof(rfc), (unsigned long) &rfc);
2601
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002602 break;
2603
2604 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002605 if (rfc.max_pdu_size > pi->conn->mtu - 10)
2606 rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10);
2607
2608 pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002609
2610 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03002611
2612 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2613 sizeof(rfc), (unsigned long) &rfc);
2614
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002615 break;
2616
2617 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02002618 result = L2CAP_CONF_UNACCEPT;
2619
2620 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002621 rfc.mode = pi->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002622 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002623
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002624 if (result == L2CAP_CONF_SUCCESS)
2625 pi->conf_state |= L2CAP_CONF_OUTPUT_DONE;
2626 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002627 rsp->scid = cpu_to_le16(pi->dcid);
2628 rsp->result = cpu_to_le16(result);
2629 rsp->flags = cpu_to_le16(0x0000);
2630
2631 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002632}
2633
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002634static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data, u16 *result)
2635{
2636 struct l2cap_pinfo *pi = l2cap_pi(sk);
2637 struct l2cap_conf_req *req = data;
2638 void *ptr = req->data;
2639 int type, olen;
2640 unsigned long val;
2641 struct l2cap_conf_rfc rfc;
2642
2643 BT_DBG("sk %p, rsp %p, len %d, req %p", sk, rsp, len, data);
2644
2645 while (len >= L2CAP_CONF_OPT_SIZE) {
2646 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
2647
2648 switch (type) {
2649 case L2CAP_CONF_MTU:
2650 if (val < L2CAP_DEFAULT_MIN_MTU) {
2651 *result = L2CAP_CONF_UNACCEPT;
2652 pi->omtu = L2CAP_DEFAULT_MIN_MTU;
2653 } else
2654 pi->omtu = val;
2655 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
2656 break;
2657
2658 case L2CAP_CONF_FLUSH_TO:
2659 pi->flush_to = val;
2660 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
2661 2, pi->flush_to);
2662 break;
2663
2664 case L2CAP_CONF_RFC:
2665 if (olen == sizeof(rfc))
2666 memcpy(&rfc, (void *)val, olen);
2667
2668 if ((pi->conf_state & L2CAP_CONF_STATE2_DEVICE) &&
2669 rfc.mode != pi->mode)
2670 return -ECONNREFUSED;
2671
2672 pi->mode = rfc.mode;
2673 pi->fcs = 0;
2674
2675 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2676 sizeof(rfc), (unsigned long) &rfc);
2677 break;
2678 }
2679 }
2680
2681 if (*result == L2CAP_CONF_SUCCESS) {
2682 switch (rfc.mode) {
2683 case L2CAP_MODE_ERTM:
2684 pi->remote_tx_win = rfc.txwin_size;
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002685 pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
2686 pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002687 pi->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002688 break;
2689 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002690 pi->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002691 }
2692 }
2693
2694 req->dcid = cpu_to_le16(pi->dcid);
2695 req->flags = cpu_to_le16(0x0000);
2696
2697 return ptr - data;
2698}
2699
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002700static int l2cap_build_conf_rsp(struct sock *sk, void *data, u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002701{
2702 struct l2cap_conf_rsp *rsp = data;
2703 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002704
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002705 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002706
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002707 rsp->scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002708 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002709 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002710
2711 return ptr - data;
2712}
2713
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002714static void l2cap_conf_rfc_get(struct sock *sk, void *rsp, int len)
2715{
2716 struct l2cap_pinfo *pi = l2cap_pi(sk);
2717 int type, olen;
2718 unsigned long val;
2719 struct l2cap_conf_rfc rfc;
2720
2721 BT_DBG("sk %p, rsp %p, len %d", sk, rsp, len);
2722
2723 if ((pi->mode != L2CAP_MODE_ERTM) && (pi->mode != L2CAP_MODE_STREAMING))
2724 return;
2725
2726 while (len >= L2CAP_CONF_OPT_SIZE) {
2727 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
2728
2729 switch (type) {
2730 case L2CAP_CONF_RFC:
2731 if (olen == sizeof(rfc))
2732 memcpy(&rfc, (void *)val, olen);
2733 goto done;
2734 }
2735 }
2736
2737done:
2738 switch (rfc.mode) {
2739 case L2CAP_MODE_ERTM:
2740 pi->remote_tx_win = rfc.txwin_size;
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002741 pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
2742 pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002743 pi->mps = le16_to_cpu(rfc.max_pdu_size);
2744 break;
2745 case L2CAP_MODE_STREAMING:
2746 pi->mps = le16_to_cpu(rfc.max_pdu_size);
2747 }
2748}
2749
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002750static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2751{
2752 struct l2cap_cmd_rej *rej = (struct l2cap_cmd_rej *) data;
2753
2754 if (rej->reason != 0x0000)
2755 return 0;
2756
2757 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
2758 cmd->ident == conn->info_ident) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002759 del_timer(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01002760
2761 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002762 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01002763
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002764 l2cap_conn_start(conn);
2765 }
2766
2767 return 0;
2768}
2769
Linus Torvalds1da177e2005-04-16 15:20:36 -07002770static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2771{
2772 struct l2cap_chan_list *list = &conn->chan_list;
2773 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
2774 struct l2cap_conn_rsp rsp;
2775 struct sock *sk, *parent;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002776 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002777
2778 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002779 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002780
2781 BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
2782
2783 /* Check if we have socket listening on psm */
2784 parent = l2cap_get_sock_by_psm(BT_LISTEN, psm, conn->src);
2785 if (!parent) {
2786 result = L2CAP_CR_BAD_PSM;
2787 goto sendresp;
2788 }
2789
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002790 /* Check if the ACL is secure enough (if not SDP) */
2791 if (psm != cpu_to_le16(0x0001) &&
2792 !hci_conn_check_link_mode(conn->hcon)) {
Marcel Holtmann2950f212009-02-12 14:02:50 +01002793 conn->disc_reason = 0x05;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002794 result = L2CAP_CR_SEC_BLOCK;
2795 goto response;
2796 }
2797
Linus Torvalds1da177e2005-04-16 15:20:36 -07002798 result = L2CAP_CR_NO_MEM;
2799
2800 /* Check for backlog size */
2801 if (sk_acceptq_is_full(parent)) {
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09002802 BT_DBG("backlog full %d", parent->sk_ack_backlog);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002803 goto response;
2804 }
2805
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09002806 sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002807 if (!sk)
2808 goto response;
2809
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002810 write_lock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002811
2812 /* Check if we already have channel with that dcid */
2813 if (__l2cap_get_chan_by_dcid(list, scid)) {
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002814 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002815 sock_set_flag(sk, SOCK_ZAPPED);
2816 l2cap_sock_kill(sk);
2817 goto response;
2818 }
2819
2820 hci_conn_hold(conn->hcon);
2821
2822 l2cap_sock_init(sk, parent);
2823 bacpy(&bt_sk(sk)->src, conn->src);
2824 bacpy(&bt_sk(sk)->dst, conn->dst);
2825 l2cap_pi(sk)->psm = psm;
2826 l2cap_pi(sk)->dcid = scid;
2827
2828 __l2cap_chan_add(conn, sk, parent);
2829 dcid = l2cap_pi(sk)->scid;
2830
2831 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
2832
Linus Torvalds1da177e2005-04-16 15:20:36 -07002833 l2cap_pi(sk)->ident = cmd->ident;
2834
Marcel Holtmann984947d2009-02-06 23:35:19 +01002835 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002836 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002837 if (bt_sk(sk)->defer_setup) {
2838 sk->sk_state = BT_CONNECT2;
2839 result = L2CAP_CR_PEND;
2840 status = L2CAP_CS_AUTHOR_PEND;
2841 parent->sk_data_ready(parent, 0);
2842 } else {
2843 sk->sk_state = BT_CONFIG;
2844 result = L2CAP_CR_SUCCESS;
2845 status = L2CAP_CS_NO_INFO;
2846 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002847 } else {
2848 sk->sk_state = BT_CONNECT2;
2849 result = L2CAP_CR_PEND;
2850 status = L2CAP_CS_AUTHEN_PEND;
2851 }
2852 } else {
2853 sk->sk_state = BT_CONNECT2;
2854 result = L2CAP_CR_PEND;
2855 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002856 }
2857
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002858 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002859
2860response:
2861 bh_unlock_sock(parent);
2862
2863sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002864 rsp.scid = cpu_to_le16(scid);
2865 rsp.dcid = cpu_to_le16(dcid);
2866 rsp.result = cpu_to_le16(result);
2867 rsp.status = cpu_to_le16(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002868 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002869
2870 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
2871 struct l2cap_info_req info;
2872 info.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
2873
2874 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
2875 conn->info_ident = l2cap_get_ident(conn);
2876
2877 mod_timer(&conn->info_timer, jiffies +
2878 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
2879
2880 l2cap_send_cmd(conn, conn->info_ident,
2881 L2CAP_INFO_REQ, sizeof(info), &info);
2882 }
2883
Linus Torvalds1da177e2005-04-16 15:20:36 -07002884 return 0;
2885}
2886
2887static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2888{
2889 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
2890 u16 scid, dcid, result, status;
2891 struct sock *sk;
2892 u8 req[128];
2893
2894 scid = __le16_to_cpu(rsp->scid);
2895 dcid = __le16_to_cpu(rsp->dcid);
2896 result = __le16_to_cpu(rsp->result);
2897 status = __le16_to_cpu(rsp->status);
2898
2899 BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
2900
2901 if (scid) {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002902 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2903 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002904 return 0;
2905 } else {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002906 sk = l2cap_get_chan_by_ident(&conn->chan_list, cmd->ident);
2907 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002908 return 0;
2909 }
2910
2911 switch (result) {
2912 case L2CAP_CR_SUCCESS:
2913 sk->sk_state = BT_CONFIG;
2914 l2cap_pi(sk)->ident = 0;
2915 l2cap_pi(sk)->dcid = dcid;
2916 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
2917
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002918 l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_CONNECT_PEND;
2919
Linus Torvalds1da177e2005-04-16 15:20:36 -07002920 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
2921 l2cap_build_conf_req(sk, req), req);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002922 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002923 break;
2924
2925 case L2CAP_CR_PEND:
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002926 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002927 break;
2928
2929 default:
2930 l2cap_chan_del(sk, ECONNREFUSED);
2931 break;
2932 }
2933
2934 bh_unlock_sock(sk);
2935 return 0;
2936}
2937
Al Viro88219a02007-07-29 00:17:25 -07002938static 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 -07002939{
2940 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
2941 u16 dcid, flags;
2942 u8 rsp[64];
2943 struct sock *sk;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002944 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002945
2946 dcid = __le16_to_cpu(req->dcid);
2947 flags = __le16_to_cpu(req->flags);
2948
2949 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
2950
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002951 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
2952 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002953 return -ENOENT;
2954
Marcel Holtmann354f60a2006-11-18 22:15:20 +01002955 if (sk->sk_state == BT_DISCONN)
2956 goto unlock;
2957
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002958 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07002959 len = cmd_len - sizeof(*req);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002960 if (l2cap_pi(sk)->conf_len + len > sizeof(l2cap_pi(sk)->conf_req)) {
2961 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
2962 l2cap_build_conf_rsp(sk, rsp,
2963 L2CAP_CONF_REJECT, flags), rsp);
2964 goto unlock;
2965 }
2966
2967 /* Store config. */
2968 memcpy(l2cap_pi(sk)->conf_req + l2cap_pi(sk)->conf_len, req->data, len);
2969 l2cap_pi(sk)->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002970
2971 if (flags & 0x0001) {
2972 /* Incomplete config. Send empty response. */
2973 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002974 l2cap_build_conf_rsp(sk, rsp,
2975 L2CAP_CONF_SUCCESS, 0x0001), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002976 goto unlock;
2977 }
2978
2979 /* Complete config. */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002980 len = l2cap_parse_conf_req(sk, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002981 if (len < 0) {
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002982 l2cap_send_disconn_req(conn, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002983 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002984 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002985
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002986 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002987 l2cap_pi(sk)->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002988
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002989 /* Reset config buffer. */
2990 l2cap_pi(sk)->conf_len = 0;
2991
Marcel Holtmann876d9482007-10-20 13:35:42 +02002992 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE))
2993 goto unlock;
2994
Linus Torvalds1da177e2005-04-16 15:20:36 -07002995 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) {
Joe Perchesf64f9e72009-11-29 16:55:45 -08002996 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) ||
2997 l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002998 l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
2999
Linus Torvalds1da177e2005-04-16 15:20:36 -07003000 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003001
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003002 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003003 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003004 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003005 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
3006 l2cap_ertm_init(sk);
3007
Linus Torvalds1da177e2005-04-16 15:20:36 -07003008 l2cap_chan_ready(sk);
Marcel Holtmann876d9482007-10-20 13:35:42 +02003009 goto unlock;
3010 }
3011
3012 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003013 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003014 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003015 l2cap_build_conf_req(sk, buf), buf);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003016 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003017 }
3018
3019unlock:
3020 bh_unlock_sock(sk);
3021 return 0;
3022}
3023
3024static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3025{
3026 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
3027 u16 scid, flags, result;
3028 struct sock *sk;
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003029 int len = cmd->len - sizeof(*rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003030
3031 scid = __le16_to_cpu(rsp->scid);
3032 flags = __le16_to_cpu(rsp->flags);
3033 result = __le16_to_cpu(rsp->result);
3034
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003035 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x",
3036 scid, flags, result);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003037
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003038 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
3039 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003040 return 0;
3041
3042 switch (result) {
3043 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003044 l2cap_conf_rfc_get(sk, rsp->data, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003045 break;
3046
3047 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003048 if (l2cap_pi(sk)->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003049 char req[64];
3050
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02003051 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
3052 l2cap_send_disconn_req(conn, sk);
3053 goto done;
3054 }
3055
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003056 /* throw out any old stored conf requests */
3057 result = L2CAP_CONF_SUCCESS;
3058 len = l2cap_parse_conf_rsp(sk, rsp->data,
3059 len, req, &result);
3060 if (len < 0) {
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03003061 l2cap_send_disconn_req(conn, sk);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003062 goto done;
3063 }
3064
3065 l2cap_send_cmd(conn, l2cap_get_ident(conn),
3066 L2CAP_CONF_REQ, len, req);
3067 l2cap_pi(sk)->num_conf_req++;
3068 if (result != L2CAP_CONF_SUCCESS)
3069 goto done;
3070 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003071 }
3072
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09003073 default:
Linus Torvalds1da177e2005-04-16 15:20:36 -07003074 sk->sk_state = BT_DISCONN;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02003075 sk->sk_err = ECONNRESET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003076 l2cap_sock_set_timer(sk, HZ * 5);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03003077 l2cap_send_disconn_req(conn, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003078 goto done;
3079 }
3080
3081 if (flags & 0x01)
3082 goto done;
3083
Linus Torvalds1da177e2005-04-16 15:20:36 -07003084 l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE;
3085
3086 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) {
Joe Perchesf64f9e72009-11-29 16:55:45 -08003087 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) ||
3088 l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003089 l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
3090
Linus Torvalds1da177e2005-04-16 15:20:36 -07003091 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003092 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003093 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003094 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003095 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
3096 l2cap_ertm_init(sk);
3097
Linus Torvalds1da177e2005-04-16 15:20:36 -07003098 l2cap_chan_ready(sk);
3099 }
3100
3101done:
3102 bh_unlock_sock(sk);
3103 return 0;
3104}
3105
3106static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3107{
3108 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
3109 struct l2cap_disconn_rsp rsp;
3110 u16 dcid, scid;
3111 struct sock *sk;
3112
3113 scid = __le16_to_cpu(req->scid);
3114 dcid = __le16_to_cpu(req->dcid);
3115
3116 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
3117
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003118 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
3119 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003120 return 0;
3121
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003122 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
3123 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003124 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
3125
3126 sk->sk_shutdown = SHUTDOWN_MASK;
3127
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003128 skb_queue_purge(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003129
3130 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
3131 skb_queue_purge(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003132 skb_queue_purge(BUSY_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003133 del_timer(&l2cap_pi(sk)->retrans_timer);
3134 del_timer(&l2cap_pi(sk)->monitor_timer);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003135 del_timer(&l2cap_pi(sk)->ack_timer);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003136 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003137
Linus Torvalds1da177e2005-04-16 15:20:36 -07003138 l2cap_chan_del(sk, ECONNRESET);
3139 bh_unlock_sock(sk);
3140
3141 l2cap_sock_kill(sk);
3142 return 0;
3143}
3144
3145static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3146{
3147 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
3148 u16 dcid, scid;
3149 struct sock *sk;
3150
3151 scid = __le16_to_cpu(rsp->scid);
3152 dcid = __le16_to_cpu(rsp->dcid);
3153
3154 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
3155
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003156 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
3157 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003158 return 0;
3159
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003160 skb_queue_purge(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003161
3162 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
3163 skb_queue_purge(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003164 skb_queue_purge(BUSY_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003165 del_timer(&l2cap_pi(sk)->retrans_timer);
3166 del_timer(&l2cap_pi(sk)->monitor_timer);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003167 del_timer(&l2cap_pi(sk)->ack_timer);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003168 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003169
Linus Torvalds1da177e2005-04-16 15:20:36 -07003170 l2cap_chan_del(sk, 0);
3171 bh_unlock_sock(sk);
3172
3173 l2cap_sock_kill(sk);
3174 return 0;
3175}
3176
3177static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3178{
3179 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003180 u16 type;
3181
3182 type = __le16_to_cpu(req->type);
3183
3184 BT_DBG("type 0x%4.4x", type);
3185
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003186 if (type == L2CAP_IT_FEAT_MASK) {
3187 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003188 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003189 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
3190 rsp->type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
3191 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003192 if (enable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003193 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
3194 | L2CAP_FEAT_FCS;
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03003195 put_unaligned_le32(feat_mask, rsp->data);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003196 l2cap_send_cmd(conn, cmd->ident,
3197 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003198 } else if (type == L2CAP_IT_FIXED_CHAN) {
3199 u8 buf[12];
3200 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
3201 rsp->type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3202 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
3203 memcpy(buf + 4, l2cap_fixed_chan, 8);
3204 l2cap_send_cmd(conn, cmd->ident,
3205 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003206 } else {
3207 struct l2cap_info_rsp rsp;
3208 rsp.type = cpu_to_le16(type);
3209 rsp.result = cpu_to_le16(L2CAP_IR_NOTSUPP);
3210 l2cap_send_cmd(conn, cmd->ident,
3211 L2CAP_INFO_RSP, sizeof(rsp), &rsp);
3212 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003213
3214 return 0;
3215}
3216
3217static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3218{
3219 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
3220 u16 type, result;
3221
3222 type = __le16_to_cpu(rsp->type);
3223 result = __le16_to_cpu(rsp->result);
3224
3225 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
3226
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003227 del_timer(&conn->info_timer);
3228
Marcel Holtmann984947d2009-02-06 23:35:19 +01003229 if (type == L2CAP_IT_FEAT_MASK) {
Harvey Harrison83985312008-05-02 16:25:46 -07003230 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003231
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003232 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003233 struct l2cap_info_req req;
3234 req.type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3235
3236 conn->info_ident = l2cap_get_ident(conn);
3237
3238 l2cap_send_cmd(conn, conn->info_ident,
3239 L2CAP_INFO_REQ, sizeof(req), &req);
3240 } else {
3241 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
3242 conn->info_ident = 0;
3243
3244 l2cap_conn_start(conn);
3245 }
3246 } else if (type == L2CAP_IT_FIXED_CHAN) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01003247 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003248 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003249
3250 l2cap_conn_start(conn);
3251 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003252
Linus Torvalds1da177e2005-04-16 15:20:36 -07003253 return 0;
3254}
3255
3256static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
3257{
3258 u8 *data = skb->data;
3259 int len = skb->len;
3260 struct l2cap_cmd_hdr cmd;
3261 int err = 0;
3262
3263 l2cap_raw_recv(conn, skb);
3264
3265 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07003266 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003267 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
3268 data += L2CAP_CMD_HDR_SIZE;
3269 len -= L2CAP_CMD_HDR_SIZE;
3270
Al Viro88219a02007-07-29 00:17:25 -07003271 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003272
Al Viro88219a02007-07-29 00:17:25 -07003273 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 -07003274
Al Viro88219a02007-07-29 00:17:25 -07003275 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003276 BT_DBG("corrupted command");
3277 break;
3278 }
3279
3280 switch (cmd.code) {
3281 case L2CAP_COMMAND_REJ:
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003282 l2cap_command_rej(conn, &cmd, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003283 break;
3284
3285 case L2CAP_CONN_REQ:
3286 err = l2cap_connect_req(conn, &cmd, data);
3287 break;
3288
3289 case L2CAP_CONN_RSP:
3290 err = l2cap_connect_rsp(conn, &cmd, data);
3291 break;
3292
3293 case L2CAP_CONF_REQ:
Al Viro88219a02007-07-29 00:17:25 -07003294 err = l2cap_config_req(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003295 break;
3296
3297 case L2CAP_CONF_RSP:
3298 err = l2cap_config_rsp(conn, &cmd, data);
3299 break;
3300
3301 case L2CAP_DISCONN_REQ:
3302 err = l2cap_disconnect_req(conn, &cmd, data);
3303 break;
3304
3305 case L2CAP_DISCONN_RSP:
3306 err = l2cap_disconnect_rsp(conn, &cmd, data);
3307 break;
3308
3309 case L2CAP_ECHO_REQ:
Al Viro88219a02007-07-29 00:17:25 -07003310 l2cap_send_cmd(conn, cmd.ident, L2CAP_ECHO_RSP, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003311 break;
3312
3313 case L2CAP_ECHO_RSP:
3314 break;
3315
3316 case L2CAP_INFO_REQ:
3317 err = l2cap_information_req(conn, &cmd, data);
3318 break;
3319
3320 case L2CAP_INFO_RSP:
3321 err = l2cap_information_rsp(conn, &cmd, data);
3322 break;
3323
3324 default:
3325 BT_ERR("Unknown signaling command 0x%2.2x", cmd.code);
3326 err = -EINVAL;
3327 break;
3328 }
3329
3330 if (err) {
3331 struct l2cap_cmd_rej rej;
3332 BT_DBG("error %d", err);
3333
3334 /* FIXME: Map err to a valid reason */
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003335 rej.reason = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003336 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
3337 }
3338
Al Viro88219a02007-07-29 00:17:25 -07003339 data += cmd_len;
3340 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003341 }
3342
3343 kfree_skb(skb);
3344}
3345
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003346static int l2cap_check_fcs(struct l2cap_pinfo *pi, struct sk_buff *skb)
3347{
3348 u16 our_fcs, rcv_fcs;
3349 int hdr_size = L2CAP_HDR_SIZE + 2;
3350
3351 if (pi->fcs == L2CAP_FCS_CRC16) {
3352 skb_trim(skb, skb->len - 2);
3353 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
3354 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
3355
3356 if (our_fcs != rcv_fcs)
3357 return -EINVAL;
3358 }
3359 return 0;
3360}
3361
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003362static inline void l2cap_send_i_or_rr_or_rnr(struct sock *sk)
3363{
3364 struct l2cap_pinfo *pi = l2cap_pi(sk);
3365 u16 control = 0;
3366
3367 pi->frames_sent = 0;
3368 pi->conn_state |= L2CAP_CONN_SEND_FBIT;
3369
3370 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3371
3372 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
3373 control |= L2CAP_SUPER_RCV_NOT_READY | L2CAP_CTRL_FINAL;
3374 l2cap_send_sframe(pi, control);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003375 pi->conn_state |= L2CAP_CONN_RNR_SENT;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003376 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
3377 }
3378
3379 if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY && pi->unacked_frames > 0)
3380 __mod_retrans_timer();
3381
Gustavo F. Padovan844c0972010-05-04 23:16:01 -03003382 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3383
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003384 spin_lock_bh(&pi->send_lock);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003385 l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003386 spin_unlock_bh(&pi->send_lock);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003387
3388 if (!(pi->conn_state & L2CAP_CONN_LOCAL_BUSY) &&
3389 pi->frames_sent == 0) {
3390 control |= L2CAP_SUPER_RCV_READY;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003391 l2cap_send_sframe(pi, control);
3392 }
3393}
3394
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003395static 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 -03003396{
3397 struct sk_buff *next_skb;
3398
3399 bt_cb(skb)->tx_seq = tx_seq;
3400 bt_cb(skb)->sar = sar;
3401
3402 next_skb = skb_peek(SREJ_QUEUE(sk));
3403 if (!next_skb) {
3404 __skb_queue_tail(SREJ_QUEUE(sk), skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003405 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003406 }
3407
3408 do {
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003409 if (bt_cb(next_skb)->tx_seq == tx_seq)
3410 return -EINVAL;
3411
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003412 if (bt_cb(next_skb)->tx_seq > tx_seq) {
3413 __skb_queue_before(SREJ_QUEUE(sk), next_skb, skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003414 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003415 }
3416
3417 if (skb_queue_is_last(SREJ_QUEUE(sk), next_skb))
3418 break;
3419
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003420 } while ((next_skb = skb_queue_next(SREJ_QUEUE(sk), next_skb)));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003421
3422 __skb_queue_tail(SREJ_QUEUE(sk), skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003423
3424 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003425}
3426
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003427static int l2cap_ertm_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
3428{
3429 struct l2cap_pinfo *pi = l2cap_pi(sk);
3430 struct sk_buff *_skb;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003431 int err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003432
3433 switch (control & L2CAP_CTRL_SAR) {
3434 case L2CAP_SDU_UNSEGMENTED:
3435 if (pi->conn_state & L2CAP_CONN_SAR_SDU)
3436 goto drop;
3437
3438 err = sock_queue_rcv_skb(sk, skb);
3439 if (!err)
3440 return err;
3441
3442 break;
3443
3444 case L2CAP_SDU_START:
3445 if (pi->conn_state & L2CAP_CONN_SAR_SDU)
3446 goto drop;
3447
3448 pi->sdu_len = get_unaligned_le16(skb->data);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003449
3450 if (pi->sdu_len > pi->imtu)
3451 goto disconnect;
3452
3453 pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003454 if (!pi->sdu)
3455 return -ENOMEM;
3456
3457 /* pull sdu_len bytes only after alloc, because of Local Busy
3458 * condition we have to be sure that this will be executed
3459 * only once, i.e., when alloc does not fail */
3460 skb_pull(skb, 2);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003461
3462 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3463
3464 pi->conn_state |= L2CAP_CONN_SAR_SDU;
3465 pi->partial_sdu_len = skb->len;
3466 break;
3467
3468 case L2CAP_SDU_CONTINUE:
3469 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3470 goto disconnect;
3471
3472 if (!pi->sdu)
3473 goto disconnect;
3474
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003475 pi->partial_sdu_len += skb->len;
3476 if (pi->partial_sdu_len > pi->sdu_len)
3477 goto drop;
3478
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03003479 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3480
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003481 break;
3482
3483 case L2CAP_SDU_END:
3484 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3485 goto disconnect;
3486
3487 if (!pi->sdu)
3488 goto disconnect;
3489
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003490 if (!(pi->conn_state & L2CAP_CONN_SAR_RETRY)) {
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003491 pi->partial_sdu_len += skb->len;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003492
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003493 if (pi->partial_sdu_len > pi->imtu)
3494 goto drop;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003495
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003496 if (pi->partial_sdu_len != pi->sdu_len)
3497 goto drop;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03003498
3499 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003500 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003501
3502 _skb = skb_clone(pi->sdu, GFP_ATOMIC);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003503 if (!_skb) {
3504 pi->conn_state |= L2CAP_CONN_SAR_RETRY;
3505 return -ENOMEM;
3506 }
3507
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003508 err = sock_queue_rcv_skb(sk, _skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003509 if (err < 0) {
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003510 kfree_skb(_skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003511 pi->conn_state |= L2CAP_CONN_SAR_RETRY;
3512 return err;
3513 }
3514
3515 pi->conn_state &= ~L2CAP_CONN_SAR_RETRY;
3516 pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003517
3518 kfree_skb(pi->sdu);
3519 break;
3520 }
3521
3522 kfree_skb(skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003523 return 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003524
3525drop:
3526 kfree_skb(pi->sdu);
3527 pi->sdu = NULL;
3528
3529disconnect:
3530 l2cap_send_disconn_req(pi->conn, sk);
3531 kfree_skb(skb);
3532 return 0;
3533}
3534
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003535static void l2cap_busy_work(struct work_struct *work)
3536{
3537 DECLARE_WAITQUEUE(wait, current);
3538 struct l2cap_pinfo *pi =
3539 container_of(work, struct l2cap_pinfo, busy_work);
3540 struct sock *sk = (struct sock *)pi;
3541 int n_tries = 0, timeo = HZ/5, err;
3542 struct sk_buff *skb;
3543 u16 control;
3544
3545 lock_sock(sk);
3546
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02003547 add_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003548 while ((skb = skb_peek(BUSY_QUEUE(sk)))) {
3549 set_current_state(TASK_INTERRUPTIBLE);
3550
3551 if (n_tries++ > L2CAP_LOCAL_BUSY_TRIES) {
3552 err = -EBUSY;
3553 l2cap_send_disconn_req(pi->conn, sk);
3554 goto done;
3555 }
3556
3557 if (!timeo)
3558 timeo = HZ/5;
3559
3560 if (signal_pending(current)) {
3561 err = sock_intr_errno(timeo);
3562 goto done;
3563 }
3564
3565 release_sock(sk);
3566 timeo = schedule_timeout(timeo);
3567 lock_sock(sk);
3568
3569 err = sock_error(sk);
3570 if (err)
3571 goto done;
3572
3573 while ((skb = skb_dequeue(BUSY_QUEUE(sk)))) {
3574 control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
3575 err = l2cap_ertm_reassembly_sdu(sk, skb, control);
3576 if (err < 0) {
3577 skb_queue_head(BUSY_QUEUE(sk), skb);
3578 break;
3579 }
3580
3581 pi->buffer_seq = (pi->buffer_seq + 1) % 64;
3582 }
3583
3584 if (!skb)
3585 break;
3586 }
3587
3588 if (!(pi->conn_state & L2CAP_CONN_RNR_SENT))
3589 goto done;
3590
3591 control = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3592 control |= L2CAP_SUPER_RCV_READY | L2CAP_CTRL_POLL;
3593 l2cap_send_sframe(pi, control);
3594 l2cap_pi(sk)->retry_count = 1;
3595
3596 del_timer(&pi->retrans_timer);
3597 __mod_monitor_timer();
3598
3599 l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
3600
3601done:
3602 pi->conn_state &= ~L2CAP_CONN_LOCAL_BUSY;
3603 pi->conn_state &= ~L2CAP_CONN_RNR_SENT;
3604
3605 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02003606 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003607
3608 release_sock(sk);
3609}
3610
3611static int l2cap_push_rx_skb(struct sock *sk, struct sk_buff *skb, u16 control)
3612{
3613 struct l2cap_pinfo *pi = l2cap_pi(sk);
3614 int sctrl, err;
3615
3616 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
3617 bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT;
3618 __skb_queue_tail(BUSY_QUEUE(sk), skb);
3619 return -EBUSY;
3620 }
3621
3622 err = l2cap_ertm_reassembly_sdu(sk, skb, control);
3623 if (err >= 0) {
3624 pi->buffer_seq = (pi->buffer_seq + 1) % 64;
3625 return err;
3626 }
3627
3628 /* Busy Condition */
3629 pi->conn_state |= L2CAP_CONN_LOCAL_BUSY;
3630 bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT;
3631 __skb_queue_tail(BUSY_QUEUE(sk), skb);
3632
3633 sctrl = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3634 sctrl |= L2CAP_SUPER_RCV_NOT_READY;
3635 l2cap_send_sframe(pi, sctrl);
3636
3637 pi->conn_state |= L2CAP_CONN_RNR_SENT;
3638
3639 queue_work(_busy_wq, &pi->busy_work);
3640
3641 return err;
3642}
3643
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003644static int l2cap_streaming_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003645{
3646 struct l2cap_pinfo *pi = l2cap_pi(sk);
3647 struct sk_buff *_skb;
3648 int err = -EINVAL;
3649
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003650 /*
3651 * TODO: We have to notify the userland if some data is lost with the
3652 * Streaming Mode.
3653 */
3654
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003655 switch (control & L2CAP_CTRL_SAR) {
3656 case L2CAP_SDU_UNSEGMENTED:
3657 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3658 kfree_skb(pi->sdu);
3659 break;
3660 }
3661
3662 err = sock_queue_rcv_skb(sk, skb);
3663 if (!err)
3664 return 0;
3665
3666 break;
3667
3668 case L2CAP_SDU_START:
3669 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3670 kfree_skb(pi->sdu);
3671 break;
3672 }
3673
3674 pi->sdu_len = get_unaligned_le16(skb->data);
3675 skb_pull(skb, 2);
3676
Gustavo F. Padovan052897c2010-05-01 16:15:40 -03003677 if (pi->sdu_len > pi->imtu) {
3678 err = -EMSGSIZE;
3679 break;
3680 }
3681
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003682 pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
3683 if (!pi->sdu) {
3684 err = -ENOMEM;
3685 break;
3686 }
3687
3688 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3689
3690 pi->conn_state |= L2CAP_CONN_SAR_SDU;
3691 pi->partial_sdu_len = skb->len;
3692 err = 0;
3693 break;
3694
3695 case L2CAP_SDU_CONTINUE:
3696 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3697 break;
3698
3699 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3700
3701 pi->partial_sdu_len += skb->len;
3702 if (pi->partial_sdu_len > pi->sdu_len)
3703 kfree_skb(pi->sdu);
3704 else
3705 err = 0;
3706
3707 break;
3708
3709 case L2CAP_SDU_END:
3710 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3711 break;
3712
3713 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3714
3715 pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
3716 pi->partial_sdu_len += skb->len;
3717
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003718 if (pi->partial_sdu_len > pi->imtu)
3719 goto drop;
3720
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003721 if (pi->partial_sdu_len == pi->sdu_len) {
3722 _skb = skb_clone(pi->sdu, GFP_ATOMIC);
3723 err = sock_queue_rcv_skb(sk, _skb);
3724 if (err < 0)
3725 kfree_skb(_skb);
3726 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003727 err = 0;
3728
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003729drop:
3730 kfree_skb(pi->sdu);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003731 break;
3732 }
3733
3734 kfree_skb(skb);
3735 return err;
3736}
3737
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003738static void l2cap_check_srej_gap(struct sock *sk, u8 tx_seq)
3739{
3740 struct sk_buff *skb;
Gustavo F. Padovanafefdbc2010-05-01 16:15:43 -03003741 u16 control;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003742
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003743 while ((skb = skb_peek(SREJ_QUEUE(sk)))) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003744 if (bt_cb(skb)->tx_seq != tx_seq)
3745 break;
3746
3747 skb = skb_dequeue(SREJ_QUEUE(sk));
Gustavo F. Padovanafefdbc2010-05-01 16:15:43 -03003748 control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003749 l2cap_ertm_reassembly_sdu(sk, skb, control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003750 l2cap_pi(sk)->buffer_seq_srej =
3751 (l2cap_pi(sk)->buffer_seq_srej + 1) % 64;
3752 tx_seq++;
3753 }
3754}
3755
3756static void l2cap_resend_srejframe(struct sock *sk, u8 tx_seq)
3757{
3758 struct l2cap_pinfo *pi = l2cap_pi(sk);
3759 struct srej_list *l, *tmp;
3760 u16 control;
3761
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003762 list_for_each_entry_safe(l, tmp, SREJ_LIST(sk), list) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003763 if (l->tx_seq == tx_seq) {
3764 list_del(&l->list);
3765 kfree(l);
3766 return;
3767 }
3768 control = L2CAP_SUPER_SELECT_REJECT;
3769 control |= l->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3770 l2cap_send_sframe(pi, control);
3771 list_del(&l->list);
3772 list_add_tail(&l->list, SREJ_LIST(sk));
3773 }
3774}
3775
3776static void l2cap_send_srejframe(struct sock *sk, u8 tx_seq)
3777{
3778 struct l2cap_pinfo *pi = l2cap_pi(sk);
3779 struct srej_list *new;
3780 u16 control;
3781
3782 while (tx_seq != pi->expected_tx_seq) {
3783 control = L2CAP_SUPER_SELECT_REJECT;
3784 control |= pi->expected_tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3785 l2cap_send_sframe(pi, control);
3786
3787 new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC);
3788 new->tx_seq = pi->expected_tx_seq++;
3789 list_add_tail(&new->list, SREJ_LIST(sk));
3790 }
3791 pi->expected_tx_seq++;
3792}
3793
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003794static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
3795{
3796 struct l2cap_pinfo *pi = l2cap_pi(sk);
3797 u8 tx_seq = __get_txseq(rx_control);
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003798 u8 req_seq = __get_reqseq(rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003799 u8 sar = rx_control >> L2CAP_CTRL_SAR_SHIFT;
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003800 u8 tx_seq_offset, expected_tx_seq_offset;
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03003801 int num_to_ack = (pi->tx_win/6) + 1;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003802 int err = 0;
3803
3804 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
3805
Gustavo F. Padovan9b16dc62010-05-05 20:05:57 -03003806 if (L2CAP_CTRL_FINAL & rx_control &&
3807 l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) {
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003808 del_timer(&pi->monitor_timer);
3809 if (pi->unacked_frames > 0)
3810 __mod_retrans_timer();
3811 pi->conn_state &= ~L2CAP_CONN_WAIT_F;
3812 }
3813
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003814 pi->expected_ack_seq = req_seq;
3815 l2cap_drop_acked_frames(sk);
3816
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003817 if (tx_seq == pi->expected_tx_seq)
3818 goto expected;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003819
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003820 tx_seq_offset = (tx_seq - pi->buffer_seq) % 64;
3821 if (tx_seq_offset < 0)
3822 tx_seq_offset += 64;
3823
3824 /* invalid tx_seq */
3825 if (tx_seq_offset >= pi->tx_win) {
3826 l2cap_send_disconn_req(pi->conn, sk);
3827 goto drop;
3828 }
3829
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003830 if (pi->conn_state == L2CAP_CONN_LOCAL_BUSY)
3831 goto drop;
3832
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003833 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3834 struct srej_list *first;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003835
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003836 first = list_first_entry(SREJ_LIST(sk),
3837 struct srej_list, list);
3838 if (tx_seq == first->tx_seq) {
3839 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3840 l2cap_check_srej_gap(sk, tx_seq);
3841
3842 list_del(&first->list);
3843 kfree(first);
3844
3845 if (list_empty(SREJ_LIST(sk))) {
3846 pi->buffer_seq = pi->buffer_seq_srej;
3847 pi->conn_state &= ~L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan855666cc2010-05-01 16:15:40 -03003848 l2cap_send_ack(pi);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003849 }
3850 } else {
3851 struct srej_list *l;
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003852
3853 /* duplicated tx_seq */
3854 if (l2cap_add_to_srej_queue(sk, skb, tx_seq, sar) < 0)
3855 goto drop;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003856
3857 list_for_each_entry(l, SREJ_LIST(sk), list) {
3858 if (l->tx_seq == tx_seq) {
3859 l2cap_resend_srejframe(sk, tx_seq);
3860 return 0;
3861 }
3862 }
3863 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003864 }
3865 } else {
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003866 expected_tx_seq_offset =
3867 (pi->expected_tx_seq - pi->buffer_seq) % 64;
3868 if (expected_tx_seq_offset < 0)
3869 expected_tx_seq_offset += 64;
3870
3871 /* duplicated tx_seq */
3872 if (tx_seq_offset < expected_tx_seq_offset)
3873 goto drop;
3874
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003875 pi->conn_state |= L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003876
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003877 INIT_LIST_HEAD(SREJ_LIST(sk));
3878 pi->buffer_seq_srej = pi->buffer_seq;
3879
3880 __skb_queue_head_init(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003881 __skb_queue_head_init(BUSY_QUEUE(sk));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003882 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3883
Gustavo F. Padovanef54fd92009-08-20 22:26:04 -03003884 pi->conn_state |= L2CAP_CONN_SEND_PBIT;
3885
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003886 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003887 }
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003888 return 0;
3889
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003890expected:
3891 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
3892
3893 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
Gustavo F. Padovan3b1a9f32010-05-01 16:15:42 -03003894 bt_cb(skb)->tx_seq = tx_seq;
3895 bt_cb(skb)->sar = sar;
3896 __skb_queue_tail(SREJ_QUEUE(sk), skb);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003897 return 0;
3898 }
3899
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03003900 if (rx_control & L2CAP_CTRL_FINAL) {
3901 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3902 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003903 else
3904 l2cap_retransmit_frames(sk);
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03003905 }
3906
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003907 err = l2cap_push_rx_skb(sk, skb, rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003908 if (err < 0)
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003909 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003910
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003911 __mod_ack_timer();
3912
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03003913 pi->num_acked = (pi->num_acked + 1) % num_to_ack;
3914 if (pi->num_acked == num_to_ack - 1)
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03003915 l2cap_send_ack(pi);
3916
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003917 return 0;
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003918
3919drop:
3920 kfree_skb(skb);
3921 return 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003922}
3923
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003924static inline void l2cap_data_channel_rrframe(struct sock *sk, u16 rx_control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003925{
3926 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan6e3a5982010-05-01 16:15:38 -03003927
3928 pi->expected_ack_seq = __get_reqseq(rx_control);
3929 l2cap_drop_acked_frames(sk);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003930
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003931 if (rx_control & L2CAP_CTRL_POLL) {
Gustavo F. Padovan05fbd892010-05-01 16:15:39 -03003932 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3933 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
3934 (pi->unacked_frames > 0))
3935 __mod_retrans_timer();
3936
3937 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3938 l2cap_send_srejtail(sk);
3939 } else {
3940 l2cap_send_i_or_rr_or_rnr(sk);
Gustavo F. Padovan05fbd892010-05-01 16:15:39 -03003941 }
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003942
3943 } else if (rx_control & L2CAP_CTRL_FINAL) {
3944 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003945
3946 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3947 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003948 else
3949 l2cap_retransmit_frames(sk);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003950
3951 } else {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003952 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
3953 (pi->unacked_frames > 0))
3954 __mod_retrans_timer();
3955
3956 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003957 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003958 l2cap_send_ack(pi);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003959 } else {
3960 spin_lock_bh(&pi->send_lock);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003961 l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003962 spin_unlock_bh(&pi->send_lock);
3963 }
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003964 }
3965}
3966
3967static inline void l2cap_data_channel_rejframe(struct sock *sk, u16 rx_control)
3968{
3969 struct l2cap_pinfo *pi = l2cap_pi(sk);
3970 u8 tx_seq = __get_reqseq(rx_control);
3971
3972 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3973
Gustavo F. Padovan8abb52e2010-05-01 16:15:38 -03003974 pi->expected_ack_seq = tx_seq;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003975 l2cap_drop_acked_frames(sk);
3976
3977 if (rx_control & L2CAP_CTRL_FINAL) {
3978 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3979 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003980 else
3981 l2cap_retransmit_frames(sk);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003982 } else {
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003983 l2cap_retransmit_frames(sk);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003984
Gustavo F. Padovan0301ef02010-05-05 20:56:43 -03003985 if (pi->conn_state & L2CAP_CONN_WAIT_F)
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003986 pi->conn_state |= L2CAP_CONN_REJ_ACT;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003987 }
3988}
3989static inline void l2cap_data_channel_srejframe(struct sock *sk, u16 rx_control)
3990{
3991 struct l2cap_pinfo *pi = l2cap_pi(sk);
3992 u8 tx_seq = __get_reqseq(rx_control);
3993
3994 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3995
3996 if (rx_control & L2CAP_CTRL_POLL) {
3997 pi->expected_ack_seq = tx_seq;
3998 l2cap_drop_acked_frames(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003999 l2cap_retransmit_one_frame(sk, tx_seq);
4000
4001 spin_lock_bh(&pi->send_lock);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004002 l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004003 spin_unlock_bh(&pi->send_lock);
4004
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004005 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
4006 pi->srej_save_reqseq = tx_seq;
4007 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
4008 }
4009 } else if (rx_control & L2CAP_CTRL_FINAL) {
4010 if ((pi->conn_state & L2CAP_CONN_SREJ_ACT) &&
4011 pi->srej_save_reqseq == tx_seq)
4012 pi->conn_state &= ~L2CAP_CONN_SREJ_ACT;
4013 else
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004014 l2cap_retransmit_one_frame(sk, tx_seq);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004015 } else {
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004016 l2cap_retransmit_one_frame(sk, tx_seq);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004017 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
4018 pi->srej_save_reqseq = tx_seq;
4019 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
4020 }
4021 }
4022}
4023
4024static inline void l2cap_data_channel_rnrframe(struct sock *sk, u16 rx_control)
4025{
4026 struct l2cap_pinfo *pi = l2cap_pi(sk);
4027 u8 tx_seq = __get_reqseq(rx_control);
4028
4029 pi->conn_state |= L2CAP_CONN_REMOTE_BUSY;
4030 pi->expected_ack_seq = tx_seq;
4031 l2cap_drop_acked_frames(sk);
4032
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03004033 if (!(pi->conn_state & L2CAP_CONN_SREJ_SENT)) {
4034 del_timer(&pi->retrans_timer);
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -03004035 if (rx_control & L2CAP_CTRL_POLL)
4036 l2cap_send_rr_or_rnr(pi, L2CAP_CTRL_FINAL);
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03004037 return;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004038 }
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03004039
4040 if (rx_control & L2CAP_CTRL_POLL)
4041 l2cap_send_srejtail(sk);
4042 else
4043 l2cap_send_sframe(pi, L2CAP_SUPER_RCV_READY);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004044}
4045
4046static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
4047{
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004048 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
4049
Gustavo F. Padovan9b16dc62010-05-05 20:05:57 -03004050 if (L2CAP_CTRL_FINAL & rx_control &&
4051 l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004052 del_timer(&l2cap_pi(sk)->monitor_timer);
4053 if (l2cap_pi(sk)->unacked_frames > 0)
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03004054 __mod_retrans_timer();
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004055 l2cap_pi(sk)->conn_state &= ~L2CAP_CONN_WAIT_F;
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03004056 }
4057
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004058 switch (rx_control & L2CAP_CTRL_SUPERVISE) {
4059 case L2CAP_SUPER_RCV_READY:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004060 l2cap_data_channel_rrframe(sk, rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004061 break;
4062
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004063 case L2CAP_SUPER_REJECT:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004064 l2cap_data_channel_rejframe(sk, rx_control);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03004065 break;
4066
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004067 case L2CAP_SUPER_SELECT_REJECT:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004068 l2cap_data_channel_srejframe(sk, rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004069 break;
4070
4071 case L2CAP_SUPER_RCV_NOT_READY:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004072 l2cap_data_channel_rnrframe(sk, rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004073 break;
4074 }
4075
Gustavo F. Padovanfaaebd12010-05-01 16:15:35 -03004076 kfree_skb(skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004077 return 0;
4078}
4079
Linus Torvalds1da177e2005-04-16 15:20:36 -07004080static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk_buff *skb)
4081{
4082 struct sock *sk;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004083 struct l2cap_pinfo *pi;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03004084 u16 control, len;
João Paulo Rechi Vita01760bd2010-05-01 16:15:43 -03004085 u8 tx_seq, req_seq, next_tx_seq_offset, req_seq_offset;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004086
4087 sk = l2cap_get_chan_by_scid(&conn->chan_list, cid);
4088 if (!sk) {
4089 BT_DBG("unknown cid 0x%4.4x", cid);
4090 goto drop;
4091 }
4092
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004093 pi = l2cap_pi(sk);
4094
Linus Torvalds1da177e2005-04-16 15:20:36 -07004095 BT_DBG("sk %p, len %d", sk, skb->len);
4096
4097 if (sk->sk_state != BT_CONNECTED)
4098 goto drop;
4099
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004100 switch (pi->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004101 case L2CAP_MODE_BASIC:
4102 /* If socket recv buffers overflows we drop data here
4103 * which is *bad* because L2CAP has to be reliable.
4104 * But we don't have any other choice. L2CAP doesn't
4105 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07004106
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004107 if (pi->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004108 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004109
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004110 if (!sock_queue_rcv_skb(sk, skb))
4111 goto done;
4112 break;
4113
4114 case L2CAP_MODE_ERTM:
4115 control = get_unaligned_le16(skb->data);
4116 skb_pull(skb, 2);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03004117 len = skb->len;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004118
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03004119 if (__is_sar_start(control))
4120 len -= 2;
4121
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004122 if (pi->fcs == L2CAP_FCS_CRC16)
4123 len -= 2;
4124
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03004125 /*
4126 * We can just drop the corrupted I-frame here.
4127 * Receiver will miss it and start proper recovery
4128 * procedures and ask retransmission.
4129 */
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004130 if (len > pi->mps) {
4131 l2cap_send_disconn_req(pi->conn, sk);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004132 goto drop;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004133 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004134
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004135 if (l2cap_check_fcs(pi, skb))
4136 goto drop;
4137
João Paulo Rechi Vita01760bd2010-05-01 16:15:43 -03004138 req_seq = __get_reqseq(control);
4139 req_seq_offset = (req_seq - pi->expected_ack_seq) % 64;
4140 if (req_seq_offset < 0)
4141 req_seq_offset += 64;
4142
4143 next_tx_seq_offset =
4144 (pi->next_tx_seq - pi->expected_ack_seq) % 64;
4145 if (next_tx_seq_offset < 0)
4146 next_tx_seq_offset += 64;
4147
4148 /* check for invalid req-seq */
4149 if (req_seq_offset > next_tx_seq_offset) {
4150 l2cap_send_disconn_req(pi->conn, sk);
4151 goto drop;
4152 }
4153
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004154 if (__is_iframe(control)) {
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004155 if (len < 4) {
4156 l2cap_send_disconn_req(pi->conn, sk);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004157 goto drop;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004158 }
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004159
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02004160 l2cap_data_channel_iframe(sk, control, skb);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004161 } else {
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004162 if (len != 0) {
4163 l2cap_send_disconn_req(pi->conn, sk);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004164 goto drop;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004165 }
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004166
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02004167 l2cap_data_channel_sframe(sk, control, skb);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004168 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004169
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02004170 goto done;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004171
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004172 case L2CAP_MODE_STREAMING:
4173 control = get_unaligned_le16(skb->data);
4174 skb_pull(skb, 2);
4175 len = skb->len;
4176
4177 if (__is_sar_start(control))
4178 len -= 2;
4179
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004180 if (pi->fcs == L2CAP_FCS_CRC16)
4181 len -= 2;
4182
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03004183 if (len > pi->mps || len < 4 || __is_sframe(control))
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004184 goto drop;
4185
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004186 if (l2cap_check_fcs(pi, skb))
4187 goto drop;
4188
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004189 tx_seq = __get_txseq(control);
4190
4191 if (pi->expected_tx_seq == tx_seq)
4192 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
4193 else
Gustavo F. Padovan7dffe422010-05-01 16:15:36 -03004194 pi->expected_tx_seq = (tx_seq + 1) % 64;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004195
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004196 l2cap_streaming_reassembly_sdu(sk, skb, control);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004197
4198 goto done;
4199
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004200 default:
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03004201 BT_DBG("sk %p: bad mode 0x%2.2x", sk, pi->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004202 break;
4203 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004204
4205drop:
4206 kfree_skb(skb);
4207
4208done:
Marcel Holtmann01394182006-07-03 10:02:46 +02004209 if (sk)
4210 bh_unlock_sock(sk);
4211
Linus Torvalds1da177e2005-04-16 15:20:36 -07004212 return 0;
4213}
4214
Al Viro8e036fc2007-07-29 00:16:36 -07004215static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004216{
4217 struct sock *sk;
4218
4219 sk = l2cap_get_sock_by_psm(0, psm, conn->src);
4220 if (!sk)
4221 goto drop;
4222
4223 BT_DBG("sk %p, len %d", sk, skb->len);
4224
4225 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_CONNECTED)
4226 goto drop;
4227
4228 if (l2cap_pi(sk)->imtu < skb->len)
4229 goto drop;
4230
4231 if (!sock_queue_rcv_skb(sk, skb))
4232 goto done;
4233
4234drop:
4235 kfree_skb(skb);
4236
4237done:
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03004238 if (sk)
4239 bh_unlock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004240 return 0;
4241}
4242
4243static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
4244{
4245 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07004246 u16 cid, len;
4247 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004248
4249 skb_pull(skb, L2CAP_HDR_SIZE);
4250 cid = __le16_to_cpu(lh->cid);
4251 len = __le16_to_cpu(lh->len);
4252
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004253 if (len != skb->len) {
4254 kfree_skb(skb);
4255 return;
4256 }
4257
Linus Torvalds1da177e2005-04-16 15:20:36 -07004258 BT_DBG("len %d, cid 0x%4.4x", len, cid);
4259
4260 switch (cid) {
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03004261 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07004262 l2cap_sig_channel(conn, skb);
4263 break;
4264
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03004265 case L2CAP_CID_CONN_LESS:
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03004266 psm = get_unaligned_le16(skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004267 skb_pull(skb, 2);
4268 l2cap_conless_channel(conn, psm, skb);
4269 break;
4270
4271 default:
4272 l2cap_data_channel(conn, cid, skb);
4273 break;
4274 }
4275}
4276
4277/* ---- L2CAP interface with lower layer (HCI) ---- */
4278
4279static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
4280{
4281 int exact = 0, lm1 = 0, lm2 = 0;
4282 register struct sock *sk;
4283 struct hlist_node *node;
4284
4285 if (type != ACL_LINK)
4286 return 0;
4287
4288 BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
4289
4290 /* Find listening sockets and check their link_mode */
4291 read_lock(&l2cap_sk_list.lock);
4292 sk_for_each(sk, node, &l2cap_sk_list.head) {
4293 if (sk->sk_state != BT_LISTEN)
4294 continue;
4295
4296 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01004297 lm1 |= HCI_LM_ACCEPT;
4298 if (l2cap_pi(sk)->role_switch)
4299 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004300 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01004301 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
4302 lm2 |= HCI_LM_ACCEPT;
4303 if (l2cap_pi(sk)->role_switch)
4304 lm2 |= HCI_LM_MASTER;
4305 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004306 }
4307 read_unlock(&l2cap_sk_list.lock);
4308
4309 return exact ? lm1 : lm2;
4310}
4311
4312static int l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
4313{
Marcel Holtmann01394182006-07-03 10:02:46 +02004314 struct l2cap_conn *conn;
4315
Linus Torvalds1da177e2005-04-16 15:20:36 -07004316 BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
4317
4318 if (hcon->type != ACL_LINK)
4319 return 0;
4320
4321 if (!status) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004322 conn = l2cap_conn_add(hcon, status);
4323 if (conn)
4324 l2cap_conn_ready(conn);
Marcel Holtmann01394182006-07-03 10:02:46 +02004325 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -07004326 l2cap_conn_del(hcon, bt_err(status));
4327
4328 return 0;
4329}
4330
Marcel Holtmann2950f212009-02-12 14:02:50 +01004331static int l2cap_disconn_ind(struct hci_conn *hcon)
4332{
4333 struct l2cap_conn *conn = hcon->l2cap_data;
4334
4335 BT_DBG("hcon %p", hcon);
4336
4337 if (hcon->type != ACL_LINK || !conn)
4338 return 0x13;
4339
4340 return conn->disc_reason;
4341}
4342
4343static int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004344{
4345 BT_DBG("hcon %p reason %d", hcon, reason);
4346
4347 if (hcon->type != ACL_LINK)
4348 return 0;
4349
4350 l2cap_conn_del(hcon, bt_err(reason));
Marcel Holtmann01394182006-07-03 10:02:46 +02004351
Linus Torvalds1da177e2005-04-16 15:20:36 -07004352 return 0;
4353}
4354
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004355static inline void l2cap_check_encryption(struct sock *sk, u8 encrypt)
4356{
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03004357 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM)
Marcel Holtmann255c7602009-02-04 21:07:19 +01004358 return;
4359
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004360 if (encrypt == 0x00) {
4361 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM) {
4362 l2cap_sock_clear_timer(sk);
4363 l2cap_sock_set_timer(sk, HZ * 5);
4364 } else if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
4365 __l2cap_sock_close(sk, ECONNREFUSED);
4366 } else {
4367 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM)
4368 l2cap_sock_clear_timer(sk);
4369 }
4370}
4371
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004372static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004373{
4374 struct l2cap_chan_list *l;
Marcel Holtmann40be4922008-07-14 20:13:50 +02004375 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004376 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004377
Marcel Holtmann01394182006-07-03 10:02:46 +02004378 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004379 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02004380
Linus Torvalds1da177e2005-04-16 15:20:36 -07004381 l = &conn->chan_list;
4382
4383 BT_DBG("conn %p", conn);
4384
4385 read_lock(&l->lock);
4386
4387 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
4388 bh_lock_sock(sk);
4389
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01004390 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND) {
4391 bh_unlock_sock(sk);
4392 continue;
4393 }
4394
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004395 if (!status && (sk->sk_state == BT_CONNECTED ||
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004396 sk->sk_state == BT_CONFIG)) {
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004397 l2cap_check_encryption(sk, encrypt);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02004398 bh_unlock_sock(sk);
4399 continue;
4400 }
4401
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004402 if (sk->sk_state == BT_CONNECT) {
4403 if (!status) {
4404 struct l2cap_conn_req req;
4405 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
4406 req.psm = l2cap_pi(sk)->psm;
4407
4408 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
4409
4410 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
4411 L2CAP_CONN_REQ, sizeof(req), &req);
4412 } else {
4413 l2cap_sock_clear_timer(sk);
4414 l2cap_sock_set_timer(sk, HZ / 10);
4415 }
4416 } else if (sk->sk_state == BT_CONNECT2) {
4417 struct l2cap_conn_rsp rsp;
4418 __u16 result;
4419
4420 if (!status) {
4421 sk->sk_state = BT_CONFIG;
4422 result = L2CAP_CR_SUCCESS;
4423 } else {
4424 sk->sk_state = BT_DISCONN;
4425 l2cap_sock_set_timer(sk, HZ / 10);
4426 result = L2CAP_CR_SEC_BLOCK;
4427 }
4428
4429 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
4430 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
4431 rsp.result = cpu_to_le16(result);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02004432 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004433 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
4434 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004435 }
4436
Linus Torvalds1da177e2005-04-16 15:20:36 -07004437 bh_unlock_sock(sk);
4438 }
4439
4440 read_unlock(&l->lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004441
Linus Torvalds1da177e2005-04-16 15:20:36 -07004442 return 0;
4443}
4444
4445static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
4446{
4447 struct l2cap_conn *conn = hcon->l2cap_data;
4448
4449 if (!conn && !(conn = l2cap_conn_add(hcon, 0)))
4450 goto drop;
4451
4452 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
4453
4454 if (flags & ACL_START) {
4455 struct l2cap_hdr *hdr;
4456 int len;
4457
4458 if (conn->rx_len) {
4459 BT_ERR("Unexpected start frame (len %d)", skb->len);
4460 kfree_skb(conn->rx_skb);
4461 conn->rx_skb = NULL;
4462 conn->rx_len = 0;
4463 l2cap_conn_unreliable(conn, ECOMM);
4464 }
4465
4466 if (skb->len < 2) {
4467 BT_ERR("Frame is too short (len %d)", skb->len);
4468 l2cap_conn_unreliable(conn, ECOMM);
4469 goto drop;
4470 }
4471
4472 hdr = (struct l2cap_hdr *) skb->data;
4473 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
4474
4475 if (len == skb->len) {
4476 /* Complete frame received */
4477 l2cap_recv_frame(conn, skb);
4478 return 0;
4479 }
4480
4481 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
4482
4483 if (skb->len > len) {
4484 BT_ERR("Frame is too long (len %d, expected len %d)",
4485 skb->len, len);
4486 l2cap_conn_unreliable(conn, ECOMM);
4487 goto drop;
4488 }
4489
4490 /* Allocate skb for the complete frame (with header) */
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03004491 conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC);
4492 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004493 goto drop;
4494
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03004495 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004496 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004497 conn->rx_len = len - skb->len;
4498 } else {
4499 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
4500
4501 if (!conn->rx_len) {
4502 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
4503 l2cap_conn_unreliable(conn, ECOMM);
4504 goto drop;
4505 }
4506
4507 if (skb->len > conn->rx_len) {
4508 BT_ERR("Fragment is too long (len %d, expected %d)",
4509 skb->len, conn->rx_len);
4510 kfree_skb(conn->rx_skb);
4511 conn->rx_skb = NULL;
4512 conn->rx_len = 0;
4513 l2cap_conn_unreliable(conn, ECOMM);
4514 goto drop;
4515 }
4516
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03004517 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004518 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004519 conn->rx_len -= skb->len;
4520
4521 if (!conn->rx_len) {
4522 /* Complete frame received */
4523 l2cap_recv_frame(conn, conn->rx_skb);
4524 conn->rx_skb = NULL;
4525 }
4526 }
4527
4528drop:
4529 kfree_skb(skb);
4530 return 0;
4531}
4532
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004533static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004534{
4535 struct sock *sk;
4536 struct hlist_node *node;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004537
4538 read_lock_bh(&l2cap_sk_list.lock);
4539
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004540 sk_for_each(sk, node, &l2cap_sk_list.head) {
4541 struct l2cap_pinfo *pi = l2cap_pi(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004542
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004543 seq_printf(f, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d\n",
4544 batostr(&bt_sk(sk)->src),
4545 batostr(&bt_sk(sk)->dst),
4546 sk->sk_state, __le16_to_cpu(pi->psm),
4547 pi->scid, pi->dcid,
4548 pi->imtu, pi->omtu, pi->sec_level);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004549 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004550
Linus Torvalds1da177e2005-04-16 15:20:36 -07004551 read_unlock_bh(&l2cap_sk_list.lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004552
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004553 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004554}
4555
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004556static int l2cap_debugfs_open(struct inode *inode, struct file *file)
4557{
4558 return single_open(file, l2cap_debugfs_show, inode->i_private);
4559}
4560
4561static const struct file_operations l2cap_debugfs_fops = {
4562 .open = l2cap_debugfs_open,
4563 .read = seq_read,
4564 .llseek = seq_lseek,
4565 .release = single_release,
4566};
4567
4568static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004569
Eric Dumazet90ddc4f2005-12-22 12:49:22 -08004570static const struct proto_ops l2cap_sock_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004571 .family = PF_BLUETOOTH,
4572 .owner = THIS_MODULE,
4573 .release = l2cap_sock_release,
4574 .bind = l2cap_sock_bind,
4575 .connect = l2cap_sock_connect,
4576 .listen = l2cap_sock_listen,
4577 .accept = l2cap_sock_accept,
4578 .getname = l2cap_sock_getname,
4579 .sendmsg = l2cap_sock_sendmsg,
Marcel Holtmannf66dc812009-01-15 21:57:00 +01004580 .recvmsg = l2cap_sock_recvmsg,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004581 .poll = bt_sock_poll,
Marcel Holtmann3241ad82008-07-14 20:13:50 +02004582 .ioctl = bt_sock_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004583 .mmap = sock_no_mmap,
4584 .socketpair = sock_no_socketpair,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004585 .shutdown = l2cap_sock_shutdown,
4586 .setsockopt = l2cap_sock_setsockopt,
4587 .getsockopt = l2cap_sock_getsockopt
4588};
4589
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +00004590static const struct net_proto_family l2cap_sock_family_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004591 .family = PF_BLUETOOTH,
4592 .owner = THIS_MODULE,
4593 .create = l2cap_sock_create,
4594};
4595
4596static struct hci_proto l2cap_hci_proto = {
4597 .name = "L2CAP",
4598 .id = HCI_PROTO_L2CAP,
4599 .connect_ind = l2cap_connect_ind,
4600 .connect_cfm = l2cap_connect_cfm,
4601 .disconn_ind = l2cap_disconn_ind,
Marcel Holtmann2950f212009-02-12 14:02:50 +01004602 .disconn_cfm = l2cap_disconn_cfm,
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004603 .security_cfm = l2cap_security_cfm,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004604 .recv_acldata = l2cap_recv_acldata
4605};
4606
4607static int __init l2cap_init(void)
4608{
4609 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004610
Linus Torvalds1da177e2005-04-16 15:20:36 -07004611 err = proto_register(&l2cap_proto, 0);
4612 if (err < 0)
4613 return err;
4614
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004615 _busy_wq = create_singlethread_workqueue("l2cap");
4616 if (!_busy_wq)
4617 goto error;
4618
Linus Torvalds1da177e2005-04-16 15:20:36 -07004619 err = bt_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops);
4620 if (err < 0) {
4621 BT_ERR("L2CAP socket registration failed");
4622 goto error;
4623 }
4624
4625 err = hci_register_proto(&l2cap_hci_proto);
4626 if (err < 0) {
4627 BT_ERR("L2CAP protocol registration failed");
4628 bt_sock_unregister(BTPROTO_L2CAP);
4629 goto error;
4630 }
4631
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004632 if (bt_debugfs) {
4633 l2cap_debugfs = debugfs_create_file("l2cap", 0444,
4634 bt_debugfs, NULL, &l2cap_debugfs_fops);
4635 if (!l2cap_debugfs)
4636 BT_ERR("Failed to create L2CAP debug file");
4637 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004638
4639 BT_INFO("L2CAP ver %s", VERSION);
4640 BT_INFO("L2CAP socket layer initialized");
4641
4642 return 0;
4643
4644error:
4645 proto_unregister(&l2cap_proto);
4646 return err;
4647}
4648
4649static void __exit l2cap_exit(void)
4650{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004651 debugfs_remove(l2cap_debugfs);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004652
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004653 flush_workqueue(_busy_wq);
4654 destroy_workqueue(_busy_wq);
4655
Linus Torvalds1da177e2005-04-16 15:20:36 -07004656 if (bt_sock_unregister(BTPROTO_L2CAP) < 0)
4657 BT_ERR("L2CAP socket unregistration failed");
4658
4659 if (hci_unregister_proto(&l2cap_hci_proto) < 0)
4660 BT_ERR("L2CAP protocol unregistration failed");
4661
4662 proto_unregister(&l2cap_proto);
4663}
4664
4665void l2cap_load(void)
4666{
4667 /* Dummy function to trigger automatic L2CAP module loading by
4668 * other modules that use L2CAP sockets but don't use any other
4669 * symbols from it. */
4670 return;
4671}
4672EXPORT_SYMBOL(l2cap_load);
4673
4674module_init(l2cap_init);
4675module_exit(l2cap_exit);
4676
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07004677module_param(enable_ertm, bool, 0644);
4678MODULE_PARM_DESC(enable_ertm, "Enable enhanced retransmission mode");
4679
Marcel Holtmann5fbcd3d2009-10-05 11:35:43 +02004680module_param(max_transmit, uint, 0644);
4681MODULE_PARM_DESC(max_transmit, "Max transmit value (default = 3)");
4682
Gustavo F. Padovan369ba302010-05-01 16:15:41 -03004683module_param(tx_window, uint, 0644);
4684MODULE_PARM_DESC(tx_window, "Transmission window size value (default = 63)");
4685
Marcel Holtmann63fbd242008-08-18 13:23:53 +02004686MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004687MODULE_DESCRIPTION("Bluetooth L2CAP ver " VERSION);
4688MODULE_VERSION(VERSION);
4689MODULE_LICENSE("GPL");
4690MODULE_ALIAS("bt-proto-0");