blob: 1b682a5aa0616911c2861b5d836c015230922faf [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);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001325}
1326
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001327static inline void l2cap_do_send(struct sock *sk, struct sk_buff *skb)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001328{
1329 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001330
1331 BT_DBG("sk %p, skb %p len %d", sk, skb, skb->len);
1332
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001333 hci_send_acl(pi->conn->hcon, skb, 0);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001334}
1335
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001336static int l2cap_streaming_send(struct sock *sk)
1337{
1338 struct sk_buff *skb, *tx_skb;
1339 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001340 u16 control, fcs;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001341
1342 while ((skb = sk->sk_send_head)) {
1343 tx_skb = skb_clone(skb, GFP_ATOMIC);
1344
1345 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
1346 control |= pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT;
1347 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1348
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001349 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001350 fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
1351 put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
1352 }
1353
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001354 l2cap_do_send(sk, tx_skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001355
1356 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
1357
1358 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1359 sk->sk_send_head = NULL;
1360 else
1361 sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
1362
1363 skb = skb_dequeue(TX_QUEUE(sk));
1364 kfree_skb(skb);
1365 }
1366 return 0;
1367}
1368
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001369static void l2cap_retransmit_one_frame(struct sock *sk, u8 tx_seq)
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001370{
1371 struct l2cap_pinfo *pi = l2cap_pi(sk);
1372 struct sk_buff *skb, *tx_skb;
1373 u16 control, fcs;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001374
1375 skb = skb_peek(TX_QUEUE(sk));
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001376 if (!skb)
1377 return;
1378
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001379 do {
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001380 if (bt_cb(skb)->tx_seq == tx_seq)
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001381 break;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001382
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001383 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1384 return;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001385
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001386 } while ((skb = skb_queue_next(TX_QUEUE(sk), skb)));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001387
Gustavo F. Padovanf11d6762010-05-01 16:15:44 -03001388 if (pi->remote_max_tx &&
1389 bt_cb(skb)->retries == pi->remote_max_tx) {
1390 l2cap_send_disconn_req(pi->conn, sk);
1391 return;
1392 }
1393
1394 tx_skb = skb_clone(skb, GFP_ATOMIC);
1395 bt_cb(skb)->retries++;
1396 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
1397 control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
1398 | (tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
1399 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1400
1401 if (pi->fcs == L2CAP_FCS_CRC16) {
1402 fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
1403 put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
1404 }
1405
1406 l2cap_do_send(sk, tx_skb);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001407}
1408
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001409static int l2cap_ertm_send(struct sock *sk)
1410{
1411 struct sk_buff *skb, *tx_skb;
1412 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001413 u16 control, fcs;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001414 int nsent = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001415
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001416 if (pi->conn_state & L2CAP_CONN_WAIT_F)
1417 return 0;
1418
Joe Perchesf64f9e72009-11-29 16:55:45 -08001419 while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(sk)) &&
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03001420 !(pi->conn_state & L2CAP_CONN_REMOTE_BUSY)) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001421
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001422 if (pi->remote_max_tx &&
1423 bt_cb(skb)->retries == pi->remote_max_tx) {
1424 l2cap_send_disconn_req(pi->conn, sk);
1425 break;
1426 }
1427
Andrei Emeltchenkoe420aba2009-12-23 13:07:14 +02001428 tx_skb = skb_clone(skb, GFP_ATOMIC);
1429
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001430 bt_cb(skb)->retries++;
1431
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001432 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001433 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
1434 control |= L2CAP_CTRL_FINAL;
1435 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
1436 }
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03001437 control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001438 | (pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
1439 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1440
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001441
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001442 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001443 fcs = crc16(0, (u8 *)skb->data, tx_skb->len - 2);
1444 put_unaligned_le16(fcs, skb->data + tx_skb->len - 2);
1445 }
1446
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001447 l2cap_do_send(sk, tx_skb);
1448
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001449 __mod_retrans_timer();
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001450
1451 bt_cb(skb)->tx_seq = pi->next_tx_seq;
1452 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
1453
1454 pi->unacked_frames++;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001455 pi->frames_sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001456
1457 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1458 sk->sk_send_head = NULL;
1459 else
1460 sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001461
1462 nsent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001463 }
1464
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001465 return nsent;
1466}
1467
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001468static int l2cap_retransmit_frames(struct sock *sk)
1469{
1470 struct l2cap_pinfo *pi = l2cap_pi(sk);
1471 int ret;
1472
1473 spin_lock_bh(&pi->send_lock);
1474
1475 if (!skb_queue_empty(TX_QUEUE(sk)))
1476 sk->sk_send_head = TX_QUEUE(sk)->next;
1477
1478 pi->next_tx_seq = pi->expected_ack_seq;
1479 ret = l2cap_ertm_send(sk);
1480
1481 spin_unlock_bh(&pi->send_lock);
1482
1483 return ret;
1484}
1485
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001486static void l2cap_send_ack(struct l2cap_pinfo *pi)
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001487{
1488 struct sock *sk = (struct sock *)pi;
1489 u16 control = 0;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001490 int nframes;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001491
1492 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1493
1494 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
1495 control |= L2CAP_SUPER_RCV_NOT_READY;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03001496 pi->conn_state |= L2CAP_CONN_RNR_SENT;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001497 l2cap_send_sframe(pi, control);
1498 return;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001499 }
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001500
1501 spin_lock_bh(&pi->send_lock);
1502 nframes = l2cap_ertm_send(sk);
1503 spin_unlock_bh(&pi->send_lock);
1504
1505 if (nframes > 0)
1506 return;
1507
1508 control |= L2CAP_SUPER_RCV_READY;
1509 l2cap_send_sframe(pi, control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001510}
1511
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001512static void l2cap_send_srejtail(struct sock *sk)
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03001513{
1514 struct srej_list *tail;
1515 u16 control;
1516
1517 control = L2CAP_SUPER_SELECT_REJECT;
1518 control |= L2CAP_CTRL_FINAL;
1519
1520 tail = list_entry(SREJ_LIST(sk)->prev, struct srej_list, list);
1521 control |= tail->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1522
1523 l2cap_send_sframe(l2cap_pi(sk), control);
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03001524}
1525
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001526static 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 -07001527{
1528 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001529 struct sk_buff **frag;
1530 int err, sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001531
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03001532 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001533 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001534
1535 sent += count;
1536 len -= count;
1537
1538 /* Continuation fragments (no L2CAP header) */
1539 frag = &skb_shinfo(skb)->frag_list;
1540 while (len) {
1541 count = min_t(unsigned int, conn->mtu, len);
1542
1543 *frag = bt_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err);
1544 if (!*frag)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001545 return -EFAULT;
1546 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
1547 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001548
1549 sent += count;
1550 len -= count;
1551
1552 frag = &(*frag)->next;
1553 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001554
1555 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001556}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001557
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001558static struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, size_t len)
1559{
1560 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1561 struct sk_buff *skb;
1562 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1563 struct l2cap_hdr *lh;
1564
1565 BT_DBG("sk %p len %d", sk, (int)len);
1566
1567 count = min_t(unsigned int, (conn->mtu - hlen), len);
1568 skb = bt_skb_send_alloc(sk, count + hlen,
1569 msg->msg_flags & MSG_DONTWAIT, &err);
1570 if (!skb)
1571 return ERR_PTR(-ENOMEM);
1572
1573 /* Create L2CAP header */
1574 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1575 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1576 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1577 put_unaligned_le16(l2cap_pi(sk)->psm, skb_put(skb, 2));
1578
1579 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1580 if (unlikely(err < 0)) {
1581 kfree_skb(skb);
1582 return ERR_PTR(err);
1583 }
1584 return skb;
1585}
1586
1587static struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *msg, size_t len)
1588{
1589 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1590 struct sk_buff *skb;
1591 int err, count, hlen = L2CAP_HDR_SIZE;
1592 struct l2cap_hdr *lh;
1593
1594 BT_DBG("sk %p len %d", sk, (int)len);
1595
1596 count = min_t(unsigned int, (conn->mtu - hlen), len);
1597 skb = bt_skb_send_alloc(sk, count + hlen,
1598 msg->msg_flags & MSG_DONTWAIT, &err);
1599 if (!skb)
1600 return ERR_PTR(-ENOMEM);
1601
1602 /* Create L2CAP header */
1603 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1604 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1605 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1606
1607 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1608 if (unlikely(err < 0)) {
1609 kfree_skb(skb);
1610 return ERR_PTR(err);
1611 }
1612 return skb;
1613}
1614
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001615static 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 -03001616{
1617 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1618 struct sk_buff *skb;
1619 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1620 struct l2cap_hdr *lh;
1621
1622 BT_DBG("sk %p len %d", sk, (int)len);
1623
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03001624 if (!conn)
1625 return ERR_PTR(-ENOTCONN);
1626
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001627 if (sdulen)
1628 hlen += 2;
1629
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001630 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1631 hlen += 2;
1632
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001633 count = min_t(unsigned int, (conn->mtu - hlen), len);
1634 skb = bt_skb_send_alloc(sk, count + hlen,
1635 msg->msg_flags & MSG_DONTWAIT, &err);
1636 if (!skb)
1637 return ERR_PTR(-ENOMEM);
1638
1639 /* Create L2CAP header */
1640 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1641 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1642 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1643 put_unaligned_le16(control, skb_put(skb, 2));
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001644 if (sdulen)
1645 put_unaligned_le16(sdulen, skb_put(skb, 2));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001646
1647 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1648 if (unlikely(err < 0)) {
1649 kfree_skb(skb);
1650 return ERR_PTR(err);
1651 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001652
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001653 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1654 put_unaligned_le16(0, skb_put(skb, 2));
1655
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001656 bt_cb(skb)->retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001657 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001658}
1659
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001660static inline int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len)
1661{
1662 struct l2cap_pinfo *pi = l2cap_pi(sk);
1663 struct sk_buff *skb;
1664 struct sk_buff_head sar_queue;
1665 u16 control;
1666 size_t size = 0;
1667
Gustavo F. Padovanff12fd62010-05-05 22:09:15 -03001668 skb_queue_head_init(&sar_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001669 control = L2CAP_SDU_START;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001670 skb = l2cap_create_iframe_pdu(sk, msg, pi->remote_mps, control, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001671 if (IS_ERR(skb))
1672 return PTR_ERR(skb);
1673
1674 __skb_queue_tail(&sar_queue, skb);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001675 len -= pi->remote_mps;
1676 size += pi->remote_mps;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001677
1678 while (len > 0) {
1679 size_t buflen;
1680
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001681 if (len > pi->remote_mps) {
Gustavo F. Padovan44651b82010-05-01 16:15:43 -03001682 control = L2CAP_SDU_CONTINUE;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001683 buflen = pi->remote_mps;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001684 } else {
Gustavo F. Padovan44651b82010-05-01 16:15:43 -03001685 control = L2CAP_SDU_END;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001686 buflen = len;
1687 }
1688
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001689 skb = l2cap_create_iframe_pdu(sk, msg, buflen, control, 0);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001690 if (IS_ERR(skb)) {
1691 skb_queue_purge(&sar_queue);
1692 return PTR_ERR(skb);
1693 }
1694
1695 __skb_queue_tail(&sar_queue, skb);
1696 len -= buflen;
1697 size += buflen;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001698 }
1699 skb_queue_splice_tail(&sar_queue, TX_QUEUE(sk));
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001700 spin_lock_bh(&pi->send_lock);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001701 if (sk->sk_send_head == NULL)
1702 sk->sk_send_head = sar_queue.next;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001703 spin_unlock_bh(&pi->send_lock);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001704
1705 return size;
1706}
1707
Linus Torvalds1da177e2005-04-16 15:20:36 -07001708static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len)
1709{
1710 struct sock *sk = sock->sk;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001711 struct l2cap_pinfo *pi = l2cap_pi(sk);
1712 struct sk_buff *skb;
1713 u16 control;
1714 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001715
1716 BT_DBG("sock %p, sk %p", sock, sk);
1717
Benjamin LaHaisec1cbe4b2005-12-13 23:22:19 -08001718 err = sock_error(sk);
1719 if (err)
1720 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001721
1722 if (msg->msg_flags & MSG_OOB)
1723 return -EOPNOTSUPP;
1724
Linus Torvalds1da177e2005-04-16 15:20:36 -07001725 lock_sock(sk);
1726
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001727 if (sk->sk_state != BT_CONNECTED) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001728 err = -ENOTCONN;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001729 goto done;
1730 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001731
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001732 /* Connectionless channel */
1733 if (sk->sk_type == SOCK_DGRAM) {
1734 skb = l2cap_create_connless_pdu(sk, msg, len);
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001735 if (IS_ERR(skb)) {
Dan Carpenter477fffb2010-04-21 23:52:01 +00001736 err = PTR_ERR(skb);
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001737 } else {
1738 l2cap_do_send(sk, skb);
1739 err = len;
1740 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001741 goto done;
1742 }
1743
1744 switch (pi->mode) {
1745 case L2CAP_MODE_BASIC:
Gustavo F. Padovanc69163e2010-05-01 16:15:35 -03001746 /* Check outgoing MTU */
1747 if (len > pi->omtu) {
1748 err = -EINVAL;
1749 goto done;
1750 }
1751
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001752 /* Create a basic PDU */
1753 skb = l2cap_create_basic_pdu(sk, msg, len);
1754 if (IS_ERR(skb)) {
1755 err = PTR_ERR(skb);
1756 goto done;
1757 }
1758
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001759 l2cap_do_send(sk, skb);
1760 err = len;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001761 break;
1762
1763 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001764 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001765 /* Entire SDU fits into one PDU */
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001766 if (len <= pi->remote_mps) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001767 control = L2CAP_SDU_UNSEGMENTED;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001768 skb = l2cap_create_iframe_pdu(sk, msg, len, control, 0);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001769 if (IS_ERR(skb)) {
1770 err = PTR_ERR(skb);
1771 goto done;
1772 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001773 __skb_queue_tail(TX_QUEUE(sk), skb);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001774
1775 if (pi->mode == L2CAP_MODE_ERTM)
1776 spin_lock_bh(&pi->send_lock);
1777
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001778 if (sk->sk_send_head == NULL)
1779 sk->sk_send_head = skb;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001780
1781 if (pi->mode == L2CAP_MODE_ERTM)
1782 spin_unlock_bh(&pi->send_lock);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001783 } else {
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001784 /* Segment SDU into multiples PDUs */
1785 err = l2cap_sar_segment_sdu(sk, msg, len);
1786 if (err < 0)
1787 goto done;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001788 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001789
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001790 if (pi->mode == L2CAP_MODE_STREAMING) {
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001791 err = l2cap_streaming_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001792 } else {
1793 spin_lock_bh(&pi->send_lock);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001794 err = l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03001795 spin_unlock_bh(&pi->send_lock);
1796 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001797
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001798 if (err >= 0)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001799 err = len;
1800 break;
1801
1802 default:
1803 BT_DBG("bad state %1.1x", pi->mode);
1804 err = -EINVAL;
1805 }
1806
1807done:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001808 release_sock(sk);
1809 return err;
1810}
1811
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001812static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags)
1813{
1814 struct sock *sk = sock->sk;
1815
1816 lock_sock(sk);
1817
1818 if (sk->sk_state == BT_CONNECT2 && bt_sk(sk)->defer_setup) {
1819 struct l2cap_conn_rsp rsp;
1820
1821 sk->sk_state = BT_CONFIG;
1822
1823 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
1824 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
1825 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
1826 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
1827 l2cap_send_cmd(l2cap_pi(sk)->conn, l2cap_pi(sk)->ident,
1828 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
1829
1830 release_sock(sk);
1831 return 0;
1832 }
1833
1834 release_sock(sk);
1835
1836 return bt_sock_recvmsg(iocb, sock, msg, len, flags);
1837}
1838
David S. Millerb7058842009-09-30 16:12:20 -07001839static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001840{
1841 struct sock *sk = sock->sk;
1842 struct l2cap_options opts;
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001843 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001844 u32 opt;
1845
1846 BT_DBG("sk %p", sk);
1847
1848 lock_sock(sk);
1849
1850 switch (optname) {
1851 case L2CAP_OPTIONS:
Marcel Holtmann0878b662007-05-05 00:35:59 +02001852 opts.imtu = l2cap_pi(sk)->imtu;
1853 opts.omtu = l2cap_pi(sk)->omtu;
1854 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001855 opts.mode = l2cap_pi(sk)->mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001856 opts.fcs = l2cap_pi(sk)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03001857 opts.max_tx = l2cap_pi(sk)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03001858 opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
Marcel Holtmann0878b662007-05-05 00:35:59 +02001859
Linus Torvalds1da177e2005-04-16 15:20:36 -07001860 len = min_t(unsigned int, sizeof(opts), optlen);
1861 if (copy_from_user((char *) &opts, optval, len)) {
1862 err = -EFAULT;
1863 break;
1864 }
Marcel Holtmann0878b662007-05-05 00:35:59 +02001865
João Paulo Rechi Vita0041ecf2010-05-01 16:15:42 -03001866 l2cap_pi(sk)->mode = opts.mode;
1867 switch (l2cap_pi(sk)->mode) {
1868 case L2CAP_MODE_BASIC:
1869 break;
1870 case L2CAP_MODE_ERTM:
1871 case L2CAP_MODE_STREAMING:
1872 if (enable_ertm)
1873 break;
1874 /* fall through */
1875 default:
1876 err = -EINVAL;
1877 break;
1878 }
1879
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001880 l2cap_pi(sk)->imtu = opts.imtu;
1881 l2cap_pi(sk)->omtu = opts.omtu;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001882 l2cap_pi(sk)->fcs = opts.fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03001883 l2cap_pi(sk)->max_tx = opts.max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03001884 l2cap_pi(sk)->tx_win = (__u8)opts.txwin_size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001885 break;
1886
1887 case L2CAP_LM:
1888 if (get_user(opt, (u32 __user *) optval)) {
1889 err = -EFAULT;
1890 break;
1891 }
1892
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001893 if (opt & L2CAP_LM_AUTH)
1894 l2cap_pi(sk)->sec_level = BT_SECURITY_LOW;
1895 if (opt & L2CAP_LM_ENCRYPT)
1896 l2cap_pi(sk)->sec_level = BT_SECURITY_MEDIUM;
1897 if (opt & L2CAP_LM_SECURE)
1898 l2cap_pi(sk)->sec_level = BT_SECURITY_HIGH;
1899
1900 l2cap_pi(sk)->role_switch = (opt & L2CAP_LM_MASTER);
1901 l2cap_pi(sk)->force_reliable = (opt & L2CAP_LM_RELIABLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001902 break;
1903
1904 default:
1905 err = -ENOPROTOOPT;
1906 break;
1907 }
1908
1909 release_sock(sk);
1910 return err;
1911}
1912
David S. Millerb7058842009-09-30 16:12:20 -07001913static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001914{
1915 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001916 struct bt_security sec;
1917 int len, err = 0;
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001918 u32 opt;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001919
1920 BT_DBG("sk %p", sk);
1921
1922 if (level == SOL_L2CAP)
1923 return l2cap_sock_setsockopt_old(sock, optname, optval, optlen);
1924
Marcel Holtmann0588d942009-01-16 10:06:13 +01001925 if (level != SOL_BLUETOOTH)
1926 return -ENOPROTOOPT;
1927
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001928 lock_sock(sk);
1929
1930 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001931 case BT_SECURITY:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001932 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
1933 && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01001934 err = -EINVAL;
1935 break;
1936 }
1937
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001938 sec.level = BT_SECURITY_LOW;
1939
1940 len = min_t(unsigned int, sizeof(sec), optlen);
1941 if (copy_from_user((char *) &sec, optval, len)) {
1942 err = -EFAULT;
1943 break;
1944 }
1945
1946 if (sec.level < BT_SECURITY_LOW ||
1947 sec.level > BT_SECURITY_HIGH) {
1948 err = -EINVAL;
1949 break;
1950 }
1951
1952 l2cap_pi(sk)->sec_level = sec.level;
1953 break;
1954
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001955 case BT_DEFER_SETUP:
1956 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
1957 err = -EINVAL;
1958 break;
1959 }
1960
1961 if (get_user(opt, (u32 __user *) optval)) {
1962 err = -EFAULT;
1963 break;
1964 }
1965
1966 bt_sk(sk)->defer_setup = opt;
1967 break;
1968
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001969 default:
1970 err = -ENOPROTOOPT;
1971 break;
1972 }
1973
1974 release_sock(sk);
1975 return err;
1976}
1977
1978static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001979{
1980 struct sock *sk = sock->sk;
1981 struct l2cap_options opts;
1982 struct l2cap_conninfo cinfo;
1983 int len, err = 0;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001984 u32 opt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001985
1986 BT_DBG("sk %p", sk);
1987
1988 if (get_user(len, optlen))
1989 return -EFAULT;
1990
1991 lock_sock(sk);
1992
1993 switch (optname) {
1994 case L2CAP_OPTIONS:
1995 opts.imtu = l2cap_pi(sk)->imtu;
1996 opts.omtu = l2cap_pi(sk)->omtu;
1997 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001998 opts.mode = l2cap_pi(sk)->mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001999 opts.fcs = l2cap_pi(sk)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03002000 opts.max_tx = l2cap_pi(sk)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03002001 opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002002
2003 len = min_t(unsigned int, len, sizeof(opts));
2004 if (copy_to_user(optval, (char *) &opts, len))
2005 err = -EFAULT;
2006
2007 break;
2008
2009 case L2CAP_LM:
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002010 switch (l2cap_pi(sk)->sec_level) {
2011 case BT_SECURITY_LOW:
2012 opt = L2CAP_LM_AUTH;
2013 break;
2014 case BT_SECURITY_MEDIUM:
2015 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT;
2016 break;
2017 case BT_SECURITY_HIGH:
2018 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT |
2019 L2CAP_LM_SECURE;
2020 break;
2021 default:
2022 opt = 0;
2023 break;
2024 }
2025
2026 if (l2cap_pi(sk)->role_switch)
2027 opt |= L2CAP_LM_MASTER;
2028
2029 if (l2cap_pi(sk)->force_reliable)
2030 opt |= L2CAP_LM_RELIABLE;
2031
2032 if (put_user(opt, (u32 __user *) optval))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002033 err = -EFAULT;
2034 break;
2035
2036 case L2CAP_CONNINFO:
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002037 if (sk->sk_state != BT_CONNECTED &&
2038 !(sk->sk_state == BT_CONNECT2 &&
2039 bt_sk(sk)->defer_setup)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002040 err = -ENOTCONN;
2041 break;
2042 }
2043
2044 cinfo.hci_handle = l2cap_pi(sk)->conn->hcon->handle;
2045 memcpy(cinfo.dev_class, l2cap_pi(sk)->conn->hcon->dev_class, 3);
2046
2047 len = min_t(unsigned int, len, sizeof(cinfo));
2048 if (copy_to_user(optval, (char *) &cinfo, len))
2049 err = -EFAULT;
2050
2051 break;
2052
2053 default:
2054 err = -ENOPROTOOPT;
2055 break;
2056 }
2057
2058 release_sock(sk);
2059 return err;
2060}
2061
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002062static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
2063{
2064 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002065 struct bt_security sec;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002066 int len, err = 0;
2067
2068 BT_DBG("sk %p", sk);
2069
2070 if (level == SOL_L2CAP)
2071 return l2cap_sock_getsockopt_old(sock, optname, optval, optlen);
2072
Marcel Holtmann0588d942009-01-16 10:06:13 +01002073 if (level != SOL_BLUETOOTH)
2074 return -ENOPROTOOPT;
2075
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002076 if (get_user(len, optlen))
2077 return -EFAULT;
2078
2079 lock_sock(sk);
2080
2081 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002082 case BT_SECURITY:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03002083 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
2084 && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01002085 err = -EINVAL;
2086 break;
2087 }
2088
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002089 sec.level = l2cap_pi(sk)->sec_level;
2090
2091 len = min_t(unsigned int, len, sizeof(sec));
2092 if (copy_to_user(optval, (char *) &sec, len))
2093 err = -EFAULT;
2094
2095 break;
2096
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002097 case BT_DEFER_SETUP:
2098 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
2099 err = -EINVAL;
2100 break;
2101 }
2102
2103 if (put_user(bt_sk(sk)->defer_setup, (u32 __user *) optval))
2104 err = -EFAULT;
2105
2106 break;
2107
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002108 default:
2109 err = -ENOPROTOOPT;
2110 break;
2111 }
2112
2113 release_sock(sk);
2114 return err;
2115}
2116
Linus Torvalds1da177e2005-04-16 15:20:36 -07002117static int l2cap_sock_shutdown(struct socket *sock, int how)
2118{
2119 struct sock *sk = sock->sk;
2120 int err = 0;
2121
2122 BT_DBG("sock %p, sk %p", sock, sk);
2123
2124 if (!sk)
2125 return 0;
2126
2127 lock_sock(sk);
2128 if (!sk->sk_shutdown) {
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03002129 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
2130 err = __l2cap_wait_ack(sk);
2131
Linus Torvalds1da177e2005-04-16 15:20:36 -07002132 sk->sk_shutdown = SHUTDOWN_MASK;
2133 l2cap_sock_clear_timer(sk);
2134 __l2cap_sock_close(sk, 0);
2135
2136 if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
Marcel Holtmannb1235d72008-07-14 20:13:54 +02002137 err = bt_sock_wait_state(sk, BT_CLOSED,
2138 sk->sk_lingertime);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002139 }
2140 release_sock(sk);
2141 return err;
2142}
2143
2144static int l2cap_sock_release(struct socket *sock)
2145{
2146 struct sock *sk = sock->sk;
2147 int err;
2148
2149 BT_DBG("sock %p, sk %p", sock, sk);
2150
2151 if (!sk)
2152 return 0;
2153
2154 err = l2cap_sock_shutdown(sock, 2);
2155
2156 sock_orphan(sk);
2157 l2cap_sock_kill(sk);
2158 return err;
2159}
2160
Linus Torvalds1da177e2005-04-16 15:20:36 -07002161static void l2cap_chan_ready(struct sock *sk)
2162{
2163 struct sock *parent = bt_sk(sk)->parent;
2164
2165 BT_DBG("sk %p, parent %p", sk, parent);
2166
2167 l2cap_pi(sk)->conf_state = 0;
2168 l2cap_sock_clear_timer(sk);
2169
2170 if (!parent) {
2171 /* Outgoing channel.
2172 * Wake up socket sleeping on connect.
2173 */
2174 sk->sk_state = BT_CONNECTED;
2175 sk->sk_state_change(sk);
2176 } else {
2177 /* Incoming channel.
2178 * Wake up socket sleeping on accept.
2179 */
2180 parent->sk_data_ready(parent, 0);
2181 }
2182}
2183
2184/* Copy frame to all raw sockets on that connection */
2185static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2186{
2187 struct l2cap_chan_list *l = &conn->chan_list;
2188 struct sk_buff *nskb;
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002189 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002190
2191 BT_DBG("conn %p", conn);
2192
2193 read_lock(&l->lock);
2194 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
2195 if (sk->sk_type != SOCK_RAW)
2196 continue;
2197
2198 /* Don't send frame to the socket it came from */
2199 if (skb->sk == sk)
2200 continue;
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002201 nskb = skb_clone(skb, GFP_ATOMIC);
2202 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002203 continue;
2204
2205 if (sock_queue_rcv_skb(sk, nskb))
2206 kfree_skb(nskb);
2207 }
2208 read_unlock(&l->lock);
2209}
2210
2211/* ---- L2CAP signalling commands ---- */
2212static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
2213 u8 code, u8 ident, u16 dlen, void *data)
2214{
2215 struct sk_buff *skb, **frag;
2216 struct l2cap_cmd_hdr *cmd;
2217 struct l2cap_hdr *lh;
2218 int len, count;
2219
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002220 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d",
2221 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002222
2223 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2224 count = min_t(unsigned int, conn->mtu, len);
2225
2226 skb = bt_skb_alloc(count, GFP_ATOMIC);
2227 if (!skb)
2228 return NULL;
2229
2230 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002231 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03002232 lh->cid = cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002233
2234 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2235 cmd->code = code;
2236 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002237 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002238
2239 if (dlen) {
2240 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2241 memcpy(skb_put(skb, count), data, count);
2242 data += count;
2243 }
2244
2245 len -= skb->len;
2246
2247 /* Continuation fragments (no L2CAP header) */
2248 frag = &skb_shinfo(skb)->frag_list;
2249 while (len) {
2250 count = min_t(unsigned int, conn->mtu, len);
2251
2252 *frag = bt_skb_alloc(count, GFP_ATOMIC);
2253 if (!*frag)
2254 goto fail;
2255
2256 memcpy(skb_put(*frag, count), data, count);
2257
2258 len -= count;
2259 data += count;
2260
2261 frag = &(*frag)->next;
2262 }
2263
2264 return skb;
2265
2266fail:
2267 kfree_skb(skb);
2268 return NULL;
2269}
2270
2271static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned long *val)
2272{
2273 struct l2cap_conf_opt *opt = *ptr;
2274 int len;
2275
2276 len = L2CAP_CONF_OPT_SIZE + opt->len;
2277 *ptr += len;
2278
2279 *type = opt->type;
2280 *olen = opt->len;
2281
2282 switch (opt->len) {
2283 case 1:
2284 *val = *((u8 *) opt->val);
2285 break;
2286
2287 case 2:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002288 *val = __le16_to_cpu(*((__le16 *) opt->val));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002289 break;
2290
2291 case 4:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002292 *val = __le32_to_cpu(*((__le32 *) opt->val));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002293 break;
2294
2295 default:
2296 *val = (unsigned long) opt->val;
2297 break;
2298 }
2299
2300 BT_DBG("type 0x%2.2x len %d val 0x%lx", *type, opt->len, *val);
2301 return len;
2302}
2303
Linus Torvalds1da177e2005-04-16 15:20:36 -07002304static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2305{
2306 struct l2cap_conf_opt *opt = *ptr;
2307
2308 BT_DBG("type 0x%2.2x len %d val 0x%lx", type, len, val);
2309
2310 opt->type = type;
2311 opt->len = len;
2312
2313 switch (len) {
2314 case 1:
2315 *((u8 *) opt->val) = val;
2316 break;
2317
2318 case 2:
Al Viro8e036fc2007-07-29 00:16:36 -07002319 *((__le16 *) opt->val) = cpu_to_le16(val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002320 break;
2321
2322 case 4:
Al Viro8e036fc2007-07-29 00:16:36 -07002323 *((__le32 *) opt->val) = cpu_to_le32(val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002324 break;
2325
2326 default:
2327 memcpy(opt->val, (void *) val, len);
2328 break;
2329 }
2330
2331 *ptr += L2CAP_CONF_OPT_SIZE + len;
2332}
2333
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002334static void l2cap_ack_timeout(unsigned long arg)
2335{
2336 struct sock *sk = (void *) arg;
2337
2338 bh_lock_sock(sk);
2339 l2cap_send_ack(l2cap_pi(sk));
2340 bh_unlock_sock(sk);
2341}
2342
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002343static inline void l2cap_ertm_init(struct sock *sk)
2344{
2345 l2cap_pi(sk)->expected_ack_seq = 0;
2346 l2cap_pi(sk)->unacked_frames = 0;
2347 l2cap_pi(sk)->buffer_seq = 0;
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03002348 l2cap_pi(sk)->num_acked = 0;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03002349 l2cap_pi(sk)->frames_sent = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002350
2351 setup_timer(&l2cap_pi(sk)->retrans_timer,
2352 l2cap_retrans_timeout, (unsigned long) sk);
2353 setup_timer(&l2cap_pi(sk)->monitor_timer,
2354 l2cap_monitor_timeout, (unsigned long) sk);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002355 setup_timer(&l2cap_pi(sk)->ack_timer,
2356 l2cap_ack_timeout, (unsigned long) sk);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002357
2358 __skb_queue_head_init(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002359 __skb_queue_head_init(BUSY_QUEUE(sk));
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03002360 spin_lock_init(&l2cap_pi(sk)->send_lock);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002361
2362 INIT_WORK(&l2cap_pi(sk)->busy_work, l2cap_busy_work);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002363}
2364
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002365static int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
2366{
2367 u32 local_feat_mask = l2cap_feat_mask;
2368 if (enable_ertm)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002369 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002370
2371 switch (mode) {
2372 case L2CAP_MODE_ERTM:
2373 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
2374 case L2CAP_MODE_STREAMING:
2375 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
2376 default:
2377 return 0x00;
2378 }
2379}
2380
2381static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
2382{
2383 switch (mode) {
2384 case L2CAP_MODE_STREAMING:
2385 case L2CAP_MODE_ERTM:
2386 if (l2cap_mode_supported(mode, remote_feat_mask))
2387 return mode;
2388 /* fall through */
2389 default:
2390 return L2CAP_MODE_BASIC;
2391 }
2392}
2393
Linus Torvalds1da177e2005-04-16 15:20:36 -07002394static int l2cap_build_conf_req(struct sock *sk, void *data)
2395{
2396 struct l2cap_pinfo *pi = l2cap_pi(sk);
2397 struct l2cap_conf_req *req = data;
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03002398 struct l2cap_conf_rfc rfc = { .mode = pi->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07002399 void *ptr = req->data;
2400
2401 BT_DBG("sk %p", sk);
2402
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002403 if (pi->num_conf_req || pi->num_conf_rsp)
2404 goto done;
2405
2406 switch (pi->mode) {
2407 case L2CAP_MODE_STREAMING:
2408 case L2CAP_MODE_ERTM:
2409 pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002410 if (!l2cap_mode_supported(pi->mode, pi->conn->feat_mask))
2411 l2cap_send_disconn_req(pi->conn, sk);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002412 break;
2413 default:
2414 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
2415 break;
2416 }
2417
2418done:
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002419 switch (pi->mode) {
2420 case L2CAP_MODE_BASIC:
2421 if (pi->imtu != L2CAP_DEFAULT_MTU)
2422 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
2423 break;
2424
2425 case L2CAP_MODE_ERTM:
2426 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03002427 rfc.txwin_size = pi->tx_win;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03002428 rfc.max_transmit = pi->max_tx;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002429 rfc.retrans_timeout = 0;
2430 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002431 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03002432 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002433 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002434
2435 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2436 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002437
2438 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2439 break;
2440
2441 if (pi->fcs == L2CAP_FCS_NONE ||
2442 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
2443 pi->fcs = L2CAP_FCS_NONE;
2444 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
2445 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002446 break;
2447
2448 case L2CAP_MODE_STREAMING:
2449 rfc.mode = L2CAP_MODE_STREAMING;
2450 rfc.txwin_size = 0;
2451 rfc.max_transmit = 0;
2452 rfc.retrans_timeout = 0;
2453 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002454 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03002455 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002456 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002457
2458 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2459 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002460
2461 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2462 break;
2463
2464 if (pi->fcs == L2CAP_FCS_NONE ||
2465 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
2466 pi->fcs = L2CAP_FCS_NONE;
2467 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
2468 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002469 break;
2470 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002471
2472 /* FIXME: Need actual value of the flush timeout */
2473 //if (flush_to != L2CAP_DEFAULT_FLUSH_TO)
2474 // l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2, pi->flush_to);
2475
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002476 req->dcid = cpu_to_le16(pi->dcid);
2477 req->flags = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002478
2479 return ptr - data;
2480}
2481
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002482static int l2cap_parse_conf_req(struct sock *sk, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002483{
2484 struct l2cap_pinfo *pi = l2cap_pi(sk);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002485 struct l2cap_conf_rsp *rsp = data;
2486 void *ptr = rsp->data;
2487 void *req = pi->conf_req;
2488 int len = pi->conf_len;
2489 int type, hint, olen;
2490 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002491 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Marcel Holtmann861d6882007-10-20 13:37:06 +02002492 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002493 u16 result = L2CAP_CONF_SUCCESS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002494
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002495 BT_DBG("sk %p", sk);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01002496
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002497 while (len >= L2CAP_CONF_OPT_SIZE) {
2498 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002499
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03002500 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07002501 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002502
2503 switch (type) {
2504 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002505 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002506 break;
2507
2508 case L2CAP_CONF_FLUSH_TO:
2509 pi->flush_to = val;
2510 break;
2511
2512 case L2CAP_CONF_QOS:
2513 break;
2514
Marcel Holtmann6464f352007-10-20 13:39:51 +02002515 case L2CAP_CONF_RFC:
2516 if (olen == sizeof(rfc))
2517 memcpy(&rfc, (void *) val, olen);
2518 break;
2519
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002520 case L2CAP_CONF_FCS:
2521 if (val == L2CAP_FCS_NONE)
2522 pi->conf_state |= L2CAP_CONF_NO_FCS_RECV;
2523
2524 break;
2525
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002526 default:
2527 if (hint)
2528 break;
2529
2530 result = L2CAP_CONF_UNKNOWN;
2531 *((u8 *) ptr++) = type;
2532 break;
2533 }
2534 }
2535
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002536 if (pi->num_conf_rsp || pi->num_conf_req)
2537 goto done;
2538
2539 switch (pi->mode) {
2540 case L2CAP_MODE_STREAMING:
2541 case L2CAP_MODE_ERTM:
2542 pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
2543 if (!l2cap_mode_supported(pi->mode, pi->conn->feat_mask))
2544 return -ECONNREFUSED;
2545 break;
2546 default:
2547 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
2548 break;
2549 }
2550
2551done:
2552 if (pi->mode != rfc.mode) {
2553 result = L2CAP_CONF_UNACCEPT;
2554 rfc.mode = pi->mode;
2555
2556 if (pi->num_conf_rsp == 1)
2557 return -ECONNREFUSED;
2558
2559 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2560 sizeof(rfc), (unsigned long) &rfc);
2561 }
2562
2563
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002564 if (result == L2CAP_CONF_SUCCESS) {
2565 /* Configure output options and let the other side know
2566 * which ones we don't like. */
2567
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002568 if (mtu < L2CAP_DEFAULT_MIN_MTU)
2569 result = L2CAP_CONF_UNACCEPT;
2570 else {
2571 pi->omtu = mtu;
2572 pi->conf_state |= L2CAP_CONF_MTU_DONE;
2573 }
2574 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002575
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002576 switch (rfc.mode) {
2577 case L2CAP_MODE_BASIC:
2578 pi->fcs = L2CAP_FCS_NONE;
2579 pi->conf_state |= L2CAP_CONF_MODE_DONE;
2580 break;
2581
2582 case L2CAP_MODE_ERTM:
2583 pi->remote_tx_win = rfc.txwin_size;
2584 pi->remote_max_tx = rfc.max_transmit;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002585 if (rfc.max_pdu_size > pi->conn->mtu - 10)
2586 rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10);
2587
2588 pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002589
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002590 rfc.retrans_timeout =
2591 le16_to_cpu(L2CAP_DEFAULT_RETRANS_TO);
2592 rfc.monitor_timeout =
2593 le16_to_cpu(L2CAP_DEFAULT_MONITOR_TO);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002594
2595 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03002596
2597 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2598 sizeof(rfc), (unsigned long) &rfc);
2599
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002600 break;
2601
2602 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002603 if (rfc.max_pdu_size > pi->conn->mtu - 10)
2604 rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10);
2605
2606 pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002607
2608 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03002609
2610 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2611 sizeof(rfc), (unsigned long) &rfc);
2612
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002613 break;
2614
2615 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02002616 result = L2CAP_CONF_UNACCEPT;
2617
2618 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002619 rfc.mode = pi->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002620 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002621
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002622 if (result == L2CAP_CONF_SUCCESS)
2623 pi->conf_state |= L2CAP_CONF_OUTPUT_DONE;
2624 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002625 rsp->scid = cpu_to_le16(pi->dcid);
2626 rsp->result = cpu_to_le16(result);
2627 rsp->flags = cpu_to_le16(0x0000);
2628
2629 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002630}
2631
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002632static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data, u16 *result)
2633{
2634 struct l2cap_pinfo *pi = l2cap_pi(sk);
2635 struct l2cap_conf_req *req = data;
2636 void *ptr = req->data;
2637 int type, olen;
2638 unsigned long val;
2639 struct l2cap_conf_rfc rfc;
2640
2641 BT_DBG("sk %p, rsp %p, len %d, req %p", sk, rsp, len, data);
2642
2643 while (len >= L2CAP_CONF_OPT_SIZE) {
2644 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
2645
2646 switch (type) {
2647 case L2CAP_CONF_MTU:
2648 if (val < L2CAP_DEFAULT_MIN_MTU) {
2649 *result = L2CAP_CONF_UNACCEPT;
2650 pi->omtu = L2CAP_DEFAULT_MIN_MTU;
2651 } else
2652 pi->omtu = val;
2653 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
2654 break;
2655
2656 case L2CAP_CONF_FLUSH_TO:
2657 pi->flush_to = val;
2658 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
2659 2, pi->flush_to);
2660 break;
2661
2662 case L2CAP_CONF_RFC:
2663 if (olen == sizeof(rfc))
2664 memcpy(&rfc, (void *)val, olen);
2665
2666 if ((pi->conf_state & L2CAP_CONF_STATE2_DEVICE) &&
2667 rfc.mode != pi->mode)
2668 return -ECONNREFUSED;
2669
2670 pi->mode = rfc.mode;
2671 pi->fcs = 0;
2672
2673 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2674 sizeof(rfc), (unsigned long) &rfc);
2675 break;
2676 }
2677 }
2678
2679 if (*result == L2CAP_CONF_SUCCESS) {
2680 switch (rfc.mode) {
2681 case L2CAP_MODE_ERTM:
2682 pi->remote_tx_win = rfc.txwin_size;
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002683 pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
2684 pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002685 pi->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002686 break;
2687 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002688 pi->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002689 }
2690 }
2691
2692 req->dcid = cpu_to_le16(pi->dcid);
2693 req->flags = cpu_to_le16(0x0000);
2694
2695 return ptr - data;
2696}
2697
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002698static int l2cap_build_conf_rsp(struct sock *sk, void *data, u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002699{
2700 struct l2cap_conf_rsp *rsp = data;
2701 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002702
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002703 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002704
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002705 rsp->scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002706 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002707 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002708
2709 return ptr - data;
2710}
2711
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002712static void l2cap_conf_rfc_get(struct sock *sk, void *rsp, int len)
2713{
2714 struct l2cap_pinfo *pi = l2cap_pi(sk);
2715 int type, olen;
2716 unsigned long val;
2717 struct l2cap_conf_rfc rfc;
2718
2719 BT_DBG("sk %p, rsp %p, len %d", sk, rsp, len);
2720
2721 if ((pi->mode != L2CAP_MODE_ERTM) && (pi->mode != L2CAP_MODE_STREAMING))
2722 return;
2723
2724 while (len >= L2CAP_CONF_OPT_SIZE) {
2725 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
2726
2727 switch (type) {
2728 case L2CAP_CONF_RFC:
2729 if (olen == sizeof(rfc))
2730 memcpy(&rfc, (void *)val, olen);
2731 goto done;
2732 }
2733 }
2734
2735done:
2736 switch (rfc.mode) {
2737 case L2CAP_MODE_ERTM:
2738 pi->remote_tx_win = rfc.txwin_size;
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002739 pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
2740 pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002741 pi->mps = le16_to_cpu(rfc.max_pdu_size);
2742 break;
2743 case L2CAP_MODE_STREAMING:
2744 pi->mps = le16_to_cpu(rfc.max_pdu_size);
2745 }
2746}
2747
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002748static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2749{
2750 struct l2cap_cmd_rej *rej = (struct l2cap_cmd_rej *) data;
2751
2752 if (rej->reason != 0x0000)
2753 return 0;
2754
2755 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
2756 cmd->ident == conn->info_ident) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002757 del_timer(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01002758
2759 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002760 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01002761
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002762 l2cap_conn_start(conn);
2763 }
2764
2765 return 0;
2766}
2767
Linus Torvalds1da177e2005-04-16 15:20:36 -07002768static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2769{
2770 struct l2cap_chan_list *list = &conn->chan_list;
2771 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
2772 struct l2cap_conn_rsp rsp;
2773 struct sock *sk, *parent;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002774 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002775
2776 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002777 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002778
2779 BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
2780
2781 /* Check if we have socket listening on psm */
2782 parent = l2cap_get_sock_by_psm(BT_LISTEN, psm, conn->src);
2783 if (!parent) {
2784 result = L2CAP_CR_BAD_PSM;
2785 goto sendresp;
2786 }
2787
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002788 /* Check if the ACL is secure enough (if not SDP) */
2789 if (psm != cpu_to_le16(0x0001) &&
2790 !hci_conn_check_link_mode(conn->hcon)) {
Marcel Holtmann2950f212009-02-12 14:02:50 +01002791 conn->disc_reason = 0x05;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002792 result = L2CAP_CR_SEC_BLOCK;
2793 goto response;
2794 }
2795
Linus Torvalds1da177e2005-04-16 15:20:36 -07002796 result = L2CAP_CR_NO_MEM;
2797
2798 /* Check for backlog size */
2799 if (sk_acceptq_is_full(parent)) {
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09002800 BT_DBG("backlog full %d", parent->sk_ack_backlog);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002801 goto response;
2802 }
2803
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09002804 sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002805 if (!sk)
2806 goto response;
2807
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002808 write_lock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002809
2810 /* Check if we already have channel with that dcid */
2811 if (__l2cap_get_chan_by_dcid(list, scid)) {
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002812 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002813 sock_set_flag(sk, SOCK_ZAPPED);
2814 l2cap_sock_kill(sk);
2815 goto response;
2816 }
2817
2818 hci_conn_hold(conn->hcon);
2819
2820 l2cap_sock_init(sk, parent);
2821 bacpy(&bt_sk(sk)->src, conn->src);
2822 bacpy(&bt_sk(sk)->dst, conn->dst);
2823 l2cap_pi(sk)->psm = psm;
2824 l2cap_pi(sk)->dcid = scid;
2825
2826 __l2cap_chan_add(conn, sk, parent);
2827 dcid = l2cap_pi(sk)->scid;
2828
2829 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
2830
Linus Torvalds1da177e2005-04-16 15:20:36 -07002831 l2cap_pi(sk)->ident = cmd->ident;
2832
Marcel Holtmann984947d2009-02-06 23:35:19 +01002833 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002834 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002835 if (bt_sk(sk)->defer_setup) {
2836 sk->sk_state = BT_CONNECT2;
2837 result = L2CAP_CR_PEND;
2838 status = L2CAP_CS_AUTHOR_PEND;
2839 parent->sk_data_ready(parent, 0);
2840 } else {
2841 sk->sk_state = BT_CONFIG;
2842 result = L2CAP_CR_SUCCESS;
2843 status = L2CAP_CS_NO_INFO;
2844 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002845 } else {
2846 sk->sk_state = BT_CONNECT2;
2847 result = L2CAP_CR_PEND;
2848 status = L2CAP_CS_AUTHEN_PEND;
2849 }
2850 } else {
2851 sk->sk_state = BT_CONNECT2;
2852 result = L2CAP_CR_PEND;
2853 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002854 }
2855
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002856 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002857
2858response:
2859 bh_unlock_sock(parent);
2860
2861sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002862 rsp.scid = cpu_to_le16(scid);
2863 rsp.dcid = cpu_to_le16(dcid);
2864 rsp.result = cpu_to_le16(result);
2865 rsp.status = cpu_to_le16(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002866 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002867
2868 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
2869 struct l2cap_info_req info;
2870 info.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
2871
2872 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
2873 conn->info_ident = l2cap_get_ident(conn);
2874
2875 mod_timer(&conn->info_timer, jiffies +
2876 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
2877
2878 l2cap_send_cmd(conn, conn->info_ident,
2879 L2CAP_INFO_REQ, sizeof(info), &info);
2880 }
2881
Linus Torvalds1da177e2005-04-16 15:20:36 -07002882 return 0;
2883}
2884
2885static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2886{
2887 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
2888 u16 scid, dcid, result, status;
2889 struct sock *sk;
2890 u8 req[128];
2891
2892 scid = __le16_to_cpu(rsp->scid);
2893 dcid = __le16_to_cpu(rsp->dcid);
2894 result = __le16_to_cpu(rsp->result);
2895 status = __le16_to_cpu(rsp->status);
2896
2897 BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
2898
2899 if (scid) {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002900 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2901 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002902 return 0;
2903 } else {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002904 sk = l2cap_get_chan_by_ident(&conn->chan_list, cmd->ident);
2905 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002906 return 0;
2907 }
2908
2909 switch (result) {
2910 case L2CAP_CR_SUCCESS:
2911 sk->sk_state = BT_CONFIG;
2912 l2cap_pi(sk)->ident = 0;
2913 l2cap_pi(sk)->dcid = dcid;
2914 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
2915
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002916 l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_CONNECT_PEND;
2917
Linus Torvalds1da177e2005-04-16 15:20:36 -07002918 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
2919 l2cap_build_conf_req(sk, req), req);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002920 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002921 break;
2922
2923 case L2CAP_CR_PEND:
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002924 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002925 break;
2926
2927 default:
2928 l2cap_chan_del(sk, ECONNREFUSED);
2929 break;
2930 }
2931
2932 bh_unlock_sock(sk);
2933 return 0;
2934}
2935
Al Viro88219a02007-07-29 00:17:25 -07002936static 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 -07002937{
2938 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
2939 u16 dcid, flags;
2940 u8 rsp[64];
2941 struct sock *sk;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002942 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002943
2944 dcid = __le16_to_cpu(req->dcid);
2945 flags = __le16_to_cpu(req->flags);
2946
2947 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
2948
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002949 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
2950 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002951 return -ENOENT;
2952
Marcel Holtmann354f60a2006-11-18 22:15:20 +01002953 if (sk->sk_state == BT_DISCONN)
2954 goto unlock;
2955
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002956 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07002957 len = cmd_len - sizeof(*req);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002958 if (l2cap_pi(sk)->conf_len + len > sizeof(l2cap_pi(sk)->conf_req)) {
2959 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
2960 l2cap_build_conf_rsp(sk, rsp,
2961 L2CAP_CONF_REJECT, flags), rsp);
2962 goto unlock;
2963 }
2964
2965 /* Store config. */
2966 memcpy(l2cap_pi(sk)->conf_req + l2cap_pi(sk)->conf_len, req->data, len);
2967 l2cap_pi(sk)->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002968
2969 if (flags & 0x0001) {
2970 /* Incomplete config. Send empty response. */
2971 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002972 l2cap_build_conf_rsp(sk, rsp,
2973 L2CAP_CONF_SUCCESS, 0x0001), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002974 goto unlock;
2975 }
2976
2977 /* Complete config. */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002978 len = l2cap_parse_conf_req(sk, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002979 if (len < 0) {
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002980 l2cap_send_disconn_req(conn, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002981 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002982 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002983
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002984 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002985 l2cap_pi(sk)->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002986
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002987 /* Reset config buffer. */
2988 l2cap_pi(sk)->conf_len = 0;
2989
Marcel Holtmann876d9482007-10-20 13:35:42 +02002990 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE))
2991 goto unlock;
2992
Linus Torvalds1da177e2005-04-16 15:20:36 -07002993 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) {
Joe Perchesf64f9e72009-11-29 16:55:45 -08002994 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) ||
2995 l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002996 l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
2997
Linus Torvalds1da177e2005-04-16 15:20:36 -07002998 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002999
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003000 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003001 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003002 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003003 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
3004 l2cap_ertm_init(sk);
3005
Linus Torvalds1da177e2005-04-16 15:20:36 -07003006 l2cap_chan_ready(sk);
Marcel Holtmann876d9482007-10-20 13:35:42 +02003007 goto unlock;
3008 }
3009
3010 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003011 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003012 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003013 l2cap_build_conf_req(sk, buf), buf);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003014 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003015 }
3016
3017unlock:
3018 bh_unlock_sock(sk);
3019 return 0;
3020}
3021
3022static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3023{
3024 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
3025 u16 scid, flags, result;
3026 struct sock *sk;
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003027 int len = cmd->len - sizeof(*rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003028
3029 scid = __le16_to_cpu(rsp->scid);
3030 flags = __le16_to_cpu(rsp->flags);
3031 result = __le16_to_cpu(rsp->result);
3032
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003033 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x",
3034 scid, flags, result);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003035
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003036 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
3037 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003038 return 0;
3039
3040 switch (result) {
3041 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003042 l2cap_conf_rfc_get(sk, rsp->data, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003043 break;
3044
3045 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003046 if (l2cap_pi(sk)->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003047 char req[64];
3048
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02003049 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
3050 l2cap_send_disconn_req(conn, sk);
3051 goto done;
3052 }
3053
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003054 /* throw out any old stored conf requests */
3055 result = L2CAP_CONF_SUCCESS;
3056 len = l2cap_parse_conf_rsp(sk, rsp->data,
3057 len, req, &result);
3058 if (len < 0) {
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03003059 l2cap_send_disconn_req(conn, sk);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003060 goto done;
3061 }
3062
3063 l2cap_send_cmd(conn, l2cap_get_ident(conn),
3064 L2CAP_CONF_REQ, len, req);
3065 l2cap_pi(sk)->num_conf_req++;
3066 if (result != L2CAP_CONF_SUCCESS)
3067 goto done;
3068 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003069 }
3070
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09003071 default:
Linus Torvalds1da177e2005-04-16 15:20:36 -07003072 sk->sk_state = BT_DISCONN;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02003073 sk->sk_err = ECONNRESET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003074 l2cap_sock_set_timer(sk, HZ * 5);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03003075 l2cap_send_disconn_req(conn, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003076 goto done;
3077 }
3078
3079 if (flags & 0x01)
3080 goto done;
3081
Linus Torvalds1da177e2005-04-16 15:20:36 -07003082 l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE;
3083
3084 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) {
Joe Perchesf64f9e72009-11-29 16:55:45 -08003085 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) ||
3086 l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003087 l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
3088
Linus Torvalds1da177e2005-04-16 15:20:36 -07003089 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003090 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003091 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003092 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003093 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
3094 l2cap_ertm_init(sk);
3095
Linus Torvalds1da177e2005-04-16 15:20:36 -07003096 l2cap_chan_ready(sk);
3097 }
3098
3099done:
3100 bh_unlock_sock(sk);
3101 return 0;
3102}
3103
3104static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3105{
3106 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
3107 struct l2cap_disconn_rsp rsp;
3108 u16 dcid, scid;
3109 struct sock *sk;
3110
3111 scid = __le16_to_cpu(req->scid);
3112 dcid = __le16_to_cpu(req->dcid);
3113
3114 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
3115
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003116 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
3117 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003118 return 0;
3119
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003120 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
3121 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003122 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
3123
3124 sk->sk_shutdown = SHUTDOWN_MASK;
3125
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003126 skb_queue_purge(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003127
3128 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
3129 skb_queue_purge(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003130 skb_queue_purge(BUSY_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003131 del_timer(&l2cap_pi(sk)->retrans_timer);
3132 del_timer(&l2cap_pi(sk)->monitor_timer);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003133 del_timer(&l2cap_pi(sk)->ack_timer);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003134 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003135
Linus Torvalds1da177e2005-04-16 15:20:36 -07003136 l2cap_chan_del(sk, ECONNRESET);
3137 bh_unlock_sock(sk);
3138
3139 l2cap_sock_kill(sk);
3140 return 0;
3141}
3142
3143static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3144{
3145 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
3146 u16 dcid, scid;
3147 struct sock *sk;
3148
3149 scid = __le16_to_cpu(rsp->scid);
3150 dcid = __le16_to_cpu(rsp->dcid);
3151
3152 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
3153
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003154 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
3155 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003156 return 0;
3157
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003158 skb_queue_purge(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003159
3160 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
3161 skb_queue_purge(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003162 skb_queue_purge(BUSY_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003163 del_timer(&l2cap_pi(sk)->retrans_timer);
3164 del_timer(&l2cap_pi(sk)->monitor_timer);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003165 del_timer(&l2cap_pi(sk)->ack_timer);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003166 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003167
Linus Torvalds1da177e2005-04-16 15:20:36 -07003168 l2cap_chan_del(sk, 0);
3169 bh_unlock_sock(sk);
3170
3171 l2cap_sock_kill(sk);
3172 return 0;
3173}
3174
3175static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3176{
3177 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003178 u16 type;
3179
3180 type = __le16_to_cpu(req->type);
3181
3182 BT_DBG("type 0x%4.4x", type);
3183
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003184 if (type == L2CAP_IT_FEAT_MASK) {
3185 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003186 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003187 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
3188 rsp->type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
3189 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003190 if (enable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003191 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
3192 | L2CAP_FEAT_FCS;
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03003193 put_unaligned_le32(feat_mask, rsp->data);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003194 l2cap_send_cmd(conn, cmd->ident,
3195 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003196 } else if (type == L2CAP_IT_FIXED_CHAN) {
3197 u8 buf[12];
3198 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
3199 rsp->type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3200 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
3201 memcpy(buf + 4, l2cap_fixed_chan, 8);
3202 l2cap_send_cmd(conn, cmd->ident,
3203 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003204 } else {
3205 struct l2cap_info_rsp rsp;
3206 rsp.type = cpu_to_le16(type);
3207 rsp.result = cpu_to_le16(L2CAP_IR_NOTSUPP);
3208 l2cap_send_cmd(conn, cmd->ident,
3209 L2CAP_INFO_RSP, sizeof(rsp), &rsp);
3210 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003211
3212 return 0;
3213}
3214
3215static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3216{
3217 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
3218 u16 type, result;
3219
3220 type = __le16_to_cpu(rsp->type);
3221 result = __le16_to_cpu(rsp->result);
3222
3223 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
3224
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003225 del_timer(&conn->info_timer);
3226
Marcel Holtmann984947d2009-02-06 23:35:19 +01003227 if (type == L2CAP_IT_FEAT_MASK) {
Harvey Harrison83985312008-05-02 16:25:46 -07003228 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003229
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003230 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003231 struct l2cap_info_req req;
3232 req.type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3233
3234 conn->info_ident = l2cap_get_ident(conn);
3235
3236 l2cap_send_cmd(conn, conn->info_ident,
3237 L2CAP_INFO_REQ, sizeof(req), &req);
3238 } else {
3239 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
3240 conn->info_ident = 0;
3241
3242 l2cap_conn_start(conn);
3243 }
3244 } else if (type == L2CAP_IT_FIXED_CHAN) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01003245 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003246 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003247
3248 l2cap_conn_start(conn);
3249 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003250
Linus Torvalds1da177e2005-04-16 15:20:36 -07003251 return 0;
3252}
3253
3254static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
3255{
3256 u8 *data = skb->data;
3257 int len = skb->len;
3258 struct l2cap_cmd_hdr cmd;
3259 int err = 0;
3260
3261 l2cap_raw_recv(conn, skb);
3262
3263 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07003264 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003265 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
3266 data += L2CAP_CMD_HDR_SIZE;
3267 len -= L2CAP_CMD_HDR_SIZE;
3268
Al Viro88219a02007-07-29 00:17:25 -07003269 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003270
Al Viro88219a02007-07-29 00:17:25 -07003271 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 -07003272
Al Viro88219a02007-07-29 00:17:25 -07003273 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003274 BT_DBG("corrupted command");
3275 break;
3276 }
3277
3278 switch (cmd.code) {
3279 case L2CAP_COMMAND_REJ:
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003280 l2cap_command_rej(conn, &cmd, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003281 break;
3282
3283 case L2CAP_CONN_REQ:
3284 err = l2cap_connect_req(conn, &cmd, data);
3285 break;
3286
3287 case L2CAP_CONN_RSP:
3288 err = l2cap_connect_rsp(conn, &cmd, data);
3289 break;
3290
3291 case L2CAP_CONF_REQ:
Al Viro88219a02007-07-29 00:17:25 -07003292 err = l2cap_config_req(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003293 break;
3294
3295 case L2CAP_CONF_RSP:
3296 err = l2cap_config_rsp(conn, &cmd, data);
3297 break;
3298
3299 case L2CAP_DISCONN_REQ:
3300 err = l2cap_disconnect_req(conn, &cmd, data);
3301 break;
3302
3303 case L2CAP_DISCONN_RSP:
3304 err = l2cap_disconnect_rsp(conn, &cmd, data);
3305 break;
3306
3307 case L2CAP_ECHO_REQ:
Al Viro88219a02007-07-29 00:17:25 -07003308 l2cap_send_cmd(conn, cmd.ident, L2CAP_ECHO_RSP, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003309 break;
3310
3311 case L2CAP_ECHO_RSP:
3312 break;
3313
3314 case L2CAP_INFO_REQ:
3315 err = l2cap_information_req(conn, &cmd, data);
3316 break;
3317
3318 case L2CAP_INFO_RSP:
3319 err = l2cap_information_rsp(conn, &cmd, data);
3320 break;
3321
3322 default:
3323 BT_ERR("Unknown signaling command 0x%2.2x", cmd.code);
3324 err = -EINVAL;
3325 break;
3326 }
3327
3328 if (err) {
3329 struct l2cap_cmd_rej rej;
3330 BT_DBG("error %d", err);
3331
3332 /* FIXME: Map err to a valid reason */
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003333 rej.reason = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003334 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
3335 }
3336
Al Viro88219a02007-07-29 00:17:25 -07003337 data += cmd_len;
3338 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003339 }
3340
3341 kfree_skb(skb);
3342}
3343
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003344static int l2cap_check_fcs(struct l2cap_pinfo *pi, struct sk_buff *skb)
3345{
3346 u16 our_fcs, rcv_fcs;
3347 int hdr_size = L2CAP_HDR_SIZE + 2;
3348
3349 if (pi->fcs == L2CAP_FCS_CRC16) {
3350 skb_trim(skb, skb->len - 2);
3351 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
3352 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
3353
3354 if (our_fcs != rcv_fcs)
3355 return -EINVAL;
3356 }
3357 return 0;
3358}
3359
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003360static inline void l2cap_send_i_or_rr_or_rnr(struct sock *sk)
3361{
3362 struct l2cap_pinfo *pi = l2cap_pi(sk);
3363 u16 control = 0;
3364
3365 pi->frames_sent = 0;
3366 pi->conn_state |= L2CAP_CONN_SEND_FBIT;
3367
3368 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3369
3370 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
3371 control |= L2CAP_SUPER_RCV_NOT_READY | L2CAP_CTRL_FINAL;
3372 l2cap_send_sframe(pi, control);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003373 pi->conn_state |= L2CAP_CONN_RNR_SENT;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003374 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
3375 }
3376
3377 if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY && pi->unacked_frames > 0)
3378 __mod_retrans_timer();
3379
Gustavo F. Padovan844c0972010-05-04 23:16:01 -03003380 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3381
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003382 spin_lock_bh(&pi->send_lock);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003383 l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003384 spin_unlock_bh(&pi->send_lock);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003385
3386 if (!(pi->conn_state & L2CAP_CONN_LOCAL_BUSY) &&
3387 pi->frames_sent == 0) {
3388 control |= L2CAP_SUPER_RCV_READY;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003389 l2cap_send_sframe(pi, control);
3390 }
3391}
3392
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003393static 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 -03003394{
3395 struct sk_buff *next_skb;
3396
3397 bt_cb(skb)->tx_seq = tx_seq;
3398 bt_cb(skb)->sar = sar;
3399
3400 next_skb = skb_peek(SREJ_QUEUE(sk));
3401 if (!next_skb) {
3402 __skb_queue_tail(SREJ_QUEUE(sk), skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003403 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003404 }
3405
3406 do {
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003407 if (bt_cb(next_skb)->tx_seq == tx_seq)
3408 return -EINVAL;
3409
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003410 if (bt_cb(next_skb)->tx_seq > tx_seq) {
3411 __skb_queue_before(SREJ_QUEUE(sk), next_skb, skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003412 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003413 }
3414
3415 if (skb_queue_is_last(SREJ_QUEUE(sk), next_skb))
3416 break;
3417
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003418 } while ((next_skb = skb_queue_next(SREJ_QUEUE(sk), next_skb)));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003419
3420 __skb_queue_tail(SREJ_QUEUE(sk), skb);
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003421
3422 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003423}
3424
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003425static int l2cap_ertm_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
3426{
3427 struct l2cap_pinfo *pi = l2cap_pi(sk);
3428 struct sk_buff *_skb;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003429 int err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003430
3431 switch (control & L2CAP_CTRL_SAR) {
3432 case L2CAP_SDU_UNSEGMENTED:
3433 if (pi->conn_state & L2CAP_CONN_SAR_SDU)
3434 goto drop;
3435
3436 err = sock_queue_rcv_skb(sk, skb);
3437 if (!err)
3438 return err;
3439
3440 break;
3441
3442 case L2CAP_SDU_START:
3443 if (pi->conn_state & L2CAP_CONN_SAR_SDU)
3444 goto drop;
3445
3446 pi->sdu_len = get_unaligned_le16(skb->data);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003447
3448 if (pi->sdu_len > pi->imtu)
3449 goto disconnect;
3450
3451 pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003452 if (!pi->sdu)
3453 return -ENOMEM;
3454
3455 /* pull sdu_len bytes only after alloc, because of Local Busy
3456 * condition we have to be sure that this will be executed
3457 * only once, i.e., when alloc does not fail */
3458 skb_pull(skb, 2);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003459
3460 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3461
3462 pi->conn_state |= L2CAP_CONN_SAR_SDU;
3463 pi->partial_sdu_len = skb->len;
3464 break;
3465
3466 case L2CAP_SDU_CONTINUE:
3467 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3468 goto disconnect;
3469
3470 if (!pi->sdu)
3471 goto disconnect;
3472
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003473 pi->partial_sdu_len += skb->len;
3474 if (pi->partial_sdu_len > pi->sdu_len)
3475 goto drop;
3476
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03003477 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3478
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003479 break;
3480
3481 case L2CAP_SDU_END:
3482 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3483 goto disconnect;
3484
3485 if (!pi->sdu)
3486 goto disconnect;
3487
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003488 if (!(pi->conn_state & L2CAP_CONN_SAR_RETRY)) {
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003489 pi->partial_sdu_len += skb->len;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003490
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003491 if (pi->partial_sdu_len > pi->imtu)
3492 goto drop;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003493
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003494 if (pi->partial_sdu_len != pi->sdu_len)
3495 goto drop;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03003496
3497 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003498 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003499
3500 _skb = skb_clone(pi->sdu, GFP_ATOMIC);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003501 if (!_skb) {
3502 pi->conn_state |= L2CAP_CONN_SAR_RETRY;
3503 return -ENOMEM;
3504 }
3505
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003506 err = sock_queue_rcv_skb(sk, _skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003507 if (err < 0) {
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003508 kfree_skb(_skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003509 pi->conn_state |= L2CAP_CONN_SAR_RETRY;
3510 return err;
3511 }
3512
3513 pi->conn_state &= ~L2CAP_CONN_SAR_RETRY;
3514 pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003515
3516 kfree_skb(pi->sdu);
3517 break;
3518 }
3519
3520 kfree_skb(skb);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003521 return 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003522
3523drop:
3524 kfree_skb(pi->sdu);
3525 pi->sdu = NULL;
3526
3527disconnect:
3528 l2cap_send_disconn_req(pi->conn, sk);
3529 kfree_skb(skb);
3530 return 0;
3531}
3532
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003533static void l2cap_busy_work(struct work_struct *work)
3534{
3535 DECLARE_WAITQUEUE(wait, current);
3536 struct l2cap_pinfo *pi =
3537 container_of(work, struct l2cap_pinfo, busy_work);
3538 struct sock *sk = (struct sock *)pi;
3539 int n_tries = 0, timeo = HZ/5, err;
3540 struct sk_buff *skb;
3541 u16 control;
3542
3543 lock_sock(sk);
3544
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02003545 add_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003546 while ((skb = skb_peek(BUSY_QUEUE(sk)))) {
3547 set_current_state(TASK_INTERRUPTIBLE);
3548
3549 if (n_tries++ > L2CAP_LOCAL_BUSY_TRIES) {
3550 err = -EBUSY;
3551 l2cap_send_disconn_req(pi->conn, sk);
3552 goto done;
3553 }
3554
3555 if (!timeo)
3556 timeo = HZ/5;
3557
3558 if (signal_pending(current)) {
3559 err = sock_intr_errno(timeo);
3560 goto done;
3561 }
3562
3563 release_sock(sk);
3564 timeo = schedule_timeout(timeo);
3565 lock_sock(sk);
3566
3567 err = sock_error(sk);
3568 if (err)
3569 goto done;
3570
3571 while ((skb = skb_dequeue(BUSY_QUEUE(sk)))) {
3572 control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
3573 err = l2cap_ertm_reassembly_sdu(sk, skb, control);
3574 if (err < 0) {
3575 skb_queue_head(BUSY_QUEUE(sk), skb);
3576 break;
3577 }
3578
3579 pi->buffer_seq = (pi->buffer_seq + 1) % 64;
3580 }
3581
3582 if (!skb)
3583 break;
3584 }
3585
3586 if (!(pi->conn_state & L2CAP_CONN_RNR_SENT))
3587 goto done;
3588
3589 control = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3590 control |= L2CAP_SUPER_RCV_READY | L2CAP_CTRL_POLL;
3591 l2cap_send_sframe(pi, control);
3592 l2cap_pi(sk)->retry_count = 1;
3593
3594 del_timer(&pi->retrans_timer);
3595 __mod_monitor_timer();
3596
3597 l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
3598
3599done:
3600 pi->conn_state &= ~L2CAP_CONN_LOCAL_BUSY;
3601 pi->conn_state &= ~L2CAP_CONN_RNR_SENT;
3602
3603 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02003604 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003605
3606 release_sock(sk);
3607}
3608
3609static int l2cap_push_rx_skb(struct sock *sk, struct sk_buff *skb, u16 control)
3610{
3611 struct l2cap_pinfo *pi = l2cap_pi(sk);
3612 int sctrl, err;
3613
3614 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
3615 bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT;
3616 __skb_queue_tail(BUSY_QUEUE(sk), skb);
3617 return -EBUSY;
3618 }
3619
3620 err = l2cap_ertm_reassembly_sdu(sk, skb, control);
3621 if (err >= 0) {
3622 pi->buffer_seq = (pi->buffer_seq + 1) % 64;
3623 return err;
3624 }
3625
3626 /* Busy Condition */
3627 pi->conn_state |= L2CAP_CONN_LOCAL_BUSY;
3628 bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT;
3629 __skb_queue_tail(BUSY_QUEUE(sk), skb);
3630
3631 sctrl = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3632 sctrl |= L2CAP_SUPER_RCV_NOT_READY;
3633 l2cap_send_sframe(pi, sctrl);
3634
3635 pi->conn_state |= L2CAP_CONN_RNR_SENT;
3636
3637 queue_work(_busy_wq, &pi->busy_work);
3638
3639 return err;
3640}
3641
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003642static int l2cap_streaming_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003643{
3644 struct l2cap_pinfo *pi = l2cap_pi(sk);
3645 struct sk_buff *_skb;
3646 int err = -EINVAL;
3647
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003648 /*
3649 * TODO: We have to notify the userland if some data is lost with the
3650 * Streaming Mode.
3651 */
3652
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003653 switch (control & L2CAP_CTRL_SAR) {
3654 case L2CAP_SDU_UNSEGMENTED:
3655 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3656 kfree_skb(pi->sdu);
3657 break;
3658 }
3659
3660 err = sock_queue_rcv_skb(sk, skb);
3661 if (!err)
3662 return 0;
3663
3664 break;
3665
3666 case L2CAP_SDU_START:
3667 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3668 kfree_skb(pi->sdu);
3669 break;
3670 }
3671
3672 pi->sdu_len = get_unaligned_le16(skb->data);
3673 skb_pull(skb, 2);
3674
Gustavo F. Padovan052897c2010-05-01 16:15:40 -03003675 if (pi->sdu_len > pi->imtu) {
3676 err = -EMSGSIZE;
3677 break;
3678 }
3679
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003680 pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
3681 if (!pi->sdu) {
3682 err = -ENOMEM;
3683 break;
3684 }
3685
3686 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3687
3688 pi->conn_state |= L2CAP_CONN_SAR_SDU;
3689 pi->partial_sdu_len = skb->len;
3690 err = 0;
3691 break;
3692
3693 case L2CAP_SDU_CONTINUE:
3694 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3695 break;
3696
3697 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3698
3699 pi->partial_sdu_len += skb->len;
3700 if (pi->partial_sdu_len > pi->sdu_len)
3701 kfree_skb(pi->sdu);
3702 else
3703 err = 0;
3704
3705 break;
3706
3707 case L2CAP_SDU_END:
3708 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3709 break;
3710
3711 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3712
3713 pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
3714 pi->partial_sdu_len += skb->len;
3715
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003716 if (pi->partial_sdu_len > pi->imtu)
3717 goto drop;
3718
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003719 if (pi->partial_sdu_len == pi->sdu_len) {
3720 _skb = skb_clone(pi->sdu, GFP_ATOMIC);
3721 err = sock_queue_rcv_skb(sk, _skb);
3722 if (err < 0)
3723 kfree_skb(_skb);
3724 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003725 err = 0;
3726
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003727drop:
3728 kfree_skb(pi->sdu);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003729 break;
3730 }
3731
3732 kfree_skb(skb);
3733 return err;
3734}
3735
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003736static void l2cap_check_srej_gap(struct sock *sk, u8 tx_seq)
3737{
3738 struct sk_buff *skb;
Gustavo F. Padovanafefdbc2010-05-01 16:15:43 -03003739 u16 control;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003740
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003741 while ((skb = skb_peek(SREJ_QUEUE(sk)))) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003742 if (bt_cb(skb)->tx_seq != tx_seq)
3743 break;
3744
3745 skb = skb_dequeue(SREJ_QUEUE(sk));
Gustavo F. Padovanafefdbc2010-05-01 16:15:43 -03003746 control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03003747 l2cap_ertm_reassembly_sdu(sk, skb, control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003748 l2cap_pi(sk)->buffer_seq_srej =
3749 (l2cap_pi(sk)->buffer_seq_srej + 1) % 64;
3750 tx_seq++;
3751 }
3752}
3753
3754static void l2cap_resend_srejframe(struct sock *sk, u8 tx_seq)
3755{
3756 struct l2cap_pinfo *pi = l2cap_pi(sk);
3757 struct srej_list *l, *tmp;
3758 u16 control;
3759
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003760 list_for_each_entry_safe(l, tmp, SREJ_LIST(sk), list) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003761 if (l->tx_seq == tx_seq) {
3762 list_del(&l->list);
3763 kfree(l);
3764 return;
3765 }
3766 control = L2CAP_SUPER_SELECT_REJECT;
3767 control |= l->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3768 l2cap_send_sframe(pi, control);
3769 list_del(&l->list);
3770 list_add_tail(&l->list, SREJ_LIST(sk));
3771 }
3772}
3773
3774static void l2cap_send_srejframe(struct sock *sk, u8 tx_seq)
3775{
3776 struct l2cap_pinfo *pi = l2cap_pi(sk);
3777 struct srej_list *new;
3778 u16 control;
3779
3780 while (tx_seq != pi->expected_tx_seq) {
3781 control = L2CAP_SUPER_SELECT_REJECT;
3782 control |= pi->expected_tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3783 l2cap_send_sframe(pi, control);
3784
3785 new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC);
3786 new->tx_seq = pi->expected_tx_seq++;
3787 list_add_tail(&new->list, SREJ_LIST(sk));
3788 }
3789 pi->expected_tx_seq++;
3790}
3791
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003792static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
3793{
3794 struct l2cap_pinfo *pi = l2cap_pi(sk);
3795 u8 tx_seq = __get_txseq(rx_control);
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003796 u8 req_seq = __get_reqseq(rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003797 u8 sar = rx_control >> L2CAP_CTRL_SAR_SHIFT;
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003798 u8 tx_seq_offset, expected_tx_seq_offset;
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03003799 int num_to_ack = (pi->tx_win/6) + 1;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003800 int err = 0;
3801
3802 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
3803
Gustavo F. Padovan9b16dc62010-05-05 20:05:57 -03003804 if (L2CAP_CTRL_FINAL & rx_control &&
3805 l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) {
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003806 del_timer(&pi->monitor_timer);
3807 if (pi->unacked_frames > 0)
3808 __mod_retrans_timer();
3809 pi->conn_state &= ~L2CAP_CONN_WAIT_F;
3810 }
3811
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003812 pi->expected_ack_seq = req_seq;
3813 l2cap_drop_acked_frames(sk);
3814
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003815 if (tx_seq == pi->expected_tx_seq)
3816 goto expected;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003817
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003818 tx_seq_offset = (tx_seq - pi->buffer_seq) % 64;
3819 if (tx_seq_offset < 0)
3820 tx_seq_offset += 64;
3821
3822 /* invalid tx_seq */
3823 if (tx_seq_offset >= pi->tx_win) {
3824 l2cap_send_disconn_req(pi->conn, sk);
3825 goto drop;
3826 }
3827
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003828 if (pi->conn_state == L2CAP_CONN_LOCAL_BUSY)
3829 goto drop;
3830
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003831 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3832 struct srej_list *first;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003833
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003834 first = list_first_entry(SREJ_LIST(sk),
3835 struct srej_list, list);
3836 if (tx_seq == first->tx_seq) {
3837 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3838 l2cap_check_srej_gap(sk, tx_seq);
3839
3840 list_del(&first->list);
3841 kfree(first);
3842
3843 if (list_empty(SREJ_LIST(sk))) {
3844 pi->buffer_seq = pi->buffer_seq_srej;
3845 pi->conn_state &= ~L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan855666cc2010-05-01 16:15:40 -03003846 l2cap_send_ack(pi);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003847 }
3848 } else {
3849 struct srej_list *l;
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003850
3851 /* duplicated tx_seq */
3852 if (l2cap_add_to_srej_queue(sk, skb, tx_seq, sar) < 0)
3853 goto drop;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003854
3855 list_for_each_entry(l, SREJ_LIST(sk), list) {
3856 if (l->tx_seq == tx_seq) {
3857 l2cap_resend_srejframe(sk, tx_seq);
3858 return 0;
3859 }
3860 }
3861 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003862 }
3863 } else {
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003864 expected_tx_seq_offset =
3865 (pi->expected_tx_seq - pi->buffer_seq) % 64;
3866 if (expected_tx_seq_offset < 0)
3867 expected_tx_seq_offset += 64;
3868
3869 /* duplicated tx_seq */
3870 if (tx_seq_offset < expected_tx_seq_offset)
3871 goto drop;
3872
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003873 pi->conn_state |= L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003874
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003875 INIT_LIST_HEAD(SREJ_LIST(sk));
3876 pi->buffer_seq_srej = pi->buffer_seq;
3877
3878 __skb_queue_head_init(SREJ_QUEUE(sk));
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003879 __skb_queue_head_init(BUSY_QUEUE(sk));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003880 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3881
Gustavo F. Padovanef54fd92009-08-20 22:26:04 -03003882 pi->conn_state |= L2CAP_CONN_SEND_PBIT;
3883
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003884 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003885 }
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003886 return 0;
3887
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003888expected:
3889 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
3890
3891 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
Gustavo F. Padovan3b1a9f32010-05-01 16:15:42 -03003892 bt_cb(skb)->tx_seq = tx_seq;
3893 bt_cb(skb)->sar = sar;
3894 __skb_queue_tail(SREJ_QUEUE(sk), skb);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003895 return 0;
3896 }
3897
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03003898 if (rx_control & L2CAP_CTRL_FINAL) {
3899 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3900 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003901 else
3902 l2cap_retransmit_frames(sk);
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03003903 }
3904
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003905 err = l2cap_push_rx_skb(sk, skb, rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003906 if (err < 0)
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003907 return 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003908
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003909 __mod_ack_timer();
3910
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03003911 pi->num_acked = (pi->num_acked + 1) % num_to_ack;
3912 if (pi->num_acked == num_to_ack - 1)
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03003913 l2cap_send_ack(pi);
3914
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003915 return 0;
João Paulo Rechi Vita9b533502010-05-01 16:15:44 -03003916
3917drop:
3918 kfree_skb(skb);
3919 return 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003920}
3921
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003922static inline void l2cap_data_channel_rrframe(struct sock *sk, u16 rx_control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003923{
3924 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan6e3a5982010-05-01 16:15:38 -03003925
3926 pi->expected_ack_seq = __get_reqseq(rx_control);
3927 l2cap_drop_acked_frames(sk);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003928
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003929 if (rx_control & L2CAP_CTRL_POLL) {
Gustavo F. Padovan05fbd892010-05-01 16:15:39 -03003930 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3931 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
3932 (pi->unacked_frames > 0))
3933 __mod_retrans_timer();
3934
3935 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3936 l2cap_send_srejtail(sk);
3937 } else {
3938 l2cap_send_i_or_rr_or_rnr(sk);
Gustavo F. Padovan05fbd892010-05-01 16:15:39 -03003939 }
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003940
3941 } else if (rx_control & L2CAP_CTRL_FINAL) {
3942 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003943
3944 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3945 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003946 else
3947 l2cap_retransmit_frames(sk);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003948
3949 } else {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003950 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
3951 (pi->unacked_frames > 0))
3952 __mod_retrans_timer();
3953
3954 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003955 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003956 l2cap_send_ack(pi);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003957 } else {
3958 spin_lock_bh(&pi->send_lock);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003959 l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003960 spin_unlock_bh(&pi->send_lock);
3961 }
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003962 }
3963}
3964
3965static inline void l2cap_data_channel_rejframe(struct sock *sk, u16 rx_control)
3966{
3967 struct l2cap_pinfo *pi = l2cap_pi(sk);
3968 u8 tx_seq = __get_reqseq(rx_control);
3969
3970 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3971
Gustavo F. Padovan8abb52e2010-05-01 16:15:38 -03003972 pi->expected_ack_seq = tx_seq;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003973 l2cap_drop_acked_frames(sk);
3974
3975 if (rx_control & L2CAP_CTRL_FINAL) {
3976 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3977 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003978 else
3979 l2cap_retransmit_frames(sk);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003980 } else {
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003981 l2cap_retransmit_frames(sk);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003982
Gustavo F. Padovan0301ef02010-05-05 20:56:43 -03003983 if (pi->conn_state & L2CAP_CONN_WAIT_F)
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003984 pi->conn_state |= L2CAP_CONN_REJ_ACT;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003985 }
3986}
3987static inline void l2cap_data_channel_srejframe(struct sock *sk, u16 rx_control)
3988{
3989 struct l2cap_pinfo *pi = l2cap_pi(sk);
3990 u8 tx_seq = __get_reqseq(rx_control);
3991
3992 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3993
3994 if (rx_control & L2CAP_CTRL_POLL) {
3995 pi->expected_ack_seq = tx_seq;
3996 l2cap_drop_acked_frames(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03003997 l2cap_retransmit_one_frame(sk, tx_seq);
3998
3999 spin_lock_bh(&pi->send_lock);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004000 l2cap_ertm_send(sk);
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004001 spin_unlock_bh(&pi->send_lock);
4002
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004003 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
4004 pi->srej_save_reqseq = tx_seq;
4005 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
4006 }
4007 } else if (rx_control & L2CAP_CTRL_FINAL) {
4008 if ((pi->conn_state & L2CAP_CONN_SREJ_ACT) &&
4009 pi->srej_save_reqseq == tx_seq)
4010 pi->conn_state &= ~L2CAP_CONN_SREJ_ACT;
4011 else
Gustavo F. Padovandfc909b2010-05-01 16:15:45 -03004012 l2cap_retransmit_one_frame(sk, tx_seq);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004013 } 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 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
4016 pi->srej_save_reqseq = tx_seq;
4017 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
4018 }
4019 }
4020}
4021
4022static inline void l2cap_data_channel_rnrframe(struct sock *sk, u16 rx_control)
4023{
4024 struct l2cap_pinfo *pi = l2cap_pi(sk);
4025 u8 tx_seq = __get_reqseq(rx_control);
4026
4027 pi->conn_state |= L2CAP_CONN_REMOTE_BUSY;
4028 pi->expected_ack_seq = tx_seq;
4029 l2cap_drop_acked_frames(sk);
4030
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03004031 if (!(pi->conn_state & L2CAP_CONN_SREJ_SENT)) {
4032 del_timer(&pi->retrans_timer);
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -03004033 if (rx_control & L2CAP_CTRL_POLL)
4034 l2cap_send_rr_or_rnr(pi, L2CAP_CTRL_FINAL);
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03004035 return;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004036 }
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03004037
4038 if (rx_control & L2CAP_CTRL_POLL)
4039 l2cap_send_srejtail(sk);
4040 else
4041 l2cap_send_sframe(pi, L2CAP_SUPER_RCV_READY);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004042}
4043
4044static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
4045{
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004046 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
4047
Gustavo F. Padovan9b16dc62010-05-05 20:05:57 -03004048 if (L2CAP_CTRL_FINAL & rx_control &&
4049 l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004050 del_timer(&l2cap_pi(sk)->monitor_timer);
4051 if (l2cap_pi(sk)->unacked_frames > 0)
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03004052 __mod_retrans_timer();
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004053 l2cap_pi(sk)->conn_state &= ~L2CAP_CONN_WAIT_F;
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03004054 }
4055
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004056 switch (rx_control & L2CAP_CTRL_SUPERVISE) {
4057 case L2CAP_SUPER_RCV_READY:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004058 l2cap_data_channel_rrframe(sk, rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004059 break;
4060
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004061 case L2CAP_SUPER_REJECT:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004062 l2cap_data_channel_rejframe(sk, rx_control);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03004063 break;
4064
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004065 case L2CAP_SUPER_SELECT_REJECT:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004066 l2cap_data_channel_srejframe(sk, rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03004067 break;
4068
4069 case L2CAP_SUPER_RCV_NOT_READY:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03004070 l2cap_data_channel_rnrframe(sk, rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004071 break;
4072 }
4073
Gustavo F. Padovanfaaebd12010-05-01 16:15:35 -03004074 kfree_skb(skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004075 return 0;
4076}
4077
Linus Torvalds1da177e2005-04-16 15:20:36 -07004078static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk_buff *skb)
4079{
4080 struct sock *sk;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004081 struct l2cap_pinfo *pi;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03004082 u16 control, len;
João Paulo Rechi Vita01760bd2010-05-01 16:15:43 -03004083 u8 tx_seq, req_seq, next_tx_seq_offset, req_seq_offset;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004084
4085 sk = l2cap_get_chan_by_scid(&conn->chan_list, cid);
4086 if (!sk) {
4087 BT_DBG("unknown cid 0x%4.4x", cid);
4088 goto drop;
4089 }
4090
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004091 pi = l2cap_pi(sk);
4092
Linus Torvalds1da177e2005-04-16 15:20:36 -07004093 BT_DBG("sk %p, len %d", sk, skb->len);
4094
4095 if (sk->sk_state != BT_CONNECTED)
4096 goto drop;
4097
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004098 switch (pi->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004099 case L2CAP_MODE_BASIC:
4100 /* If socket recv buffers overflows we drop data here
4101 * which is *bad* because L2CAP has to be reliable.
4102 * But we don't have any other choice. L2CAP doesn't
4103 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07004104
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004105 if (pi->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004106 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004107
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004108 if (!sock_queue_rcv_skb(sk, skb))
4109 goto done;
4110 break;
4111
4112 case L2CAP_MODE_ERTM:
4113 control = get_unaligned_le16(skb->data);
4114 skb_pull(skb, 2);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03004115 len = skb->len;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004116
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03004117 if (__is_sar_start(control))
4118 len -= 2;
4119
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004120 if (pi->fcs == L2CAP_FCS_CRC16)
4121 len -= 2;
4122
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03004123 /*
4124 * We can just drop the corrupted I-frame here.
4125 * Receiver will miss it and start proper recovery
4126 * procedures and ask retransmission.
4127 */
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004128 if (len > pi->mps) {
4129 l2cap_send_disconn_req(pi->conn, sk);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004130 goto drop;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004131 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004132
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004133 if (l2cap_check_fcs(pi, skb))
4134 goto drop;
4135
João Paulo Rechi Vita01760bd2010-05-01 16:15:43 -03004136 req_seq = __get_reqseq(control);
4137 req_seq_offset = (req_seq - pi->expected_ack_seq) % 64;
4138 if (req_seq_offset < 0)
4139 req_seq_offset += 64;
4140
4141 next_tx_seq_offset =
4142 (pi->next_tx_seq - pi->expected_ack_seq) % 64;
4143 if (next_tx_seq_offset < 0)
4144 next_tx_seq_offset += 64;
4145
4146 /* check for invalid req-seq */
4147 if (req_seq_offset > next_tx_seq_offset) {
4148 l2cap_send_disconn_req(pi->conn, sk);
4149 goto drop;
4150 }
4151
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004152 if (__is_iframe(control)) {
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004153 if (len < 4) {
4154 l2cap_send_disconn_req(pi->conn, sk);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004155 goto drop;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004156 }
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004157
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02004158 l2cap_data_channel_iframe(sk, control, skb);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004159 } else {
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004160 if (len != 0) {
4161 l2cap_send_disconn_req(pi->conn, sk);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004162 goto drop;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004163 }
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004164
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02004165 l2cap_data_channel_sframe(sk, control, skb);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03004166 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004167
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02004168 goto done;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004169
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004170 case L2CAP_MODE_STREAMING:
4171 control = get_unaligned_le16(skb->data);
4172 skb_pull(skb, 2);
4173 len = skb->len;
4174
4175 if (__is_sar_start(control))
4176 len -= 2;
4177
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004178 if (pi->fcs == L2CAP_FCS_CRC16)
4179 len -= 2;
4180
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03004181 if (len > pi->mps || len < 4 || __is_sframe(control))
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004182 goto drop;
4183
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004184 if (l2cap_check_fcs(pi, skb))
4185 goto drop;
4186
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004187 tx_seq = __get_txseq(control);
4188
4189 if (pi->expected_tx_seq == tx_seq)
4190 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
4191 else
Gustavo F. Padovan7dffe422010-05-01 16:15:36 -03004192 pi->expected_tx_seq = (tx_seq + 1) % 64;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004193
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004194 l2cap_streaming_reassembly_sdu(sk, skb, control);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03004195
4196 goto done;
4197
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004198 default:
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03004199 BT_DBG("sk %p: bad mode 0x%2.2x", sk, pi->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004200 break;
4201 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004202
4203drop:
4204 kfree_skb(skb);
4205
4206done:
Marcel Holtmann01394182006-07-03 10:02:46 +02004207 if (sk)
4208 bh_unlock_sock(sk);
4209
Linus Torvalds1da177e2005-04-16 15:20:36 -07004210 return 0;
4211}
4212
Al Viro8e036fc2007-07-29 00:16:36 -07004213static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004214{
4215 struct sock *sk;
4216
4217 sk = l2cap_get_sock_by_psm(0, psm, conn->src);
4218 if (!sk)
4219 goto drop;
4220
4221 BT_DBG("sk %p, len %d", sk, skb->len);
4222
4223 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_CONNECTED)
4224 goto drop;
4225
4226 if (l2cap_pi(sk)->imtu < skb->len)
4227 goto drop;
4228
4229 if (!sock_queue_rcv_skb(sk, skb))
4230 goto done;
4231
4232drop:
4233 kfree_skb(skb);
4234
4235done:
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03004236 if (sk)
4237 bh_unlock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004238 return 0;
4239}
4240
4241static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
4242{
4243 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07004244 u16 cid, len;
4245 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004246
4247 skb_pull(skb, L2CAP_HDR_SIZE);
4248 cid = __le16_to_cpu(lh->cid);
4249 len = __le16_to_cpu(lh->len);
4250
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03004251 if (len != skb->len) {
4252 kfree_skb(skb);
4253 return;
4254 }
4255
Linus Torvalds1da177e2005-04-16 15:20:36 -07004256 BT_DBG("len %d, cid 0x%4.4x", len, cid);
4257
4258 switch (cid) {
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03004259 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07004260 l2cap_sig_channel(conn, skb);
4261 break;
4262
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03004263 case L2CAP_CID_CONN_LESS:
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03004264 psm = get_unaligned_le16(skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004265 skb_pull(skb, 2);
4266 l2cap_conless_channel(conn, psm, skb);
4267 break;
4268
4269 default:
4270 l2cap_data_channel(conn, cid, skb);
4271 break;
4272 }
4273}
4274
4275/* ---- L2CAP interface with lower layer (HCI) ---- */
4276
4277static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
4278{
4279 int exact = 0, lm1 = 0, lm2 = 0;
4280 register struct sock *sk;
4281 struct hlist_node *node;
4282
4283 if (type != ACL_LINK)
4284 return 0;
4285
4286 BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
4287
4288 /* Find listening sockets and check their link_mode */
4289 read_lock(&l2cap_sk_list.lock);
4290 sk_for_each(sk, node, &l2cap_sk_list.head) {
4291 if (sk->sk_state != BT_LISTEN)
4292 continue;
4293
4294 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01004295 lm1 |= HCI_LM_ACCEPT;
4296 if (l2cap_pi(sk)->role_switch)
4297 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004298 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01004299 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
4300 lm2 |= HCI_LM_ACCEPT;
4301 if (l2cap_pi(sk)->role_switch)
4302 lm2 |= HCI_LM_MASTER;
4303 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004304 }
4305 read_unlock(&l2cap_sk_list.lock);
4306
4307 return exact ? lm1 : lm2;
4308}
4309
4310static int l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
4311{
Marcel Holtmann01394182006-07-03 10:02:46 +02004312 struct l2cap_conn *conn;
4313
Linus Torvalds1da177e2005-04-16 15:20:36 -07004314 BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
4315
4316 if (hcon->type != ACL_LINK)
4317 return 0;
4318
4319 if (!status) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004320 conn = l2cap_conn_add(hcon, status);
4321 if (conn)
4322 l2cap_conn_ready(conn);
Marcel Holtmann01394182006-07-03 10:02:46 +02004323 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -07004324 l2cap_conn_del(hcon, bt_err(status));
4325
4326 return 0;
4327}
4328
Marcel Holtmann2950f212009-02-12 14:02:50 +01004329static int l2cap_disconn_ind(struct hci_conn *hcon)
4330{
4331 struct l2cap_conn *conn = hcon->l2cap_data;
4332
4333 BT_DBG("hcon %p", hcon);
4334
4335 if (hcon->type != ACL_LINK || !conn)
4336 return 0x13;
4337
4338 return conn->disc_reason;
4339}
4340
4341static int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004342{
4343 BT_DBG("hcon %p reason %d", hcon, reason);
4344
4345 if (hcon->type != ACL_LINK)
4346 return 0;
4347
4348 l2cap_conn_del(hcon, bt_err(reason));
Marcel Holtmann01394182006-07-03 10:02:46 +02004349
Linus Torvalds1da177e2005-04-16 15:20:36 -07004350 return 0;
4351}
4352
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004353static inline void l2cap_check_encryption(struct sock *sk, u8 encrypt)
4354{
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03004355 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM)
Marcel Holtmann255c7602009-02-04 21:07:19 +01004356 return;
4357
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004358 if (encrypt == 0x00) {
4359 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM) {
4360 l2cap_sock_clear_timer(sk);
4361 l2cap_sock_set_timer(sk, HZ * 5);
4362 } else if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
4363 __l2cap_sock_close(sk, ECONNREFUSED);
4364 } else {
4365 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM)
4366 l2cap_sock_clear_timer(sk);
4367 }
4368}
4369
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004370static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004371{
4372 struct l2cap_chan_list *l;
Marcel Holtmann40be4922008-07-14 20:13:50 +02004373 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004374 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004375
Marcel Holtmann01394182006-07-03 10:02:46 +02004376 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004377 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02004378
Linus Torvalds1da177e2005-04-16 15:20:36 -07004379 l = &conn->chan_list;
4380
4381 BT_DBG("conn %p", conn);
4382
4383 read_lock(&l->lock);
4384
4385 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
4386 bh_lock_sock(sk);
4387
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01004388 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND) {
4389 bh_unlock_sock(sk);
4390 continue;
4391 }
4392
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004393 if (!status && (sk->sk_state == BT_CONNECTED ||
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004394 sk->sk_state == BT_CONFIG)) {
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004395 l2cap_check_encryption(sk, encrypt);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02004396 bh_unlock_sock(sk);
4397 continue;
4398 }
4399
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004400 if (sk->sk_state == BT_CONNECT) {
4401 if (!status) {
4402 struct l2cap_conn_req req;
4403 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
4404 req.psm = l2cap_pi(sk)->psm;
4405
4406 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
4407
4408 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
4409 L2CAP_CONN_REQ, sizeof(req), &req);
4410 } else {
4411 l2cap_sock_clear_timer(sk);
4412 l2cap_sock_set_timer(sk, HZ / 10);
4413 }
4414 } else if (sk->sk_state == BT_CONNECT2) {
4415 struct l2cap_conn_rsp rsp;
4416 __u16 result;
4417
4418 if (!status) {
4419 sk->sk_state = BT_CONFIG;
4420 result = L2CAP_CR_SUCCESS;
4421 } else {
4422 sk->sk_state = BT_DISCONN;
4423 l2cap_sock_set_timer(sk, HZ / 10);
4424 result = L2CAP_CR_SEC_BLOCK;
4425 }
4426
4427 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
4428 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
4429 rsp.result = cpu_to_le16(result);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02004430 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004431 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
4432 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004433 }
4434
Linus Torvalds1da177e2005-04-16 15:20:36 -07004435 bh_unlock_sock(sk);
4436 }
4437
4438 read_unlock(&l->lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004439
Linus Torvalds1da177e2005-04-16 15:20:36 -07004440 return 0;
4441}
4442
4443static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
4444{
4445 struct l2cap_conn *conn = hcon->l2cap_data;
4446
4447 if (!conn && !(conn = l2cap_conn_add(hcon, 0)))
4448 goto drop;
4449
4450 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
4451
4452 if (flags & ACL_START) {
4453 struct l2cap_hdr *hdr;
4454 int len;
4455
4456 if (conn->rx_len) {
4457 BT_ERR("Unexpected start frame (len %d)", skb->len);
4458 kfree_skb(conn->rx_skb);
4459 conn->rx_skb = NULL;
4460 conn->rx_len = 0;
4461 l2cap_conn_unreliable(conn, ECOMM);
4462 }
4463
4464 if (skb->len < 2) {
4465 BT_ERR("Frame is too short (len %d)", skb->len);
4466 l2cap_conn_unreliable(conn, ECOMM);
4467 goto drop;
4468 }
4469
4470 hdr = (struct l2cap_hdr *) skb->data;
4471 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
4472
4473 if (len == skb->len) {
4474 /* Complete frame received */
4475 l2cap_recv_frame(conn, skb);
4476 return 0;
4477 }
4478
4479 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
4480
4481 if (skb->len > len) {
4482 BT_ERR("Frame is too long (len %d, expected len %d)",
4483 skb->len, len);
4484 l2cap_conn_unreliable(conn, ECOMM);
4485 goto drop;
4486 }
4487
4488 /* Allocate skb for the complete frame (with header) */
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03004489 conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC);
4490 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004491 goto drop;
4492
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03004493 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004494 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004495 conn->rx_len = len - skb->len;
4496 } else {
4497 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
4498
4499 if (!conn->rx_len) {
4500 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
4501 l2cap_conn_unreliable(conn, ECOMM);
4502 goto drop;
4503 }
4504
4505 if (skb->len > conn->rx_len) {
4506 BT_ERR("Fragment is too long (len %d, expected %d)",
4507 skb->len, conn->rx_len);
4508 kfree_skb(conn->rx_skb);
4509 conn->rx_skb = NULL;
4510 conn->rx_len = 0;
4511 l2cap_conn_unreliable(conn, ECOMM);
4512 goto drop;
4513 }
4514
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03004515 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004516 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004517 conn->rx_len -= skb->len;
4518
4519 if (!conn->rx_len) {
4520 /* Complete frame received */
4521 l2cap_recv_frame(conn, conn->rx_skb);
4522 conn->rx_skb = NULL;
4523 }
4524 }
4525
4526drop:
4527 kfree_skb(skb);
4528 return 0;
4529}
4530
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004531static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004532{
4533 struct sock *sk;
4534 struct hlist_node *node;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004535
4536 read_lock_bh(&l2cap_sk_list.lock);
4537
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004538 sk_for_each(sk, node, &l2cap_sk_list.head) {
4539 struct l2cap_pinfo *pi = l2cap_pi(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004540
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004541 seq_printf(f, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d\n",
4542 batostr(&bt_sk(sk)->src),
4543 batostr(&bt_sk(sk)->dst),
4544 sk->sk_state, __le16_to_cpu(pi->psm),
4545 pi->scid, pi->dcid,
4546 pi->imtu, pi->omtu, pi->sec_level);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004547 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004548
Linus Torvalds1da177e2005-04-16 15:20:36 -07004549 read_unlock_bh(&l2cap_sk_list.lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004550
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004551 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004552}
4553
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004554static int l2cap_debugfs_open(struct inode *inode, struct file *file)
4555{
4556 return single_open(file, l2cap_debugfs_show, inode->i_private);
4557}
4558
4559static const struct file_operations l2cap_debugfs_fops = {
4560 .open = l2cap_debugfs_open,
4561 .read = seq_read,
4562 .llseek = seq_lseek,
4563 .release = single_release,
4564};
4565
4566static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004567
Eric Dumazet90ddc4f2005-12-22 12:49:22 -08004568static const struct proto_ops l2cap_sock_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004569 .family = PF_BLUETOOTH,
4570 .owner = THIS_MODULE,
4571 .release = l2cap_sock_release,
4572 .bind = l2cap_sock_bind,
4573 .connect = l2cap_sock_connect,
4574 .listen = l2cap_sock_listen,
4575 .accept = l2cap_sock_accept,
4576 .getname = l2cap_sock_getname,
4577 .sendmsg = l2cap_sock_sendmsg,
Marcel Holtmannf66dc812009-01-15 21:57:00 +01004578 .recvmsg = l2cap_sock_recvmsg,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004579 .poll = bt_sock_poll,
Marcel Holtmann3241ad82008-07-14 20:13:50 +02004580 .ioctl = bt_sock_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004581 .mmap = sock_no_mmap,
4582 .socketpair = sock_no_socketpair,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004583 .shutdown = l2cap_sock_shutdown,
4584 .setsockopt = l2cap_sock_setsockopt,
4585 .getsockopt = l2cap_sock_getsockopt
4586};
4587
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +00004588static const struct net_proto_family l2cap_sock_family_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004589 .family = PF_BLUETOOTH,
4590 .owner = THIS_MODULE,
4591 .create = l2cap_sock_create,
4592};
4593
4594static struct hci_proto l2cap_hci_proto = {
4595 .name = "L2CAP",
4596 .id = HCI_PROTO_L2CAP,
4597 .connect_ind = l2cap_connect_ind,
4598 .connect_cfm = l2cap_connect_cfm,
4599 .disconn_ind = l2cap_disconn_ind,
Marcel Holtmann2950f212009-02-12 14:02:50 +01004600 .disconn_cfm = l2cap_disconn_cfm,
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004601 .security_cfm = l2cap_security_cfm,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004602 .recv_acldata = l2cap_recv_acldata
4603};
4604
4605static int __init l2cap_init(void)
4606{
4607 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004608
Linus Torvalds1da177e2005-04-16 15:20:36 -07004609 err = proto_register(&l2cap_proto, 0);
4610 if (err < 0)
4611 return err;
4612
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004613 _busy_wq = create_singlethread_workqueue("l2cap");
4614 if (!_busy_wq)
4615 goto error;
4616
Linus Torvalds1da177e2005-04-16 15:20:36 -07004617 err = bt_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops);
4618 if (err < 0) {
4619 BT_ERR("L2CAP socket registration failed");
4620 goto error;
4621 }
4622
4623 err = hci_register_proto(&l2cap_hci_proto);
4624 if (err < 0) {
4625 BT_ERR("L2CAP protocol registration failed");
4626 bt_sock_unregister(BTPROTO_L2CAP);
4627 goto error;
4628 }
4629
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004630 if (bt_debugfs) {
4631 l2cap_debugfs = debugfs_create_file("l2cap", 0444,
4632 bt_debugfs, NULL, &l2cap_debugfs_fops);
4633 if (!l2cap_debugfs)
4634 BT_ERR("Failed to create L2CAP debug file");
4635 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004636
4637 BT_INFO("L2CAP ver %s", VERSION);
4638 BT_INFO("L2CAP socket layer initialized");
4639
4640 return 0;
4641
4642error:
4643 proto_unregister(&l2cap_proto);
4644 return err;
4645}
4646
4647static void __exit l2cap_exit(void)
4648{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004649 debugfs_remove(l2cap_debugfs);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004650
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004651 flush_workqueue(_busy_wq);
4652 destroy_workqueue(_busy_wq);
4653
Linus Torvalds1da177e2005-04-16 15:20:36 -07004654 if (bt_sock_unregister(BTPROTO_L2CAP) < 0)
4655 BT_ERR("L2CAP socket unregistration failed");
4656
4657 if (hci_unregister_proto(&l2cap_hci_proto) < 0)
4658 BT_ERR("L2CAP protocol unregistration failed");
4659
4660 proto_unregister(&l2cap_proto);
4661}
4662
4663void l2cap_load(void)
4664{
4665 /* Dummy function to trigger automatic L2CAP module loading by
4666 * other modules that use L2CAP sockets but don't use any other
4667 * symbols from it. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07004668}
4669EXPORT_SYMBOL(l2cap_load);
4670
4671module_init(l2cap_init);
4672module_exit(l2cap_exit);
4673
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07004674module_param(enable_ertm, bool, 0644);
4675MODULE_PARM_DESC(enable_ertm, "Enable enhanced retransmission mode");
4676
Marcel Holtmann5fbcd3d2009-10-05 11:35:43 +02004677module_param(max_transmit, uint, 0644);
4678MODULE_PARM_DESC(max_transmit, "Max transmit value (default = 3)");
4679
Gustavo F. Padovan369ba302010-05-01 16:15:41 -03004680module_param(tx_window, uint, 0644);
4681MODULE_PARM_DESC(tx_window, "Transmission window size value (default = 63)");
4682
Marcel Holtmann63fbd242008-08-18 13:23:53 +02004683MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004684MODULE_DESCRIPTION("Bluetooth L2CAP ver " VERSION);
4685MODULE_VERSION(VERSION);
4686MODULE_LICENSE("GPL");
4687MODULE_ALIAS("bt-proto-0");