blob: eb5cb29115a7e27e03e3a6842e53469d3e2308de [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;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001242
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001243 bh_lock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001244 if (l2cap_pi(sk)->retry_count >= l2cap_pi(sk)->remote_max_tx) {
1245 l2cap_send_disconn_req(l2cap_pi(sk)->conn, sk);
Andrei Emeltchenkob13f5862009-12-15 11:38:04 +02001246 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001247 return;
1248 }
1249
1250 l2cap_pi(sk)->retry_count++;
1251 __mod_monitor_timer();
1252
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -03001253 l2cap_send_rr_or_rnr(l2cap_pi(sk), L2CAP_CTRL_POLL);
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001254 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001255}
1256
1257static void l2cap_retrans_timeout(unsigned long arg)
1258{
1259 struct sock *sk = (void *) arg;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001260
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001261 bh_lock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001262 l2cap_pi(sk)->retry_count = 1;
1263 __mod_monitor_timer();
1264
1265 l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
1266
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -03001267 l2cap_send_rr_or_rnr(l2cap_pi(sk), L2CAP_CTRL_POLL);
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001268 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001269}
1270
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001271static void l2cap_drop_acked_frames(struct sock *sk)
1272{
1273 struct sk_buff *skb;
1274
Gustavo F. Padovan812e7372010-05-01 16:15:42 -03001275 while ((skb = skb_peek(TX_QUEUE(sk))) &&
1276 l2cap_pi(sk)->unacked_frames) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001277 if (bt_cb(skb)->tx_seq == l2cap_pi(sk)->expected_ack_seq)
1278 break;
1279
1280 skb = skb_dequeue(TX_QUEUE(sk));
1281 kfree_skb(skb);
1282
1283 l2cap_pi(sk)->unacked_frames--;
1284 }
1285
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001286 if (!l2cap_pi(sk)->unacked_frames)
1287 del_timer(&l2cap_pi(sk)->retrans_timer);
1288
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001289 return;
1290}
1291
1292static inline int l2cap_do_send(struct sock *sk, struct sk_buff *skb)
1293{
1294 struct l2cap_pinfo *pi = l2cap_pi(sk);
1295 int err;
1296
1297 BT_DBG("sk %p, skb %p len %d", sk, skb, skb->len);
1298
1299 err = hci_send_acl(pi->conn->hcon, skb, 0);
1300 if (err < 0)
1301 kfree_skb(skb);
1302
1303 return err;
1304}
1305
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001306static int l2cap_streaming_send(struct sock *sk)
1307{
1308 struct sk_buff *skb, *tx_skb;
1309 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001310 u16 control, fcs;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001311 int err;
1312
1313 while ((skb = sk->sk_send_head)) {
1314 tx_skb = skb_clone(skb, GFP_ATOMIC);
1315
1316 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
1317 control |= pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT;
1318 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1319
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001320 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001321 fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
1322 put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
1323 }
1324
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001325 err = l2cap_do_send(sk, tx_skb);
1326 if (err < 0) {
1327 l2cap_send_disconn_req(pi->conn, sk);
1328 return err;
1329 }
1330
1331 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
1332
1333 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1334 sk->sk_send_head = NULL;
1335 else
1336 sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
1337
1338 skb = skb_dequeue(TX_QUEUE(sk));
1339 kfree_skb(skb);
1340 }
1341 return 0;
1342}
1343
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001344static int l2cap_retransmit_frame(struct sock *sk, u8 tx_seq)
1345{
1346 struct l2cap_pinfo *pi = l2cap_pi(sk);
1347 struct sk_buff *skb, *tx_skb;
1348 u16 control, fcs;
1349 int err;
1350
1351 skb = skb_peek(TX_QUEUE(sk));
1352 do {
1353 if (bt_cb(skb)->tx_seq != tx_seq) {
1354 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1355 break;
1356 skb = skb_queue_next(TX_QUEUE(sk), skb);
1357 continue;
1358 }
1359
1360 if (pi->remote_max_tx &&
1361 bt_cb(skb)->retries == pi->remote_max_tx) {
1362 l2cap_send_disconn_req(pi->conn, sk);
1363 break;
1364 }
1365
1366 tx_skb = skb_clone(skb, GFP_ATOMIC);
1367 bt_cb(skb)->retries++;
1368 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03001369 control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001370 | (tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
1371 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1372
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001373 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001374 fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
1375 put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
1376 }
1377
1378 err = l2cap_do_send(sk, tx_skb);
1379 if (err < 0) {
1380 l2cap_send_disconn_req(pi->conn, sk);
1381 return err;
1382 }
1383 break;
1384 } while(1);
1385 return 0;
1386}
1387
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001388static int l2cap_ertm_send(struct sock *sk)
1389{
1390 struct sk_buff *skb, *tx_skb;
1391 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001392 u16 control, fcs;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001393 int err, nsent = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001394
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001395 if (pi->conn_state & L2CAP_CONN_WAIT_F)
1396 return 0;
1397
Joe Perchesf64f9e72009-11-29 16:55:45 -08001398 while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(sk)) &&
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03001399 !(pi->conn_state & L2CAP_CONN_REMOTE_BUSY)) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001400
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001401 if (pi->remote_max_tx &&
1402 bt_cb(skb)->retries == pi->remote_max_tx) {
1403 l2cap_send_disconn_req(pi->conn, sk);
1404 break;
1405 }
1406
Andrei Emeltchenkoe420aba2009-12-23 13:07:14 +02001407 tx_skb = skb_clone(skb, GFP_ATOMIC);
1408
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001409 bt_cb(skb)->retries++;
1410
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001411 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001412 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
1413 control |= L2CAP_CTRL_FINAL;
1414 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
1415 }
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03001416 control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001417 | (pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
1418 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1419
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001420
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001421 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001422 fcs = crc16(0, (u8 *)skb->data, tx_skb->len - 2);
1423 put_unaligned_le16(fcs, skb->data + tx_skb->len - 2);
1424 }
1425
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001426 err = l2cap_do_send(sk, tx_skb);
1427 if (err < 0) {
1428 l2cap_send_disconn_req(pi->conn, sk);
1429 return err;
1430 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001431 __mod_retrans_timer();
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001432
1433 bt_cb(skb)->tx_seq = pi->next_tx_seq;
1434 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
1435
1436 pi->unacked_frames++;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001437 pi->frames_sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001438
1439 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1440 sk->sk_send_head = NULL;
1441 else
1442 sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001443
1444 nsent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001445 }
1446
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001447 return nsent;
1448}
1449
1450static int l2cap_send_ack(struct l2cap_pinfo *pi)
1451{
1452 struct sock *sk = (struct sock *)pi;
1453 u16 control = 0;
1454
1455 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1456
1457 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
1458 control |= L2CAP_SUPER_RCV_NOT_READY;
1459 return l2cap_send_sframe(pi, control);
1460 } else if (l2cap_ertm_send(sk) == 0) {
1461 control |= L2CAP_SUPER_RCV_READY;
1462 return l2cap_send_sframe(pi, control);
1463 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001464 return 0;
1465}
1466
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03001467static int l2cap_send_srejtail(struct sock *sk)
1468{
1469 struct srej_list *tail;
1470 u16 control;
1471
1472 control = L2CAP_SUPER_SELECT_REJECT;
1473 control |= L2CAP_CTRL_FINAL;
1474
1475 tail = list_entry(SREJ_LIST(sk)->prev, struct srej_list, list);
1476 control |= tail->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1477
1478 l2cap_send_sframe(l2cap_pi(sk), control);
1479
1480 return 0;
1481}
1482
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001483static 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 -07001484{
1485 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001486 struct sk_buff **frag;
1487 int err, sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001488
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03001489 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001490 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001491
1492 sent += count;
1493 len -= count;
1494
1495 /* Continuation fragments (no L2CAP header) */
1496 frag = &skb_shinfo(skb)->frag_list;
1497 while (len) {
1498 count = min_t(unsigned int, conn->mtu, len);
1499
1500 *frag = bt_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err);
1501 if (!*frag)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001502 return -EFAULT;
1503 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
1504 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001505
1506 sent += count;
1507 len -= count;
1508
1509 frag = &(*frag)->next;
1510 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001511
1512 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001513}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001514
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001515static struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, size_t len)
1516{
1517 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1518 struct sk_buff *skb;
1519 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1520 struct l2cap_hdr *lh;
1521
1522 BT_DBG("sk %p len %d", sk, (int)len);
1523
1524 count = min_t(unsigned int, (conn->mtu - hlen), len);
1525 skb = bt_skb_send_alloc(sk, count + hlen,
1526 msg->msg_flags & MSG_DONTWAIT, &err);
1527 if (!skb)
1528 return ERR_PTR(-ENOMEM);
1529
1530 /* Create L2CAP header */
1531 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1532 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1533 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1534 put_unaligned_le16(l2cap_pi(sk)->psm, skb_put(skb, 2));
1535
1536 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1537 if (unlikely(err < 0)) {
1538 kfree_skb(skb);
1539 return ERR_PTR(err);
1540 }
1541 return skb;
1542}
1543
1544static struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *msg, size_t len)
1545{
1546 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1547 struct sk_buff *skb;
1548 int err, count, hlen = L2CAP_HDR_SIZE;
1549 struct l2cap_hdr *lh;
1550
1551 BT_DBG("sk %p len %d", sk, (int)len);
1552
1553 count = min_t(unsigned int, (conn->mtu - hlen), len);
1554 skb = bt_skb_send_alloc(sk, count + hlen,
1555 msg->msg_flags & MSG_DONTWAIT, &err);
1556 if (!skb)
1557 return ERR_PTR(-ENOMEM);
1558
1559 /* Create L2CAP header */
1560 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1561 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1562 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1563
1564 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1565 if (unlikely(err < 0)) {
1566 kfree_skb(skb);
1567 return ERR_PTR(err);
1568 }
1569 return skb;
1570}
1571
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001572static 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 -03001573{
1574 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1575 struct sk_buff *skb;
1576 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1577 struct l2cap_hdr *lh;
1578
1579 BT_DBG("sk %p len %d", sk, (int)len);
1580
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03001581 if (!conn)
1582 return ERR_PTR(-ENOTCONN);
1583
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001584 if (sdulen)
1585 hlen += 2;
1586
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001587 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1588 hlen += 2;
1589
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001590 count = min_t(unsigned int, (conn->mtu - hlen), len);
1591 skb = bt_skb_send_alloc(sk, count + hlen,
1592 msg->msg_flags & MSG_DONTWAIT, &err);
1593 if (!skb)
1594 return ERR_PTR(-ENOMEM);
1595
1596 /* Create L2CAP header */
1597 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1598 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1599 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1600 put_unaligned_le16(control, skb_put(skb, 2));
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001601 if (sdulen)
1602 put_unaligned_le16(sdulen, skb_put(skb, 2));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001603
1604 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1605 if (unlikely(err < 0)) {
1606 kfree_skb(skb);
1607 return ERR_PTR(err);
1608 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001609
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001610 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1611 put_unaligned_le16(0, skb_put(skb, 2));
1612
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001613 bt_cb(skb)->retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001614 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001615}
1616
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001617static inline int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len)
1618{
1619 struct l2cap_pinfo *pi = l2cap_pi(sk);
1620 struct sk_buff *skb;
1621 struct sk_buff_head sar_queue;
1622 u16 control;
1623 size_t size = 0;
1624
1625 __skb_queue_head_init(&sar_queue);
1626 control = L2CAP_SDU_START;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001627 skb = l2cap_create_iframe_pdu(sk, msg, pi->remote_mps, control, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001628 if (IS_ERR(skb))
1629 return PTR_ERR(skb);
1630
1631 __skb_queue_tail(&sar_queue, skb);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001632 len -= pi->remote_mps;
1633 size += pi->remote_mps;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001634
1635 while (len > 0) {
1636 size_t buflen;
1637
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001638 if (len > pi->remote_mps) {
Gustavo F. Padovan44651b82010-05-01 16:15:43 -03001639 control = L2CAP_SDU_CONTINUE;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001640 buflen = pi->remote_mps;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001641 } else {
Gustavo F. Padovan44651b82010-05-01 16:15:43 -03001642 control = L2CAP_SDU_END;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001643 buflen = len;
1644 }
1645
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001646 skb = l2cap_create_iframe_pdu(sk, msg, buflen, control, 0);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001647 if (IS_ERR(skb)) {
1648 skb_queue_purge(&sar_queue);
1649 return PTR_ERR(skb);
1650 }
1651
1652 __skb_queue_tail(&sar_queue, skb);
1653 len -= buflen;
1654 size += buflen;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001655 }
1656 skb_queue_splice_tail(&sar_queue, TX_QUEUE(sk));
1657 if (sk->sk_send_head == NULL)
1658 sk->sk_send_head = sar_queue.next;
1659
1660 return size;
1661}
1662
Linus Torvalds1da177e2005-04-16 15:20:36 -07001663static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len)
1664{
1665 struct sock *sk = sock->sk;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001666 struct l2cap_pinfo *pi = l2cap_pi(sk);
1667 struct sk_buff *skb;
1668 u16 control;
1669 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001670
1671 BT_DBG("sock %p, sk %p", sock, sk);
1672
Benjamin LaHaisec1cbe4b2005-12-13 23:22:19 -08001673 err = sock_error(sk);
1674 if (err)
1675 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001676
1677 if (msg->msg_flags & MSG_OOB)
1678 return -EOPNOTSUPP;
1679
Linus Torvalds1da177e2005-04-16 15:20:36 -07001680 lock_sock(sk);
1681
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001682 if (sk->sk_state != BT_CONNECTED) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001683 err = -ENOTCONN;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001684 goto done;
1685 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001686
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001687 /* Connectionless channel */
1688 if (sk->sk_type == SOCK_DGRAM) {
1689 skb = l2cap_create_connless_pdu(sk, msg, len);
Dan Carpenter477fffb2010-04-21 23:52:01 +00001690 if (IS_ERR(skb))
1691 err = PTR_ERR(skb);
1692 else
1693 err = l2cap_do_send(sk, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001694 goto done;
1695 }
1696
1697 switch (pi->mode) {
1698 case L2CAP_MODE_BASIC:
Gustavo F. Padovanc69163e2010-05-01 16:15:35 -03001699 /* Check outgoing MTU */
1700 if (len > pi->omtu) {
1701 err = -EINVAL;
1702 goto done;
1703 }
1704
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001705 /* Create a basic PDU */
1706 skb = l2cap_create_basic_pdu(sk, msg, len);
1707 if (IS_ERR(skb)) {
1708 err = PTR_ERR(skb);
1709 goto done;
1710 }
1711
1712 err = l2cap_do_send(sk, skb);
1713 if (!err)
1714 err = len;
1715 break;
1716
1717 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001718 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001719 /* Entire SDU fits into one PDU */
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001720 if (len <= pi->remote_mps) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001721 control = L2CAP_SDU_UNSEGMENTED;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001722 skb = l2cap_create_iframe_pdu(sk, msg, len, control, 0);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001723 if (IS_ERR(skb)) {
1724 err = PTR_ERR(skb);
1725 goto done;
1726 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001727 __skb_queue_tail(TX_QUEUE(sk), skb);
1728 if (sk->sk_send_head == NULL)
1729 sk->sk_send_head = skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001730 } else {
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001731 /* Segment SDU into multiples PDUs */
1732 err = l2cap_sar_segment_sdu(sk, msg, len);
1733 if (err < 0)
1734 goto done;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001735 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001736
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001737 if (pi->mode == L2CAP_MODE_STREAMING)
1738 err = l2cap_streaming_send(sk);
1739 else
1740 err = l2cap_ertm_send(sk);
1741
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001742 if (err >= 0)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001743 err = len;
1744 break;
1745
1746 default:
1747 BT_DBG("bad state %1.1x", pi->mode);
1748 err = -EINVAL;
1749 }
1750
1751done:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001752 release_sock(sk);
1753 return err;
1754}
1755
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001756static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags)
1757{
1758 struct sock *sk = sock->sk;
1759
1760 lock_sock(sk);
1761
1762 if (sk->sk_state == BT_CONNECT2 && bt_sk(sk)->defer_setup) {
1763 struct l2cap_conn_rsp rsp;
1764
1765 sk->sk_state = BT_CONFIG;
1766
1767 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
1768 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
1769 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
1770 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
1771 l2cap_send_cmd(l2cap_pi(sk)->conn, l2cap_pi(sk)->ident,
1772 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
1773
1774 release_sock(sk);
1775 return 0;
1776 }
1777
1778 release_sock(sk);
1779
1780 return bt_sock_recvmsg(iocb, sock, msg, len, flags);
1781}
1782
David S. Millerb7058842009-09-30 16:12:20 -07001783static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001784{
1785 struct sock *sk = sock->sk;
1786 struct l2cap_options opts;
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001787 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001788 u32 opt;
1789
1790 BT_DBG("sk %p", sk);
1791
1792 lock_sock(sk);
1793
1794 switch (optname) {
1795 case L2CAP_OPTIONS:
Marcel Holtmann0878b662007-05-05 00:35:59 +02001796 opts.imtu = l2cap_pi(sk)->imtu;
1797 opts.omtu = l2cap_pi(sk)->omtu;
1798 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001799 opts.mode = l2cap_pi(sk)->mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001800 opts.fcs = l2cap_pi(sk)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03001801 opts.max_tx = l2cap_pi(sk)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03001802 opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
Marcel Holtmann0878b662007-05-05 00:35:59 +02001803
Linus Torvalds1da177e2005-04-16 15:20:36 -07001804 len = min_t(unsigned int, sizeof(opts), optlen);
1805 if (copy_from_user((char *) &opts, optval, len)) {
1806 err = -EFAULT;
1807 break;
1808 }
Marcel Holtmann0878b662007-05-05 00:35:59 +02001809
João Paulo Rechi Vita0041ecf2010-05-01 16:15:42 -03001810 l2cap_pi(sk)->mode = opts.mode;
1811 switch (l2cap_pi(sk)->mode) {
1812 case L2CAP_MODE_BASIC:
1813 break;
1814 case L2CAP_MODE_ERTM:
1815 case L2CAP_MODE_STREAMING:
1816 if (enable_ertm)
1817 break;
1818 /* fall through */
1819 default:
1820 err = -EINVAL;
1821 break;
1822 }
1823
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001824 l2cap_pi(sk)->imtu = opts.imtu;
1825 l2cap_pi(sk)->omtu = opts.omtu;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001826 l2cap_pi(sk)->fcs = opts.fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03001827 l2cap_pi(sk)->max_tx = opts.max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03001828 l2cap_pi(sk)->tx_win = (__u8)opts.txwin_size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001829 break;
1830
1831 case L2CAP_LM:
1832 if (get_user(opt, (u32 __user *) optval)) {
1833 err = -EFAULT;
1834 break;
1835 }
1836
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001837 if (opt & L2CAP_LM_AUTH)
1838 l2cap_pi(sk)->sec_level = BT_SECURITY_LOW;
1839 if (opt & L2CAP_LM_ENCRYPT)
1840 l2cap_pi(sk)->sec_level = BT_SECURITY_MEDIUM;
1841 if (opt & L2CAP_LM_SECURE)
1842 l2cap_pi(sk)->sec_level = BT_SECURITY_HIGH;
1843
1844 l2cap_pi(sk)->role_switch = (opt & L2CAP_LM_MASTER);
1845 l2cap_pi(sk)->force_reliable = (opt & L2CAP_LM_RELIABLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001846 break;
1847
1848 default:
1849 err = -ENOPROTOOPT;
1850 break;
1851 }
1852
1853 release_sock(sk);
1854 return err;
1855}
1856
David S. Millerb7058842009-09-30 16:12:20 -07001857static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001858{
1859 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001860 struct bt_security sec;
1861 int len, err = 0;
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001862 u32 opt;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001863
1864 BT_DBG("sk %p", sk);
1865
1866 if (level == SOL_L2CAP)
1867 return l2cap_sock_setsockopt_old(sock, optname, optval, optlen);
1868
Marcel Holtmann0588d942009-01-16 10:06:13 +01001869 if (level != SOL_BLUETOOTH)
1870 return -ENOPROTOOPT;
1871
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001872 lock_sock(sk);
1873
1874 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001875 case BT_SECURITY:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001876 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
1877 && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01001878 err = -EINVAL;
1879 break;
1880 }
1881
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001882 sec.level = BT_SECURITY_LOW;
1883
1884 len = min_t(unsigned int, sizeof(sec), optlen);
1885 if (copy_from_user((char *) &sec, optval, len)) {
1886 err = -EFAULT;
1887 break;
1888 }
1889
1890 if (sec.level < BT_SECURITY_LOW ||
1891 sec.level > BT_SECURITY_HIGH) {
1892 err = -EINVAL;
1893 break;
1894 }
1895
1896 l2cap_pi(sk)->sec_level = sec.level;
1897 break;
1898
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001899 case BT_DEFER_SETUP:
1900 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
1901 err = -EINVAL;
1902 break;
1903 }
1904
1905 if (get_user(opt, (u32 __user *) optval)) {
1906 err = -EFAULT;
1907 break;
1908 }
1909
1910 bt_sk(sk)->defer_setup = opt;
1911 break;
1912
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001913 default:
1914 err = -ENOPROTOOPT;
1915 break;
1916 }
1917
1918 release_sock(sk);
1919 return err;
1920}
1921
1922static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001923{
1924 struct sock *sk = sock->sk;
1925 struct l2cap_options opts;
1926 struct l2cap_conninfo cinfo;
1927 int len, err = 0;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001928 u32 opt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001929
1930 BT_DBG("sk %p", sk);
1931
1932 if (get_user(len, optlen))
1933 return -EFAULT;
1934
1935 lock_sock(sk);
1936
1937 switch (optname) {
1938 case L2CAP_OPTIONS:
1939 opts.imtu = l2cap_pi(sk)->imtu;
1940 opts.omtu = l2cap_pi(sk)->omtu;
1941 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001942 opts.mode = l2cap_pi(sk)->mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001943 opts.fcs = l2cap_pi(sk)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03001944 opts.max_tx = l2cap_pi(sk)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03001945 opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001946
1947 len = min_t(unsigned int, len, sizeof(opts));
1948 if (copy_to_user(optval, (char *) &opts, len))
1949 err = -EFAULT;
1950
1951 break;
1952
1953 case L2CAP_LM:
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001954 switch (l2cap_pi(sk)->sec_level) {
1955 case BT_SECURITY_LOW:
1956 opt = L2CAP_LM_AUTH;
1957 break;
1958 case BT_SECURITY_MEDIUM:
1959 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT;
1960 break;
1961 case BT_SECURITY_HIGH:
1962 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT |
1963 L2CAP_LM_SECURE;
1964 break;
1965 default:
1966 opt = 0;
1967 break;
1968 }
1969
1970 if (l2cap_pi(sk)->role_switch)
1971 opt |= L2CAP_LM_MASTER;
1972
1973 if (l2cap_pi(sk)->force_reliable)
1974 opt |= L2CAP_LM_RELIABLE;
1975
1976 if (put_user(opt, (u32 __user *) optval))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001977 err = -EFAULT;
1978 break;
1979
1980 case L2CAP_CONNINFO:
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001981 if (sk->sk_state != BT_CONNECTED &&
1982 !(sk->sk_state == BT_CONNECT2 &&
1983 bt_sk(sk)->defer_setup)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001984 err = -ENOTCONN;
1985 break;
1986 }
1987
1988 cinfo.hci_handle = l2cap_pi(sk)->conn->hcon->handle;
1989 memcpy(cinfo.dev_class, l2cap_pi(sk)->conn->hcon->dev_class, 3);
1990
1991 len = min_t(unsigned int, len, sizeof(cinfo));
1992 if (copy_to_user(optval, (char *) &cinfo, len))
1993 err = -EFAULT;
1994
1995 break;
1996
1997 default:
1998 err = -ENOPROTOOPT;
1999 break;
2000 }
2001
2002 release_sock(sk);
2003 return err;
2004}
2005
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002006static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
2007{
2008 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002009 struct bt_security sec;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002010 int len, err = 0;
2011
2012 BT_DBG("sk %p", sk);
2013
2014 if (level == SOL_L2CAP)
2015 return l2cap_sock_getsockopt_old(sock, optname, optval, optlen);
2016
Marcel Holtmann0588d942009-01-16 10:06:13 +01002017 if (level != SOL_BLUETOOTH)
2018 return -ENOPROTOOPT;
2019
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002020 if (get_user(len, optlen))
2021 return -EFAULT;
2022
2023 lock_sock(sk);
2024
2025 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002026 case BT_SECURITY:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03002027 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
2028 && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01002029 err = -EINVAL;
2030 break;
2031 }
2032
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002033 sec.level = l2cap_pi(sk)->sec_level;
2034
2035 len = min_t(unsigned int, len, sizeof(sec));
2036 if (copy_to_user(optval, (char *) &sec, len))
2037 err = -EFAULT;
2038
2039 break;
2040
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002041 case BT_DEFER_SETUP:
2042 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
2043 err = -EINVAL;
2044 break;
2045 }
2046
2047 if (put_user(bt_sk(sk)->defer_setup, (u32 __user *) optval))
2048 err = -EFAULT;
2049
2050 break;
2051
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002052 default:
2053 err = -ENOPROTOOPT;
2054 break;
2055 }
2056
2057 release_sock(sk);
2058 return err;
2059}
2060
Linus Torvalds1da177e2005-04-16 15:20:36 -07002061static int l2cap_sock_shutdown(struct socket *sock, int how)
2062{
2063 struct sock *sk = sock->sk;
2064 int err = 0;
2065
2066 BT_DBG("sock %p, sk %p", sock, sk);
2067
2068 if (!sk)
2069 return 0;
2070
2071 lock_sock(sk);
2072 if (!sk->sk_shutdown) {
2073 sk->sk_shutdown = SHUTDOWN_MASK;
2074 l2cap_sock_clear_timer(sk);
2075 __l2cap_sock_close(sk, 0);
2076
2077 if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
Marcel Holtmannb1235d72008-07-14 20:13:54 +02002078 err = bt_sock_wait_state(sk, BT_CLOSED,
2079 sk->sk_lingertime);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002080 }
2081 release_sock(sk);
2082 return err;
2083}
2084
2085static int l2cap_sock_release(struct socket *sock)
2086{
2087 struct sock *sk = sock->sk;
2088 int err;
2089
2090 BT_DBG("sock %p, sk %p", sock, sk);
2091
2092 if (!sk)
2093 return 0;
2094
2095 err = l2cap_sock_shutdown(sock, 2);
2096
2097 sock_orphan(sk);
2098 l2cap_sock_kill(sk);
2099 return err;
2100}
2101
Linus Torvalds1da177e2005-04-16 15:20:36 -07002102static void l2cap_chan_ready(struct sock *sk)
2103{
2104 struct sock *parent = bt_sk(sk)->parent;
2105
2106 BT_DBG("sk %p, parent %p", sk, parent);
2107
2108 l2cap_pi(sk)->conf_state = 0;
2109 l2cap_sock_clear_timer(sk);
2110
2111 if (!parent) {
2112 /* Outgoing channel.
2113 * Wake up socket sleeping on connect.
2114 */
2115 sk->sk_state = BT_CONNECTED;
2116 sk->sk_state_change(sk);
2117 } else {
2118 /* Incoming channel.
2119 * Wake up socket sleeping on accept.
2120 */
2121 parent->sk_data_ready(parent, 0);
2122 }
2123}
2124
2125/* Copy frame to all raw sockets on that connection */
2126static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2127{
2128 struct l2cap_chan_list *l = &conn->chan_list;
2129 struct sk_buff *nskb;
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002130 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002131
2132 BT_DBG("conn %p", conn);
2133
2134 read_lock(&l->lock);
2135 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
2136 if (sk->sk_type != SOCK_RAW)
2137 continue;
2138
2139 /* Don't send frame to the socket it came from */
2140 if (skb->sk == sk)
2141 continue;
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002142 nskb = skb_clone(skb, GFP_ATOMIC);
2143 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002144 continue;
2145
2146 if (sock_queue_rcv_skb(sk, nskb))
2147 kfree_skb(nskb);
2148 }
2149 read_unlock(&l->lock);
2150}
2151
2152/* ---- L2CAP signalling commands ---- */
2153static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
2154 u8 code, u8 ident, u16 dlen, void *data)
2155{
2156 struct sk_buff *skb, **frag;
2157 struct l2cap_cmd_hdr *cmd;
2158 struct l2cap_hdr *lh;
2159 int len, count;
2160
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002161 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d",
2162 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002163
2164 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2165 count = min_t(unsigned int, conn->mtu, len);
2166
2167 skb = bt_skb_alloc(count, GFP_ATOMIC);
2168 if (!skb)
2169 return NULL;
2170
2171 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002172 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03002173 lh->cid = cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002174
2175 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2176 cmd->code = code;
2177 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002178 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002179
2180 if (dlen) {
2181 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2182 memcpy(skb_put(skb, count), data, count);
2183 data += count;
2184 }
2185
2186 len -= skb->len;
2187
2188 /* Continuation fragments (no L2CAP header) */
2189 frag = &skb_shinfo(skb)->frag_list;
2190 while (len) {
2191 count = min_t(unsigned int, conn->mtu, len);
2192
2193 *frag = bt_skb_alloc(count, GFP_ATOMIC);
2194 if (!*frag)
2195 goto fail;
2196
2197 memcpy(skb_put(*frag, count), data, count);
2198
2199 len -= count;
2200 data += count;
2201
2202 frag = &(*frag)->next;
2203 }
2204
2205 return skb;
2206
2207fail:
2208 kfree_skb(skb);
2209 return NULL;
2210}
2211
2212static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned long *val)
2213{
2214 struct l2cap_conf_opt *opt = *ptr;
2215 int len;
2216
2217 len = L2CAP_CONF_OPT_SIZE + opt->len;
2218 *ptr += len;
2219
2220 *type = opt->type;
2221 *olen = opt->len;
2222
2223 switch (opt->len) {
2224 case 1:
2225 *val = *((u8 *) opt->val);
2226 break;
2227
2228 case 2:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002229 *val = __le16_to_cpu(*((__le16 *) opt->val));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002230 break;
2231
2232 case 4:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002233 *val = __le32_to_cpu(*((__le32 *) opt->val));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002234 break;
2235
2236 default:
2237 *val = (unsigned long) opt->val;
2238 break;
2239 }
2240
2241 BT_DBG("type 0x%2.2x len %d val 0x%lx", *type, opt->len, *val);
2242 return len;
2243}
2244
Linus Torvalds1da177e2005-04-16 15:20:36 -07002245static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2246{
2247 struct l2cap_conf_opt *opt = *ptr;
2248
2249 BT_DBG("type 0x%2.2x len %d val 0x%lx", type, len, val);
2250
2251 opt->type = type;
2252 opt->len = len;
2253
2254 switch (len) {
2255 case 1:
2256 *((u8 *) opt->val) = val;
2257 break;
2258
2259 case 2:
Al Viro8e036fc2007-07-29 00:16:36 -07002260 *((__le16 *) opt->val) = cpu_to_le16(val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002261 break;
2262
2263 case 4:
Al Viro8e036fc2007-07-29 00:16:36 -07002264 *((__le32 *) opt->val) = cpu_to_le32(val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002265 break;
2266
2267 default:
2268 memcpy(opt->val, (void *) val, len);
2269 break;
2270 }
2271
2272 *ptr += L2CAP_CONF_OPT_SIZE + len;
2273}
2274
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002275static void l2cap_ack_timeout(unsigned long arg)
2276{
2277 struct sock *sk = (void *) arg;
2278
2279 bh_lock_sock(sk);
2280 l2cap_send_ack(l2cap_pi(sk));
2281 bh_unlock_sock(sk);
2282}
2283
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002284static inline void l2cap_ertm_init(struct sock *sk)
2285{
2286 l2cap_pi(sk)->expected_ack_seq = 0;
2287 l2cap_pi(sk)->unacked_frames = 0;
2288 l2cap_pi(sk)->buffer_seq = 0;
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03002289 l2cap_pi(sk)->num_acked = 0;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03002290 l2cap_pi(sk)->frames_sent = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002291
2292 setup_timer(&l2cap_pi(sk)->retrans_timer,
2293 l2cap_retrans_timeout, (unsigned long) sk);
2294 setup_timer(&l2cap_pi(sk)->monitor_timer,
2295 l2cap_monitor_timeout, (unsigned long) sk);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002296 setup_timer(&l2cap_pi(sk)->ack_timer,
2297 l2cap_ack_timeout, (unsigned long) sk);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002298
2299 __skb_queue_head_init(SREJ_QUEUE(sk));
2300}
2301
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002302static int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
2303{
2304 u32 local_feat_mask = l2cap_feat_mask;
2305 if (enable_ertm)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002306 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002307
2308 switch (mode) {
2309 case L2CAP_MODE_ERTM:
2310 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
2311 case L2CAP_MODE_STREAMING:
2312 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
2313 default:
2314 return 0x00;
2315 }
2316}
2317
2318static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
2319{
2320 switch (mode) {
2321 case L2CAP_MODE_STREAMING:
2322 case L2CAP_MODE_ERTM:
2323 if (l2cap_mode_supported(mode, remote_feat_mask))
2324 return mode;
2325 /* fall through */
2326 default:
2327 return L2CAP_MODE_BASIC;
2328 }
2329}
2330
Linus Torvalds1da177e2005-04-16 15:20:36 -07002331static int l2cap_build_conf_req(struct sock *sk, void *data)
2332{
2333 struct l2cap_pinfo *pi = l2cap_pi(sk);
2334 struct l2cap_conf_req *req = data;
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03002335 struct l2cap_conf_rfc rfc = { .mode = pi->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07002336 void *ptr = req->data;
2337
2338 BT_DBG("sk %p", sk);
2339
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002340 if (pi->num_conf_req || pi->num_conf_rsp)
2341 goto done;
2342
2343 switch (pi->mode) {
2344 case L2CAP_MODE_STREAMING:
2345 case L2CAP_MODE_ERTM:
2346 pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002347 if (!l2cap_mode_supported(pi->mode, pi->conn->feat_mask))
2348 l2cap_send_disconn_req(pi->conn, sk);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002349 break;
2350 default:
2351 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
2352 break;
2353 }
2354
2355done:
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002356 switch (pi->mode) {
2357 case L2CAP_MODE_BASIC:
2358 if (pi->imtu != L2CAP_DEFAULT_MTU)
2359 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
2360 break;
2361
2362 case L2CAP_MODE_ERTM:
2363 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03002364 rfc.txwin_size = pi->tx_win;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03002365 rfc.max_transmit = pi->max_tx;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002366 rfc.retrans_timeout = 0;
2367 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002368 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03002369 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002370 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002371
2372 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2373 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002374
2375 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2376 break;
2377
2378 if (pi->fcs == L2CAP_FCS_NONE ||
2379 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
2380 pi->fcs = L2CAP_FCS_NONE;
2381 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
2382 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002383 break;
2384
2385 case L2CAP_MODE_STREAMING:
2386 rfc.mode = L2CAP_MODE_STREAMING;
2387 rfc.txwin_size = 0;
2388 rfc.max_transmit = 0;
2389 rfc.retrans_timeout = 0;
2390 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002391 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03002392 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002393 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002394
2395 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2396 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002397
2398 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2399 break;
2400
2401 if (pi->fcs == L2CAP_FCS_NONE ||
2402 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
2403 pi->fcs = L2CAP_FCS_NONE;
2404 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
2405 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002406 break;
2407 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002408
2409 /* FIXME: Need actual value of the flush timeout */
2410 //if (flush_to != L2CAP_DEFAULT_FLUSH_TO)
2411 // l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2, pi->flush_to);
2412
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002413 req->dcid = cpu_to_le16(pi->dcid);
2414 req->flags = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002415
2416 return ptr - data;
2417}
2418
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002419static int l2cap_parse_conf_req(struct sock *sk, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002420{
2421 struct l2cap_pinfo *pi = l2cap_pi(sk);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002422 struct l2cap_conf_rsp *rsp = data;
2423 void *ptr = rsp->data;
2424 void *req = pi->conf_req;
2425 int len = pi->conf_len;
2426 int type, hint, olen;
2427 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002428 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Marcel Holtmann861d6882007-10-20 13:37:06 +02002429 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002430 u16 result = L2CAP_CONF_SUCCESS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002431
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002432 BT_DBG("sk %p", sk);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01002433
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002434 while (len >= L2CAP_CONF_OPT_SIZE) {
2435 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002436
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03002437 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07002438 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002439
2440 switch (type) {
2441 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002442 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002443 break;
2444
2445 case L2CAP_CONF_FLUSH_TO:
2446 pi->flush_to = val;
2447 break;
2448
2449 case L2CAP_CONF_QOS:
2450 break;
2451
Marcel Holtmann6464f352007-10-20 13:39:51 +02002452 case L2CAP_CONF_RFC:
2453 if (olen == sizeof(rfc))
2454 memcpy(&rfc, (void *) val, olen);
2455 break;
2456
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002457 case L2CAP_CONF_FCS:
2458 if (val == L2CAP_FCS_NONE)
2459 pi->conf_state |= L2CAP_CONF_NO_FCS_RECV;
2460
2461 break;
2462
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002463 default:
2464 if (hint)
2465 break;
2466
2467 result = L2CAP_CONF_UNKNOWN;
2468 *((u8 *) ptr++) = type;
2469 break;
2470 }
2471 }
2472
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002473 if (pi->num_conf_rsp || pi->num_conf_req)
2474 goto done;
2475
2476 switch (pi->mode) {
2477 case L2CAP_MODE_STREAMING:
2478 case L2CAP_MODE_ERTM:
2479 pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
2480 if (!l2cap_mode_supported(pi->mode, pi->conn->feat_mask))
2481 return -ECONNREFUSED;
2482 break;
2483 default:
2484 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
2485 break;
2486 }
2487
2488done:
2489 if (pi->mode != rfc.mode) {
2490 result = L2CAP_CONF_UNACCEPT;
2491 rfc.mode = pi->mode;
2492
2493 if (pi->num_conf_rsp == 1)
2494 return -ECONNREFUSED;
2495
2496 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2497 sizeof(rfc), (unsigned long) &rfc);
2498 }
2499
2500
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002501 if (result == L2CAP_CONF_SUCCESS) {
2502 /* Configure output options and let the other side know
2503 * which ones we don't like. */
2504
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002505 if (mtu < L2CAP_DEFAULT_MIN_MTU)
2506 result = L2CAP_CONF_UNACCEPT;
2507 else {
2508 pi->omtu = mtu;
2509 pi->conf_state |= L2CAP_CONF_MTU_DONE;
2510 }
2511 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002512
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002513 switch (rfc.mode) {
2514 case L2CAP_MODE_BASIC:
2515 pi->fcs = L2CAP_FCS_NONE;
2516 pi->conf_state |= L2CAP_CONF_MODE_DONE;
2517 break;
2518
2519 case L2CAP_MODE_ERTM:
2520 pi->remote_tx_win = rfc.txwin_size;
2521 pi->remote_max_tx = rfc.max_transmit;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002522 if (rfc.max_pdu_size > pi->conn->mtu - 10)
2523 rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10);
2524
2525 pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002526
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002527 rfc.retrans_timeout =
2528 le16_to_cpu(L2CAP_DEFAULT_RETRANS_TO);
2529 rfc.monitor_timeout =
2530 le16_to_cpu(L2CAP_DEFAULT_MONITOR_TO);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002531
2532 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03002533
2534 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2535 sizeof(rfc), (unsigned long) &rfc);
2536
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002537 break;
2538
2539 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002540 if (rfc.max_pdu_size > pi->conn->mtu - 10)
2541 rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10);
2542
2543 pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002544
2545 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03002546
2547 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2548 sizeof(rfc), (unsigned long) &rfc);
2549
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002550 break;
2551
2552 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02002553 result = L2CAP_CONF_UNACCEPT;
2554
2555 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002556 rfc.mode = pi->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002557 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002558
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002559 if (result == L2CAP_CONF_SUCCESS)
2560 pi->conf_state |= L2CAP_CONF_OUTPUT_DONE;
2561 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002562 rsp->scid = cpu_to_le16(pi->dcid);
2563 rsp->result = cpu_to_le16(result);
2564 rsp->flags = cpu_to_le16(0x0000);
2565
2566 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002567}
2568
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002569static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data, u16 *result)
2570{
2571 struct l2cap_pinfo *pi = l2cap_pi(sk);
2572 struct l2cap_conf_req *req = data;
2573 void *ptr = req->data;
2574 int type, olen;
2575 unsigned long val;
2576 struct l2cap_conf_rfc rfc;
2577
2578 BT_DBG("sk %p, rsp %p, len %d, req %p", sk, rsp, len, data);
2579
2580 while (len >= L2CAP_CONF_OPT_SIZE) {
2581 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
2582
2583 switch (type) {
2584 case L2CAP_CONF_MTU:
2585 if (val < L2CAP_DEFAULT_MIN_MTU) {
2586 *result = L2CAP_CONF_UNACCEPT;
2587 pi->omtu = L2CAP_DEFAULT_MIN_MTU;
2588 } else
2589 pi->omtu = val;
2590 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
2591 break;
2592
2593 case L2CAP_CONF_FLUSH_TO:
2594 pi->flush_to = val;
2595 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
2596 2, pi->flush_to);
2597 break;
2598
2599 case L2CAP_CONF_RFC:
2600 if (olen == sizeof(rfc))
2601 memcpy(&rfc, (void *)val, olen);
2602
2603 if ((pi->conf_state & L2CAP_CONF_STATE2_DEVICE) &&
2604 rfc.mode != pi->mode)
2605 return -ECONNREFUSED;
2606
2607 pi->mode = rfc.mode;
2608 pi->fcs = 0;
2609
2610 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2611 sizeof(rfc), (unsigned long) &rfc);
2612 break;
2613 }
2614 }
2615
2616 if (*result == L2CAP_CONF_SUCCESS) {
2617 switch (rfc.mode) {
2618 case L2CAP_MODE_ERTM:
2619 pi->remote_tx_win = rfc.txwin_size;
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002620 pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
2621 pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002622 pi->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002623 break;
2624 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002625 pi->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002626 }
2627 }
2628
2629 req->dcid = cpu_to_le16(pi->dcid);
2630 req->flags = cpu_to_le16(0x0000);
2631
2632 return ptr - data;
2633}
2634
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002635static int l2cap_build_conf_rsp(struct sock *sk, void *data, u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002636{
2637 struct l2cap_conf_rsp *rsp = data;
2638 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002639
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002640 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002641
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002642 rsp->scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002643 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002644 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002645
2646 return ptr - data;
2647}
2648
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002649static void l2cap_conf_rfc_get(struct sock *sk, void *rsp, int len)
2650{
2651 struct l2cap_pinfo *pi = l2cap_pi(sk);
2652 int type, olen;
2653 unsigned long val;
2654 struct l2cap_conf_rfc rfc;
2655
2656 BT_DBG("sk %p, rsp %p, len %d", sk, rsp, len);
2657
2658 if ((pi->mode != L2CAP_MODE_ERTM) && (pi->mode != L2CAP_MODE_STREAMING))
2659 return;
2660
2661 while (len >= L2CAP_CONF_OPT_SIZE) {
2662 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
2663
2664 switch (type) {
2665 case L2CAP_CONF_RFC:
2666 if (olen == sizeof(rfc))
2667 memcpy(&rfc, (void *)val, olen);
2668 goto done;
2669 }
2670 }
2671
2672done:
2673 switch (rfc.mode) {
2674 case L2CAP_MODE_ERTM:
2675 pi->remote_tx_win = rfc.txwin_size;
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002676 pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
2677 pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002678 pi->mps = le16_to_cpu(rfc.max_pdu_size);
2679 break;
2680 case L2CAP_MODE_STREAMING:
2681 pi->mps = le16_to_cpu(rfc.max_pdu_size);
2682 }
2683}
2684
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002685static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2686{
2687 struct l2cap_cmd_rej *rej = (struct l2cap_cmd_rej *) data;
2688
2689 if (rej->reason != 0x0000)
2690 return 0;
2691
2692 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
2693 cmd->ident == conn->info_ident) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002694 del_timer(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01002695
2696 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002697 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01002698
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002699 l2cap_conn_start(conn);
2700 }
2701
2702 return 0;
2703}
2704
Linus Torvalds1da177e2005-04-16 15:20:36 -07002705static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2706{
2707 struct l2cap_chan_list *list = &conn->chan_list;
2708 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
2709 struct l2cap_conn_rsp rsp;
2710 struct sock *sk, *parent;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002711 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002712
2713 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002714 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002715
2716 BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
2717
2718 /* Check if we have socket listening on psm */
2719 parent = l2cap_get_sock_by_psm(BT_LISTEN, psm, conn->src);
2720 if (!parent) {
2721 result = L2CAP_CR_BAD_PSM;
2722 goto sendresp;
2723 }
2724
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002725 /* Check if the ACL is secure enough (if not SDP) */
2726 if (psm != cpu_to_le16(0x0001) &&
2727 !hci_conn_check_link_mode(conn->hcon)) {
Marcel Holtmann2950f212009-02-12 14:02:50 +01002728 conn->disc_reason = 0x05;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002729 result = L2CAP_CR_SEC_BLOCK;
2730 goto response;
2731 }
2732
Linus Torvalds1da177e2005-04-16 15:20:36 -07002733 result = L2CAP_CR_NO_MEM;
2734
2735 /* Check for backlog size */
2736 if (sk_acceptq_is_full(parent)) {
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09002737 BT_DBG("backlog full %d", parent->sk_ack_backlog);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002738 goto response;
2739 }
2740
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09002741 sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002742 if (!sk)
2743 goto response;
2744
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002745 write_lock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002746
2747 /* Check if we already have channel with that dcid */
2748 if (__l2cap_get_chan_by_dcid(list, scid)) {
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002749 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002750 sock_set_flag(sk, SOCK_ZAPPED);
2751 l2cap_sock_kill(sk);
2752 goto response;
2753 }
2754
2755 hci_conn_hold(conn->hcon);
2756
2757 l2cap_sock_init(sk, parent);
2758 bacpy(&bt_sk(sk)->src, conn->src);
2759 bacpy(&bt_sk(sk)->dst, conn->dst);
2760 l2cap_pi(sk)->psm = psm;
2761 l2cap_pi(sk)->dcid = scid;
2762
2763 __l2cap_chan_add(conn, sk, parent);
2764 dcid = l2cap_pi(sk)->scid;
2765
2766 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
2767
Linus Torvalds1da177e2005-04-16 15:20:36 -07002768 l2cap_pi(sk)->ident = cmd->ident;
2769
Marcel Holtmann984947d2009-02-06 23:35:19 +01002770 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002771 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002772 if (bt_sk(sk)->defer_setup) {
2773 sk->sk_state = BT_CONNECT2;
2774 result = L2CAP_CR_PEND;
2775 status = L2CAP_CS_AUTHOR_PEND;
2776 parent->sk_data_ready(parent, 0);
2777 } else {
2778 sk->sk_state = BT_CONFIG;
2779 result = L2CAP_CR_SUCCESS;
2780 status = L2CAP_CS_NO_INFO;
2781 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002782 } else {
2783 sk->sk_state = BT_CONNECT2;
2784 result = L2CAP_CR_PEND;
2785 status = L2CAP_CS_AUTHEN_PEND;
2786 }
2787 } else {
2788 sk->sk_state = BT_CONNECT2;
2789 result = L2CAP_CR_PEND;
2790 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002791 }
2792
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002793 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002794
2795response:
2796 bh_unlock_sock(parent);
2797
2798sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002799 rsp.scid = cpu_to_le16(scid);
2800 rsp.dcid = cpu_to_le16(dcid);
2801 rsp.result = cpu_to_le16(result);
2802 rsp.status = cpu_to_le16(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002803 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002804
2805 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
2806 struct l2cap_info_req info;
2807 info.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
2808
2809 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
2810 conn->info_ident = l2cap_get_ident(conn);
2811
2812 mod_timer(&conn->info_timer, jiffies +
2813 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
2814
2815 l2cap_send_cmd(conn, conn->info_ident,
2816 L2CAP_INFO_REQ, sizeof(info), &info);
2817 }
2818
Linus Torvalds1da177e2005-04-16 15:20:36 -07002819 return 0;
2820}
2821
2822static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2823{
2824 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
2825 u16 scid, dcid, result, status;
2826 struct sock *sk;
2827 u8 req[128];
2828
2829 scid = __le16_to_cpu(rsp->scid);
2830 dcid = __le16_to_cpu(rsp->dcid);
2831 result = __le16_to_cpu(rsp->result);
2832 status = __le16_to_cpu(rsp->status);
2833
2834 BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
2835
2836 if (scid) {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002837 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2838 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002839 return 0;
2840 } else {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002841 sk = l2cap_get_chan_by_ident(&conn->chan_list, cmd->ident);
2842 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002843 return 0;
2844 }
2845
2846 switch (result) {
2847 case L2CAP_CR_SUCCESS:
2848 sk->sk_state = BT_CONFIG;
2849 l2cap_pi(sk)->ident = 0;
2850 l2cap_pi(sk)->dcid = dcid;
2851 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
2852
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002853 l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_CONNECT_PEND;
2854
Linus Torvalds1da177e2005-04-16 15:20:36 -07002855 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
2856 l2cap_build_conf_req(sk, req), req);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002857 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002858 break;
2859
2860 case L2CAP_CR_PEND:
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002861 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002862 break;
2863
2864 default:
2865 l2cap_chan_del(sk, ECONNREFUSED);
2866 break;
2867 }
2868
2869 bh_unlock_sock(sk);
2870 return 0;
2871}
2872
Al Viro88219a02007-07-29 00:17:25 -07002873static 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 -07002874{
2875 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
2876 u16 dcid, flags;
2877 u8 rsp[64];
2878 struct sock *sk;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002879 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002880
2881 dcid = __le16_to_cpu(req->dcid);
2882 flags = __le16_to_cpu(req->flags);
2883
2884 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
2885
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002886 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
2887 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002888 return -ENOENT;
2889
Marcel Holtmann354f60a2006-11-18 22:15:20 +01002890 if (sk->sk_state == BT_DISCONN)
2891 goto unlock;
2892
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002893 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07002894 len = cmd_len - sizeof(*req);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002895 if (l2cap_pi(sk)->conf_len + len > sizeof(l2cap_pi(sk)->conf_req)) {
2896 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
2897 l2cap_build_conf_rsp(sk, rsp,
2898 L2CAP_CONF_REJECT, flags), rsp);
2899 goto unlock;
2900 }
2901
2902 /* Store config. */
2903 memcpy(l2cap_pi(sk)->conf_req + l2cap_pi(sk)->conf_len, req->data, len);
2904 l2cap_pi(sk)->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002905
2906 if (flags & 0x0001) {
2907 /* Incomplete config. Send empty response. */
2908 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002909 l2cap_build_conf_rsp(sk, rsp,
2910 L2CAP_CONF_SUCCESS, 0x0001), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002911 goto unlock;
2912 }
2913
2914 /* Complete config. */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002915 len = l2cap_parse_conf_req(sk, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002916 if (len < 0) {
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002917 l2cap_send_disconn_req(conn, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002918 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002919 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002920
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002921 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002922 l2cap_pi(sk)->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002923
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002924 /* Reset config buffer. */
2925 l2cap_pi(sk)->conf_len = 0;
2926
Marcel Holtmann876d9482007-10-20 13:35:42 +02002927 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE))
2928 goto unlock;
2929
Linus Torvalds1da177e2005-04-16 15:20:36 -07002930 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) {
Joe Perchesf64f9e72009-11-29 16:55:45 -08002931 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) ||
2932 l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002933 l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
2934
Linus Torvalds1da177e2005-04-16 15:20:36 -07002935 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002936
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002937 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002938 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002939 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002940 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
2941 l2cap_ertm_init(sk);
2942
Linus Torvalds1da177e2005-04-16 15:20:36 -07002943 l2cap_chan_ready(sk);
Marcel Holtmann876d9482007-10-20 13:35:42 +02002944 goto unlock;
2945 }
2946
2947 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002948 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002949 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002950 l2cap_build_conf_req(sk, buf), buf);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002951 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002952 }
2953
2954unlock:
2955 bh_unlock_sock(sk);
2956 return 0;
2957}
2958
2959static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2960{
2961 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
2962 u16 scid, flags, result;
2963 struct sock *sk;
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002964 int len = cmd->len - sizeof(*rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002965
2966 scid = __le16_to_cpu(rsp->scid);
2967 flags = __le16_to_cpu(rsp->flags);
2968 result = __le16_to_cpu(rsp->result);
2969
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002970 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x",
2971 scid, flags, result);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002972
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002973 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2974 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002975 return 0;
2976
2977 switch (result) {
2978 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002979 l2cap_conf_rfc_get(sk, rsp->data, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002980 break;
2981
2982 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002983 if (l2cap_pi(sk)->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002984 char req[64];
2985
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02002986 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
2987 l2cap_send_disconn_req(conn, sk);
2988 goto done;
2989 }
2990
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002991 /* throw out any old stored conf requests */
2992 result = L2CAP_CONF_SUCCESS;
2993 len = l2cap_parse_conf_rsp(sk, rsp->data,
2994 len, req, &result);
2995 if (len < 0) {
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002996 l2cap_send_disconn_req(conn, sk);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002997 goto done;
2998 }
2999
3000 l2cap_send_cmd(conn, l2cap_get_ident(conn),
3001 L2CAP_CONF_REQ, len, req);
3002 l2cap_pi(sk)->num_conf_req++;
3003 if (result != L2CAP_CONF_SUCCESS)
3004 goto done;
3005 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003006 }
3007
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09003008 default:
Linus Torvalds1da177e2005-04-16 15:20:36 -07003009 sk->sk_state = BT_DISCONN;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02003010 sk->sk_err = ECONNRESET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003011 l2cap_sock_set_timer(sk, HZ * 5);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03003012 l2cap_send_disconn_req(conn, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003013 goto done;
3014 }
3015
3016 if (flags & 0x01)
3017 goto done;
3018
Linus Torvalds1da177e2005-04-16 15:20:36 -07003019 l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE;
3020
3021 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) {
Joe Perchesf64f9e72009-11-29 16:55:45 -08003022 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) ||
3023 l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003024 l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
3025
Linus Torvalds1da177e2005-04-16 15:20:36 -07003026 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003027 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003028 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003029 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003030 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
3031 l2cap_ertm_init(sk);
3032
Linus Torvalds1da177e2005-04-16 15:20:36 -07003033 l2cap_chan_ready(sk);
3034 }
3035
3036done:
3037 bh_unlock_sock(sk);
3038 return 0;
3039}
3040
3041static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3042{
3043 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
3044 struct l2cap_disconn_rsp rsp;
3045 u16 dcid, scid;
3046 struct sock *sk;
3047
3048 scid = __le16_to_cpu(req->scid);
3049 dcid = __le16_to_cpu(req->dcid);
3050
3051 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
3052
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003053 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
3054 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003055 return 0;
3056
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003057 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
3058 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003059 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
3060
3061 sk->sk_shutdown = SHUTDOWN_MASK;
3062
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003063 skb_queue_purge(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003064
3065 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
3066 skb_queue_purge(SREJ_QUEUE(sk));
3067 del_timer(&l2cap_pi(sk)->retrans_timer);
3068 del_timer(&l2cap_pi(sk)->monitor_timer);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003069 del_timer(&l2cap_pi(sk)->ack_timer);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003070 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003071
Linus Torvalds1da177e2005-04-16 15:20:36 -07003072 l2cap_chan_del(sk, ECONNRESET);
3073 bh_unlock_sock(sk);
3074
3075 l2cap_sock_kill(sk);
3076 return 0;
3077}
3078
3079static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3080{
3081 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
3082 u16 dcid, scid;
3083 struct sock *sk;
3084
3085 scid = __le16_to_cpu(rsp->scid);
3086 dcid = __le16_to_cpu(rsp->dcid);
3087
3088 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
3089
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003090 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
3091 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003092 return 0;
3093
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003094 skb_queue_purge(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003095
3096 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
3097 skb_queue_purge(SREJ_QUEUE(sk));
3098 del_timer(&l2cap_pi(sk)->retrans_timer);
3099 del_timer(&l2cap_pi(sk)->monitor_timer);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003100 del_timer(&l2cap_pi(sk)->ack_timer);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003101 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003102
Linus Torvalds1da177e2005-04-16 15:20:36 -07003103 l2cap_chan_del(sk, 0);
3104 bh_unlock_sock(sk);
3105
3106 l2cap_sock_kill(sk);
3107 return 0;
3108}
3109
3110static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3111{
3112 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003113 u16 type;
3114
3115 type = __le16_to_cpu(req->type);
3116
3117 BT_DBG("type 0x%4.4x", type);
3118
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003119 if (type == L2CAP_IT_FEAT_MASK) {
3120 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003121 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003122 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
3123 rsp->type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
3124 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003125 if (enable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003126 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
3127 | L2CAP_FEAT_FCS;
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03003128 put_unaligned_le32(feat_mask, rsp->data);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003129 l2cap_send_cmd(conn, cmd->ident,
3130 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003131 } else if (type == L2CAP_IT_FIXED_CHAN) {
3132 u8 buf[12];
3133 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
3134 rsp->type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3135 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
3136 memcpy(buf + 4, l2cap_fixed_chan, 8);
3137 l2cap_send_cmd(conn, cmd->ident,
3138 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003139 } else {
3140 struct l2cap_info_rsp rsp;
3141 rsp.type = cpu_to_le16(type);
3142 rsp.result = cpu_to_le16(L2CAP_IR_NOTSUPP);
3143 l2cap_send_cmd(conn, cmd->ident,
3144 L2CAP_INFO_RSP, sizeof(rsp), &rsp);
3145 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003146
3147 return 0;
3148}
3149
3150static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3151{
3152 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
3153 u16 type, result;
3154
3155 type = __le16_to_cpu(rsp->type);
3156 result = __le16_to_cpu(rsp->result);
3157
3158 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
3159
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003160 del_timer(&conn->info_timer);
3161
Marcel Holtmann984947d2009-02-06 23:35:19 +01003162 if (type == L2CAP_IT_FEAT_MASK) {
Harvey Harrison83985312008-05-02 16:25:46 -07003163 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003164
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003165 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003166 struct l2cap_info_req req;
3167 req.type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3168
3169 conn->info_ident = l2cap_get_ident(conn);
3170
3171 l2cap_send_cmd(conn, conn->info_ident,
3172 L2CAP_INFO_REQ, sizeof(req), &req);
3173 } else {
3174 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
3175 conn->info_ident = 0;
3176
3177 l2cap_conn_start(conn);
3178 }
3179 } else if (type == L2CAP_IT_FIXED_CHAN) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01003180 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003181 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003182
3183 l2cap_conn_start(conn);
3184 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003185
Linus Torvalds1da177e2005-04-16 15:20:36 -07003186 return 0;
3187}
3188
3189static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
3190{
3191 u8 *data = skb->data;
3192 int len = skb->len;
3193 struct l2cap_cmd_hdr cmd;
3194 int err = 0;
3195
3196 l2cap_raw_recv(conn, skb);
3197
3198 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07003199 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003200 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
3201 data += L2CAP_CMD_HDR_SIZE;
3202 len -= L2CAP_CMD_HDR_SIZE;
3203
Al Viro88219a02007-07-29 00:17:25 -07003204 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003205
Al Viro88219a02007-07-29 00:17:25 -07003206 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 -07003207
Al Viro88219a02007-07-29 00:17:25 -07003208 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003209 BT_DBG("corrupted command");
3210 break;
3211 }
3212
3213 switch (cmd.code) {
3214 case L2CAP_COMMAND_REJ:
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003215 l2cap_command_rej(conn, &cmd, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003216 break;
3217
3218 case L2CAP_CONN_REQ:
3219 err = l2cap_connect_req(conn, &cmd, data);
3220 break;
3221
3222 case L2CAP_CONN_RSP:
3223 err = l2cap_connect_rsp(conn, &cmd, data);
3224 break;
3225
3226 case L2CAP_CONF_REQ:
Al Viro88219a02007-07-29 00:17:25 -07003227 err = l2cap_config_req(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003228 break;
3229
3230 case L2CAP_CONF_RSP:
3231 err = l2cap_config_rsp(conn, &cmd, data);
3232 break;
3233
3234 case L2CAP_DISCONN_REQ:
3235 err = l2cap_disconnect_req(conn, &cmd, data);
3236 break;
3237
3238 case L2CAP_DISCONN_RSP:
3239 err = l2cap_disconnect_rsp(conn, &cmd, data);
3240 break;
3241
3242 case L2CAP_ECHO_REQ:
Al Viro88219a02007-07-29 00:17:25 -07003243 l2cap_send_cmd(conn, cmd.ident, L2CAP_ECHO_RSP, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003244 break;
3245
3246 case L2CAP_ECHO_RSP:
3247 break;
3248
3249 case L2CAP_INFO_REQ:
3250 err = l2cap_information_req(conn, &cmd, data);
3251 break;
3252
3253 case L2CAP_INFO_RSP:
3254 err = l2cap_information_rsp(conn, &cmd, data);
3255 break;
3256
3257 default:
3258 BT_ERR("Unknown signaling command 0x%2.2x", cmd.code);
3259 err = -EINVAL;
3260 break;
3261 }
3262
3263 if (err) {
3264 struct l2cap_cmd_rej rej;
3265 BT_DBG("error %d", err);
3266
3267 /* FIXME: Map err to a valid reason */
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003268 rej.reason = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003269 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
3270 }
3271
Al Viro88219a02007-07-29 00:17:25 -07003272 data += cmd_len;
3273 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003274 }
3275
3276 kfree_skb(skb);
3277}
3278
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003279static int l2cap_check_fcs(struct l2cap_pinfo *pi, struct sk_buff *skb)
3280{
3281 u16 our_fcs, rcv_fcs;
3282 int hdr_size = L2CAP_HDR_SIZE + 2;
3283
3284 if (pi->fcs == L2CAP_FCS_CRC16) {
3285 skb_trim(skb, skb->len - 2);
3286 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
3287 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
3288
3289 if (our_fcs != rcv_fcs)
3290 return -EINVAL;
3291 }
3292 return 0;
3293}
3294
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003295static inline void l2cap_send_i_or_rr_or_rnr(struct sock *sk)
3296{
3297 struct l2cap_pinfo *pi = l2cap_pi(sk);
3298 u16 control = 0;
3299
3300 pi->frames_sent = 0;
3301 pi->conn_state |= L2CAP_CONN_SEND_FBIT;
3302
3303 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3304
3305 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
3306 control |= L2CAP_SUPER_RCV_NOT_READY | L2CAP_CTRL_FINAL;
3307 l2cap_send_sframe(pi, control);
3308 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
3309 }
3310
3311 if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY && pi->unacked_frames > 0)
3312 __mod_retrans_timer();
3313
3314 l2cap_ertm_send(sk);
3315
3316 if (!(pi->conn_state & L2CAP_CONN_LOCAL_BUSY) &&
3317 pi->frames_sent == 0) {
3318 control |= L2CAP_SUPER_RCV_READY;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003319 l2cap_send_sframe(pi, control);
3320 }
3321}
3322
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003323static void l2cap_add_to_srej_queue(struct sock *sk, struct sk_buff *skb, u8 tx_seq, u8 sar)
3324{
3325 struct sk_buff *next_skb;
3326
3327 bt_cb(skb)->tx_seq = tx_seq;
3328 bt_cb(skb)->sar = sar;
3329
3330 next_skb = skb_peek(SREJ_QUEUE(sk));
3331 if (!next_skb) {
3332 __skb_queue_tail(SREJ_QUEUE(sk), skb);
3333 return;
3334 }
3335
3336 do {
3337 if (bt_cb(next_skb)->tx_seq > tx_seq) {
3338 __skb_queue_before(SREJ_QUEUE(sk), next_skb, skb);
3339 return;
3340 }
3341
3342 if (skb_queue_is_last(SREJ_QUEUE(sk), next_skb))
3343 break;
3344
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003345 } while ((next_skb = skb_queue_next(SREJ_QUEUE(sk), next_skb)));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003346
3347 __skb_queue_tail(SREJ_QUEUE(sk), skb);
3348}
3349
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003350static int l2cap_sar_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
3351{
3352 struct l2cap_pinfo *pi = l2cap_pi(sk);
3353 struct sk_buff *_skb;
3354 int err = -EINVAL;
3355
3356 switch (control & L2CAP_CTRL_SAR) {
3357 case L2CAP_SDU_UNSEGMENTED:
3358 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3359 kfree_skb(pi->sdu);
3360 break;
3361 }
3362
3363 err = sock_queue_rcv_skb(sk, skb);
3364 if (!err)
3365 return 0;
3366
3367 break;
3368
3369 case L2CAP_SDU_START:
3370 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3371 kfree_skb(pi->sdu);
3372 break;
3373 }
3374
3375 pi->sdu_len = get_unaligned_le16(skb->data);
3376 skb_pull(skb, 2);
3377
Gustavo F. Padovan052897c2010-05-01 16:15:40 -03003378 if (pi->sdu_len > pi->imtu) {
3379 err = -EMSGSIZE;
3380 break;
3381 }
3382
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003383 pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
3384 if (!pi->sdu) {
3385 err = -ENOMEM;
3386 break;
3387 }
3388
3389 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3390
3391 pi->conn_state |= L2CAP_CONN_SAR_SDU;
3392 pi->partial_sdu_len = skb->len;
3393 err = 0;
3394 break;
3395
3396 case L2CAP_SDU_CONTINUE:
3397 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3398 break;
3399
3400 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3401
3402 pi->partial_sdu_len += skb->len;
3403 if (pi->partial_sdu_len > pi->sdu_len)
3404 kfree_skb(pi->sdu);
3405 else
3406 err = 0;
3407
3408 break;
3409
3410 case L2CAP_SDU_END:
3411 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3412 break;
3413
3414 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3415
3416 pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
3417 pi->partial_sdu_len += skb->len;
3418
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003419 if (pi->partial_sdu_len > pi->imtu)
3420 goto drop;
3421
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003422 if (pi->partial_sdu_len == pi->sdu_len) {
3423 _skb = skb_clone(pi->sdu, GFP_ATOMIC);
3424 err = sock_queue_rcv_skb(sk, _skb);
3425 if (err < 0)
3426 kfree_skb(_skb);
3427 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003428 err = 0;
3429
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003430drop:
3431 kfree_skb(pi->sdu);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003432 break;
3433 }
3434
3435 kfree_skb(skb);
3436 return err;
3437}
3438
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003439static void l2cap_check_srej_gap(struct sock *sk, u8 tx_seq)
3440{
3441 struct sk_buff *skb;
Gustavo F. Padovanafefdbc2010-05-01 16:15:43 -03003442 u16 control;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003443
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003444 while ((skb = skb_peek(SREJ_QUEUE(sk)))) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003445 if (bt_cb(skb)->tx_seq != tx_seq)
3446 break;
3447
3448 skb = skb_dequeue(SREJ_QUEUE(sk));
Gustavo F. Padovanafefdbc2010-05-01 16:15:43 -03003449 control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003450 l2cap_sar_reassembly_sdu(sk, skb, control);
3451 l2cap_pi(sk)->buffer_seq_srej =
3452 (l2cap_pi(sk)->buffer_seq_srej + 1) % 64;
3453 tx_seq++;
3454 }
3455}
3456
3457static void l2cap_resend_srejframe(struct sock *sk, u8 tx_seq)
3458{
3459 struct l2cap_pinfo *pi = l2cap_pi(sk);
3460 struct srej_list *l, *tmp;
3461 u16 control;
3462
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003463 list_for_each_entry_safe(l, tmp, SREJ_LIST(sk), list) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003464 if (l->tx_seq == tx_seq) {
3465 list_del(&l->list);
3466 kfree(l);
3467 return;
3468 }
3469 control = L2CAP_SUPER_SELECT_REJECT;
3470 control |= l->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3471 l2cap_send_sframe(pi, control);
3472 list_del(&l->list);
3473 list_add_tail(&l->list, SREJ_LIST(sk));
3474 }
3475}
3476
3477static void l2cap_send_srejframe(struct sock *sk, u8 tx_seq)
3478{
3479 struct l2cap_pinfo *pi = l2cap_pi(sk);
3480 struct srej_list *new;
3481 u16 control;
3482
3483 while (tx_seq != pi->expected_tx_seq) {
3484 control = L2CAP_SUPER_SELECT_REJECT;
3485 control |= pi->expected_tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3486 l2cap_send_sframe(pi, control);
3487
3488 new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC);
3489 new->tx_seq = pi->expected_tx_seq++;
3490 list_add_tail(&new->list, SREJ_LIST(sk));
3491 }
3492 pi->expected_tx_seq++;
3493}
3494
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003495static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
3496{
3497 struct l2cap_pinfo *pi = l2cap_pi(sk);
3498 u8 tx_seq = __get_txseq(rx_control);
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003499 u8 req_seq = __get_reqseq(rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003500 u8 sar = rx_control >> L2CAP_CTRL_SAR_SHIFT;
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03003501 int num_to_ack = (pi->tx_win/6) + 1;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003502 int err = 0;
3503
3504 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
3505
Gustavo F. Padovan9b16dc62010-05-05 20:05:57 -03003506 if (L2CAP_CTRL_FINAL & rx_control &&
3507 l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) {
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003508 del_timer(&pi->monitor_timer);
3509 if (pi->unacked_frames > 0)
3510 __mod_retrans_timer();
3511 pi->conn_state &= ~L2CAP_CONN_WAIT_F;
3512 }
3513
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003514 pi->expected_ack_seq = req_seq;
3515 l2cap_drop_acked_frames(sk);
3516
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003517 if (tx_seq == pi->expected_tx_seq)
3518 goto expected;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003519
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003520 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3521 struct srej_list *first;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003522
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003523 first = list_first_entry(SREJ_LIST(sk),
3524 struct srej_list, list);
3525 if (tx_seq == first->tx_seq) {
3526 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3527 l2cap_check_srej_gap(sk, tx_seq);
3528
3529 list_del(&first->list);
3530 kfree(first);
3531
3532 if (list_empty(SREJ_LIST(sk))) {
3533 pi->buffer_seq = pi->buffer_seq_srej;
3534 pi->conn_state &= ~L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan855666cc2010-05-01 16:15:40 -03003535 l2cap_send_ack(pi);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003536 }
3537 } else {
3538 struct srej_list *l;
3539 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3540
3541 list_for_each_entry(l, SREJ_LIST(sk), list) {
3542 if (l->tx_seq == tx_seq) {
3543 l2cap_resend_srejframe(sk, tx_seq);
3544 return 0;
3545 }
3546 }
3547 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003548 }
3549 } else {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003550 pi->conn_state |= L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003551
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003552 INIT_LIST_HEAD(SREJ_LIST(sk));
3553 pi->buffer_seq_srej = pi->buffer_seq;
3554
3555 __skb_queue_head_init(SREJ_QUEUE(sk));
3556 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3557
Gustavo F. Padovanef54fd92009-08-20 22:26:04 -03003558 pi->conn_state |= L2CAP_CONN_SEND_PBIT;
3559
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003560 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003561 }
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003562 return 0;
3563
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003564expected:
3565 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
3566
3567 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
Gustavo F. Padovan3b1a9f32010-05-01 16:15:42 -03003568 bt_cb(skb)->tx_seq = tx_seq;
3569 bt_cb(skb)->sar = sar;
3570 __skb_queue_tail(SREJ_QUEUE(sk), skb);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003571 return 0;
3572 }
3573
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03003574 if (rx_control & L2CAP_CTRL_FINAL) {
3575 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3576 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
3577 else {
Gustavo F. Padovanf6e6b162010-05-01 16:15:41 -03003578 if (!skb_queue_empty(TX_QUEUE(sk)))
3579 sk->sk_send_head = TX_QUEUE(sk)->next;
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03003580 pi->next_tx_seq = pi->expected_ack_seq;
3581 l2cap_ertm_send(sk);
3582 }
3583 }
3584
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003585 pi->buffer_seq = (pi->buffer_seq + 1) % 64;
3586
3587 err = l2cap_sar_reassembly_sdu(sk, skb, rx_control);
3588 if (err < 0)
3589 return err;
3590
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003591 __mod_ack_timer();
3592
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03003593 pi->num_acked = (pi->num_acked + 1) % num_to_ack;
3594 if (pi->num_acked == num_to_ack - 1)
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03003595 l2cap_send_ack(pi);
3596
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003597 return 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003598}
3599
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003600static inline void l2cap_data_channel_rrframe(struct sock *sk, u16 rx_control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003601{
3602 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan6e3a5982010-05-01 16:15:38 -03003603
3604 pi->expected_ack_seq = __get_reqseq(rx_control);
3605 l2cap_drop_acked_frames(sk);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003606
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003607 if (rx_control & L2CAP_CTRL_POLL) {
Gustavo F. Padovan05fbd892010-05-01 16:15:39 -03003608 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3609 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
3610 (pi->unacked_frames > 0))
3611 __mod_retrans_timer();
3612
3613 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3614 l2cap_send_srejtail(sk);
3615 } else {
3616 l2cap_send_i_or_rr_or_rnr(sk);
3617 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3618 }
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003619
3620 } else if (rx_control & L2CAP_CTRL_FINAL) {
3621 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003622
3623 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3624 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
3625 else {
Gustavo F. Padovanf6e6b162010-05-01 16:15:41 -03003626 if (!skb_queue_empty(TX_QUEUE(sk)))
3627 sk->sk_send_head = TX_QUEUE(sk)->next;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003628 pi->next_tx_seq = pi->expected_ack_seq;
3629 l2cap_ertm_send(sk);
3630 }
3631
3632 } else {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003633 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
3634 (pi->unacked_frames > 0))
3635 __mod_retrans_timer();
3636
3637 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3638 if (pi->conn_state & L2CAP_CONN_SREJ_SENT)
3639 l2cap_send_ack(pi);
3640 else
3641 l2cap_ertm_send(sk);
3642 }
3643}
3644
3645static inline void l2cap_data_channel_rejframe(struct sock *sk, u16 rx_control)
3646{
3647 struct l2cap_pinfo *pi = l2cap_pi(sk);
3648 u8 tx_seq = __get_reqseq(rx_control);
3649
3650 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3651
Gustavo F. Padovan8abb52e2010-05-01 16:15:38 -03003652 pi->expected_ack_seq = tx_seq;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003653 l2cap_drop_acked_frames(sk);
3654
3655 if (rx_control & L2CAP_CTRL_FINAL) {
3656 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3657 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
3658 else {
Gustavo F. Padovanf6e6b162010-05-01 16:15:41 -03003659 if (!skb_queue_empty(TX_QUEUE(sk)))
3660 sk->sk_send_head = TX_QUEUE(sk)->next;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003661 pi->next_tx_seq = pi->expected_ack_seq;
3662 l2cap_ertm_send(sk);
3663 }
3664 } else {
Gustavo F. Padovanf6e6b162010-05-01 16:15:41 -03003665 if (!skb_queue_empty(TX_QUEUE(sk)))
3666 sk->sk_send_head = TX_QUEUE(sk)->next;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003667 pi->next_tx_seq = pi->expected_ack_seq;
3668 l2cap_ertm_send(sk);
3669
Gustavo F. Padovan0301ef02010-05-05 20:56:43 -03003670 if (pi->conn_state & L2CAP_CONN_WAIT_F)
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003671 pi->conn_state |= L2CAP_CONN_REJ_ACT;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003672 }
3673}
3674static inline void l2cap_data_channel_srejframe(struct sock *sk, u16 rx_control)
3675{
3676 struct l2cap_pinfo *pi = l2cap_pi(sk);
3677 u8 tx_seq = __get_reqseq(rx_control);
3678
3679 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3680
3681 if (rx_control & L2CAP_CTRL_POLL) {
3682 pi->expected_ack_seq = tx_seq;
3683 l2cap_drop_acked_frames(sk);
3684 l2cap_retransmit_frame(sk, tx_seq);
3685 l2cap_ertm_send(sk);
3686 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
3687 pi->srej_save_reqseq = tx_seq;
3688 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
3689 }
3690 } else if (rx_control & L2CAP_CTRL_FINAL) {
3691 if ((pi->conn_state & L2CAP_CONN_SREJ_ACT) &&
3692 pi->srej_save_reqseq == tx_seq)
3693 pi->conn_state &= ~L2CAP_CONN_SREJ_ACT;
3694 else
3695 l2cap_retransmit_frame(sk, tx_seq);
3696 } else {
3697 l2cap_retransmit_frame(sk, tx_seq);
3698 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
3699 pi->srej_save_reqseq = tx_seq;
3700 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
3701 }
3702 }
3703}
3704
3705static inline void l2cap_data_channel_rnrframe(struct sock *sk, u16 rx_control)
3706{
3707 struct l2cap_pinfo *pi = l2cap_pi(sk);
3708 u8 tx_seq = __get_reqseq(rx_control);
3709
3710 pi->conn_state |= L2CAP_CONN_REMOTE_BUSY;
3711 pi->expected_ack_seq = tx_seq;
3712 l2cap_drop_acked_frames(sk);
3713
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03003714 if (!(pi->conn_state & L2CAP_CONN_SREJ_SENT)) {
3715 del_timer(&pi->retrans_timer);
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -03003716 if (rx_control & L2CAP_CTRL_POLL)
3717 l2cap_send_rr_or_rnr(pi, L2CAP_CTRL_FINAL);
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03003718 return;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003719 }
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03003720
3721 if (rx_control & L2CAP_CTRL_POLL)
3722 l2cap_send_srejtail(sk);
3723 else
3724 l2cap_send_sframe(pi, L2CAP_SUPER_RCV_READY);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003725}
3726
3727static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
3728{
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003729 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
3730
Gustavo F. Padovan9b16dc62010-05-05 20:05:57 -03003731 if (L2CAP_CTRL_FINAL & rx_control &&
3732 l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003733 del_timer(&l2cap_pi(sk)->monitor_timer);
3734 if (l2cap_pi(sk)->unacked_frames > 0)
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003735 __mod_retrans_timer();
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003736 l2cap_pi(sk)->conn_state &= ~L2CAP_CONN_WAIT_F;
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003737 }
3738
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003739 switch (rx_control & L2CAP_CTRL_SUPERVISE) {
3740 case L2CAP_SUPER_RCV_READY:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003741 l2cap_data_channel_rrframe(sk, rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003742 break;
3743
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003744 case L2CAP_SUPER_REJECT:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003745 l2cap_data_channel_rejframe(sk, rx_control);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003746 break;
3747
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003748 case L2CAP_SUPER_SELECT_REJECT:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003749 l2cap_data_channel_srejframe(sk, rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003750 break;
3751
3752 case L2CAP_SUPER_RCV_NOT_READY:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003753 l2cap_data_channel_rnrframe(sk, rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003754 break;
3755 }
3756
Gustavo F. Padovanfaaebd12010-05-01 16:15:35 -03003757 kfree_skb(skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003758 return 0;
3759}
3760
Linus Torvalds1da177e2005-04-16 15:20:36 -07003761static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk_buff *skb)
3762{
3763 struct sock *sk;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003764 struct l2cap_pinfo *pi;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003765 u16 control, len;
João Paulo Rechi Vita01760bd2010-05-01 16:15:43 -03003766 u8 tx_seq, req_seq, next_tx_seq_offset, req_seq_offset;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003767
3768 sk = l2cap_get_chan_by_scid(&conn->chan_list, cid);
3769 if (!sk) {
3770 BT_DBG("unknown cid 0x%4.4x", cid);
3771 goto drop;
3772 }
3773
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003774 pi = l2cap_pi(sk);
3775
Linus Torvalds1da177e2005-04-16 15:20:36 -07003776 BT_DBG("sk %p, len %d", sk, skb->len);
3777
3778 if (sk->sk_state != BT_CONNECTED)
3779 goto drop;
3780
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003781 switch (pi->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003782 case L2CAP_MODE_BASIC:
3783 /* If socket recv buffers overflows we drop data here
3784 * which is *bad* because L2CAP has to be reliable.
3785 * But we don't have any other choice. L2CAP doesn't
3786 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003787
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003788 if (pi->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003789 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003790
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003791 if (!sock_queue_rcv_skb(sk, skb))
3792 goto done;
3793 break;
3794
3795 case L2CAP_MODE_ERTM:
3796 control = get_unaligned_le16(skb->data);
3797 skb_pull(skb, 2);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003798 len = skb->len;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003799
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003800 if (__is_sar_start(control))
3801 len -= 2;
3802
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003803 if (pi->fcs == L2CAP_FCS_CRC16)
3804 len -= 2;
3805
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003806 /*
3807 * We can just drop the corrupted I-frame here.
3808 * Receiver will miss it and start proper recovery
3809 * procedures and ask retransmission.
3810 */
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03003811 if (len > pi->mps)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003812 goto drop;
3813
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003814 if (l2cap_check_fcs(pi, skb))
3815 goto drop;
3816
João Paulo Rechi Vita01760bd2010-05-01 16:15:43 -03003817 req_seq = __get_reqseq(control);
3818 req_seq_offset = (req_seq - pi->expected_ack_seq) % 64;
3819 if (req_seq_offset < 0)
3820 req_seq_offset += 64;
3821
3822 next_tx_seq_offset =
3823 (pi->next_tx_seq - pi->expected_ack_seq) % 64;
3824 if (next_tx_seq_offset < 0)
3825 next_tx_seq_offset += 64;
3826
3827 /* check for invalid req-seq */
3828 if (req_seq_offset > next_tx_seq_offset) {
3829 l2cap_send_disconn_req(pi->conn, sk);
3830 goto drop;
3831 }
3832
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03003833 if (__is_iframe(control)) {
3834 if (len < 4)
3835 goto drop;
3836
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02003837 l2cap_data_channel_iframe(sk, control, skb);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03003838 } else {
3839 if (len != 0)
3840 goto drop;
3841
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02003842 l2cap_data_channel_sframe(sk, control, skb);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03003843 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003844
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02003845 goto done;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003846
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003847 case L2CAP_MODE_STREAMING:
3848 control = get_unaligned_le16(skb->data);
3849 skb_pull(skb, 2);
3850 len = skb->len;
3851
3852 if (__is_sar_start(control))
3853 len -= 2;
3854
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003855 if (pi->fcs == L2CAP_FCS_CRC16)
3856 len -= 2;
3857
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03003858 if (len > pi->mps || len < 4 || __is_sframe(control))
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003859 goto drop;
3860
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003861 if (l2cap_check_fcs(pi, skb))
3862 goto drop;
3863
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003864 tx_seq = __get_txseq(control);
3865
3866 if (pi->expected_tx_seq == tx_seq)
3867 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
3868 else
Gustavo F. Padovan7dffe422010-05-01 16:15:36 -03003869 pi->expected_tx_seq = (tx_seq + 1) % 64;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003870
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02003871 l2cap_sar_reassembly_sdu(sk, skb, control);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003872
3873 goto done;
3874
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003875 default:
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03003876 BT_DBG("sk %p: bad mode 0x%2.2x", sk, pi->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003877 break;
3878 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003879
3880drop:
3881 kfree_skb(skb);
3882
3883done:
Marcel Holtmann01394182006-07-03 10:02:46 +02003884 if (sk)
3885 bh_unlock_sock(sk);
3886
Linus Torvalds1da177e2005-04-16 15:20:36 -07003887 return 0;
3888}
3889
Al Viro8e036fc2007-07-29 00:16:36 -07003890static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003891{
3892 struct sock *sk;
3893
3894 sk = l2cap_get_sock_by_psm(0, psm, conn->src);
3895 if (!sk)
3896 goto drop;
3897
3898 BT_DBG("sk %p, len %d", sk, skb->len);
3899
3900 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_CONNECTED)
3901 goto drop;
3902
3903 if (l2cap_pi(sk)->imtu < skb->len)
3904 goto drop;
3905
3906 if (!sock_queue_rcv_skb(sk, skb))
3907 goto done;
3908
3909drop:
3910 kfree_skb(skb);
3911
3912done:
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003913 if (sk)
3914 bh_unlock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003915 return 0;
3916}
3917
3918static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
3919{
3920 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07003921 u16 cid, len;
3922 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003923
3924 skb_pull(skb, L2CAP_HDR_SIZE);
3925 cid = __le16_to_cpu(lh->cid);
3926 len = __le16_to_cpu(lh->len);
3927
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003928 if (len != skb->len) {
3929 kfree_skb(skb);
3930 return;
3931 }
3932
Linus Torvalds1da177e2005-04-16 15:20:36 -07003933 BT_DBG("len %d, cid 0x%4.4x", len, cid);
3934
3935 switch (cid) {
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03003936 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07003937 l2cap_sig_channel(conn, skb);
3938 break;
3939
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03003940 case L2CAP_CID_CONN_LESS:
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03003941 psm = get_unaligned_le16(skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003942 skb_pull(skb, 2);
3943 l2cap_conless_channel(conn, psm, skb);
3944 break;
3945
3946 default:
3947 l2cap_data_channel(conn, cid, skb);
3948 break;
3949 }
3950}
3951
3952/* ---- L2CAP interface with lower layer (HCI) ---- */
3953
3954static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
3955{
3956 int exact = 0, lm1 = 0, lm2 = 0;
3957 register struct sock *sk;
3958 struct hlist_node *node;
3959
3960 if (type != ACL_LINK)
3961 return 0;
3962
3963 BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
3964
3965 /* Find listening sockets and check their link_mode */
3966 read_lock(&l2cap_sk_list.lock);
3967 sk_for_each(sk, node, &l2cap_sk_list.head) {
3968 if (sk->sk_state != BT_LISTEN)
3969 continue;
3970
3971 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01003972 lm1 |= HCI_LM_ACCEPT;
3973 if (l2cap_pi(sk)->role_switch)
3974 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003975 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01003976 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
3977 lm2 |= HCI_LM_ACCEPT;
3978 if (l2cap_pi(sk)->role_switch)
3979 lm2 |= HCI_LM_MASTER;
3980 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003981 }
3982 read_unlock(&l2cap_sk_list.lock);
3983
3984 return exact ? lm1 : lm2;
3985}
3986
3987static int l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
3988{
Marcel Holtmann01394182006-07-03 10:02:46 +02003989 struct l2cap_conn *conn;
3990
Linus Torvalds1da177e2005-04-16 15:20:36 -07003991 BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
3992
3993 if (hcon->type != ACL_LINK)
3994 return 0;
3995
3996 if (!status) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003997 conn = l2cap_conn_add(hcon, status);
3998 if (conn)
3999 l2cap_conn_ready(conn);
Marcel Holtmann01394182006-07-03 10:02:46 +02004000 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -07004001 l2cap_conn_del(hcon, bt_err(status));
4002
4003 return 0;
4004}
4005
Marcel Holtmann2950f212009-02-12 14:02:50 +01004006static int l2cap_disconn_ind(struct hci_conn *hcon)
4007{
4008 struct l2cap_conn *conn = hcon->l2cap_data;
4009
4010 BT_DBG("hcon %p", hcon);
4011
4012 if (hcon->type != ACL_LINK || !conn)
4013 return 0x13;
4014
4015 return conn->disc_reason;
4016}
4017
4018static int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004019{
4020 BT_DBG("hcon %p reason %d", hcon, reason);
4021
4022 if (hcon->type != ACL_LINK)
4023 return 0;
4024
4025 l2cap_conn_del(hcon, bt_err(reason));
Marcel Holtmann01394182006-07-03 10:02:46 +02004026
Linus Torvalds1da177e2005-04-16 15:20:36 -07004027 return 0;
4028}
4029
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004030static inline void l2cap_check_encryption(struct sock *sk, u8 encrypt)
4031{
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03004032 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM)
Marcel Holtmann255c7602009-02-04 21:07:19 +01004033 return;
4034
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004035 if (encrypt == 0x00) {
4036 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM) {
4037 l2cap_sock_clear_timer(sk);
4038 l2cap_sock_set_timer(sk, HZ * 5);
4039 } else if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
4040 __l2cap_sock_close(sk, ECONNREFUSED);
4041 } else {
4042 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM)
4043 l2cap_sock_clear_timer(sk);
4044 }
4045}
4046
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004047static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004048{
4049 struct l2cap_chan_list *l;
Marcel Holtmann40be4922008-07-14 20:13:50 +02004050 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004051 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004052
Marcel Holtmann01394182006-07-03 10:02:46 +02004053 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004054 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02004055
Linus Torvalds1da177e2005-04-16 15:20:36 -07004056 l = &conn->chan_list;
4057
4058 BT_DBG("conn %p", conn);
4059
4060 read_lock(&l->lock);
4061
4062 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
4063 bh_lock_sock(sk);
4064
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01004065 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND) {
4066 bh_unlock_sock(sk);
4067 continue;
4068 }
4069
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004070 if (!status && (sk->sk_state == BT_CONNECTED ||
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004071 sk->sk_state == BT_CONFIG)) {
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004072 l2cap_check_encryption(sk, encrypt);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02004073 bh_unlock_sock(sk);
4074 continue;
4075 }
4076
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004077 if (sk->sk_state == BT_CONNECT) {
4078 if (!status) {
4079 struct l2cap_conn_req req;
4080 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
4081 req.psm = l2cap_pi(sk)->psm;
4082
4083 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
4084
4085 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
4086 L2CAP_CONN_REQ, sizeof(req), &req);
4087 } else {
4088 l2cap_sock_clear_timer(sk);
4089 l2cap_sock_set_timer(sk, HZ / 10);
4090 }
4091 } else if (sk->sk_state == BT_CONNECT2) {
4092 struct l2cap_conn_rsp rsp;
4093 __u16 result;
4094
4095 if (!status) {
4096 sk->sk_state = BT_CONFIG;
4097 result = L2CAP_CR_SUCCESS;
4098 } else {
4099 sk->sk_state = BT_DISCONN;
4100 l2cap_sock_set_timer(sk, HZ / 10);
4101 result = L2CAP_CR_SEC_BLOCK;
4102 }
4103
4104 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
4105 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
4106 rsp.result = cpu_to_le16(result);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02004107 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004108 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
4109 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004110 }
4111
Linus Torvalds1da177e2005-04-16 15:20:36 -07004112 bh_unlock_sock(sk);
4113 }
4114
4115 read_unlock(&l->lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004116
Linus Torvalds1da177e2005-04-16 15:20:36 -07004117 return 0;
4118}
4119
4120static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
4121{
4122 struct l2cap_conn *conn = hcon->l2cap_data;
4123
4124 if (!conn && !(conn = l2cap_conn_add(hcon, 0)))
4125 goto drop;
4126
4127 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
4128
4129 if (flags & ACL_START) {
4130 struct l2cap_hdr *hdr;
4131 int len;
4132
4133 if (conn->rx_len) {
4134 BT_ERR("Unexpected start frame (len %d)", skb->len);
4135 kfree_skb(conn->rx_skb);
4136 conn->rx_skb = NULL;
4137 conn->rx_len = 0;
4138 l2cap_conn_unreliable(conn, ECOMM);
4139 }
4140
4141 if (skb->len < 2) {
4142 BT_ERR("Frame is too short (len %d)", skb->len);
4143 l2cap_conn_unreliable(conn, ECOMM);
4144 goto drop;
4145 }
4146
4147 hdr = (struct l2cap_hdr *) skb->data;
4148 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
4149
4150 if (len == skb->len) {
4151 /* Complete frame received */
4152 l2cap_recv_frame(conn, skb);
4153 return 0;
4154 }
4155
4156 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
4157
4158 if (skb->len > len) {
4159 BT_ERR("Frame is too long (len %d, expected len %d)",
4160 skb->len, len);
4161 l2cap_conn_unreliable(conn, ECOMM);
4162 goto drop;
4163 }
4164
4165 /* Allocate skb for the complete frame (with header) */
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03004166 conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC);
4167 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004168 goto drop;
4169
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03004170 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004171 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004172 conn->rx_len = len - skb->len;
4173 } else {
4174 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
4175
4176 if (!conn->rx_len) {
4177 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
4178 l2cap_conn_unreliable(conn, ECOMM);
4179 goto drop;
4180 }
4181
4182 if (skb->len > conn->rx_len) {
4183 BT_ERR("Fragment is too long (len %d, expected %d)",
4184 skb->len, conn->rx_len);
4185 kfree_skb(conn->rx_skb);
4186 conn->rx_skb = NULL;
4187 conn->rx_len = 0;
4188 l2cap_conn_unreliable(conn, ECOMM);
4189 goto drop;
4190 }
4191
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03004192 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004193 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004194 conn->rx_len -= skb->len;
4195
4196 if (!conn->rx_len) {
4197 /* Complete frame received */
4198 l2cap_recv_frame(conn, conn->rx_skb);
4199 conn->rx_skb = NULL;
4200 }
4201 }
4202
4203drop:
4204 kfree_skb(skb);
4205 return 0;
4206}
4207
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004208static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004209{
4210 struct sock *sk;
4211 struct hlist_node *node;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004212
4213 read_lock_bh(&l2cap_sk_list.lock);
4214
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004215 sk_for_each(sk, node, &l2cap_sk_list.head) {
4216 struct l2cap_pinfo *pi = l2cap_pi(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004217
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004218 seq_printf(f, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d\n",
4219 batostr(&bt_sk(sk)->src),
4220 batostr(&bt_sk(sk)->dst),
4221 sk->sk_state, __le16_to_cpu(pi->psm),
4222 pi->scid, pi->dcid,
4223 pi->imtu, pi->omtu, pi->sec_level);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004224 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004225
Linus Torvalds1da177e2005-04-16 15:20:36 -07004226 read_unlock_bh(&l2cap_sk_list.lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004227
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004228 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004229}
4230
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004231static int l2cap_debugfs_open(struct inode *inode, struct file *file)
4232{
4233 return single_open(file, l2cap_debugfs_show, inode->i_private);
4234}
4235
4236static const struct file_operations l2cap_debugfs_fops = {
4237 .open = l2cap_debugfs_open,
4238 .read = seq_read,
4239 .llseek = seq_lseek,
4240 .release = single_release,
4241};
4242
4243static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004244
Eric Dumazet90ddc4f2005-12-22 12:49:22 -08004245static const struct proto_ops l2cap_sock_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004246 .family = PF_BLUETOOTH,
4247 .owner = THIS_MODULE,
4248 .release = l2cap_sock_release,
4249 .bind = l2cap_sock_bind,
4250 .connect = l2cap_sock_connect,
4251 .listen = l2cap_sock_listen,
4252 .accept = l2cap_sock_accept,
4253 .getname = l2cap_sock_getname,
4254 .sendmsg = l2cap_sock_sendmsg,
Marcel Holtmannf66dc812009-01-15 21:57:00 +01004255 .recvmsg = l2cap_sock_recvmsg,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004256 .poll = bt_sock_poll,
Marcel Holtmann3241ad82008-07-14 20:13:50 +02004257 .ioctl = bt_sock_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004258 .mmap = sock_no_mmap,
4259 .socketpair = sock_no_socketpair,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004260 .shutdown = l2cap_sock_shutdown,
4261 .setsockopt = l2cap_sock_setsockopt,
4262 .getsockopt = l2cap_sock_getsockopt
4263};
4264
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +00004265static const struct net_proto_family l2cap_sock_family_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004266 .family = PF_BLUETOOTH,
4267 .owner = THIS_MODULE,
4268 .create = l2cap_sock_create,
4269};
4270
4271static struct hci_proto l2cap_hci_proto = {
4272 .name = "L2CAP",
4273 .id = HCI_PROTO_L2CAP,
4274 .connect_ind = l2cap_connect_ind,
4275 .connect_cfm = l2cap_connect_cfm,
4276 .disconn_ind = l2cap_disconn_ind,
Marcel Holtmann2950f212009-02-12 14:02:50 +01004277 .disconn_cfm = l2cap_disconn_cfm,
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004278 .security_cfm = l2cap_security_cfm,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004279 .recv_acldata = l2cap_recv_acldata
4280};
4281
4282static int __init l2cap_init(void)
4283{
4284 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004285
Linus Torvalds1da177e2005-04-16 15:20:36 -07004286 err = proto_register(&l2cap_proto, 0);
4287 if (err < 0)
4288 return err;
4289
4290 err = bt_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops);
4291 if (err < 0) {
4292 BT_ERR("L2CAP socket registration failed");
4293 goto error;
4294 }
4295
4296 err = hci_register_proto(&l2cap_hci_proto);
4297 if (err < 0) {
4298 BT_ERR("L2CAP protocol registration failed");
4299 bt_sock_unregister(BTPROTO_L2CAP);
4300 goto error;
4301 }
4302
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004303 if (bt_debugfs) {
4304 l2cap_debugfs = debugfs_create_file("l2cap", 0444,
4305 bt_debugfs, NULL, &l2cap_debugfs_fops);
4306 if (!l2cap_debugfs)
4307 BT_ERR("Failed to create L2CAP debug file");
4308 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004309
4310 BT_INFO("L2CAP ver %s", VERSION);
4311 BT_INFO("L2CAP socket layer initialized");
4312
4313 return 0;
4314
4315error:
4316 proto_unregister(&l2cap_proto);
4317 return err;
4318}
4319
4320static void __exit l2cap_exit(void)
4321{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004322 debugfs_remove(l2cap_debugfs);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004323
4324 if (bt_sock_unregister(BTPROTO_L2CAP) < 0)
4325 BT_ERR("L2CAP socket unregistration failed");
4326
4327 if (hci_unregister_proto(&l2cap_hci_proto) < 0)
4328 BT_ERR("L2CAP protocol unregistration failed");
4329
4330 proto_unregister(&l2cap_proto);
4331}
4332
4333void l2cap_load(void)
4334{
4335 /* Dummy function to trigger automatic L2CAP module loading by
4336 * other modules that use L2CAP sockets but don't use any other
4337 * symbols from it. */
4338 return;
4339}
4340EXPORT_SYMBOL(l2cap_load);
4341
4342module_init(l2cap_init);
4343module_exit(l2cap_exit);
4344
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07004345module_param(enable_ertm, bool, 0644);
4346MODULE_PARM_DESC(enable_ertm, "Enable enhanced retransmission mode");
4347
Marcel Holtmann5fbcd3d2009-10-05 11:35:43 +02004348module_param(max_transmit, uint, 0644);
4349MODULE_PARM_DESC(max_transmit, "Max transmit value (default = 3)");
4350
Gustavo F. Padovan369ba302010-05-01 16:15:41 -03004351module_param(tx_window, uint, 0644);
4352MODULE_PARM_DESC(tx_window, "Transmission window size value (default = 63)");
4353
Marcel Holtmann63fbd242008-08-18 13:23:53 +02004354MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004355MODULE_DESCRIPTION("Bluetooth L2CAP ver " VERSION);
4356MODULE_VERSION(VERSION);
4357MODULE_LICENSE("GPL");
4358MODULE_ALIAS("bt-proto-0");