blob: 2a981de071dffa5f5d2d9fead3ded7b708816f0b [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
71static struct bt_sock_list l2cap_sk_list = {
Robert P. J. Dayd5fb2962008-03-28 16:17:38 -070072 .lock = __RW_LOCK_UNLOCKED(l2cap_sk_list.lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -070073};
74
Linus Torvalds1da177e2005-04-16 15:20:36 -070075static void __l2cap_sock_close(struct sock *sk, int reason);
76static void l2cap_sock_close(struct sock *sk);
77static void l2cap_sock_kill(struct sock *sk);
78
79static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
80 u8 code, u8 ident, u16 dlen, void *data);
81
82/* ---- L2CAP timers ---- */
83static void l2cap_sock_timeout(unsigned long arg)
84{
85 struct sock *sk = (struct sock *) arg;
Marcel Holtmannb1235d72008-07-14 20:13:54 +020086 int reason;
Linus Torvalds1da177e2005-04-16 15:20:36 -070087
88 BT_DBG("sock %p state %d", sk, sk->sk_state);
89
90 bh_lock_sock(sk);
Marcel Holtmannb1235d72008-07-14 20:13:54 +020091
Marcel Holtmannf62e4322009-01-15 21:58:44 +010092 if (sk->sk_state == BT_CONNECTED || sk->sk_state == BT_CONFIG)
93 reason = ECONNREFUSED;
94 else if (sk->sk_state == BT_CONNECT &&
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +010095 l2cap_pi(sk)->sec_level != BT_SECURITY_SDP)
Marcel Holtmannb1235d72008-07-14 20:13:54 +020096 reason = ECONNREFUSED;
97 else
98 reason = ETIMEDOUT;
99
100 __l2cap_sock_close(sk, reason);
101
Linus Torvalds1da177e2005-04-16 15:20:36 -0700102 bh_unlock_sock(sk);
103
104 l2cap_sock_kill(sk);
105 sock_put(sk);
106}
107
108static void l2cap_sock_set_timer(struct sock *sk, long timeout)
109{
110 BT_DBG("sk %p state %d timeout %ld", sk, sk->sk_state, timeout);
111 sk_reset_timer(sk, &sk->sk_timer, jiffies + timeout);
112}
113
114static void l2cap_sock_clear_timer(struct sock *sk)
115{
116 BT_DBG("sock %p state %d", sk, sk->sk_state);
117 sk_stop_timer(sk, &sk->sk_timer);
118}
119
Marcel Holtmann01394182006-07-03 10:02:46 +0200120/* ---- L2CAP channels ---- */
121static struct sock *__l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, u16 cid)
122{
123 struct sock *s;
124 for (s = l->head; s; s = l2cap_pi(s)->next_c) {
125 if (l2cap_pi(s)->dcid == cid)
126 break;
127 }
128 return s;
129}
130
131static struct sock *__l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid)
132{
133 struct sock *s;
134 for (s = l->head; s; s = l2cap_pi(s)->next_c) {
135 if (l2cap_pi(s)->scid == cid)
136 break;
137 }
138 return s;
139}
140
141/* Find channel with given SCID.
142 * Returns locked socket */
143static inline struct sock *l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid)
144{
145 struct sock *s;
146 read_lock(&l->lock);
147 s = __l2cap_get_chan_by_scid(l, cid);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300148 if (s)
149 bh_lock_sock(s);
Marcel Holtmann01394182006-07-03 10:02:46 +0200150 read_unlock(&l->lock);
151 return s;
152}
153
154static struct sock *__l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 ident)
155{
156 struct sock *s;
157 for (s = l->head; s; s = l2cap_pi(s)->next_c) {
158 if (l2cap_pi(s)->ident == ident)
159 break;
160 }
161 return s;
162}
163
164static inline struct sock *l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 ident)
165{
166 struct sock *s;
167 read_lock(&l->lock);
168 s = __l2cap_get_chan_by_ident(l, ident);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300169 if (s)
170 bh_lock_sock(s);
Marcel Holtmann01394182006-07-03 10:02:46 +0200171 read_unlock(&l->lock);
172 return s;
173}
174
175static u16 l2cap_alloc_cid(struct l2cap_chan_list *l)
176{
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300177 u16 cid = L2CAP_CID_DYN_START;
Marcel Holtmann01394182006-07-03 10:02:46 +0200178
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300179 for (; cid < L2CAP_CID_DYN_END; cid++) {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300180 if (!__l2cap_get_chan_by_scid(l, cid))
Marcel Holtmann01394182006-07-03 10:02:46 +0200181 return cid;
182 }
183
184 return 0;
185}
186
187static inline void __l2cap_chan_link(struct l2cap_chan_list *l, struct sock *sk)
188{
189 sock_hold(sk);
190
191 if (l->head)
192 l2cap_pi(l->head)->prev_c = sk;
193
194 l2cap_pi(sk)->next_c = l->head;
195 l2cap_pi(sk)->prev_c = NULL;
196 l->head = sk;
197}
198
199static inline void l2cap_chan_unlink(struct l2cap_chan_list *l, struct sock *sk)
200{
201 struct sock *next = l2cap_pi(sk)->next_c, *prev = l2cap_pi(sk)->prev_c;
202
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200203 write_lock_bh(&l->lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200204 if (sk == l->head)
205 l->head = next;
206
207 if (next)
208 l2cap_pi(next)->prev_c = prev;
209 if (prev)
210 l2cap_pi(prev)->next_c = next;
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200211 write_unlock_bh(&l->lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200212
213 __sock_put(sk);
214}
215
216static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
217{
218 struct l2cap_chan_list *l = &conn->chan_list;
219
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300220 BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
221 l2cap_pi(sk)->psm, l2cap_pi(sk)->dcid);
Marcel Holtmann01394182006-07-03 10:02:46 +0200222
Marcel Holtmann2950f212009-02-12 14:02:50 +0100223 conn->disc_reason = 0x13;
224
Marcel Holtmann01394182006-07-03 10:02:46 +0200225 l2cap_pi(sk)->conn = conn;
226
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300227 if (sk->sk_type == SOCK_SEQPACKET || sk->sk_type == SOCK_STREAM) {
Marcel Holtmann01394182006-07-03 10:02:46 +0200228 /* Alloc CID for connection-oriented socket */
229 l2cap_pi(sk)->scid = l2cap_alloc_cid(l);
230 } else if (sk->sk_type == SOCK_DGRAM) {
231 /* Connectionless socket */
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300232 l2cap_pi(sk)->scid = L2CAP_CID_CONN_LESS;
233 l2cap_pi(sk)->dcid = L2CAP_CID_CONN_LESS;
Marcel Holtmann01394182006-07-03 10:02:46 +0200234 l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
235 } else {
236 /* Raw socket can send/recv signalling messages only */
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300237 l2cap_pi(sk)->scid = L2CAP_CID_SIGNALING;
238 l2cap_pi(sk)->dcid = L2CAP_CID_SIGNALING;
Marcel Holtmann01394182006-07-03 10:02:46 +0200239 l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
240 }
241
242 __l2cap_chan_link(l, sk);
243
244 if (parent)
245 bt_accept_enqueue(parent, sk);
246}
247
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900248/* Delete channel.
Marcel Holtmann01394182006-07-03 10:02:46 +0200249 * Must be called on the locked socket. */
250static void l2cap_chan_del(struct sock *sk, int err)
251{
252 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
253 struct sock *parent = bt_sk(sk)->parent;
254
255 l2cap_sock_clear_timer(sk);
256
257 BT_DBG("sk %p, conn %p, err %d", sk, conn, err);
258
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900259 if (conn) {
Marcel Holtmann01394182006-07-03 10:02:46 +0200260 /* Unlink from channel list */
261 l2cap_chan_unlink(&conn->chan_list, sk);
262 l2cap_pi(sk)->conn = NULL;
263 hci_conn_put(conn->hcon);
264 }
265
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200266 sk->sk_state = BT_CLOSED;
Marcel Holtmann01394182006-07-03 10:02:46 +0200267 sock_set_flag(sk, SOCK_ZAPPED);
268
269 if (err)
270 sk->sk_err = err;
271
272 if (parent) {
273 bt_accept_unlink(sk);
274 parent->sk_data_ready(parent, 0);
275 } else
276 sk->sk_state_change(sk);
277}
278
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200279/* Service level security */
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100280static inline int l2cap_check_security(struct sock *sk)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200281{
282 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100283 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200284
Marcel Holtmann00ae4af2009-02-12 16:19:45 +0100285 if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) {
286 if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
287 auth_type = HCI_AT_NO_BONDING_MITM;
288 else
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300289 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann00ae4af2009-02-12 16:19:45 +0100290
291 if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW)
292 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
293 } else {
294 switch (l2cap_pi(sk)->sec_level) {
295 case BT_SECURITY_HIGH:
296 auth_type = HCI_AT_GENERAL_BONDING_MITM;
297 break;
298 case BT_SECURITY_MEDIUM:
299 auth_type = HCI_AT_GENERAL_BONDING;
300 break;
301 default:
302 auth_type = HCI_AT_NO_BONDING;
303 break;
304 }
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100305 }
306
307 return hci_conn_security(conn->hcon, l2cap_pi(sk)->sec_level,
308 auth_type);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200309}
310
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200311static inline u8 l2cap_get_ident(struct l2cap_conn *conn)
312{
313 u8 id;
314
315 /* Get next available identificator.
316 * 1 - 128 are used by kernel.
317 * 129 - 199 are reserved.
318 * 200 - 254 are used by utilities like l2ping, etc.
319 */
320
321 spin_lock_bh(&conn->lock);
322
323 if (++conn->tx_ident > 128)
324 conn->tx_ident = 1;
325
326 id = conn->tx_ident;
327
328 spin_unlock_bh(&conn->lock);
329
330 return id;
331}
332
333static inline int l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data)
334{
335 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
336
337 BT_DBG("code 0x%2.2x", code);
338
339 if (!skb)
340 return -ENOMEM;
341
342 return hci_send_acl(conn->hcon, skb, 0);
343}
344
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300345static inline int l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control)
346{
347 struct sk_buff *skb;
348 struct l2cap_hdr *lh;
349 struct l2cap_conn *conn = pi->conn;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300350 int count, hlen = L2CAP_HDR_SIZE + 2;
351
352 if (pi->fcs == L2CAP_FCS_CRC16)
353 hlen += 2;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300354
355 BT_DBG("pi %p, control 0x%2.2x", pi, control);
356
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300357 count = min_t(unsigned int, conn->mtu, hlen);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300358 control |= L2CAP_CTRL_FRAME_TYPE;
359
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -0300360 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
361 control |= L2CAP_CTRL_FINAL;
362 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
363 }
364
Gustavo F. Padovanf0946cc2010-05-01 16:15:37 -0300365 if (pi->conn_state & L2CAP_CONN_SEND_PBIT) {
366 control |= L2CAP_CTRL_POLL;
367 pi->conn_state &= ~L2CAP_CONN_SEND_PBIT;
368 }
369
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300370 skb = bt_skb_alloc(count, GFP_ATOMIC);
371 if (!skb)
372 return -ENOMEM;
373
374 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300375 lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300376 lh->cid = cpu_to_le16(pi->dcid);
377 put_unaligned_le16(control, skb_put(skb, 2));
378
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300379 if (pi->fcs == L2CAP_FCS_CRC16) {
380 u16 fcs = crc16(0, (u8 *)lh, count - 2);
381 put_unaligned_le16(fcs, skb_put(skb, 2));
382 }
383
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300384 return hci_send_acl(pi->conn->hcon, skb, 0);
385}
386
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300387static inline int l2cap_send_rr_or_rnr(struct l2cap_pinfo *pi, u16 control)
388{
389 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY)
390 control |= L2CAP_SUPER_RCV_NOT_READY;
391 else
392 control |= L2CAP_SUPER_RCV_READY;
393
Gustavo F. Padovan2ab25cd2009-10-03 02:34:40 -0300394 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
395
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300396 return l2cap_send_sframe(pi, control);
397}
398
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200399static void l2cap_do_start(struct sock *sk)
400{
401 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
402
403 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +0100404 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
405 return;
406
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100407 if (l2cap_check_security(sk)) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200408 struct l2cap_conn_req req;
409 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
410 req.psm = l2cap_pi(sk)->psm;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200411
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200412 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200413
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200414 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200415 L2CAP_CONN_REQ, sizeof(req), &req);
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200416 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200417 } else {
418 struct l2cap_info_req req;
419 req.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
420
421 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
422 conn->info_ident = l2cap_get_ident(conn);
423
424 mod_timer(&conn->info_timer, jiffies +
425 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
426
427 l2cap_send_cmd(conn, conn->info_ident,
428 L2CAP_INFO_REQ, sizeof(req), &req);
429 }
430}
431
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300432static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct sock *sk)
433{
434 struct l2cap_disconn_req req;
435
436 req.dcid = cpu_to_le16(l2cap_pi(sk)->dcid);
437 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
438 l2cap_send_cmd(conn, l2cap_get_ident(conn),
439 L2CAP_DISCONN_REQ, sizeof(req), &req);
440}
441
Linus Torvalds1da177e2005-04-16 15:20:36 -0700442/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200443static void l2cap_conn_start(struct l2cap_conn *conn)
444{
445 struct l2cap_chan_list *l = &conn->chan_list;
446 struct sock *sk;
447
448 BT_DBG("conn %p", conn);
449
450 read_lock(&l->lock);
451
452 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
453 bh_lock_sock(sk);
454
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300455 if (sk->sk_type != SOCK_SEQPACKET &&
456 sk->sk_type != SOCK_STREAM) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200457 bh_unlock_sock(sk);
458 continue;
459 }
460
461 if (sk->sk_state == BT_CONNECT) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100462 if (l2cap_check_security(sk)) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200463 struct l2cap_conn_req req;
464 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
465 req.psm = l2cap_pi(sk)->psm;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200466
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200467 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200468
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200469 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200470 L2CAP_CONN_REQ, sizeof(req), &req);
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200471 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200472 } else if (sk->sk_state == BT_CONNECT2) {
473 struct l2cap_conn_rsp rsp;
474 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
475 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
476
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100477 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100478 if (bt_sk(sk)->defer_setup) {
479 struct sock *parent = bt_sk(sk)->parent;
480 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
481 rsp.status = cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
482 parent->sk_data_ready(parent, 0);
483
484 } else {
485 sk->sk_state = BT_CONFIG;
486 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
487 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
488 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200489 } else {
490 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
491 rsp.status = cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
492 }
493
494 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
495 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
496 }
497
498 bh_unlock_sock(sk);
499 }
500
501 read_unlock(&l->lock);
502}
503
504static void l2cap_conn_ready(struct l2cap_conn *conn)
505{
506 struct l2cap_chan_list *l = &conn->chan_list;
507 struct sock *sk;
508
509 BT_DBG("conn %p", conn);
510
511 read_lock(&l->lock);
512
513 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
514 bh_lock_sock(sk);
515
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300516 if (sk->sk_type != SOCK_SEQPACKET &&
517 sk->sk_type != SOCK_STREAM) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200518 l2cap_sock_clear_timer(sk);
519 sk->sk_state = BT_CONNECTED;
520 sk->sk_state_change(sk);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200521 } else if (sk->sk_state == BT_CONNECT)
522 l2cap_do_start(sk);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200523
524 bh_unlock_sock(sk);
525 }
526
527 read_unlock(&l->lock);
528}
529
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200530/* Notify sockets that we cannot guaranty reliability anymore */
531static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
532{
533 struct l2cap_chan_list *l = &conn->chan_list;
534 struct sock *sk;
535
536 BT_DBG("conn %p", conn);
537
538 read_lock(&l->lock);
539
540 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100541 if (l2cap_pi(sk)->force_reliable)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200542 sk->sk_err = err;
543 }
544
545 read_unlock(&l->lock);
546}
547
548static void l2cap_info_timeout(unsigned long arg)
549{
550 struct l2cap_conn *conn = (void *) arg;
551
Marcel Holtmann984947d2009-02-06 23:35:19 +0100552 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +0100553 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +0100554
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200555 l2cap_conn_start(conn);
556}
557
Linus Torvalds1da177e2005-04-16 15:20:36 -0700558static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
559{
Marcel Holtmann01394182006-07-03 10:02:46 +0200560 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700561
Marcel Holtmann01394182006-07-03 10:02:46 +0200562 if (conn || status)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700563 return conn;
564
Marcel Holtmann01394182006-07-03 10:02:46 +0200565 conn = kzalloc(sizeof(struct l2cap_conn), GFP_ATOMIC);
566 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700567 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700568
569 hcon->l2cap_data = conn;
570 conn->hcon = hcon;
571
Marcel Holtmann01394182006-07-03 10:02:46 +0200572 BT_DBG("hcon %p conn %p", hcon, conn);
573
Linus Torvalds1da177e2005-04-16 15:20:36 -0700574 conn->mtu = hcon->hdev->acl_mtu;
575 conn->src = &hcon->hdev->bdaddr;
576 conn->dst = &hcon->dst;
577
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200578 conn->feat_mask = 0;
579
Linus Torvalds1da177e2005-04-16 15:20:36 -0700580 spin_lock_init(&conn->lock);
581 rwlock_init(&conn->chan_list.lock);
582
Dave Young45054dc2009-10-18 20:28:30 +0000583 setup_timer(&conn->info_timer, l2cap_info_timeout,
584 (unsigned long) conn);
585
Marcel Holtmann2950f212009-02-12 14:02:50 +0100586 conn->disc_reason = 0x13;
587
Linus Torvalds1da177e2005-04-16 15:20:36 -0700588 return conn;
589}
590
Marcel Holtmann01394182006-07-03 10:02:46 +0200591static void l2cap_conn_del(struct hci_conn *hcon, int err)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700592{
Marcel Holtmann01394182006-07-03 10:02:46 +0200593 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700594 struct sock *sk;
595
Marcel Holtmann01394182006-07-03 10:02:46 +0200596 if (!conn)
597 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700598
599 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
600
Wei Yongjun7585b972009-02-25 18:29:52 +0800601 kfree_skb(conn->rx_skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700602
603 /* Kill channels */
604 while ((sk = conn->chan_list.head)) {
605 bh_lock_sock(sk);
606 l2cap_chan_del(sk, err);
607 bh_unlock_sock(sk);
608 l2cap_sock_kill(sk);
609 }
610
Dave Young8e8440f2008-03-03 12:18:55 -0800611 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
612 del_timer_sync(&conn->info_timer);
Thomas Gleixner3ab22732008-02-26 17:42:56 -0800613
Linus Torvalds1da177e2005-04-16 15:20:36 -0700614 hcon->l2cap_data = NULL;
615 kfree(conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700616}
617
618static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
619{
620 struct l2cap_chan_list *l = &conn->chan_list;
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200621 write_lock_bh(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700622 __l2cap_chan_add(conn, sk, parent);
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200623 write_unlock_bh(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700624}
625
Linus Torvalds1da177e2005-04-16 15:20:36 -0700626/* ---- Socket interface ---- */
Al Viro8e036fc2007-07-29 00:16:36 -0700627static struct sock *__l2cap_get_sock_by_addr(__le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700628{
629 struct sock *sk;
630 struct hlist_node *node;
631 sk_for_each(sk, node, &l2cap_sk_list.head)
632 if (l2cap_pi(sk)->sport == psm && !bacmp(&bt_sk(sk)->src, src))
633 goto found;
634 sk = NULL;
635found:
636 return sk;
637}
638
639/* Find socket with psm and source bdaddr.
640 * Returns closest match.
641 */
Al Viro8e036fc2007-07-29 00:16:36 -0700642static struct sock *__l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700643{
644 struct sock *sk = NULL, *sk1 = NULL;
645 struct hlist_node *node;
646
647 sk_for_each(sk, node, &l2cap_sk_list.head) {
648 if (state && sk->sk_state != state)
649 continue;
650
651 if (l2cap_pi(sk)->psm == psm) {
652 /* Exact match. */
653 if (!bacmp(&bt_sk(sk)->src, src))
654 break;
655
656 /* Closest match */
657 if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY))
658 sk1 = sk;
659 }
660 }
661 return node ? sk : sk1;
662}
663
664/* Find socket with given address (psm, src).
665 * Returns locked socket */
Al Viro8e036fc2007-07-29 00:16:36 -0700666static inline struct sock *l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700667{
668 struct sock *s;
669 read_lock(&l2cap_sk_list.lock);
670 s = __l2cap_get_sock_by_psm(state, psm, src);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300671 if (s)
672 bh_lock_sock(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700673 read_unlock(&l2cap_sk_list.lock);
674 return s;
675}
676
677static void l2cap_sock_destruct(struct sock *sk)
678{
679 BT_DBG("sk %p", sk);
680
681 skb_queue_purge(&sk->sk_receive_queue);
682 skb_queue_purge(&sk->sk_write_queue);
683}
684
685static void l2cap_sock_cleanup_listen(struct sock *parent)
686{
687 struct sock *sk;
688
689 BT_DBG("parent %p", parent);
690
691 /* Close not yet accepted channels */
692 while ((sk = bt_accept_dequeue(parent, NULL)))
693 l2cap_sock_close(sk);
694
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200695 parent->sk_state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700696 sock_set_flag(parent, SOCK_ZAPPED);
697}
698
699/* Kill socket (only if zapped and orphan)
700 * Must be called on unlocked socket.
701 */
702static void l2cap_sock_kill(struct sock *sk)
703{
704 if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket)
705 return;
706
707 BT_DBG("sk %p state %d", sk, sk->sk_state);
708
709 /* Kill poor orphan */
710 bt_sock_unlink(&l2cap_sk_list, sk);
711 sock_set_flag(sk, SOCK_DEAD);
712 sock_put(sk);
713}
714
715static void __l2cap_sock_close(struct sock *sk, int reason)
716{
717 BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket);
718
719 switch (sk->sk_state) {
720 case BT_LISTEN:
721 l2cap_sock_cleanup_listen(sk);
722 break;
723
724 case BT_CONNECTED:
725 case BT_CONFIG:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300726 if (sk->sk_type == SOCK_SEQPACKET ||
727 sk->sk_type == SOCK_STREAM) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700728 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700729
730 sk->sk_state = BT_DISCONN;
731 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300732 l2cap_send_disconn_req(conn, sk);
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200733 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -0700734 l2cap_chan_del(sk, reason);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700735 break;
736
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100737 case BT_CONNECT2:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300738 if (sk->sk_type == SOCK_SEQPACKET ||
739 sk->sk_type == SOCK_STREAM) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100740 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
741 struct l2cap_conn_rsp rsp;
742 __u16 result;
743
744 if (bt_sk(sk)->defer_setup)
745 result = L2CAP_CR_SEC_BLOCK;
746 else
747 result = L2CAP_CR_BAD_PSM;
748
749 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
750 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
751 rsp.result = cpu_to_le16(result);
752 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
753 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
754 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
755 } else
756 l2cap_chan_del(sk, reason);
757 break;
758
Linus Torvalds1da177e2005-04-16 15:20:36 -0700759 case BT_CONNECT:
760 case BT_DISCONN:
761 l2cap_chan_del(sk, reason);
762 break;
763
764 default:
765 sock_set_flag(sk, SOCK_ZAPPED);
766 break;
767 }
768}
769
770/* Must be called on unlocked socket. */
771static void l2cap_sock_close(struct sock *sk)
772{
773 l2cap_sock_clear_timer(sk);
774 lock_sock(sk);
775 __l2cap_sock_close(sk, ECONNRESET);
776 release_sock(sk);
777 l2cap_sock_kill(sk);
778}
779
780static void l2cap_sock_init(struct sock *sk, struct sock *parent)
781{
782 struct l2cap_pinfo *pi = l2cap_pi(sk);
783
784 BT_DBG("sk %p", sk);
785
786 if (parent) {
787 sk->sk_type = parent->sk_type;
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100788 bt_sk(sk)->defer_setup = bt_sk(parent)->defer_setup;
789
Linus Torvalds1da177e2005-04-16 15:20:36 -0700790 pi->imtu = l2cap_pi(parent)->imtu;
791 pi->omtu = l2cap_pi(parent)->omtu;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -0700792 pi->mode = l2cap_pi(parent)->mode;
793 pi->fcs = l2cap_pi(parent)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -0300794 pi->max_tx = l2cap_pi(parent)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -0300795 pi->tx_win = l2cap_pi(parent)->tx_win;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100796 pi->sec_level = l2cap_pi(parent)->sec_level;
797 pi->role_switch = l2cap_pi(parent)->role_switch;
798 pi->force_reliable = l2cap_pi(parent)->force_reliable;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700799 } else {
800 pi->imtu = L2CAP_DEFAULT_MTU;
801 pi->omtu = 0;
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300802 if (enable_ertm && sk->sk_type == SOCK_STREAM)
803 pi->mode = L2CAP_MODE_ERTM;
804 else
805 pi->mode = L2CAP_MODE_BASIC;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -0300806 pi->max_tx = max_transmit;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -0700807 pi->fcs = L2CAP_FCS_CRC16;
Gustavo F. Padovan369ba302010-05-01 16:15:41 -0300808 pi->tx_win = tx_window;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100809 pi->sec_level = BT_SECURITY_LOW;
810 pi->role_switch = 0;
811 pi->force_reliable = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700812 }
813
814 /* Default config options */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +0200815 pi->conf_len = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700816 pi->flush_to = L2CAP_DEFAULT_FLUSH_TO;
Dave Young45054dc2009-10-18 20:28:30 +0000817 skb_queue_head_init(TX_QUEUE(sk));
818 skb_queue_head_init(SREJ_QUEUE(sk));
819 INIT_LIST_HEAD(SREJ_LIST(sk));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700820}
821
822static struct proto l2cap_proto = {
823 .name = "L2CAP",
824 .owner = THIS_MODULE,
825 .obj_size = sizeof(struct l2cap_pinfo)
826};
827
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700828static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700829{
830 struct sock *sk;
831
Pavel Emelyanov6257ff22007-11-01 00:39:31 -0700832 sk = sk_alloc(net, PF_BLUETOOTH, prio, &l2cap_proto);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700833 if (!sk)
834 return NULL;
835
836 sock_init_data(sock, sk);
837 INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
838
839 sk->sk_destruct = l2cap_sock_destruct;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200840 sk->sk_sndtimeo = msecs_to_jiffies(L2CAP_CONN_TIMEOUT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700841
842 sock_reset_flag(sk, SOCK_ZAPPED);
843
844 sk->sk_protocol = proto;
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200845 sk->sk_state = BT_OPEN;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700846
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200847 setup_timer(&sk->sk_timer, l2cap_sock_timeout, (unsigned long) sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700848
849 bt_sock_link(&l2cap_sk_list, sk);
850 return sk;
851}
852
Eric Paris3f378b62009-11-05 22:18:14 -0800853static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol,
854 int kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700855{
856 struct sock *sk;
857
858 BT_DBG("sock %p", sock);
859
860 sock->state = SS_UNCONNECTED;
861
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300862 if (sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM &&
Linus Torvalds1da177e2005-04-16 15:20:36 -0700863 sock->type != SOCK_DGRAM && sock->type != SOCK_RAW)
864 return -ESOCKTNOSUPPORT;
865
Eric Parisc84b3262009-11-05 20:45:52 -0800866 if (sock->type == SOCK_RAW && !kern && !capable(CAP_NET_RAW))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700867 return -EPERM;
868
869 sock->ops = &l2cap_sock_ops;
870
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700871 sk = l2cap_sock_alloc(net, sock, protocol, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700872 if (!sk)
873 return -ENOMEM;
874
875 l2cap_sock_init(sk, NULL);
876 return 0;
877}
878
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100879static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700880{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700881 struct sock *sk = sock->sk;
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100882 struct sockaddr_l2 la;
883 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700884
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100885 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700886
887 if (!addr || addr->sa_family != AF_BLUETOOTH)
888 return -EINVAL;
889
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100890 memset(&la, 0, sizeof(la));
891 len = min_t(unsigned int, sizeof(la), alen);
892 memcpy(&la, addr, len);
893
Marcel Holtmann2a517ca2009-02-16 03:20:31 +0100894 if (la.l2_cid)
895 return -EINVAL;
896
Linus Torvalds1da177e2005-04-16 15:20:36 -0700897 lock_sock(sk);
898
899 if (sk->sk_state != BT_OPEN) {
900 err = -EBADFD;
901 goto done;
902 }
903
Marcel Holtmannb4324b52009-06-07 18:06:51 +0200904 if (la.l2_psm && __le16_to_cpu(la.l2_psm) < 0x1001 &&
Marcel Holtmann847641d2007-01-22 22:00:45 +0100905 !capable(CAP_NET_BIND_SERVICE)) {
906 err = -EACCES;
907 goto done;
908 }
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900909
Linus Torvalds1da177e2005-04-16 15:20:36 -0700910 write_lock_bh(&l2cap_sk_list.lock);
911
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100912 if (la.l2_psm && __l2cap_get_sock_by_addr(la.l2_psm, &la.l2_bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700913 err = -EADDRINUSE;
914 } else {
915 /* Save source address */
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100916 bacpy(&bt_sk(sk)->src, &la.l2_bdaddr);
917 l2cap_pi(sk)->psm = la.l2_psm;
918 l2cap_pi(sk)->sport = la.l2_psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700919 sk->sk_state = BT_BOUND;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100920
Marcel Holtmannb4324b52009-06-07 18:06:51 +0200921 if (__le16_to_cpu(la.l2_psm) == 0x0001 ||
922 __le16_to_cpu(la.l2_psm) == 0x0003)
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100923 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700924 }
925
926 write_unlock_bh(&l2cap_sk_list.lock);
927
928done:
929 release_sock(sk);
930 return err;
931}
932
933static int l2cap_do_connect(struct sock *sk)
934{
935 bdaddr_t *src = &bt_sk(sk)->src;
936 bdaddr_t *dst = &bt_sk(sk)->dst;
937 struct l2cap_conn *conn;
938 struct hci_conn *hcon;
939 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200940 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +0200941 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700942
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100943 BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst),
944 l2cap_pi(sk)->psm);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700945
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300946 hdev = hci_get_route(dst, src);
947 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700948 return -EHOSTUNREACH;
949
950 hci_dev_lock_bh(hdev);
951
952 err = -ENOMEM;
953
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100954 if (sk->sk_type == SOCK_RAW) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100955 switch (l2cap_pi(sk)->sec_level) {
956 case BT_SECURITY_HIGH:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100957 auth_type = HCI_AT_DEDICATED_BONDING_MITM;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100958 break;
959 case BT_SECURITY_MEDIUM:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100960 auth_type = HCI_AT_DEDICATED_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100961 break;
962 default:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100963 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100964 break;
965 }
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100966 } else if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100967 if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200968 auth_type = HCI_AT_NO_BONDING_MITM;
969 else
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200970 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann435fef22009-02-09 03:55:28 +0100971
972 if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW)
973 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100974 } else {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100975 switch (l2cap_pi(sk)->sec_level) {
976 case BT_SECURITY_HIGH:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100977 auth_type = HCI_AT_GENERAL_BONDING_MITM;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100978 break;
979 case BT_SECURITY_MEDIUM:
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200980 auth_type = HCI_AT_GENERAL_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100981 break;
982 default:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100983 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100984 break;
985 }
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200986 }
987
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100988 hcon = hci_connect(hdev, ACL_LINK, dst,
989 l2cap_pi(sk)->sec_level, auth_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700990 if (!hcon)
991 goto done;
992
993 conn = l2cap_conn_add(hcon, 0);
994 if (!conn) {
995 hci_conn_put(hcon);
996 goto done;
997 }
998
999 err = 0;
1000
1001 /* Update source addr of the socket */
1002 bacpy(src, conn->src);
1003
1004 l2cap_chan_add(conn, sk, NULL);
1005
1006 sk->sk_state = BT_CONNECT;
1007 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
1008
1009 if (hcon->state == BT_CONNECTED) {
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001010 if (sk->sk_type != SOCK_SEQPACKET &&
1011 sk->sk_type != SOCK_STREAM) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001012 l2cap_sock_clear_timer(sk);
1013 sk->sk_state = BT_CONNECTED;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001014 } else
1015 l2cap_do_start(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001016 }
1017
1018done:
1019 hci_dev_unlock_bh(hdev);
1020 hci_dev_put(hdev);
1021 return err;
1022}
1023
1024static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
1025{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001026 struct sock *sk = sock->sk;
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001027 struct sockaddr_l2 la;
1028 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001029
Linus Torvalds1da177e2005-04-16 15:20:36 -07001030 BT_DBG("sk %p", sk);
1031
Changli Gao6503d962010-03-31 22:58:26 +00001032 if (!addr || alen < sizeof(addr->sa_family) ||
1033 addr->sa_family != AF_BLUETOOTH)
Marcel Holtmann2a517ca2009-02-16 03:20:31 +01001034 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001035
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001036 memset(&la, 0, sizeof(la));
1037 len = min_t(unsigned int, sizeof(la), alen);
1038 memcpy(&la, addr, len);
1039
Marcel Holtmann2a517ca2009-02-16 03:20:31 +01001040 if (la.l2_cid)
1041 return -EINVAL;
1042
1043 lock_sock(sk);
1044
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001045 if ((sk->sk_type == SOCK_SEQPACKET || sk->sk_type == SOCK_STREAM)
1046 && !la.l2_psm) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001047 err = -EINVAL;
1048 goto done;
1049 }
1050
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001051 switch (l2cap_pi(sk)->mode) {
1052 case L2CAP_MODE_BASIC:
1053 break;
1054 case L2CAP_MODE_ERTM:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001055 case L2CAP_MODE_STREAMING:
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001056 if (enable_ertm)
1057 break;
1058 /* fall through */
1059 default:
1060 err = -ENOTSUPP;
1061 goto done;
1062 }
1063
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001064 switch (sk->sk_state) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001065 case BT_CONNECT:
1066 case BT_CONNECT2:
1067 case BT_CONFIG:
1068 /* Already connecting */
1069 goto wait;
1070
1071 case BT_CONNECTED:
1072 /* Already connected */
1073 goto done;
1074
1075 case BT_OPEN:
1076 case BT_BOUND:
1077 /* Can connect */
1078 break;
1079
1080 default:
1081 err = -EBADFD;
1082 goto done;
1083 }
1084
1085 /* Set destination address and psm */
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001086 bacpy(&bt_sk(sk)->dst, &la.l2_bdaddr);
1087 l2cap_pi(sk)->psm = la.l2_psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001088
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001089 err = l2cap_do_connect(sk);
1090 if (err)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001091 goto done;
1092
1093wait:
1094 err = bt_sock_wait_state(sk, BT_CONNECTED,
1095 sock_sndtimeo(sk, flags & O_NONBLOCK));
1096done:
1097 release_sock(sk);
1098 return err;
1099}
1100
1101static int l2cap_sock_listen(struct socket *sock, int backlog)
1102{
1103 struct sock *sk = sock->sk;
1104 int err = 0;
1105
1106 BT_DBG("sk %p backlog %d", sk, backlog);
1107
1108 lock_sock(sk);
1109
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001110 if ((sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM)
1111 || sk->sk_state != BT_BOUND) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001112 err = -EBADFD;
1113 goto done;
1114 }
1115
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001116 switch (l2cap_pi(sk)->mode) {
1117 case L2CAP_MODE_BASIC:
1118 break;
1119 case L2CAP_MODE_ERTM:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001120 case L2CAP_MODE_STREAMING:
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001121 if (enable_ertm)
1122 break;
1123 /* fall through */
1124 default:
1125 err = -ENOTSUPP;
1126 goto done;
1127 }
1128
Linus Torvalds1da177e2005-04-16 15:20:36 -07001129 if (!l2cap_pi(sk)->psm) {
1130 bdaddr_t *src = &bt_sk(sk)->src;
1131 u16 psm;
1132
1133 err = -EINVAL;
1134
1135 write_lock_bh(&l2cap_sk_list.lock);
1136
1137 for (psm = 0x1001; psm < 0x1100; psm += 2)
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001138 if (!__l2cap_get_sock_by_addr(cpu_to_le16(psm), src)) {
1139 l2cap_pi(sk)->psm = cpu_to_le16(psm);
1140 l2cap_pi(sk)->sport = cpu_to_le16(psm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001141 err = 0;
1142 break;
1143 }
1144
1145 write_unlock_bh(&l2cap_sk_list.lock);
1146
1147 if (err < 0)
1148 goto done;
1149 }
1150
1151 sk->sk_max_ack_backlog = backlog;
1152 sk->sk_ack_backlog = 0;
1153 sk->sk_state = BT_LISTEN;
1154
1155done:
1156 release_sock(sk);
1157 return err;
1158}
1159
1160static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int flags)
1161{
1162 DECLARE_WAITQUEUE(wait, current);
1163 struct sock *sk = sock->sk, *nsk;
1164 long timeo;
1165 int err = 0;
1166
Peter Zijlstrafcc70d52006-11-08 22:44:35 -08001167 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001168
1169 if (sk->sk_state != BT_LISTEN) {
1170 err = -EBADFD;
1171 goto done;
1172 }
1173
1174 timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
1175
1176 BT_DBG("sk %p timeo %ld", sk, timeo);
1177
1178 /* Wait for an incoming connection. (wake-one). */
Eric Dumazetaa395142010-04-20 13:03:51 +00001179 add_wait_queue_exclusive(sk_sleep(sk), &wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001180 while (!(nsk = bt_accept_dequeue(sk, newsock))) {
1181 set_current_state(TASK_INTERRUPTIBLE);
1182 if (!timeo) {
1183 err = -EAGAIN;
1184 break;
1185 }
1186
1187 release_sock(sk);
1188 timeo = schedule_timeout(timeo);
Peter Zijlstrafcc70d52006-11-08 22:44:35 -08001189 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001190
1191 if (sk->sk_state != BT_LISTEN) {
1192 err = -EBADFD;
1193 break;
1194 }
1195
1196 if (signal_pending(current)) {
1197 err = sock_intr_errno(timeo);
1198 break;
1199 }
1200 }
1201 set_current_state(TASK_RUNNING);
Eric Dumazetaa395142010-04-20 13:03:51 +00001202 remove_wait_queue(sk_sleep(sk), &wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001203
1204 if (err)
1205 goto done;
1206
1207 newsock->state = SS_CONNECTED;
1208
1209 BT_DBG("new socket %p", nsk);
1210
1211done:
1212 release_sock(sk);
1213 return err;
1214}
1215
1216static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
1217{
1218 struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
1219 struct sock *sk = sock->sk;
1220
1221 BT_DBG("sock %p, sk %p", sock, sk);
1222
1223 addr->sa_family = AF_BLUETOOTH;
1224 *len = sizeof(struct sockaddr_l2);
1225
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001226 if (peer) {
1227 la->l2_psm = l2cap_pi(sk)->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001228 bacpy(&la->l2_bdaddr, &bt_sk(sk)->dst);
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001229 la->l2_cid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001230 } else {
1231 la->l2_psm = l2cap_pi(sk)->sport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001232 bacpy(&la->l2_bdaddr, &bt_sk(sk)->src);
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001233 la->l2_cid = cpu_to_le16(l2cap_pi(sk)->scid);
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001234 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001235
Linus Torvalds1da177e2005-04-16 15:20:36 -07001236 return 0;
1237}
1238
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001239static void l2cap_monitor_timeout(unsigned long arg)
1240{
1241 struct sock *sk = (void *) arg;
1242 u16 control;
1243
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001244 bh_lock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001245 if (l2cap_pi(sk)->retry_count >= l2cap_pi(sk)->remote_max_tx) {
1246 l2cap_send_disconn_req(l2cap_pi(sk)->conn, sk);
Andrei Emeltchenkob13f5862009-12-15 11:38:04 +02001247 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001248 return;
1249 }
1250
1251 l2cap_pi(sk)->retry_count++;
1252 __mod_monitor_timer();
1253
1254 control = L2CAP_CTRL_POLL;
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001255 l2cap_send_rr_or_rnr(l2cap_pi(sk), control);
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001256 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001257}
1258
1259static void l2cap_retrans_timeout(unsigned long arg)
1260{
1261 struct sock *sk = (void *) arg;
1262 u16 control;
1263
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001264 bh_lock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001265 l2cap_pi(sk)->retry_count = 1;
1266 __mod_monitor_timer();
1267
1268 l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
1269
1270 control = L2CAP_CTRL_POLL;
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001271 l2cap_send_rr_or_rnr(l2cap_pi(sk), control);
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001272 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001273}
1274
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001275static void l2cap_drop_acked_frames(struct sock *sk)
1276{
1277 struct sk_buff *skb;
1278
Gustavo F. Padovan812e7372010-05-01 16:15:42 -03001279 while ((skb = skb_peek(TX_QUEUE(sk))) &&
1280 l2cap_pi(sk)->unacked_frames) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001281 if (bt_cb(skb)->tx_seq == l2cap_pi(sk)->expected_ack_seq)
1282 break;
1283
1284 skb = skb_dequeue(TX_QUEUE(sk));
1285 kfree_skb(skb);
1286
1287 l2cap_pi(sk)->unacked_frames--;
1288 }
1289
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001290 if (!l2cap_pi(sk)->unacked_frames)
1291 del_timer(&l2cap_pi(sk)->retrans_timer);
1292
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001293 return;
1294}
1295
1296static inline int l2cap_do_send(struct sock *sk, struct sk_buff *skb)
1297{
1298 struct l2cap_pinfo *pi = l2cap_pi(sk);
1299 int err;
1300
1301 BT_DBG("sk %p, skb %p len %d", sk, skb, skb->len);
1302
1303 err = hci_send_acl(pi->conn->hcon, skb, 0);
1304 if (err < 0)
1305 kfree_skb(skb);
1306
1307 return err;
1308}
1309
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001310static int l2cap_streaming_send(struct sock *sk)
1311{
1312 struct sk_buff *skb, *tx_skb;
1313 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001314 u16 control, fcs;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001315 int err;
1316
1317 while ((skb = sk->sk_send_head)) {
1318 tx_skb = skb_clone(skb, GFP_ATOMIC);
1319
1320 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
1321 control |= pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT;
1322 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1323
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001324 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001325 fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
1326 put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
1327 }
1328
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001329 err = l2cap_do_send(sk, tx_skb);
1330 if (err < 0) {
1331 l2cap_send_disconn_req(pi->conn, sk);
1332 return err;
1333 }
1334
1335 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
1336
1337 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1338 sk->sk_send_head = NULL;
1339 else
1340 sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
1341
1342 skb = skb_dequeue(TX_QUEUE(sk));
1343 kfree_skb(skb);
1344 }
1345 return 0;
1346}
1347
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001348static int l2cap_retransmit_frame(struct sock *sk, u8 tx_seq)
1349{
1350 struct l2cap_pinfo *pi = l2cap_pi(sk);
1351 struct sk_buff *skb, *tx_skb;
1352 u16 control, fcs;
1353 int err;
1354
1355 skb = skb_peek(TX_QUEUE(sk));
1356 do {
1357 if (bt_cb(skb)->tx_seq != tx_seq) {
1358 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1359 break;
1360 skb = skb_queue_next(TX_QUEUE(sk), skb);
1361 continue;
1362 }
1363
1364 if (pi->remote_max_tx &&
1365 bt_cb(skb)->retries == pi->remote_max_tx) {
1366 l2cap_send_disconn_req(pi->conn, sk);
1367 break;
1368 }
1369
1370 tx_skb = skb_clone(skb, GFP_ATOMIC);
1371 bt_cb(skb)->retries++;
1372 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03001373 control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001374 | (tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
1375 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1376
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001377 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001378 fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
1379 put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
1380 }
1381
1382 err = l2cap_do_send(sk, tx_skb);
1383 if (err < 0) {
1384 l2cap_send_disconn_req(pi->conn, sk);
1385 return err;
1386 }
1387 break;
1388 } while(1);
1389 return 0;
1390}
1391
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001392static int l2cap_ertm_send(struct sock *sk)
1393{
1394 struct sk_buff *skb, *tx_skb;
1395 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001396 u16 control, fcs;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001397 int err, nsent = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001398
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001399 if (pi->conn_state & L2CAP_CONN_WAIT_F)
1400 return 0;
1401
Joe Perchesf64f9e72009-11-29 16:55:45 -08001402 while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(sk)) &&
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03001403 !(pi->conn_state & L2CAP_CONN_REMOTE_BUSY)) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001404
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001405 if (pi->remote_max_tx &&
1406 bt_cb(skb)->retries == pi->remote_max_tx) {
1407 l2cap_send_disconn_req(pi->conn, sk);
1408 break;
1409 }
1410
Andrei Emeltchenkoe420aba2009-12-23 13:07:14 +02001411 tx_skb = skb_clone(skb, GFP_ATOMIC);
1412
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001413 bt_cb(skb)->retries++;
1414
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001415 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001416 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
1417 control |= L2CAP_CTRL_FINAL;
1418 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
1419 }
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03001420 control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001421 | (pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
1422 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1423
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001424
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001425 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001426 fcs = crc16(0, (u8 *)skb->data, tx_skb->len - 2);
1427 put_unaligned_le16(fcs, skb->data + tx_skb->len - 2);
1428 }
1429
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001430 err = l2cap_do_send(sk, tx_skb);
1431 if (err < 0) {
1432 l2cap_send_disconn_req(pi->conn, sk);
1433 return err;
1434 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001435 __mod_retrans_timer();
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001436
1437 bt_cb(skb)->tx_seq = pi->next_tx_seq;
1438 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
1439
1440 pi->unacked_frames++;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001441 pi->frames_sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001442
1443 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1444 sk->sk_send_head = NULL;
1445 else
1446 sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001447
1448 nsent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001449 }
1450
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001451 return nsent;
1452}
1453
1454static int l2cap_send_ack(struct l2cap_pinfo *pi)
1455{
1456 struct sock *sk = (struct sock *)pi;
1457 u16 control = 0;
1458
1459 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1460
1461 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
1462 control |= L2CAP_SUPER_RCV_NOT_READY;
1463 return l2cap_send_sframe(pi, control);
1464 } else if (l2cap_ertm_send(sk) == 0) {
1465 control |= L2CAP_SUPER_RCV_READY;
1466 return l2cap_send_sframe(pi, control);
1467 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001468 return 0;
1469}
1470
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03001471static int l2cap_send_srejtail(struct sock *sk)
1472{
1473 struct srej_list *tail;
1474 u16 control;
1475
1476 control = L2CAP_SUPER_SELECT_REJECT;
1477 control |= L2CAP_CTRL_FINAL;
1478
1479 tail = list_entry(SREJ_LIST(sk)->prev, struct srej_list, list);
1480 control |= tail->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1481
1482 l2cap_send_sframe(l2cap_pi(sk), control);
1483
1484 return 0;
1485}
1486
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001487static 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 -07001488{
1489 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001490 struct sk_buff **frag;
1491 int err, sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001492
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03001493 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001494 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001495
1496 sent += count;
1497 len -= count;
1498
1499 /* Continuation fragments (no L2CAP header) */
1500 frag = &skb_shinfo(skb)->frag_list;
1501 while (len) {
1502 count = min_t(unsigned int, conn->mtu, len);
1503
1504 *frag = bt_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err);
1505 if (!*frag)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001506 return -EFAULT;
1507 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
1508 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001509
1510 sent += count;
1511 len -= count;
1512
1513 frag = &(*frag)->next;
1514 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001515
1516 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001517}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001518
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001519static struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, size_t len)
1520{
1521 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1522 struct sk_buff *skb;
1523 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1524 struct l2cap_hdr *lh;
1525
1526 BT_DBG("sk %p len %d", sk, (int)len);
1527
1528 count = min_t(unsigned int, (conn->mtu - hlen), len);
1529 skb = bt_skb_send_alloc(sk, count + hlen,
1530 msg->msg_flags & MSG_DONTWAIT, &err);
1531 if (!skb)
1532 return ERR_PTR(-ENOMEM);
1533
1534 /* Create L2CAP header */
1535 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1536 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1537 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1538 put_unaligned_le16(l2cap_pi(sk)->psm, skb_put(skb, 2));
1539
1540 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1541 if (unlikely(err < 0)) {
1542 kfree_skb(skb);
1543 return ERR_PTR(err);
1544 }
1545 return skb;
1546}
1547
1548static struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *msg, size_t len)
1549{
1550 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1551 struct sk_buff *skb;
1552 int err, count, hlen = L2CAP_HDR_SIZE;
1553 struct l2cap_hdr *lh;
1554
1555 BT_DBG("sk %p len %d", sk, (int)len);
1556
1557 count = min_t(unsigned int, (conn->mtu - hlen), len);
1558 skb = bt_skb_send_alloc(sk, count + hlen,
1559 msg->msg_flags & MSG_DONTWAIT, &err);
1560 if (!skb)
1561 return ERR_PTR(-ENOMEM);
1562
1563 /* Create L2CAP header */
1564 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1565 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1566 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1567
1568 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1569 if (unlikely(err < 0)) {
1570 kfree_skb(skb);
1571 return ERR_PTR(err);
1572 }
1573 return skb;
1574}
1575
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001576static 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 -03001577{
1578 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1579 struct sk_buff *skb;
1580 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1581 struct l2cap_hdr *lh;
1582
1583 BT_DBG("sk %p len %d", sk, (int)len);
1584
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03001585 if (!conn)
1586 return ERR_PTR(-ENOTCONN);
1587
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001588 if (sdulen)
1589 hlen += 2;
1590
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001591 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1592 hlen += 2;
1593
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001594 count = min_t(unsigned int, (conn->mtu - hlen), len);
1595 skb = bt_skb_send_alloc(sk, count + hlen,
1596 msg->msg_flags & MSG_DONTWAIT, &err);
1597 if (!skb)
1598 return ERR_PTR(-ENOMEM);
1599
1600 /* Create L2CAP header */
1601 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1602 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1603 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1604 put_unaligned_le16(control, skb_put(skb, 2));
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001605 if (sdulen)
1606 put_unaligned_le16(sdulen, skb_put(skb, 2));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001607
1608 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1609 if (unlikely(err < 0)) {
1610 kfree_skb(skb);
1611 return ERR_PTR(err);
1612 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001613
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001614 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1615 put_unaligned_le16(0, skb_put(skb, 2));
1616
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001617 bt_cb(skb)->retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001618 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001619}
1620
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001621static inline int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len)
1622{
1623 struct l2cap_pinfo *pi = l2cap_pi(sk);
1624 struct sk_buff *skb;
1625 struct sk_buff_head sar_queue;
1626 u16 control;
1627 size_t size = 0;
1628
1629 __skb_queue_head_init(&sar_queue);
1630 control = L2CAP_SDU_START;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001631 skb = l2cap_create_iframe_pdu(sk, msg, pi->remote_mps, control, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001632 if (IS_ERR(skb))
1633 return PTR_ERR(skb);
1634
1635 __skb_queue_tail(&sar_queue, skb);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001636 len -= pi->remote_mps;
1637 size += pi->remote_mps;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001638
1639 while (len > 0) {
1640 size_t buflen;
1641
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001642 if (len > pi->remote_mps) {
Gustavo F. Padovan44651b82010-05-01 16:15:43 -03001643 control = L2CAP_SDU_CONTINUE;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001644 buflen = pi->remote_mps;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001645 } else {
Gustavo F. Padovan44651b82010-05-01 16:15:43 -03001646 control = L2CAP_SDU_END;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001647 buflen = len;
1648 }
1649
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001650 skb = l2cap_create_iframe_pdu(sk, msg, buflen, control, 0);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001651 if (IS_ERR(skb)) {
1652 skb_queue_purge(&sar_queue);
1653 return PTR_ERR(skb);
1654 }
1655
1656 __skb_queue_tail(&sar_queue, skb);
1657 len -= buflen;
1658 size += buflen;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001659 }
1660 skb_queue_splice_tail(&sar_queue, TX_QUEUE(sk));
1661 if (sk->sk_send_head == NULL)
1662 sk->sk_send_head = sar_queue.next;
1663
1664 return size;
1665}
1666
Linus Torvalds1da177e2005-04-16 15:20:36 -07001667static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len)
1668{
1669 struct sock *sk = sock->sk;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001670 struct l2cap_pinfo *pi = l2cap_pi(sk);
1671 struct sk_buff *skb;
1672 u16 control;
1673 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001674
1675 BT_DBG("sock %p, sk %p", sock, sk);
1676
Benjamin LaHaisec1cbe4b2005-12-13 23:22:19 -08001677 err = sock_error(sk);
1678 if (err)
1679 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001680
1681 if (msg->msg_flags & MSG_OOB)
1682 return -EOPNOTSUPP;
1683
Linus Torvalds1da177e2005-04-16 15:20:36 -07001684 lock_sock(sk);
1685
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001686 if (sk->sk_state != BT_CONNECTED) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001687 err = -ENOTCONN;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001688 goto done;
1689 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001690
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001691 /* Connectionless channel */
1692 if (sk->sk_type == SOCK_DGRAM) {
1693 skb = l2cap_create_connless_pdu(sk, msg, len);
Dan Carpenter477fffb2010-04-21 23:52:01 +00001694 if (IS_ERR(skb))
1695 err = PTR_ERR(skb);
1696 else
1697 err = l2cap_do_send(sk, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001698 goto done;
1699 }
1700
1701 switch (pi->mode) {
1702 case L2CAP_MODE_BASIC:
Gustavo F. Padovanc69163e2010-05-01 16:15:35 -03001703 /* Check outgoing MTU */
1704 if (len > pi->omtu) {
1705 err = -EINVAL;
1706 goto done;
1707 }
1708
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001709 /* Create a basic PDU */
1710 skb = l2cap_create_basic_pdu(sk, msg, len);
1711 if (IS_ERR(skb)) {
1712 err = PTR_ERR(skb);
1713 goto done;
1714 }
1715
1716 err = l2cap_do_send(sk, skb);
1717 if (!err)
1718 err = len;
1719 break;
1720
1721 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001722 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001723 /* Entire SDU fits into one PDU */
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001724 if (len <= pi->remote_mps) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001725 control = L2CAP_SDU_UNSEGMENTED;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001726 skb = l2cap_create_iframe_pdu(sk, msg, len, control, 0);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001727 if (IS_ERR(skb)) {
1728 err = PTR_ERR(skb);
1729 goto done;
1730 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001731 __skb_queue_tail(TX_QUEUE(sk), skb);
1732 if (sk->sk_send_head == NULL)
1733 sk->sk_send_head = skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001734 } else {
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001735 /* Segment SDU into multiples PDUs */
1736 err = l2cap_sar_segment_sdu(sk, msg, len);
1737 if (err < 0)
1738 goto done;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001739 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001740
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001741 if (pi->mode == L2CAP_MODE_STREAMING)
1742 err = l2cap_streaming_send(sk);
1743 else
1744 err = l2cap_ertm_send(sk);
1745
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001746 if (err >= 0)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001747 err = len;
1748 break;
1749
1750 default:
1751 BT_DBG("bad state %1.1x", pi->mode);
1752 err = -EINVAL;
1753 }
1754
1755done:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001756 release_sock(sk);
1757 return err;
1758}
1759
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001760static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags)
1761{
1762 struct sock *sk = sock->sk;
1763
1764 lock_sock(sk);
1765
1766 if (sk->sk_state == BT_CONNECT2 && bt_sk(sk)->defer_setup) {
1767 struct l2cap_conn_rsp rsp;
1768
1769 sk->sk_state = BT_CONFIG;
1770
1771 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
1772 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
1773 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
1774 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
1775 l2cap_send_cmd(l2cap_pi(sk)->conn, l2cap_pi(sk)->ident,
1776 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
1777
1778 release_sock(sk);
1779 return 0;
1780 }
1781
1782 release_sock(sk);
1783
1784 return bt_sock_recvmsg(iocb, sock, msg, len, flags);
1785}
1786
David S. Millerb7058842009-09-30 16:12:20 -07001787static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001788{
1789 struct sock *sk = sock->sk;
1790 struct l2cap_options opts;
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001791 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001792 u32 opt;
1793
1794 BT_DBG("sk %p", sk);
1795
1796 lock_sock(sk);
1797
1798 switch (optname) {
1799 case L2CAP_OPTIONS:
Marcel Holtmann0878b662007-05-05 00:35:59 +02001800 opts.imtu = l2cap_pi(sk)->imtu;
1801 opts.omtu = l2cap_pi(sk)->omtu;
1802 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001803 opts.mode = l2cap_pi(sk)->mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001804 opts.fcs = l2cap_pi(sk)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03001805 opts.max_tx = l2cap_pi(sk)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03001806 opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
Marcel Holtmann0878b662007-05-05 00:35:59 +02001807
Linus Torvalds1da177e2005-04-16 15:20:36 -07001808 len = min_t(unsigned int, sizeof(opts), optlen);
1809 if (copy_from_user((char *) &opts, optval, len)) {
1810 err = -EFAULT;
1811 break;
1812 }
Marcel Holtmann0878b662007-05-05 00:35:59 +02001813
João Paulo Rechi Vita0041ecf2010-05-01 16:15:42 -03001814 l2cap_pi(sk)->mode = opts.mode;
1815 switch (l2cap_pi(sk)->mode) {
1816 case L2CAP_MODE_BASIC:
1817 break;
1818 case L2CAP_MODE_ERTM:
1819 case L2CAP_MODE_STREAMING:
1820 if (enable_ertm)
1821 break;
1822 /* fall through */
1823 default:
1824 err = -EINVAL;
1825 break;
1826 }
1827
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001828 l2cap_pi(sk)->imtu = opts.imtu;
1829 l2cap_pi(sk)->omtu = opts.omtu;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001830 l2cap_pi(sk)->fcs = opts.fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03001831 l2cap_pi(sk)->max_tx = opts.max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03001832 l2cap_pi(sk)->tx_win = (__u8)opts.txwin_size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001833 break;
1834
1835 case L2CAP_LM:
1836 if (get_user(opt, (u32 __user *) optval)) {
1837 err = -EFAULT;
1838 break;
1839 }
1840
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001841 if (opt & L2CAP_LM_AUTH)
1842 l2cap_pi(sk)->sec_level = BT_SECURITY_LOW;
1843 if (opt & L2CAP_LM_ENCRYPT)
1844 l2cap_pi(sk)->sec_level = BT_SECURITY_MEDIUM;
1845 if (opt & L2CAP_LM_SECURE)
1846 l2cap_pi(sk)->sec_level = BT_SECURITY_HIGH;
1847
1848 l2cap_pi(sk)->role_switch = (opt & L2CAP_LM_MASTER);
1849 l2cap_pi(sk)->force_reliable = (opt & L2CAP_LM_RELIABLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001850 break;
1851
1852 default:
1853 err = -ENOPROTOOPT;
1854 break;
1855 }
1856
1857 release_sock(sk);
1858 return err;
1859}
1860
David S. Millerb7058842009-09-30 16:12:20 -07001861static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001862{
1863 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001864 struct bt_security sec;
1865 int len, err = 0;
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001866 u32 opt;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001867
1868 BT_DBG("sk %p", sk);
1869
1870 if (level == SOL_L2CAP)
1871 return l2cap_sock_setsockopt_old(sock, optname, optval, optlen);
1872
Marcel Holtmann0588d942009-01-16 10:06:13 +01001873 if (level != SOL_BLUETOOTH)
1874 return -ENOPROTOOPT;
1875
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001876 lock_sock(sk);
1877
1878 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001879 case BT_SECURITY:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001880 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
1881 && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01001882 err = -EINVAL;
1883 break;
1884 }
1885
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001886 sec.level = BT_SECURITY_LOW;
1887
1888 len = min_t(unsigned int, sizeof(sec), optlen);
1889 if (copy_from_user((char *) &sec, optval, len)) {
1890 err = -EFAULT;
1891 break;
1892 }
1893
1894 if (sec.level < BT_SECURITY_LOW ||
1895 sec.level > BT_SECURITY_HIGH) {
1896 err = -EINVAL;
1897 break;
1898 }
1899
1900 l2cap_pi(sk)->sec_level = sec.level;
1901 break;
1902
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001903 case BT_DEFER_SETUP:
1904 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
1905 err = -EINVAL;
1906 break;
1907 }
1908
1909 if (get_user(opt, (u32 __user *) optval)) {
1910 err = -EFAULT;
1911 break;
1912 }
1913
1914 bt_sk(sk)->defer_setup = opt;
1915 break;
1916
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001917 default:
1918 err = -ENOPROTOOPT;
1919 break;
1920 }
1921
1922 release_sock(sk);
1923 return err;
1924}
1925
1926static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001927{
1928 struct sock *sk = sock->sk;
1929 struct l2cap_options opts;
1930 struct l2cap_conninfo cinfo;
1931 int len, err = 0;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001932 u32 opt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001933
1934 BT_DBG("sk %p", sk);
1935
1936 if (get_user(len, optlen))
1937 return -EFAULT;
1938
1939 lock_sock(sk);
1940
1941 switch (optname) {
1942 case L2CAP_OPTIONS:
1943 opts.imtu = l2cap_pi(sk)->imtu;
1944 opts.omtu = l2cap_pi(sk)->omtu;
1945 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001946 opts.mode = l2cap_pi(sk)->mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001947 opts.fcs = l2cap_pi(sk)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03001948 opts.max_tx = l2cap_pi(sk)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03001949 opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001950
1951 len = min_t(unsigned int, len, sizeof(opts));
1952 if (copy_to_user(optval, (char *) &opts, len))
1953 err = -EFAULT;
1954
1955 break;
1956
1957 case L2CAP_LM:
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001958 switch (l2cap_pi(sk)->sec_level) {
1959 case BT_SECURITY_LOW:
1960 opt = L2CAP_LM_AUTH;
1961 break;
1962 case BT_SECURITY_MEDIUM:
1963 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT;
1964 break;
1965 case BT_SECURITY_HIGH:
1966 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT |
1967 L2CAP_LM_SECURE;
1968 break;
1969 default:
1970 opt = 0;
1971 break;
1972 }
1973
1974 if (l2cap_pi(sk)->role_switch)
1975 opt |= L2CAP_LM_MASTER;
1976
1977 if (l2cap_pi(sk)->force_reliable)
1978 opt |= L2CAP_LM_RELIABLE;
1979
1980 if (put_user(opt, (u32 __user *) optval))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001981 err = -EFAULT;
1982 break;
1983
1984 case L2CAP_CONNINFO:
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001985 if (sk->sk_state != BT_CONNECTED &&
1986 !(sk->sk_state == BT_CONNECT2 &&
1987 bt_sk(sk)->defer_setup)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001988 err = -ENOTCONN;
1989 break;
1990 }
1991
1992 cinfo.hci_handle = l2cap_pi(sk)->conn->hcon->handle;
1993 memcpy(cinfo.dev_class, l2cap_pi(sk)->conn->hcon->dev_class, 3);
1994
1995 len = min_t(unsigned int, len, sizeof(cinfo));
1996 if (copy_to_user(optval, (char *) &cinfo, len))
1997 err = -EFAULT;
1998
1999 break;
2000
2001 default:
2002 err = -ENOPROTOOPT;
2003 break;
2004 }
2005
2006 release_sock(sk);
2007 return err;
2008}
2009
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002010static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
2011{
2012 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002013 struct bt_security sec;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002014 int len, err = 0;
2015
2016 BT_DBG("sk %p", sk);
2017
2018 if (level == SOL_L2CAP)
2019 return l2cap_sock_getsockopt_old(sock, optname, optval, optlen);
2020
Marcel Holtmann0588d942009-01-16 10:06:13 +01002021 if (level != SOL_BLUETOOTH)
2022 return -ENOPROTOOPT;
2023
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002024 if (get_user(len, optlen))
2025 return -EFAULT;
2026
2027 lock_sock(sk);
2028
2029 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002030 case BT_SECURITY:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03002031 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
2032 && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01002033 err = -EINVAL;
2034 break;
2035 }
2036
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002037 sec.level = l2cap_pi(sk)->sec_level;
2038
2039 len = min_t(unsigned int, len, sizeof(sec));
2040 if (copy_to_user(optval, (char *) &sec, len))
2041 err = -EFAULT;
2042
2043 break;
2044
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002045 case BT_DEFER_SETUP:
2046 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
2047 err = -EINVAL;
2048 break;
2049 }
2050
2051 if (put_user(bt_sk(sk)->defer_setup, (u32 __user *) optval))
2052 err = -EFAULT;
2053
2054 break;
2055
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002056 default:
2057 err = -ENOPROTOOPT;
2058 break;
2059 }
2060
2061 release_sock(sk);
2062 return err;
2063}
2064
Linus Torvalds1da177e2005-04-16 15:20:36 -07002065static int l2cap_sock_shutdown(struct socket *sock, int how)
2066{
2067 struct sock *sk = sock->sk;
2068 int err = 0;
2069
2070 BT_DBG("sock %p, sk %p", sock, sk);
2071
2072 if (!sk)
2073 return 0;
2074
2075 lock_sock(sk);
2076 if (!sk->sk_shutdown) {
2077 sk->sk_shutdown = SHUTDOWN_MASK;
2078 l2cap_sock_clear_timer(sk);
2079 __l2cap_sock_close(sk, 0);
2080
2081 if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
Marcel Holtmannb1235d72008-07-14 20:13:54 +02002082 err = bt_sock_wait_state(sk, BT_CLOSED,
2083 sk->sk_lingertime);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002084 }
2085 release_sock(sk);
2086 return err;
2087}
2088
2089static int l2cap_sock_release(struct socket *sock)
2090{
2091 struct sock *sk = sock->sk;
2092 int err;
2093
2094 BT_DBG("sock %p, sk %p", sock, sk);
2095
2096 if (!sk)
2097 return 0;
2098
2099 err = l2cap_sock_shutdown(sock, 2);
2100
2101 sock_orphan(sk);
2102 l2cap_sock_kill(sk);
2103 return err;
2104}
2105
Linus Torvalds1da177e2005-04-16 15:20:36 -07002106static void l2cap_chan_ready(struct sock *sk)
2107{
2108 struct sock *parent = bt_sk(sk)->parent;
2109
2110 BT_DBG("sk %p, parent %p", sk, parent);
2111
2112 l2cap_pi(sk)->conf_state = 0;
2113 l2cap_sock_clear_timer(sk);
2114
2115 if (!parent) {
2116 /* Outgoing channel.
2117 * Wake up socket sleeping on connect.
2118 */
2119 sk->sk_state = BT_CONNECTED;
2120 sk->sk_state_change(sk);
2121 } else {
2122 /* Incoming channel.
2123 * Wake up socket sleeping on accept.
2124 */
2125 parent->sk_data_ready(parent, 0);
2126 }
2127}
2128
2129/* Copy frame to all raw sockets on that connection */
2130static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2131{
2132 struct l2cap_chan_list *l = &conn->chan_list;
2133 struct sk_buff *nskb;
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002134 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002135
2136 BT_DBG("conn %p", conn);
2137
2138 read_lock(&l->lock);
2139 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
2140 if (sk->sk_type != SOCK_RAW)
2141 continue;
2142
2143 /* Don't send frame to the socket it came from */
2144 if (skb->sk == sk)
2145 continue;
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002146 nskb = skb_clone(skb, GFP_ATOMIC);
2147 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002148 continue;
2149
2150 if (sock_queue_rcv_skb(sk, nskb))
2151 kfree_skb(nskb);
2152 }
2153 read_unlock(&l->lock);
2154}
2155
2156/* ---- L2CAP signalling commands ---- */
2157static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
2158 u8 code, u8 ident, u16 dlen, void *data)
2159{
2160 struct sk_buff *skb, **frag;
2161 struct l2cap_cmd_hdr *cmd;
2162 struct l2cap_hdr *lh;
2163 int len, count;
2164
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002165 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d",
2166 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002167
2168 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2169 count = min_t(unsigned int, conn->mtu, len);
2170
2171 skb = bt_skb_alloc(count, GFP_ATOMIC);
2172 if (!skb)
2173 return NULL;
2174
2175 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002176 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03002177 lh->cid = cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002178
2179 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2180 cmd->code = code;
2181 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002182 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002183
2184 if (dlen) {
2185 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2186 memcpy(skb_put(skb, count), data, count);
2187 data += count;
2188 }
2189
2190 len -= skb->len;
2191
2192 /* Continuation fragments (no L2CAP header) */
2193 frag = &skb_shinfo(skb)->frag_list;
2194 while (len) {
2195 count = min_t(unsigned int, conn->mtu, len);
2196
2197 *frag = bt_skb_alloc(count, GFP_ATOMIC);
2198 if (!*frag)
2199 goto fail;
2200
2201 memcpy(skb_put(*frag, count), data, count);
2202
2203 len -= count;
2204 data += count;
2205
2206 frag = &(*frag)->next;
2207 }
2208
2209 return skb;
2210
2211fail:
2212 kfree_skb(skb);
2213 return NULL;
2214}
2215
2216static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned long *val)
2217{
2218 struct l2cap_conf_opt *opt = *ptr;
2219 int len;
2220
2221 len = L2CAP_CONF_OPT_SIZE + opt->len;
2222 *ptr += len;
2223
2224 *type = opt->type;
2225 *olen = opt->len;
2226
2227 switch (opt->len) {
2228 case 1:
2229 *val = *((u8 *) opt->val);
2230 break;
2231
2232 case 2:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002233 *val = __le16_to_cpu(*((__le16 *) opt->val));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002234 break;
2235
2236 case 4:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002237 *val = __le32_to_cpu(*((__le32 *) opt->val));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002238 break;
2239
2240 default:
2241 *val = (unsigned long) opt->val;
2242 break;
2243 }
2244
2245 BT_DBG("type 0x%2.2x len %d val 0x%lx", *type, opt->len, *val);
2246 return len;
2247}
2248
Linus Torvalds1da177e2005-04-16 15:20:36 -07002249static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2250{
2251 struct l2cap_conf_opt *opt = *ptr;
2252
2253 BT_DBG("type 0x%2.2x len %d val 0x%lx", type, len, val);
2254
2255 opt->type = type;
2256 opt->len = len;
2257
2258 switch (len) {
2259 case 1:
2260 *((u8 *) opt->val) = val;
2261 break;
2262
2263 case 2:
Al Viro8e036fc2007-07-29 00:16:36 -07002264 *((__le16 *) opt->val) = cpu_to_le16(val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002265 break;
2266
2267 case 4:
Al Viro8e036fc2007-07-29 00:16:36 -07002268 *((__le32 *) opt->val) = cpu_to_le32(val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002269 break;
2270
2271 default:
2272 memcpy(opt->val, (void *) val, len);
2273 break;
2274 }
2275
2276 *ptr += L2CAP_CONF_OPT_SIZE + len;
2277}
2278
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002279static void l2cap_ack_timeout(unsigned long arg)
2280{
2281 struct sock *sk = (void *) arg;
2282
2283 bh_lock_sock(sk);
2284 l2cap_send_ack(l2cap_pi(sk));
2285 bh_unlock_sock(sk);
2286}
2287
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002288static inline void l2cap_ertm_init(struct sock *sk)
2289{
2290 l2cap_pi(sk)->expected_ack_seq = 0;
2291 l2cap_pi(sk)->unacked_frames = 0;
2292 l2cap_pi(sk)->buffer_seq = 0;
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03002293 l2cap_pi(sk)->num_acked = 0;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03002294 l2cap_pi(sk)->frames_sent = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002295
2296 setup_timer(&l2cap_pi(sk)->retrans_timer,
2297 l2cap_retrans_timeout, (unsigned long) sk);
2298 setup_timer(&l2cap_pi(sk)->monitor_timer,
2299 l2cap_monitor_timeout, (unsigned long) sk);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002300 setup_timer(&l2cap_pi(sk)->ack_timer,
2301 l2cap_ack_timeout, (unsigned long) sk);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002302
2303 __skb_queue_head_init(SREJ_QUEUE(sk));
2304}
2305
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002306static int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
2307{
2308 u32 local_feat_mask = l2cap_feat_mask;
2309 if (enable_ertm)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002310 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002311
2312 switch (mode) {
2313 case L2CAP_MODE_ERTM:
2314 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
2315 case L2CAP_MODE_STREAMING:
2316 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
2317 default:
2318 return 0x00;
2319 }
2320}
2321
2322static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
2323{
2324 switch (mode) {
2325 case L2CAP_MODE_STREAMING:
2326 case L2CAP_MODE_ERTM:
2327 if (l2cap_mode_supported(mode, remote_feat_mask))
2328 return mode;
2329 /* fall through */
2330 default:
2331 return L2CAP_MODE_BASIC;
2332 }
2333}
2334
Linus Torvalds1da177e2005-04-16 15:20:36 -07002335static int l2cap_build_conf_req(struct sock *sk, void *data)
2336{
2337 struct l2cap_pinfo *pi = l2cap_pi(sk);
2338 struct l2cap_conf_req *req = data;
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03002339 struct l2cap_conf_rfc rfc = { .mode = pi->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07002340 void *ptr = req->data;
2341
2342 BT_DBG("sk %p", sk);
2343
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002344 if (pi->num_conf_req || pi->num_conf_rsp)
2345 goto done;
2346
2347 switch (pi->mode) {
2348 case L2CAP_MODE_STREAMING:
2349 case L2CAP_MODE_ERTM:
2350 pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002351 if (!l2cap_mode_supported(pi->mode, pi->conn->feat_mask))
2352 l2cap_send_disconn_req(pi->conn, sk);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002353 break;
2354 default:
2355 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
2356 break;
2357 }
2358
2359done:
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002360 switch (pi->mode) {
2361 case L2CAP_MODE_BASIC:
2362 if (pi->imtu != L2CAP_DEFAULT_MTU)
2363 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
2364 break;
2365
2366 case L2CAP_MODE_ERTM:
2367 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03002368 rfc.txwin_size = pi->tx_win;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03002369 rfc.max_transmit = pi->max_tx;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002370 rfc.retrans_timeout = 0;
2371 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002372 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03002373 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002374 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002375
2376 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2377 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002378
2379 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2380 break;
2381
2382 if (pi->fcs == L2CAP_FCS_NONE ||
2383 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
2384 pi->fcs = L2CAP_FCS_NONE;
2385 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
2386 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002387 break;
2388
2389 case L2CAP_MODE_STREAMING:
2390 rfc.mode = L2CAP_MODE_STREAMING;
2391 rfc.txwin_size = 0;
2392 rfc.max_transmit = 0;
2393 rfc.retrans_timeout = 0;
2394 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002395 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03002396 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002397 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002398
2399 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2400 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002401
2402 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2403 break;
2404
2405 if (pi->fcs == L2CAP_FCS_NONE ||
2406 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
2407 pi->fcs = L2CAP_FCS_NONE;
2408 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
2409 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002410 break;
2411 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002412
2413 /* FIXME: Need actual value of the flush timeout */
2414 //if (flush_to != L2CAP_DEFAULT_FLUSH_TO)
2415 // l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2, pi->flush_to);
2416
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002417 req->dcid = cpu_to_le16(pi->dcid);
2418 req->flags = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002419
2420 return ptr - data;
2421}
2422
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002423static int l2cap_parse_conf_req(struct sock *sk, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002424{
2425 struct l2cap_pinfo *pi = l2cap_pi(sk);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002426 struct l2cap_conf_rsp *rsp = data;
2427 void *ptr = rsp->data;
2428 void *req = pi->conf_req;
2429 int len = pi->conf_len;
2430 int type, hint, olen;
2431 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002432 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Marcel Holtmann861d6882007-10-20 13:37:06 +02002433 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002434 u16 result = L2CAP_CONF_SUCCESS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002435
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002436 BT_DBG("sk %p", sk);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01002437
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002438 while (len >= L2CAP_CONF_OPT_SIZE) {
2439 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002440
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03002441 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07002442 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002443
2444 switch (type) {
2445 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002446 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002447 break;
2448
2449 case L2CAP_CONF_FLUSH_TO:
2450 pi->flush_to = val;
2451 break;
2452
2453 case L2CAP_CONF_QOS:
2454 break;
2455
Marcel Holtmann6464f352007-10-20 13:39:51 +02002456 case L2CAP_CONF_RFC:
2457 if (olen == sizeof(rfc))
2458 memcpy(&rfc, (void *) val, olen);
2459 break;
2460
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002461 case L2CAP_CONF_FCS:
2462 if (val == L2CAP_FCS_NONE)
2463 pi->conf_state |= L2CAP_CONF_NO_FCS_RECV;
2464
2465 break;
2466
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002467 default:
2468 if (hint)
2469 break;
2470
2471 result = L2CAP_CONF_UNKNOWN;
2472 *((u8 *) ptr++) = type;
2473 break;
2474 }
2475 }
2476
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002477 if (pi->num_conf_rsp || pi->num_conf_req)
2478 goto done;
2479
2480 switch (pi->mode) {
2481 case L2CAP_MODE_STREAMING:
2482 case L2CAP_MODE_ERTM:
2483 pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
2484 if (!l2cap_mode_supported(pi->mode, pi->conn->feat_mask))
2485 return -ECONNREFUSED;
2486 break;
2487 default:
2488 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
2489 break;
2490 }
2491
2492done:
2493 if (pi->mode != rfc.mode) {
2494 result = L2CAP_CONF_UNACCEPT;
2495 rfc.mode = pi->mode;
2496
2497 if (pi->num_conf_rsp == 1)
2498 return -ECONNREFUSED;
2499
2500 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2501 sizeof(rfc), (unsigned long) &rfc);
2502 }
2503
2504
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002505 if (result == L2CAP_CONF_SUCCESS) {
2506 /* Configure output options and let the other side know
2507 * which ones we don't like. */
2508
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002509 if (mtu < L2CAP_DEFAULT_MIN_MTU)
2510 result = L2CAP_CONF_UNACCEPT;
2511 else {
2512 pi->omtu = mtu;
2513 pi->conf_state |= L2CAP_CONF_MTU_DONE;
2514 }
2515 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002516
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002517 switch (rfc.mode) {
2518 case L2CAP_MODE_BASIC:
2519 pi->fcs = L2CAP_FCS_NONE;
2520 pi->conf_state |= L2CAP_CONF_MODE_DONE;
2521 break;
2522
2523 case L2CAP_MODE_ERTM:
2524 pi->remote_tx_win = rfc.txwin_size;
2525 pi->remote_max_tx = rfc.max_transmit;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002526 if (rfc.max_pdu_size > pi->conn->mtu - 10)
2527 rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10);
2528
2529 pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002530
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002531 rfc.retrans_timeout =
2532 le16_to_cpu(L2CAP_DEFAULT_RETRANS_TO);
2533 rfc.monitor_timeout =
2534 le16_to_cpu(L2CAP_DEFAULT_MONITOR_TO);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002535
2536 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03002537
2538 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2539 sizeof(rfc), (unsigned long) &rfc);
2540
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002541 break;
2542
2543 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002544 if (rfc.max_pdu_size > pi->conn->mtu - 10)
2545 rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10);
2546
2547 pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002548
2549 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03002550
2551 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2552 sizeof(rfc), (unsigned long) &rfc);
2553
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002554 break;
2555
2556 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02002557 result = L2CAP_CONF_UNACCEPT;
2558
2559 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002560 rfc.mode = pi->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002561 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002562
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002563 if (result == L2CAP_CONF_SUCCESS)
2564 pi->conf_state |= L2CAP_CONF_OUTPUT_DONE;
2565 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002566 rsp->scid = cpu_to_le16(pi->dcid);
2567 rsp->result = cpu_to_le16(result);
2568 rsp->flags = cpu_to_le16(0x0000);
2569
2570 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002571}
2572
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002573static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data, u16 *result)
2574{
2575 struct l2cap_pinfo *pi = l2cap_pi(sk);
2576 struct l2cap_conf_req *req = data;
2577 void *ptr = req->data;
2578 int type, olen;
2579 unsigned long val;
2580 struct l2cap_conf_rfc rfc;
2581
2582 BT_DBG("sk %p, rsp %p, len %d, req %p", sk, rsp, len, data);
2583
2584 while (len >= L2CAP_CONF_OPT_SIZE) {
2585 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
2586
2587 switch (type) {
2588 case L2CAP_CONF_MTU:
2589 if (val < L2CAP_DEFAULT_MIN_MTU) {
2590 *result = L2CAP_CONF_UNACCEPT;
2591 pi->omtu = L2CAP_DEFAULT_MIN_MTU;
2592 } else
2593 pi->omtu = val;
2594 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
2595 break;
2596
2597 case L2CAP_CONF_FLUSH_TO:
2598 pi->flush_to = val;
2599 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
2600 2, pi->flush_to);
2601 break;
2602
2603 case L2CAP_CONF_RFC:
2604 if (olen == sizeof(rfc))
2605 memcpy(&rfc, (void *)val, olen);
2606
2607 if ((pi->conf_state & L2CAP_CONF_STATE2_DEVICE) &&
2608 rfc.mode != pi->mode)
2609 return -ECONNREFUSED;
2610
2611 pi->mode = rfc.mode;
2612 pi->fcs = 0;
2613
2614 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2615 sizeof(rfc), (unsigned long) &rfc);
2616 break;
2617 }
2618 }
2619
2620 if (*result == L2CAP_CONF_SUCCESS) {
2621 switch (rfc.mode) {
2622 case L2CAP_MODE_ERTM:
2623 pi->remote_tx_win = rfc.txwin_size;
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002624 pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
2625 pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002626 pi->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002627 break;
2628 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002629 pi->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002630 }
2631 }
2632
2633 req->dcid = cpu_to_le16(pi->dcid);
2634 req->flags = cpu_to_le16(0x0000);
2635
2636 return ptr - data;
2637}
2638
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002639static int l2cap_build_conf_rsp(struct sock *sk, void *data, u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002640{
2641 struct l2cap_conf_rsp *rsp = data;
2642 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002643
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002644 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002645
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002646 rsp->scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002647 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002648 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002649
2650 return ptr - data;
2651}
2652
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002653static void l2cap_conf_rfc_get(struct sock *sk, void *rsp, int len)
2654{
2655 struct l2cap_pinfo *pi = l2cap_pi(sk);
2656 int type, olen;
2657 unsigned long val;
2658 struct l2cap_conf_rfc rfc;
2659
2660 BT_DBG("sk %p, rsp %p, len %d", sk, rsp, len);
2661
2662 if ((pi->mode != L2CAP_MODE_ERTM) && (pi->mode != L2CAP_MODE_STREAMING))
2663 return;
2664
2665 while (len >= L2CAP_CONF_OPT_SIZE) {
2666 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
2667
2668 switch (type) {
2669 case L2CAP_CONF_RFC:
2670 if (olen == sizeof(rfc))
2671 memcpy(&rfc, (void *)val, olen);
2672 goto done;
2673 }
2674 }
2675
2676done:
2677 switch (rfc.mode) {
2678 case L2CAP_MODE_ERTM:
2679 pi->remote_tx_win = rfc.txwin_size;
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002680 pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
2681 pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002682 pi->mps = le16_to_cpu(rfc.max_pdu_size);
2683 break;
2684 case L2CAP_MODE_STREAMING:
2685 pi->mps = le16_to_cpu(rfc.max_pdu_size);
2686 }
2687}
2688
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002689static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2690{
2691 struct l2cap_cmd_rej *rej = (struct l2cap_cmd_rej *) data;
2692
2693 if (rej->reason != 0x0000)
2694 return 0;
2695
2696 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
2697 cmd->ident == conn->info_ident) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002698 del_timer(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01002699
2700 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002701 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01002702
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002703 l2cap_conn_start(conn);
2704 }
2705
2706 return 0;
2707}
2708
Linus Torvalds1da177e2005-04-16 15:20:36 -07002709static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2710{
2711 struct l2cap_chan_list *list = &conn->chan_list;
2712 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
2713 struct l2cap_conn_rsp rsp;
2714 struct sock *sk, *parent;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002715 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002716
2717 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002718 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002719
2720 BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
2721
2722 /* Check if we have socket listening on psm */
2723 parent = l2cap_get_sock_by_psm(BT_LISTEN, psm, conn->src);
2724 if (!parent) {
2725 result = L2CAP_CR_BAD_PSM;
2726 goto sendresp;
2727 }
2728
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002729 /* Check if the ACL is secure enough (if not SDP) */
2730 if (psm != cpu_to_le16(0x0001) &&
2731 !hci_conn_check_link_mode(conn->hcon)) {
Marcel Holtmann2950f212009-02-12 14:02:50 +01002732 conn->disc_reason = 0x05;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002733 result = L2CAP_CR_SEC_BLOCK;
2734 goto response;
2735 }
2736
Linus Torvalds1da177e2005-04-16 15:20:36 -07002737 result = L2CAP_CR_NO_MEM;
2738
2739 /* Check for backlog size */
2740 if (sk_acceptq_is_full(parent)) {
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09002741 BT_DBG("backlog full %d", parent->sk_ack_backlog);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002742 goto response;
2743 }
2744
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09002745 sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002746 if (!sk)
2747 goto response;
2748
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002749 write_lock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002750
2751 /* Check if we already have channel with that dcid */
2752 if (__l2cap_get_chan_by_dcid(list, scid)) {
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002753 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002754 sock_set_flag(sk, SOCK_ZAPPED);
2755 l2cap_sock_kill(sk);
2756 goto response;
2757 }
2758
2759 hci_conn_hold(conn->hcon);
2760
2761 l2cap_sock_init(sk, parent);
2762 bacpy(&bt_sk(sk)->src, conn->src);
2763 bacpy(&bt_sk(sk)->dst, conn->dst);
2764 l2cap_pi(sk)->psm = psm;
2765 l2cap_pi(sk)->dcid = scid;
2766
2767 __l2cap_chan_add(conn, sk, parent);
2768 dcid = l2cap_pi(sk)->scid;
2769
2770 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
2771
Linus Torvalds1da177e2005-04-16 15:20:36 -07002772 l2cap_pi(sk)->ident = cmd->ident;
2773
Marcel Holtmann984947d2009-02-06 23:35:19 +01002774 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002775 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002776 if (bt_sk(sk)->defer_setup) {
2777 sk->sk_state = BT_CONNECT2;
2778 result = L2CAP_CR_PEND;
2779 status = L2CAP_CS_AUTHOR_PEND;
2780 parent->sk_data_ready(parent, 0);
2781 } else {
2782 sk->sk_state = BT_CONFIG;
2783 result = L2CAP_CR_SUCCESS;
2784 status = L2CAP_CS_NO_INFO;
2785 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002786 } else {
2787 sk->sk_state = BT_CONNECT2;
2788 result = L2CAP_CR_PEND;
2789 status = L2CAP_CS_AUTHEN_PEND;
2790 }
2791 } else {
2792 sk->sk_state = BT_CONNECT2;
2793 result = L2CAP_CR_PEND;
2794 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002795 }
2796
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002797 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002798
2799response:
2800 bh_unlock_sock(parent);
2801
2802sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002803 rsp.scid = cpu_to_le16(scid);
2804 rsp.dcid = cpu_to_le16(dcid);
2805 rsp.result = cpu_to_le16(result);
2806 rsp.status = cpu_to_le16(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002807 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002808
2809 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
2810 struct l2cap_info_req info;
2811 info.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
2812
2813 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
2814 conn->info_ident = l2cap_get_ident(conn);
2815
2816 mod_timer(&conn->info_timer, jiffies +
2817 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
2818
2819 l2cap_send_cmd(conn, conn->info_ident,
2820 L2CAP_INFO_REQ, sizeof(info), &info);
2821 }
2822
Linus Torvalds1da177e2005-04-16 15:20:36 -07002823 return 0;
2824}
2825
2826static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2827{
2828 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
2829 u16 scid, dcid, result, status;
2830 struct sock *sk;
2831 u8 req[128];
2832
2833 scid = __le16_to_cpu(rsp->scid);
2834 dcid = __le16_to_cpu(rsp->dcid);
2835 result = __le16_to_cpu(rsp->result);
2836 status = __le16_to_cpu(rsp->status);
2837
2838 BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
2839
2840 if (scid) {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002841 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2842 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002843 return 0;
2844 } else {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002845 sk = l2cap_get_chan_by_ident(&conn->chan_list, cmd->ident);
2846 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002847 return 0;
2848 }
2849
2850 switch (result) {
2851 case L2CAP_CR_SUCCESS:
2852 sk->sk_state = BT_CONFIG;
2853 l2cap_pi(sk)->ident = 0;
2854 l2cap_pi(sk)->dcid = dcid;
2855 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
2856
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002857 l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_CONNECT_PEND;
2858
Linus Torvalds1da177e2005-04-16 15:20:36 -07002859 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
2860 l2cap_build_conf_req(sk, req), req);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002861 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002862 break;
2863
2864 case L2CAP_CR_PEND:
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002865 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002866 break;
2867
2868 default:
2869 l2cap_chan_del(sk, ECONNREFUSED);
2870 break;
2871 }
2872
2873 bh_unlock_sock(sk);
2874 return 0;
2875}
2876
Al Viro88219a02007-07-29 00:17:25 -07002877static 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 -07002878{
2879 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
2880 u16 dcid, flags;
2881 u8 rsp[64];
2882 struct sock *sk;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002883 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002884
2885 dcid = __le16_to_cpu(req->dcid);
2886 flags = __le16_to_cpu(req->flags);
2887
2888 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
2889
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002890 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
2891 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002892 return -ENOENT;
2893
Marcel Holtmann354f60a2006-11-18 22:15:20 +01002894 if (sk->sk_state == BT_DISCONN)
2895 goto unlock;
2896
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002897 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07002898 len = cmd_len - sizeof(*req);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002899 if (l2cap_pi(sk)->conf_len + len > sizeof(l2cap_pi(sk)->conf_req)) {
2900 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
2901 l2cap_build_conf_rsp(sk, rsp,
2902 L2CAP_CONF_REJECT, flags), rsp);
2903 goto unlock;
2904 }
2905
2906 /* Store config. */
2907 memcpy(l2cap_pi(sk)->conf_req + l2cap_pi(sk)->conf_len, req->data, len);
2908 l2cap_pi(sk)->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002909
2910 if (flags & 0x0001) {
2911 /* Incomplete config. Send empty response. */
2912 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002913 l2cap_build_conf_rsp(sk, rsp,
2914 L2CAP_CONF_SUCCESS, 0x0001), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002915 goto unlock;
2916 }
2917
2918 /* Complete config. */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002919 len = l2cap_parse_conf_req(sk, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002920 if (len < 0) {
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002921 l2cap_send_disconn_req(conn, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002922 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002923 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002924
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002925 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002926 l2cap_pi(sk)->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002927
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002928 /* Reset config buffer. */
2929 l2cap_pi(sk)->conf_len = 0;
2930
Marcel Holtmann876d9482007-10-20 13:35:42 +02002931 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE))
2932 goto unlock;
2933
Linus Torvalds1da177e2005-04-16 15:20:36 -07002934 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) {
Joe Perchesf64f9e72009-11-29 16:55:45 -08002935 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) ||
2936 l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002937 l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
2938
Linus Torvalds1da177e2005-04-16 15:20:36 -07002939 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002940
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002941 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002942 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002943 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002944 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
2945 l2cap_ertm_init(sk);
2946
Linus Torvalds1da177e2005-04-16 15:20:36 -07002947 l2cap_chan_ready(sk);
Marcel Holtmann876d9482007-10-20 13:35:42 +02002948 goto unlock;
2949 }
2950
2951 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002952 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002953 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002954 l2cap_build_conf_req(sk, buf), buf);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002955 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002956 }
2957
2958unlock:
2959 bh_unlock_sock(sk);
2960 return 0;
2961}
2962
2963static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2964{
2965 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
2966 u16 scid, flags, result;
2967 struct sock *sk;
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002968 int len = cmd->len - sizeof(*rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002969
2970 scid = __le16_to_cpu(rsp->scid);
2971 flags = __le16_to_cpu(rsp->flags);
2972 result = __le16_to_cpu(rsp->result);
2973
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002974 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x",
2975 scid, flags, result);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002976
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002977 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2978 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002979 return 0;
2980
2981 switch (result) {
2982 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002983 l2cap_conf_rfc_get(sk, rsp->data, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002984 break;
2985
2986 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002987 if (l2cap_pi(sk)->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002988 char req[64];
2989
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02002990 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
2991 l2cap_send_disconn_req(conn, sk);
2992 goto done;
2993 }
2994
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002995 /* throw out any old stored conf requests */
2996 result = L2CAP_CONF_SUCCESS;
2997 len = l2cap_parse_conf_rsp(sk, rsp->data,
2998 len, req, &result);
2999 if (len < 0) {
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03003000 l2cap_send_disconn_req(conn, sk);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003001 goto done;
3002 }
3003
3004 l2cap_send_cmd(conn, l2cap_get_ident(conn),
3005 L2CAP_CONF_REQ, len, req);
3006 l2cap_pi(sk)->num_conf_req++;
3007 if (result != L2CAP_CONF_SUCCESS)
3008 goto done;
3009 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003010 }
3011
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09003012 default:
Linus Torvalds1da177e2005-04-16 15:20:36 -07003013 sk->sk_state = BT_DISCONN;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02003014 sk->sk_err = ECONNRESET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003015 l2cap_sock_set_timer(sk, HZ * 5);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03003016 l2cap_send_disconn_req(conn, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003017 goto done;
3018 }
3019
3020 if (flags & 0x01)
3021 goto done;
3022
Linus Torvalds1da177e2005-04-16 15:20:36 -07003023 l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE;
3024
3025 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) {
Joe Perchesf64f9e72009-11-29 16:55:45 -08003026 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) ||
3027 l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003028 l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
3029
Linus Torvalds1da177e2005-04-16 15:20:36 -07003030 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003031 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003032 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003033 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003034 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
3035 l2cap_ertm_init(sk);
3036
Linus Torvalds1da177e2005-04-16 15:20:36 -07003037 l2cap_chan_ready(sk);
3038 }
3039
3040done:
3041 bh_unlock_sock(sk);
3042 return 0;
3043}
3044
3045static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3046{
3047 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
3048 struct l2cap_disconn_rsp rsp;
3049 u16 dcid, scid;
3050 struct sock *sk;
3051
3052 scid = __le16_to_cpu(req->scid);
3053 dcid = __le16_to_cpu(req->dcid);
3054
3055 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
3056
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003057 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
3058 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003059 return 0;
3060
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003061 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
3062 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003063 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
3064
3065 sk->sk_shutdown = SHUTDOWN_MASK;
3066
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003067 skb_queue_purge(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003068
3069 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
3070 skb_queue_purge(SREJ_QUEUE(sk));
3071 del_timer(&l2cap_pi(sk)->retrans_timer);
3072 del_timer(&l2cap_pi(sk)->monitor_timer);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003073 del_timer(&l2cap_pi(sk)->ack_timer);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003074 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003075
Linus Torvalds1da177e2005-04-16 15:20:36 -07003076 l2cap_chan_del(sk, ECONNRESET);
3077 bh_unlock_sock(sk);
3078
3079 l2cap_sock_kill(sk);
3080 return 0;
3081}
3082
3083static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3084{
3085 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
3086 u16 dcid, scid;
3087 struct sock *sk;
3088
3089 scid = __le16_to_cpu(rsp->scid);
3090 dcid = __le16_to_cpu(rsp->dcid);
3091
3092 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
3093
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003094 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
3095 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003096 return 0;
3097
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003098 skb_queue_purge(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003099
3100 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
3101 skb_queue_purge(SREJ_QUEUE(sk));
3102 del_timer(&l2cap_pi(sk)->retrans_timer);
3103 del_timer(&l2cap_pi(sk)->monitor_timer);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003104 del_timer(&l2cap_pi(sk)->ack_timer);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003105 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003106
Linus Torvalds1da177e2005-04-16 15:20:36 -07003107 l2cap_chan_del(sk, 0);
3108 bh_unlock_sock(sk);
3109
3110 l2cap_sock_kill(sk);
3111 return 0;
3112}
3113
3114static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3115{
3116 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003117 u16 type;
3118
3119 type = __le16_to_cpu(req->type);
3120
3121 BT_DBG("type 0x%4.4x", type);
3122
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003123 if (type == L2CAP_IT_FEAT_MASK) {
3124 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003125 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003126 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
3127 rsp->type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
3128 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003129 if (enable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003130 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
3131 | L2CAP_FEAT_FCS;
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03003132 put_unaligned_le32(feat_mask, rsp->data);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003133 l2cap_send_cmd(conn, cmd->ident,
3134 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003135 } else if (type == L2CAP_IT_FIXED_CHAN) {
3136 u8 buf[12];
3137 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
3138 rsp->type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3139 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
3140 memcpy(buf + 4, l2cap_fixed_chan, 8);
3141 l2cap_send_cmd(conn, cmd->ident,
3142 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003143 } else {
3144 struct l2cap_info_rsp rsp;
3145 rsp.type = cpu_to_le16(type);
3146 rsp.result = cpu_to_le16(L2CAP_IR_NOTSUPP);
3147 l2cap_send_cmd(conn, cmd->ident,
3148 L2CAP_INFO_RSP, sizeof(rsp), &rsp);
3149 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003150
3151 return 0;
3152}
3153
3154static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3155{
3156 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
3157 u16 type, result;
3158
3159 type = __le16_to_cpu(rsp->type);
3160 result = __le16_to_cpu(rsp->result);
3161
3162 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
3163
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003164 del_timer(&conn->info_timer);
3165
Marcel Holtmann984947d2009-02-06 23:35:19 +01003166 if (type == L2CAP_IT_FEAT_MASK) {
Harvey Harrison83985312008-05-02 16:25:46 -07003167 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003168
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003169 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003170 struct l2cap_info_req req;
3171 req.type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3172
3173 conn->info_ident = l2cap_get_ident(conn);
3174
3175 l2cap_send_cmd(conn, conn->info_ident,
3176 L2CAP_INFO_REQ, sizeof(req), &req);
3177 } else {
3178 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
3179 conn->info_ident = 0;
3180
3181 l2cap_conn_start(conn);
3182 }
3183 } else if (type == L2CAP_IT_FIXED_CHAN) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01003184 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003185 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003186
3187 l2cap_conn_start(conn);
3188 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003189
Linus Torvalds1da177e2005-04-16 15:20:36 -07003190 return 0;
3191}
3192
3193static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
3194{
3195 u8 *data = skb->data;
3196 int len = skb->len;
3197 struct l2cap_cmd_hdr cmd;
3198 int err = 0;
3199
3200 l2cap_raw_recv(conn, skb);
3201
3202 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07003203 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003204 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
3205 data += L2CAP_CMD_HDR_SIZE;
3206 len -= L2CAP_CMD_HDR_SIZE;
3207
Al Viro88219a02007-07-29 00:17:25 -07003208 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003209
Al Viro88219a02007-07-29 00:17:25 -07003210 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 -07003211
Al Viro88219a02007-07-29 00:17:25 -07003212 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003213 BT_DBG("corrupted command");
3214 break;
3215 }
3216
3217 switch (cmd.code) {
3218 case L2CAP_COMMAND_REJ:
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003219 l2cap_command_rej(conn, &cmd, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003220 break;
3221
3222 case L2CAP_CONN_REQ:
3223 err = l2cap_connect_req(conn, &cmd, data);
3224 break;
3225
3226 case L2CAP_CONN_RSP:
3227 err = l2cap_connect_rsp(conn, &cmd, data);
3228 break;
3229
3230 case L2CAP_CONF_REQ:
Al Viro88219a02007-07-29 00:17:25 -07003231 err = l2cap_config_req(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003232 break;
3233
3234 case L2CAP_CONF_RSP:
3235 err = l2cap_config_rsp(conn, &cmd, data);
3236 break;
3237
3238 case L2CAP_DISCONN_REQ:
3239 err = l2cap_disconnect_req(conn, &cmd, data);
3240 break;
3241
3242 case L2CAP_DISCONN_RSP:
3243 err = l2cap_disconnect_rsp(conn, &cmd, data);
3244 break;
3245
3246 case L2CAP_ECHO_REQ:
Al Viro88219a02007-07-29 00:17:25 -07003247 l2cap_send_cmd(conn, cmd.ident, L2CAP_ECHO_RSP, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003248 break;
3249
3250 case L2CAP_ECHO_RSP:
3251 break;
3252
3253 case L2CAP_INFO_REQ:
3254 err = l2cap_information_req(conn, &cmd, data);
3255 break;
3256
3257 case L2CAP_INFO_RSP:
3258 err = l2cap_information_rsp(conn, &cmd, data);
3259 break;
3260
3261 default:
3262 BT_ERR("Unknown signaling command 0x%2.2x", cmd.code);
3263 err = -EINVAL;
3264 break;
3265 }
3266
3267 if (err) {
3268 struct l2cap_cmd_rej rej;
3269 BT_DBG("error %d", err);
3270
3271 /* FIXME: Map err to a valid reason */
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003272 rej.reason = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003273 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
3274 }
3275
Al Viro88219a02007-07-29 00:17:25 -07003276 data += cmd_len;
3277 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003278 }
3279
3280 kfree_skb(skb);
3281}
3282
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003283static int l2cap_check_fcs(struct l2cap_pinfo *pi, struct sk_buff *skb)
3284{
3285 u16 our_fcs, rcv_fcs;
3286 int hdr_size = L2CAP_HDR_SIZE + 2;
3287
3288 if (pi->fcs == L2CAP_FCS_CRC16) {
3289 skb_trim(skb, skb->len - 2);
3290 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
3291 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
3292
3293 if (our_fcs != rcv_fcs)
3294 return -EINVAL;
3295 }
3296 return 0;
3297}
3298
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003299static inline void l2cap_send_i_or_rr_or_rnr(struct sock *sk)
3300{
3301 struct l2cap_pinfo *pi = l2cap_pi(sk);
3302 u16 control = 0;
3303
3304 pi->frames_sent = 0;
3305 pi->conn_state |= L2CAP_CONN_SEND_FBIT;
3306
3307 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3308
3309 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
3310 control |= L2CAP_SUPER_RCV_NOT_READY | L2CAP_CTRL_FINAL;
3311 l2cap_send_sframe(pi, control);
3312 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
3313 }
3314
3315 if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY && pi->unacked_frames > 0)
3316 __mod_retrans_timer();
3317
3318 l2cap_ertm_send(sk);
3319
3320 if (!(pi->conn_state & L2CAP_CONN_LOCAL_BUSY) &&
3321 pi->frames_sent == 0) {
3322 control |= L2CAP_SUPER_RCV_READY;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003323 l2cap_send_sframe(pi, control);
3324 }
3325}
3326
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003327static void l2cap_add_to_srej_queue(struct sock *sk, struct sk_buff *skb, u8 tx_seq, u8 sar)
3328{
3329 struct sk_buff *next_skb;
3330
3331 bt_cb(skb)->tx_seq = tx_seq;
3332 bt_cb(skb)->sar = sar;
3333
3334 next_skb = skb_peek(SREJ_QUEUE(sk));
3335 if (!next_skb) {
3336 __skb_queue_tail(SREJ_QUEUE(sk), skb);
3337 return;
3338 }
3339
3340 do {
3341 if (bt_cb(next_skb)->tx_seq > tx_seq) {
3342 __skb_queue_before(SREJ_QUEUE(sk), next_skb, skb);
3343 return;
3344 }
3345
3346 if (skb_queue_is_last(SREJ_QUEUE(sk), next_skb))
3347 break;
3348
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003349 } while ((next_skb = skb_queue_next(SREJ_QUEUE(sk), next_skb)));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003350
3351 __skb_queue_tail(SREJ_QUEUE(sk), skb);
3352}
3353
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003354static int l2cap_sar_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
3355{
3356 struct l2cap_pinfo *pi = l2cap_pi(sk);
3357 struct sk_buff *_skb;
3358 int err = -EINVAL;
3359
3360 switch (control & L2CAP_CTRL_SAR) {
3361 case L2CAP_SDU_UNSEGMENTED:
3362 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3363 kfree_skb(pi->sdu);
3364 break;
3365 }
3366
3367 err = sock_queue_rcv_skb(sk, skb);
3368 if (!err)
3369 return 0;
3370
3371 break;
3372
3373 case L2CAP_SDU_START:
3374 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3375 kfree_skb(pi->sdu);
3376 break;
3377 }
3378
3379 pi->sdu_len = get_unaligned_le16(skb->data);
3380 skb_pull(skb, 2);
3381
Gustavo F. Padovan052897c2010-05-01 16:15:40 -03003382 if (pi->sdu_len > pi->imtu) {
3383 err = -EMSGSIZE;
3384 break;
3385 }
3386
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003387 pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
3388 if (!pi->sdu) {
3389 err = -ENOMEM;
3390 break;
3391 }
3392
3393 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3394
3395 pi->conn_state |= L2CAP_CONN_SAR_SDU;
3396 pi->partial_sdu_len = skb->len;
3397 err = 0;
3398 break;
3399
3400 case L2CAP_SDU_CONTINUE:
3401 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3402 break;
3403
3404 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3405
3406 pi->partial_sdu_len += skb->len;
3407 if (pi->partial_sdu_len > pi->sdu_len)
3408 kfree_skb(pi->sdu);
3409 else
3410 err = 0;
3411
3412 break;
3413
3414 case L2CAP_SDU_END:
3415 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3416 break;
3417
3418 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3419
3420 pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
3421 pi->partial_sdu_len += skb->len;
3422
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003423 if (pi->partial_sdu_len > pi->imtu)
3424 goto drop;
3425
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003426 if (pi->partial_sdu_len == pi->sdu_len) {
3427 _skb = skb_clone(pi->sdu, GFP_ATOMIC);
3428 err = sock_queue_rcv_skb(sk, _skb);
3429 if (err < 0)
3430 kfree_skb(_skb);
3431 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003432 err = 0;
3433
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003434drop:
3435 kfree_skb(pi->sdu);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003436 break;
3437 }
3438
3439 kfree_skb(skb);
3440 return err;
3441}
3442
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003443static void l2cap_check_srej_gap(struct sock *sk, u8 tx_seq)
3444{
3445 struct sk_buff *skb;
Gustavo F. Padovanafefdbc2010-05-01 16:15:43 -03003446 u16 control;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003447
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003448 while ((skb = skb_peek(SREJ_QUEUE(sk)))) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003449 if (bt_cb(skb)->tx_seq != tx_seq)
3450 break;
3451
3452 skb = skb_dequeue(SREJ_QUEUE(sk));
Gustavo F. Padovanafefdbc2010-05-01 16:15:43 -03003453 control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003454 l2cap_sar_reassembly_sdu(sk, skb, control);
3455 l2cap_pi(sk)->buffer_seq_srej =
3456 (l2cap_pi(sk)->buffer_seq_srej + 1) % 64;
3457 tx_seq++;
3458 }
3459}
3460
3461static void l2cap_resend_srejframe(struct sock *sk, u8 tx_seq)
3462{
3463 struct l2cap_pinfo *pi = l2cap_pi(sk);
3464 struct srej_list *l, *tmp;
3465 u16 control;
3466
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003467 list_for_each_entry_safe(l, tmp, SREJ_LIST(sk), list) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003468 if (l->tx_seq == tx_seq) {
3469 list_del(&l->list);
3470 kfree(l);
3471 return;
3472 }
3473 control = L2CAP_SUPER_SELECT_REJECT;
3474 control |= l->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3475 l2cap_send_sframe(pi, control);
3476 list_del(&l->list);
3477 list_add_tail(&l->list, SREJ_LIST(sk));
3478 }
3479}
3480
3481static void l2cap_send_srejframe(struct sock *sk, u8 tx_seq)
3482{
3483 struct l2cap_pinfo *pi = l2cap_pi(sk);
3484 struct srej_list *new;
3485 u16 control;
3486
3487 while (tx_seq != pi->expected_tx_seq) {
3488 control = L2CAP_SUPER_SELECT_REJECT;
3489 control |= pi->expected_tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3490 l2cap_send_sframe(pi, control);
3491
3492 new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC);
3493 new->tx_seq = pi->expected_tx_seq++;
3494 list_add_tail(&new->list, SREJ_LIST(sk));
3495 }
3496 pi->expected_tx_seq++;
3497}
3498
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003499static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
3500{
3501 struct l2cap_pinfo *pi = l2cap_pi(sk);
3502 u8 tx_seq = __get_txseq(rx_control);
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003503 u8 req_seq = __get_reqseq(rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003504 u8 sar = rx_control >> L2CAP_CTRL_SAR_SHIFT;
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03003505 int num_to_ack = (pi->tx_win/6) + 1;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003506 int err = 0;
3507
3508 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
3509
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003510 if (L2CAP_CTRL_FINAL & rx_control) {
3511 del_timer(&pi->monitor_timer);
3512 if (pi->unacked_frames > 0)
3513 __mod_retrans_timer();
3514 pi->conn_state &= ~L2CAP_CONN_WAIT_F;
3515 }
3516
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003517 pi->expected_ack_seq = req_seq;
3518 l2cap_drop_acked_frames(sk);
3519
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003520 if (tx_seq == pi->expected_tx_seq)
3521 goto expected;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003522
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003523 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3524 struct srej_list *first;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003525
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003526 first = list_first_entry(SREJ_LIST(sk),
3527 struct srej_list, list);
3528 if (tx_seq == first->tx_seq) {
3529 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3530 l2cap_check_srej_gap(sk, tx_seq);
3531
3532 list_del(&first->list);
3533 kfree(first);
3534
3535 if (list_empty(SREJ_LIST(sk))) {
3536 pi->buffer_seq = pi->buffer_seq_srej;
3537 pi->conn_state &= ~L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan855666cc2010-05-01 16:15:40 -03003538 l2cap_send_ack(pi);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003539 }
3540 } else {
3541 struct srej_list *l;
3542 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3543
3544 list_for_each_entry(l, SREJ_LIST(sk), list) {
3545 if (l->tx_seq == tx_seq) {
3546 l2cap_resend_srejframe(sk, tx_seq);
3547 return 0;
3548 }
3549 }
3550 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003551 }
3552 } else {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003553 pi->conn_state |= L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003554
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003555 INIT_LIST_HEAD(SREJ_LIST(sk));
3556 pi->buffer_seq_srej = pi->buffer_seq;
3557
3558 __skb_queue_head_init(SREJ_QUEUE(sk));
3559 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3560
Gustavo F. Padovanef54fd92009-08-20 22:26:04 -03003561 pi->conn_state |= L2CAP_CONN_SEND_PBIT;
3562
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003563 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003564 }
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003565 return 0;
3566
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003567expected:
3568 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
3569
3570 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
Gustavo F. Padovan3b1a9f32010-05-01 16:15:42 -03003571 bt_cb(skb)->tx_seq = tx_seq;
3572 bt_cb(skb)->sar = sar;
3573 __skb_queue_tail(SREJ_QUEUE(sk), skb);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003574 return 0;
3575 }
3576
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03003577 if (rx_control & L2CAP_CTRL_FINAL) {
3578 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3579 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
3580 else {
Gustavo F. Padovanf6e6b162010-05-01 16:15:41 -03003581 if (!skb_queue_empty(TX_QUEUE(sk)))
3582 sk->sk_send_head = TX_QUEUE(sk)->next;
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03003583 pi->next_tx_seq = pi->expected_ack_seq;
3584 l2cap_ertm_send(sk);
3585 }
3586 }
3587
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003588 pi->buffer_seq = (pi->buffer_seq + 1) % 64;
3589
3590 err = l2cap_sar_reassembly_sdu(sk, skb, rx_control);
3591 if (err < 0)
3592 return err;
3593
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003594 __mod_ack_timer();
3595
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03003596 pi->num_acked = (pi->num_acked + 1) % num_to_ack;
3597 if (pi->num_acked == num_to_ack - 1)
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03003598 l2cap_send_ack(pi);
3599
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003600 return 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003601}
3602
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003603static inline void l2cap_data_channel_rrframe(struct sock *sk, u16 rx_control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003604{
3605 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan6e3a5982010-05-01 16:15:38 -03003606
3607 pi->expected_ack_seq = __get_reqseq(rx_control);
3608 l2cap_drop_acked_frames(sk);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003609
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003610 if (rx_control & L2CAP_CTRL_POLL) {
Gustavo F. Padovan05fbd892010-05-01 16:15:39 -03003611 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3612 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
3613 (pi->unacked_frames > 0))
3614 __mod_retrans_timer();
3615
3616 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3617 l2cap_send_srejtail(sk);
3618 } else {
3619 l2cap_send_i_or_rr_or_rnr(sk);
3620 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3621 }
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003622
3623 } else if (rx_control & L2CAP_CTRL_FINAL) {
3624 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003625
3626 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3627 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
3628 else {
Gustavo F. Padovanf6e6b162010-05-01 16:15:41 -03003629 if (!skb_queue_empty(TX_QUEUE(sk)))
3630 sk->sk_send_head = TX_QUEUE(sk)->next;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003631 pi->next_tx_seq = pi->expected_ack_seq;
3632 l2cap_ertm_send(sk);
3633 }
3634
3635 } else {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003636 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
3637 (pi->unacked_frames > 0))
3638 __mod_retrans_timer();
3639
3640 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3641 if (pi->conn_state & L2CAP_CONN_SREJ_SENT)
3642 l2cap_send_ack(pi);
3643 else
3644 l2cap_ertm_send(sk);
3645 }
3646}
3647
3648static inline void l2cap_data_channel_rejframe(struct sock *sk, u16 rx_control)
3649{
3650 struct l2cap_pinfo *pi = l2cap_pi(sk);
3651 u8 tx_seq = __get_reqseq(rx_control);
3652
3653 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3654
Gustavo F. Padovan8abb52e2010-05-01 16:15:38 -03003655 pi->expected_ack_seq = tx_seq;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003656 l2cap_drop_acked_frames(sk);
3657
3658 if (rx_control & L2CAP_CTRL_FINAL) {
3659 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3660 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
3661 else {
Gustavo F. Padovanf6e6b162010-05-01 16:15:41 -03003662 if (!skb_queue_empty(TX_QUEUE(sk)))
3663 sk->sk_send_head = TX_QUEUE(sk)->next;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003664 pi->next_tx_seq = pi->expected_ack_seq;
3665 l2cap_ertm_send(sk);
3666 }
3667 } else {
Gustavo F. Padovanf6e6b162010-05-01 16:15:41 -03003668 if (!skb_queue_empty(TX_QUEUE(sk)))
3669 sk->sk_send_head = TX_QUEUE(sk)->next;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003670 pi->next_tx_seq = pi->expected_ack_seq;
3671 l2cap_ertm_send(sk);
3672
3673 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
3674 pi->srej_save_reqseq = tx_seq;
3675 pi->conn_state |= L2CAP_CONN_REJ_ACT;
3676 }
3677 }
3678}
3679static inline void l2cap_data_channel_srejframe(struct sock *sk, u16 rx_control)
3680{
3681 struct l2cap_pinfo *pi = l2cap_pi(sk);
3682 u8 tx_seq = __get_reqseq(rx_control);
3683
3684 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3685
3686 if (rx_control & L2CAP_CTRL_POLL) {
3687 pi->expected_ack_seq = tx_seq;
3688 l2cap_drop_acked_frames(sk);
3689 l2cap_retransmit_frame(sk, tx_seq);
3690 l2cap_ertm_send(sk);
3691 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
3692 pi->srej_save_reqseq = tx_seq;
3693 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
3694 }
3695 } else if (rx_control & L2CAP_CTRL_FINAL) {
3696 if ((pi->conn_state & L2CAP_CONN_SREJ_ACT) &&
3697 pi->srej_save_reqseq == tx_seq)
3698 pi->conn_state &= ~L2CAP_CONN_SREJ_ACT;
3699 else
3700 l2cap_retransmit_frame(sk, tx_seq);
3701 } else {
3702 l2cap_retransmit_frame(sk, tx_seq);
3703 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
3704 pi->srej_save_reqseq = tx_seq;
3705 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
3706 }
3707 }
3708}
3709
3710static inline void l2cap_data_channel_rnrframe(struct sock *sk, u16 rx_control)
3711{
3712 struct l2cap_pinfo *pi = l2cap_pi(sk);
3713 u8 tx_seq = __get_reqseq(rx_control);
3714
3715 pi->conn_state |= L2CAP_CONN_REMOTE_BUSY;
3716 pi->expected_ack_seq = tx_seq;
3717 l2cap_drop_acked_frames(sk);
3718
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03003719 if (!(pi->conn_state & L2CAP_CONN_SREJ_SENT)) {
3720 del_timer(&pi->retrans_timer);
3721 if (rx_control & L2CAP_CTRL_POLL) {
3722 u16 control = L2CAP_CTRL_FINAL;
3723 l2cap_send_rr_or_rnr(pi, control);
3724 }
3725 return;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003726 }
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03003727
3728 if (rx_control & L2CAP_CTRL_POLL)
3729 l2cap_send_srejtail(sk);
3730 else
3731 l2cap_send_sframe(pi, L2CAP_SUPER_RCV_READY);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003732}
3733
3734static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
3735{
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003736 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
3737
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003738 if (L2CAP_CTRL_FINAL & rx_control) {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003739 del_timer(&l2cap_pi(sk)->monitor_timer);
3740 if (l2cap_pi(sk)->unacked_frames > 0)
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003741 __mod_retrans_timer();
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003742 l2cap_pi(sk)->conn_state &= ~L2CAP_CONN_WAIT_F;
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003743 }
3744
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003745 switch (rx_control & L2CAP_CTRL_SUPERVISE) {
3746 case L2CAP_SUPER_RCV_READY:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003747 l2cap_data_channel_rrframe(sk, rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003748 break;
3749
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003750 case L2CAP_SUPER_REJECT:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003751 l2cap_data_channel_rejframe(sk, rx_control);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003752 break;
3753
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003754 case L2CAP_SUPER_SELECT_REJECT:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003755 l2cap_data_channel_srejframe(sk, rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003756 break;
3757
3758 case L2CAP_SUPER_RCV_NOT_READY:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003759 l2cap_data_channel_rnrframe(sk, rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003760 break;
3761 }
3762
Gustavo F. Padovanfaaebd12010-05-01 16:15:35 -03003763 kfree_skb(skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003764 return 0;
3765}
3766
Linus Torvalds1da177e2005-04-16 15:20:36 -07003767static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk_buff *skb)
3768{
3769 struct sock *sk;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003770 struct l2cap_pinfo *pi;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003771 u16 control, len;
João Paulo Rechi Vita01760bd2010-05-01 16:15:43 -03003772 u8 tx_seq, req_seq, next_tx_seq_offset, req_seq_offset;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003773
3774 sk = l2cap_get_chan_by_scid(&conn->chan_list, cid);
3775 if (!sk) {
3776 BT_DBG("unknown cid 0x%4.4x", cid);
3777 goto drop;
3778 }
3779
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003780 pi = l2cap_pi(sk);
3781
Linus Torvalds1da177e2005-04-16 15:20:36 -07003782 BT_DBG("sk %p, len %d", sk, skb->len);
3783
3784 if (sk->sk_state != BT_CONNECTED)
3785 goto drop;
3786
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003787 switch (pi->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003788 case L2CAP_MODE_BASIC:
3789 /* If socket recv buffers overflows we drop data here
3790 * which is *bad* because L2CAP has to be reliable.
3791 * But we don't have any other choice. L2CAP doesn't
3792 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003793
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003794 if (pi->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003795 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003796
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003797 if (!sock_queue_rcv_skb(sk, skb))
3798 goto done;
3799 break;
3800
3801 case L2CAP_MODE_ERTM:
3802 control = get_unaligned_le16(skb->data);
3803 skb_pull(skb, 2);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003804 len = skb->len;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003805
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003806 if (__is_sar_start(control))
3807 len -= 2;
3808
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003809 if (pi->fcs == L2CAP_FCS_CRC16)
3810 len -= 2;
3811
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003812 /*
3813 * We can just drop the corrupted I-frame here.
3814 * Receiver will miss it and start proper recovery
3815 * procedures and ask retransmission.
3816 */
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03003817 if (len > pi->mps)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003818 goto drop;
3819
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003820 if (l2cap_check_fcs(pi, skb))
3821 goto drop;
3822
João Paulo Rechi Vita01760bd2010-05-01 16:15:43 -03003823 req_seq = __get_reqseq(control);
3824 req_seq_offset = (req_seq - pi->expected_ack_seq) % 64;
3825 if (req_seq_offset < 0)
3826 req_seq_offset += 64;
3827
3828 next_tx_seq_offset =
3829 (pi->next_tx_seq - pi->expected_ack_seq) % 64;
3830 if (next_tx_seq_offset < 0)
3831 next_tx_seq_offset += 64;
3832
3833 /* check for invalid req-seq */
3834 if (req_seq_offset > next_tx_seq_offset) {
3835 l2cap_send_disconn_req(pi->conn, sk);
3836 goto drop;
3837 }
3838
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03003839 if (__is_iframe(control)) {
3840 if (len < 4)
3841 goto drop;
3842
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02003843 l2cap_data_channel_iframe(sk, control, skb);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03003844 } else {
3845 if (len != 0)
3846 goto drop;
3847
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02003848 l2cap_data_channel_sframe(sk, control, skb);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03003849 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003850
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02003851 goto done;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003852
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003853 case L2CAP_MODE_STREAMING:
3854 control = get_unaligned_le16(skb->data);
3855 skb_pull(skb, 2);
3856 len = skb->len;
3857
3858 if (__is_sar_start(control))
3859 len -= 2;
3860
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003861 if (pi->fcs == L2CAP_FCS_CRC16)
3862 len -= 2;
3863
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03003864 if (len > pi->mps || len < 4 || __is_sframe(control))
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003865 goto drop;
3866
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003867 if (l2cap_check_fcs(pi, skb))
3868 goto drop;
3869
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003870 tx_seq = __get_txseq(control);
3871
3872 if (pi->expected_tx_seq == tx_seq)
3873 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
3874 else
Gustavo F. Padovan7dffe422010-05-01 16:15:36 -03003875 pi->expected_tx_seq = (tx_seq + 1) % 64;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003876
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02003877 l2cap_sar_reassembly_sdu(sk, skb, control);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003878
3879 goto done;
3880
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003881 default:
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03003882 BT_DBG("sk %p: bad mode 0x%2.2x", sk, pi->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003883 break;
3884 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003885
3886drop:
3887 kfree_skb(skb);
3888
3889done:
Marcel Holtmann01394182006-07-03 10:02:46 +02003890 if (sk)
3891 bh_unlock_sock(sk);
3892
Linus Torvalds1da177e2005-04-16 15:20:36 -07003893 return 0;
3894}
3895
Al Viro8e036fc2007-07-29 00:16:36 -07003896static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003897{
3898 struct sock *sk;
3899
3900 sk = l2cap_get_sock_by_psm(0, psm, conn->src);
3901 if (!sk)
3902 goto drop;
3903
3904 BT_DBG("sk %p, len %d", sk, skb->len);
3905
3906 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_CONNECTED)
3907 goto drop;
3908
3909 if (l2cap_pi(sk)->imtu < skb->len)
3910 goto drop;
3911
3912 if (!sock_queue_rcv_skb(sk, skb))
3913 goto done;
3914
3915drop:
3916 kfree_skb(skb);
3917
3918done:
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003919 if (sk)
3920 bh_unlock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003921 return 0;
3922}
3923
3924static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
3925{
3926 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07003927 u16 cid, len;
3928 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003929
3930 skb_pull(skb, L2CAP_HDR_SIZE);
3931 cid = __le16_to_cpu(lh->cid);
3932 len = __le16_to_cpu(lh->len);
3933
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003934 if (len != skb->len) {
3935 kfree_skb(skb);
3936 return;
3937 }
3938
Linus Torvalds1da177e2005-04-16 15:20:36 -07003939 BT_DBG("len %d, cid 0x%4.4x", len, cid);
3940
3941 switch (cid) {
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03003942 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07003943 l2cap_sig_channel(conn, skb);
3944 break;
3945
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03003946 case L2CAP_CID_CONN_LESS:
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03003947 psm = get_unaligned_le16(skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003948 skb_pull(skb, 2);
3949 l2cap_conless_channel(conn, psm, skb);
3950 break;
3951
3952 default:
3953 l2cap_data_channel(conn, cid, skb);
3954 break;
3955 }
3956}
3957
3958/* ---- L2CAP interface with lower layer (HCI) ---- */
3959
3960static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
3961{
3962 int exact = 0, lm1 = 0, lm2 = 0;
3963 register struct sock *sk;
3964 struct hlist_node *node;
3965
3966 if (type != ACL_LINK)
3967 return 0;
3968
3969 BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
3970
3971 /* Find listening sockets and check their link_mode */
3972 read_lock(&l2cap_sk_list.lock);
3973 sk_for_each(sk, node, &l2cap_sk_list.head) {
3974 if (sk->sk_state != BT_LISTEN)
3975 continue;
3976
3977 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01003978 lm1 |= HCI_LM_ACCEPT;
3979 if (l2cap_pi(sk)->role_switch)
3980 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003981 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01003982 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
3983 lm2 |= HCI_LM_ACCEPT;
3984 if (l2cap_pi(sk)->role_switch)
3985 lm2 |= HCI_LM_MASTER;
3986 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003987 }
3988 read_unlock(&l2cap_sk_list.lock);
3989
3990 return exact ? lm1 : lm2;
3991}
3992
3993static int l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
3994{
Marcel Holtmann01394182006-07-03 10:02:46 +02003995 struct l2cap_conn *conn;
3996
Linus Torvalds1da177e2005-04-16 15:20:36 -07003997 BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
3998
3999 if (hcon->type != ACL_LINK)
4000 return 0;
4001
4002 if (!status) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004003 conn = l2cap_conn_add(hcon, status);
4004 if (conn)
4005 l2cap_conn_ready(conn);
Marcel Holtmann01394182006-07-03 10:02:46 +02004006 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -07004007 l2cap_conn_del(hcon, bt_err(status));
4008
4009 return 0;
4010}
4011
Marcel Holtmann2950f212009-02-12 14:02:50 +01004012static int l2cap_disconn_ind(struct hci_conn *hcon)
4013{
4014 struct l2cap_conn *conn = hcon->l2cap_data;
4015
4016 BT_DBG("hcon %p", hcon);
4017
4018 if (hcon->type != ACL_LINK || !conn)
4019 return 0x13;
4020
4021 return conn->disc_reason;
4022}
4023
4024static int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004025{
4026 BT_DBG("hcon %p reason %d", hcon, reason);
4027
4028 if (hcon->type != ACL_LINK)
4029 return 0;
4030
4031 l2cap_conn_del(hcon, bt_err(reason));
Marcel Holtmann01394182006-07-03 10:02:46 +02004032
Linus Torvalds1da177e2005-04-16 15:20:36 -07004033 return 0;
4034}
4035
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004036static inline void l2cap_check_encryption(struct sock *sk, u8 encrypt)
4037{
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03004038 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM)
Marcel Holtmann255c7602009-02-04 21:07:19 +01004039 return;
4040
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004041 if (encrypt == 0x00) {
4042 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM) {
4043 l2cap_sock_clear_timer(sk);
4044 l2cap_sock_set_timer(sk, HZ * 5);
4045 } else if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
4046 __l2cap_sock_close(sk, ECONNREFUSED);
4047 } else {
4048 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM)
4049 l2cap_sock_clear_timer(sk);
4050 }
4051}
4052
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004053static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004054{
4055 struct l2cap_chan_list *l;
Marcel Holtmann40be4922008-07-14 20:13:50 +02004056 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004057 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004058
Marcel Holtmann01394182006-07-03 10:02:46 +02004059 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004060 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02004061
Linus Torvalds1da177e2005-04-16 15:20:36 -07004062 l = &conn->chan_list;
4063
4064 BT_DBG("conn %p", conn);
4065
4066 read_lock(&l->lock);
4067
4068 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
4069 bh_lock_sock(sk);
4070
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01004071 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND) {
4072 bh_unlock_sock(sk);
4073 continue;
4074 }
4075
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004076 if (!status && (sk->sk_state == BT_CONNECTED ||
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004077 sk->sk_state == BT_CONFIG)) {
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004078 l2cap_check_encryption(sk, encrypt);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02004079 bh_unlock_sock(sk);
4080 continue;
4081 }
4082
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004083 if (sk->sk_state == BT_CONNECT) {
4084 if (!status) {
4085 struct l2cap_conn_req req;
4086 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
4087 req.psm = l2cap_pi(sk)->psm;
4088
4089 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
4090
4091 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
4092 L2CAP_CONN_REQ, sizeof(req), &req);
4093 } else {
4094 l2cap_sock_clear_timer(sk);
4095 l2cap_sock_set_timer(sk, HZ / 10);
4096 }
4097 } else if (sk->sk_state == BT_CONNECT2) {
4098 struct l2cap_conn_rsp rsp;
4099 __u16 result;
4100
4101 if (!status) {
4102 sk->sk_state = BT_CONFIG;
4103 result = L2CAP_CR_SUCCESS;
4104 } else {
4105 sk->sk_state = BT_DISCONN;
4106 l2cap_sock_set_timer(sk, HZ / 10);
4107 result = L2CAP_CR_SEC_BLOCK;
4108 }
4109
4110 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
4111 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
4112 rsp.result = cpu_to_le16(result);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02004113 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004114 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
4115 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004116 }
4117
Linus Torvalds1da177e2005-04-16 15:20:36 -07004118 bh_unlock_sock(sk);
4119 }
4120
4121 read_unlock(&l->lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004122
Linus Torvalds1da177e2005-04-16 15:20:36 -07004123 return 0;
4124}
4125
4126static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
4127{
4128 struct l2cap_conn *conn = hcon->l2cap_data;
4129
4130 if (!conn && !(conn = l2cap_conn_add(hcon, 0)))
4131 goto drop;
4132
4133 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
4134
4135 if (flags & ACL_START) {
4136 struct l2cap_hdr *hdr;
4137 int len;
4138
4139 if (conn->rx_len) {
4140 BT_ERR("Unexpected start frame (len %d)", skb->len);
4141 kfree_skb(conn->rx_skb);
4142 conn->rx_skb = NULL;
4143 conn->rx_len = 0;
4144 l2cap_conn_unreliable(conn, ECOMM);
4145 }
4146
4147 if (skb->len < 2) {
4148 BT_ERR("Frame is too short (len %d)", skb->len);
4149 l2cap_conn_unreliable(conn, ECOMM);
4150 goto drop;
4151 }
4152
4153 hdr = (struct l2cap_hdr *) skb->data;
4154 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
4155
4156 if (len == skb->len) {
4157 /* Complete frame received */
4158 l2cap_recv_frame(conn, skb);
4159 return 0;
4160 }
4161
4162 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
4163
4164 if (skb->len > len) {
4165 BT_ERR("Frame is too long (len %d, expected len %d)",
4166 skb->len, len);
4167 l2cap_conn_unreliable(conn, ECOMM);
4168 goto drop;
4169 }
4170
4171 /* Allocate skb for the complete frame (with header) */
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03004172 conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC);
4173 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004174 goto drop;
4175
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03004176 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004177 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004178 conn->rx_len = len - skb->len;
4179 } else {
4180 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
4181
4182 if (!conn->rx_len) {
4183 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
4184 l2cap_conn_unreliable(conn, ECOMM);
4185 goto drop;
4186 }
4187
4188 if (skb->len > conn->rx_len) {
4189 BT_ERR("Fragment is too long (len %d, expected %d)",
4190 skb->len, conn->rx_len);
4191 kfree_skb(conn->rx_skb);
4192 conn->rx_skb = NULL;
4193 conn->rx_len = 0;
4194 l2cap_conn_unreliable(conn, ECOMM);
4195 goto drop;
4196 }
4197
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03004198 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004199 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004200 conn->rx_len -= skb->len;
4201
4202 if (!conn->rx_len) {
4203 /* Complete frame received */
4204 l2cap_recv_frame(conn, conn->rx_skb);
4205 conn->rx_skb = NULL;
4206 }
4207 }
4208
4209drop:
4210 kfree_skb(skb);
4211 return 0;
4212}
4213
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004214static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004215{
4216 struct sock *sk;
4217 struct hlist_node *node;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004218
4219 read_lock_bh(&l2cap_sk_list.lock);
4220
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004221 sk_for_each(sk, node, &l2cap_sk_list.head) {
4222 struct l2cap_pinfo *pi = l2cap_pi(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004223
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004224 seq_printf(f, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d\n",
4225 batostr(&bt_sk(sk)->src),
4226 batostr(&bt_sk(sk)->dst),
4227 sk->sk_state, __le16_to_cpu(pi->psm),
4228 pi->scid, pi->dcid,
4229 pi->imtu, pi->omtu, pi->sec_level);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004230 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004231
Linus Torvalds1da177e2005-04-16 15:20:36 -07004232 read_unlock_bh(&l2cap_sk_list.lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004233
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004234 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004235}
4236
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004237static int l2cap_debugfs_open(struct inode *inode, struct file *file)
4238{
4239 return single_open(file, l2cap_debugfs_show, inode->i_private);
4240}
4241
4242static const struct file_operations l2cap_debugfs_fops = {
4243 .open = l2cap_debugfs_open,
4244 .read = seq_read,
4245 .llseek = seq_lseek,
4246 .release = single_release,
4247};
4248
4249static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004250
Eric Dumazet90ddc4f2005-12-22 12:49:22 -08004251static const struct proto_ops l2cap_sock_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004252 .family = PF_BLUETOOTH,
4253 .owner = THIS_MODULE,
4254 .release = l2cap_sock_release,
4255 .bind = l2cap_sock_bind,
4256 .connect = l2cap_sock_connect,
4257 .listen = l2cap_sock_listen,
4258 .accept = l2cap_sock_accept,
4259 .getname = l2cap_sock_getname,
4260 .sendmsg = l2cap_sock_sendmsg,
Marcel Holtmannf66dc812009-01-15 21:57:00 +01004261 .recvmsg = l2cap_sock_recvmsg,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004262 .poll = bt_sock_poll,
Marcel Holtmann3241ad82008-07-14 20:13:50 +02004263 .ioctl = bt_sock_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004264 .mmap = sock_no_mmap,
4265 .socketpair = sock_no_socketpair,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004266 .shutdown = l2cap_sock_shutdown,
4267 .setsockopt = l2cap_sock_setsockopt,
4268 .getsockopt = l2cap_sock_getsockopt
4269};
4270
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +00004271static const struct net_proto_family l2cap_sock_family_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004272 .family = PF_BLUETOOTH,
4273 .owner = THIS_MODULE,
4274 .create = l2cap_sock_create,
4275};
4276
4277static struct hci_proto l2cap_hci_proto = {
4278 .name = "L2CAP",
4279 .id = HCI_PROTO_L2CAP,
4280 .connect_ind = l2cap_connect_ind,
4281 .connect_cfm = l2cap_connect_cfm,
4282 .disconn_ind = l2cap_disconn_ind,
Marcel Holtmann2950f212009-02-12 14:02:50 +01004283 .disconn_cfm = l2cap_disconn_cfm,
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004284 .security_cfm = l2cap_security_cfm,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004285 .recv_acldata = l2cap_recv_acldata
4286};
4287
4288static int __init l2cap_init(void)
4289{
4290 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004291
Linus Torvalds1da177e2005-04-16 15:20:36 -07004292 err = proto_register(&l2cap_proto, 0);
4293 if (err < 0)
4294 return err;
4295
4296 err = bt_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops);
4297 if (err < 0) {
4298 BT_ERR("L2CAP socket registration failed");
4299 goto error;
4300 }
4301
4302 err = hci_register_proto(&l2cap_hci_proto);
4303 if (err < 0) {
4304 BT_ERR("L2CAP protocol registration failed");
4305 bt_sock_unregister(BTPROTO_L2CAP);
4306 goto error;
4307 }
4308
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004309 if (bt_debugfs) {
4310 l2cap_debugfs = debugfs_create_file("l2cap", 0444,
4311 bt_debugfs, NULL, &l2cap_debugfs_fops);
4312 if (!l2cap_debugfs)
4313 BT_ERR("Failed to create L2CAP debug file");
4314 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004315
4316 BT_INFO("L2CAP ver %s", VERSION);
4317 BT_INFO("L2CAP socket layer initialized");
4318
4319 return 0;
4320
4321error:
4322 proto_unregister(&l2cap_proto);
4323 return err;
4324}
4325
4326static void __exit l2cap_exit(void)
4327{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004328 debugfs_remove(l2cap_debugfs);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004329
4330 if (bt_sock_unregister(BTPROTO_L2CAP) < 0)
4331 BT_ERR("L2CAP socket unregistration failed");
4332
4333 if (hci_unregister_proto(&l2cap_hci_proto) < 0)
4334 BT_ERR("L2CAP protocol unregistration failed");
4335
4336 proto_unregister(&l2cap_proto);
4337}
4338
4339void l2cap_load(void)
4340{
4341 /* Dummy function to trigger automatic L2CAP module loading by
4342 * other modules that use L2CAP sockets but don't use any other
4343 * symbols from it. */
4344 return;
4345}
4346EXPORT_SYMBOL(l2cap_load);
4347
4348module_init(l2cap_init);
4349module_exit(l2cap_exit);
4350
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07004351module_param(enable_ertm, bool, 0644);
4352MODULE_PARM_DESC(enable_ertm, "Enable enhanced retransmission mode");
4353
Marcel Holtmann5fbcd3d2009-10-05 11:35:43 +02004354module_param(max_transmit, uint, 0644);
4355MODULE_PARM_DESC(max_transmit, "Max transmit value (default = 3)");
4356
Gustavo F. Padovan369ba302010-05-01 16:15:41 -03004357module_param(tx_window, uint, 0644);
4358MODULE_PARM_DESC(tx_window, "Transmission window size value (default = 63)");
4359
Marcel Holtmann63fbd242008-08-18 13:23:53 +02004360MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004361MODULE_DESCRIPTION("Bluetooth L2CAP ver " VERSION);
4362MODULE_VERSION(VERSION);
4363MODULE_LICENSE("GPL");
4364MODULE_ALIAS("bt-proto-0");