blob: cfb18cd9756437d55d8baec22c7ed2bc4fd36280 [file] [log] [blame]
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 BlueZ - Bluetooth protocol stack for Linux
3 Copyright (C) 2000-2001 Qualcomm Incorporated
4
5 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License version 2 as
9 published by the Free Software Foundation;
10
11 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
12 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
14 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090015 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
16 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Linus Torvalds1da177e2005-04-16 15:20:36 -070018 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090020 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
21 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
Linus Torvalds1da177e2005-04-16 15:20:36 -070022 SOFTWARE IS DISCLAIMED.
23*/
24
25/* Bluetooth L2CAP core and sockets. */
26
Linus Torvalds1da177e2005-04-16 15:20:36 -070027#include <linux/module.h>
28
29#include <linux/types.h>
Randy Dunlap4fc268d2006-01-11 12:17:47 -080030#include <linux/capability.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070031#include <linux/errno.h>
32#include <linux/kernel.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070033#include <linux/sched.h>
34#include <linux/slab.h>
35#include <linux/poll.h>
36#include <linux/fcntl.h>
37#include <linux/init.h>
38#include <linux/interrupt.h>
39#include <linux/socket.h>
40#include <linux/skbuff.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070041#include <linux/list.h>
Marcel Holtmannbe9d1222005-11-08 09:57:38 -080042#include <linux/device.h>
Marcel Holtmannaef7d972010-03-21 05:27:45 +010043#include <linux/debugfs.h>
44#include <linux/seq_file.h>
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -030045#include <linux/uaccess.h>
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -030046#include <linux/crc16.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070047#include <net/sock.h>
48
49#include <asm/system.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070050#include <asm/unaligned.h>
51
52#include <net/bluetooth/bluetooth.h>
53#include <net/bluetooth/hci_core.h>
54#include <net/bluetooth/l2cap.h>
55
Marcel Holtmann44dd46d2009-05-02 19:09:01 -070056#define VERSION "2.14"
57
Gustavo F. Padovan84fb0a62010-05-01 16:15:42 -030058#ifdef CONFIG_BT_L2CAP_EXT_FEATURES
59static int enable_ertm = 1;
60#else
Marcel Holtmann44dd46d2009-05-02 19:09:01 -070061static int enable_ertm = 0;
Gustavo F. Padovan84fb0a62010-05-01 16:15:42 -030062#endif
Marcel Holtmann5fbcd3d2009-10-05 11:35:43 +020063static int max_transmit = L2CAP_DEFAULT_MAX_TX;
Gustavo F. Padovan369ba302010-05-01 16:15:41 -030064static int tx_window = L2CAP_DEFAULT_TX_WINDOW;
Marcel Holtmannf0709e02007-10-20 13:38:51 +020065
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -070066static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN;
Marcel Holtmanne1027a72009-02-09 09:18:02 +010067static u8 l2cap_fixed_chan[8] = { 0x02, };
Linus Torvalds1da177e2005-04-16 15:20:36 -070068
Eric Dumazet90ddc4f2005-12-22 12:49:22 -080069static const struct proto_ops l2cap_sock_ops;
Linus Torvalds1da177e2005-04-16 15:20:36 -070070
71static struct bt_sock_list l2cap_sk_list = {
Robert P. J. Dayd5fb2962008-03-28 16:17:38 -070072 .lock = __RW_LOCK_UNLOCKED(l2cap_sk_list.lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -070073};
74
Linus Torvalds1da177e2005-04-16 15:20:36 -070075static void __l2cap_sock_close(struct sock *sk, int reason);
76static void l2cap_sock_close(struct sock *sk);
77static void l2cap_sock_kill(struct sock *sk);
78
79static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
80 u8 code, u8 ident, u16 dlen, void *data);
81
82/* ---- L2CAP timers ---- */
83static void l2cap_sock_timeout(unsigned long arg)
84{
85 struct sock *sk = (struct sock *) arg;
Marcel Holtmannb1235d72008-07-14 20:13:54 +020086 int reason;
Linus Torvalds1da177e2005-04-16 15:20:36 -070087
88 BT_DBG("sock %p state %d", sk, sk->sk_state);
89
90 bh_lock_sock(sk);
Marcel Holtmannb1235d72008-07-14 20:13:54 +020091
Marcel Holtmannf62e4322009-01-15 21:58:44 +010092 if (sk->sk_state == BT_CONNECTED || sk->sk_state == BT_CONFIG)
93 reason = ECONNREFUSED;
94 else if (sk->sk_state == BT_CONNECT &&
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +010095 l2cap_pi(sk)->sec_level != BT_SECURITY_SDP)
Marcel Holtmannb1235d72008-07-14 20:13:54 +020096 reason = ECONNREFUSED;
97 else
98 reason = ETIMEDOUT;
99
100 __l2cap_sock_close(sk, reason);
101
Linus Torvalds1da177e2005-04-16 15:20:36 -0700102 bh_unlock_sock(sk);
103
104 l2cap_sock_kill(sk);
105 sock_put(sk);
106}
107
108static void l2cap_sock_set_timer(struct sock *sk, long timeout)
109{
110 BT_DBG("sk %p state %d timeout %ld", sk, sk->sk_state, timeout);
111 sk_reset_timer(sk, &sk->sk_timer, jiffies + timeout);
112}
113
114static void l2cap_sock_clear_timer(struct sock *sk)
115{
116 BT_DBG("sock %p state %d", sk, sk->sk_state);
117 sk_stop_timer(sk, &sk->sk_timer);
118}
119
Marcel Holtmann01394182006-07-03 10:02:46 +0200120/* ---- L2CAP channels ---- */
121static struct sock *__l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, u16 cid)
122{
123 struct sock *s;
124 for (s = l->head; s; s = l2cap_pi(s)->next_c) {
125 if (l2cap_pi(s)->dcid == cid)
126 break;
127 }
128 return s;
129}
130
131static struct sock *__l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid)
132{
133 struct sock *s;
134 for (s = l->head; s; s = l2cap_pi(s)->next_c) {
135 if (l2cap_pi(s)->scid == cid)
136 break;
137 }
138 return s;
139}
140
141/* Find channel with given SCID.
142 * Returns locked socket */
143static inline struct sock *l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid)
144{
145 struct sock *s;
146 read_lock(&l->lock);
147 s = __l2cap_get_chan_by_scid(l, cid);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300148 if (s)
149 bh_lock_sock(s);
Marcel Holtmann01394182006-07-03 10:02:46 +0200150 read_unlock(&l->lock);
151 return s;
152}
153
154static struct sock *__l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 ident)
155{
156 struct sock *s;
157 for (s = l->head; s; s = l2cap_pi(s)->next_c) {
158 if (l2cap_pi(s)->ident == ident)
159 break;
160 }
161 return s;
162}
163
164static inline struct sock *l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 ident)
165{
166 struct sock *s;
167 read_lock(&l->lock);
168 s = __l2cap_get_chan_by_ident(l, ident);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300169 if (s)
170 bh_lock_sock(s);
Marcel Holtmann01394182006-07-03 10:02:46 +0200171 read_unlock(&l->lock);
172 return s;
173}
174
175static u16 l2cap_alloc_cid(struct l2cap_chan_list *l)
176{
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300177 u16 cid = L2CAP_CID_DYN_START;
Marcel Holtmann01394182006-07-03 10:02:46 +0200178
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300179 for (; cid < L2CAP_CID_DYN_END; cid++) {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300180 if (!__l2cap_get_chan_by_scid(l, cid))
Marcel Holtmann01394182006-07-03 10:02:46 +0200181 return cid;
182 }
183
184 return 0;
185}
186
187static inline void __l2cap_chan_link(struct l2cap_chan_list *l, struct sock *sk)
188{
189 sock_hold(sk);
190
191 if (l->head)
192 l2cap_pi(l->head)->prev_c = sk;
193
194 l2cap_pi(sk)->next_c = l->head;
195 l2cap_pi(sk)->prev_c = NULL;
196 l->head = sk;
197}
198
199static inline void l2cap_chan_unlink(struct l2cap_chan_list *l, struct sock *sk)
200{
201 struct sock *next = l2cap_pi(sk)->next_c, *prev = l2cap_pi(sk)->prev_c;
202
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200203 write_lock_bh(&l->lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200204 if (sk == l->head)
205 l->head = next;
206
207 if (next)
208 l2cap_pi(next)->prev_c = prev;
209 if (prev)
210 l2cap_pi(prev)->next_c = next;
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200211 write_unlock_bh(&l->lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200212
213 __sock_put(sk);
214}
215
216static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
217{
218 struct l2cap_chan_list *l = &conn->chan_list;
219
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300220 BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
221 l2cap_pi(sk)->psm, l2cap_pi(sk)->dcid);
Marcel Holtmann01394182006-07-03 10:02:46 +0200222
Marcel Holtmann2950f212009-02-12 14:02:50 +0100223 conn->disc_reason = 0x13;
224
Marcel Holtmann01394182006-07-03 10:02:46 +0200225 l2cap_pi(sk)->conn = conn;
226
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300227 if (sk->sk_type == SOCK_SEQPACKET || sk->sk_type == SOCK_STREAM) {
Marcel Holtmann01394182006-07-03 10:02:46 +0200228 /* Alloc CID for connection-oriented socket */
229 l2cap_pi(sk)->scid = l2cap_alloc_cid(l);
230 } else if (sk->sk_type == SOCK_DGRAM) {
231 /* Connectionless socket */
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300232 l2cap_pi(sk)->scid = L2CAP_CID_CONN_LESS;
233 l2cap_pi(sk)->dcid = L2CAP_CID_CONN_LESS;
Marcel Holtmann01394182006-07-03 10:02:46 +0200234 l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
235 } else {
236 /* Raw socket can send/recv signalling messages only */
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300237 l2cap_pi(sk)->scid = L2CAP_CID_SIGNALING;
238 l2cap_pi(sk)->dcid = L2CAP_CID_SIGNALING;
Marcel Holtmann01394182006-07-03 10:02:46 +0200239 l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
240 }
241
242 __l2cap_chan_link(l, sk);
243
244 if (parent)
245 bt_accept_enqueue(parent, sk);
246}
247
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900248/* Delete channel.
Marcel Holtmann01394182006-07-03 10:02:46 +0200249 * Must be called on the locked socket. */
250static void l2cap_chan_del(struct sock *sk, int err)
251{
252 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
253 struct sock *parent = bt_sk(sk)->parent;
254
255 l2cap_sock_clear_timer(sk);
256
257 BT_DBG("sk %p, conn %p, err %d", sk, conn, err);
258
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900259 if (conn) {
Marcel Holtmann01394182006-07-03 10:02:46 +0200260 /* Unlink from channel list */
261 l2cap_chan_unlink(&conn->chan_list, sk);
262 l2cap_pi(sk)->conn = NULL;
263 hci_conn_put(conn->hcon);
264 }
265
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200266 sk->sk_state = BT_CLOSED;
Marcel Holtmann01394182006-07-03 10:02:46 +0200267 sock_set_flag(sk, SOCK_ZAPPED);
268
269 if (err)
270 sk->sk_err = err;
271
272 if (parent) {
273 bt_accept_unlink(sk);
274 parent->sk_data_ready(parent, 0);
275 } else
276 sk->sk_state_change(sk);
277}
278
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200279/* Service level security */
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100280static inline int l2cap_check_security(struct sock *sk)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200281{
282 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100283 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200284
Marcel Holtmann00ae4af2009-02-12 16:19:45 +0100285 if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) {
286 if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
287 auth_type = HCI_AT_NO_BONDING_MITM;
288 else
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300289 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann00ae4af2009-02-12 16:19:45 +0100290
291 if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW)
292 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
293 } else {
294 switch (l2cap_pi(sk)->sec_level) {
295 case BT_SECURITY_HIGH:
296 auth_type = HCI_AT_GENERAL_BONDING_MITM;
297 break;
298 case BT_SECURITY_MEDIUM:
299 auth_type = HCI_AT_GENERAL_BONDING;
300 break;
301 default:
302 auth_type = HCI_AT_NO_BONDING;
303 break;
304 }
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100305 }
306
307 return hci_conn_security(conn->hcon, l2cap_pi(sk)->sec_level,
308 auth_type);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200309}
310
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200311static inline u8 l2cap_get_ident(struct l2cap_conn *conn)
312{
313 u8 id;
314
315 /* Get next available identificator.
316 * 1 - 128 are used by kernel.
317 * 129 - 199 are reserved.
318 * 200 - 254 are used by utilities like l2ping, etc.
319 */
320
321 spin_lock_bh(&conn->lock);
322
323 if (++conn->tx_ident > 128)
324 conn->tx_ident = 1;
325
326 id = conn->tx_ident;
327
328 spin_unlock_bh(&conn->lock);
329
330 return id;
331}
332
333static inline int l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data)
334{
335 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
336
337 BT_DBG("code 0x%2.2x", code);
338
339 if (!skb)
340 return -ENOMEM;
341
342 return hci_send_acl(conn->hcon, skb, 0);
343}
344
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300345static inline int l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control)
346{
347 struct sk_buff *skb;
348 struct l2cap_hdr *lh;
349 struct l2cap_conn *conn = pi->conn;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300350 int count, hlen = L2CAP_HDR_SIZE + 2;
351
352 if (pi->fcs == L2CAP_FCS_CRC16)
353 hlen += 2;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300354
355 BT_DBG("pi %p, control 0x%2.2x", pi, control);
356
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300357 count = min_t(unsigned int, conn->mtu, hlen);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300358 control |= L2CAP_CTRL_FRAME_TYPE;
359
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -0300360 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
361 control |= L2CAP_CTRL_FINAL;
362 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
363 }
364
Gustavo F. Padovanf0946cc2010-05-01 16:15:37 -0300365 if (pi->conn_state & L2CAP_CONN_SEND_PBIT) {
366 control |= L2CAP_CTRL_POLL;
367 pi->conn_state &= ~L2CAP_CONN_SEND_PBIT;
368 }
369
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300370 skb = bt_skb_alloc(count, GFP_ATOMIC);
371 if (!skb)
372 return -ENOMEM;
373
374 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300375 lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300376 lh->cid = cpu_to_le16(pi->dcid);
377 put_unaligned_le16(control, skb_put(skb, 2));
378
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300379 if (pi->fcs == L2CAP_FCS_CRC16) {
380 u16 fcs = crc16(0, (u8 *)lh, count - 2);
381 put_unaligned_le16(fcs, skb_put(skb, 2));
382 }
383
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300384 return hci_send_acl(pi->conn->hcon, skb, 0);
385}
386
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300387static inline int l2cap_send_rr_or_rnr(struct l2cap_pinfo *pi, u16 control)
388{
389 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY)
390 control |= L2CAP_SUPER_RCV_NOT_READY;
391 else
392 control |= L2CAP_SUPER_RCV_READY;
393
Gustavo F. Padovan2ab25cd2009-10-03 02:34:40 -0300394 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
395
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300396 return l2cap_send_sframe(pi, control);
397}
398
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200399static void l2cap_do_start(struct sock *sk)
400{
401 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
402
403 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +0100404 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
405 return;
406
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100407 if (l2cap_check_security(sk)) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200408 struct l2cap_conn_req req;
409 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
410 req.psm = l2cap_pi(sk)->psm;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200411
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200412 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200413
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200414 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200415 L2CAP_CONN_REQ, sizeof(req), &req);
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200416 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200417 } else {
418 struct l2cap_info_req req;
419 req.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
420
421 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
422 conn->info_ident = l2cap_get_ident(conn);
423
424 mod_timer(&conn->info_timer, jiffies +
425 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
426
427 l2cap_send_cmd(conn, conn->info_ident,
428 L2CAP_INFO_REQ, sizeof(req), &req);
429 }
430}
431
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300432static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct sock *sk)
433{
434 struct l2cap_disconn_req req;
435
436 req.dcid = cpu_to_le16(l2cap_pi(sk)->dcid);
437 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
438 l2cap_send_cmd(conn, l2cap_get_ident(conn),
439 L2CAP_DISCONN_REQ, sizeof(req), &req);
440}
441
Linus Torvalds1da177e2005-04-16 15:20:36 -0700442/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200443static void l2cap_conn_start(struct l2cap_conn *conn)
444{
445 struct l2cap_chan_list *l = &conn->chan_list;
446 struct sock *sk;
447
448 BT_DBG("conn %p", conn);
449
450 read_lock(&l->lock);
451
452 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
453 bh_lock_sock(sk);
454
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300455 if (sk->sk_type != SOCK_SEQPACKET &&
456 sk->sk_type != SOCK_STREAM) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200457 bh_unlock_sock(sk);
458 continue;
459 }
460
461 if (sk->sk_state == BT_CONNECT) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100462 if (l2cap_check_security(sk)) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200463 struct l2cap_conn_req req;
464 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
465 req.psm = l2cap_pi(sk)->psm;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200466
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200467 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200468
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200469 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200470 L2CAP_CONN_REQ, sizeof(req), &req);
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200471 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200472 } else if (sk->sk_state == BT_CONNECT2) {
473 struct l2cap_conn_rsp rsp;
474 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
475 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
476
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100477 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100478 if (bt_sk(sk)->defer_setup) {
479 struct sock *parent = bt_sk(sk)->parent;
480 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
481 rsp.status = cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
482 parent->sk_data_ready(parent, 0);
483
484 } else {
485 sk->sk_state = BT_CONFIG;
486 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
487 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
488 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200489 } else {
490 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
491 rsp.status = cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
492 }
493
494 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
495 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
496 }
497
498 bh_unlock_sock(sk);
499 }
500
501 read_unlock(&l->lock);
502}
503
504static void l2cap_conn_ready(struct l2cap_conn *conn)
505{
506 struct l2cap_chan_list *l = &conn->chan_list;
507 struct sock *sk;
508
509 BT_DBG("conn %p", conn);
510
511 read_lock(&l->lock);
512
513 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
514 bh_lock_sock(sk);
515
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300516 if (sk->sk_type != SOCK_SEQPACKET &&
517 sk->sk_type != SOCK_STREAM) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200518 l2cap_sock_clear_timer(sk);
519 sk->sk_state = BT_CONNECTED;
520 sk->sk_state_change(sk);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200521 } else if (sk->sk_state == BT_CONNECT)
522 l2cap_do_start(sk);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200523
524 bh_unlock_sock(sk);
525 }
526
527 read_unlock(&l->lock);
528}
529
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200530/* Notify sockets that we cannot guaranty reliability anymore */
531static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
532{
533 struct l2cap_chan_list *l = &conn->chan_list;
534 struct sock *sk;
535
536 BT_DBG("conn %p", conn);
537
538 read_lock(&l->lock);
539
540 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100541 if (l2cap_pi(sk)->force_reliable)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200542 sk->sk_err = err;
543 }
544
545 read_unlock(&l->lock);
546}
547
548static void l2cap_info_timeout(unsigned long arg)
549{
550 struct l2cap_conn *conn = (void *) arg;
551
Marcel Holtmann984947d2009-02-06 23:35:19 +0100552 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +0100553 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +0100554
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200555 l2cap_conn_start(conn);
556}
557
Linus Torvalds1da177e2005-04-16 15:20:36 -0700558static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
559{
Marcel Holtmann01394182006-07-03 10:02:46 +0200560 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700561
Marcel Holtmann01394182006-07-03 10:02:46 +0200562 if (conn || status)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700563 return conn;
564
Marcel Holtmann01394182006-07-03 10:02:46 +0200565 conn = kzalloc(sizeof(struct l2cap_conn), GFP_ATOMIC);
566 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700567 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700568
569 hcon->l2cap_data = conn;
570 conn->hcon = hcon;
571
Marcel Holtmann01394182006-07-03 10:02:46 +0200572 BT_DBG("hcon %p conn %p", hcon, conn);
573
Linus Torvalds1da177e2005-04-16 15:20:36 -0700574 conn->mtu = hcon->hdev->acl_mtu;
575 conn->src = &hcon->hdev->bdaddr;
576 conn->dst = &hcon->dst;
577
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200578 conn->feat_mask = 0;
579
Linus Torvalds1da177e2005-04-16 15:20:36 -0700580 spin_lock_init(&conn->lock);
581 rwlock_init(&conn->chan_list.lock);
582
Dave Young45054dc2009-10-18 20:28:30 +0000583 setup_timer(&conn->info_timer, l2cap_info_timeout,
584 (unsigned long) conn);
585
Marcel Holtmann2950f212009-02-12 14:02:50 +0100586 conn->disc_reason = 0x13;
587
Linus Torvalds1da177e2005-04-16 15:20:36 -0700588 return conn;
589}
590
Marcel Holtmann01394182006-07-03 10:02:46 +0200591static void l2cap_conn_del(struct hci_conn *hcon, int err)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700592{
Marcel Holtmann01394182006-07-03 10:02:46 +0200593 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700594 struct sock *sk;
595
Marcel Holtmann01394182006-07-03 10:02:46 +0200596 if (!conn)
597 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700598
599 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
600
Wei Yongjun7585b972009-02-25 18:29:52 +0800601 kfree_skb(conn->rx_skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700602
603 /* Kill channels */
604 while ((sk = conn->chan_list.head)) {
605 bh_lock_sock(sk);
606 l2cap_chan_del(sk, err);
607 bh_unlock_sock(sk);
608 l2cap_sock_kill(sk);
609 }
610
Dave Young8e8440f2008-03-03 12:18:55 -0800611 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
612 del_timer_sync(&conn->info_timer);
Thomas Gleixner3ab22732008-02-26 17:42:56 -0800613
Linus Torvalds1da177e2005-04-16 15:20:36 -0700614 hcon->l2cap_data = NULL;
615 kfree(conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700616}
617
618static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
619{
620 struct l2cap_chan_list *l = &conn->chan_list;
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200621 write_lock_bh(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700622 __l2cap_chan_add(conn, sk, parent);
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200623 write_unlock_bh(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700624}
625
Linus Torvalds1da177e2005-04-16 15:20:36 -0700626/* ---- Socket interface ---- */
Al Viro8e036fc2007-07-29 00:16:36 -0700627static struct sock *__l2cap_get_sock_by_addr(__le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700628{
629 struct sock *sk;
630 struct hlist_node *node;
631 sk_for_each(sk, node, &l2cap_sk_list.head)
632 if (l2cap_pi(sk)->sport == psm && !bacmp(&bt_sk(sk)->src, src))
633 goto found;
634 sk = NULL;
635found:
636 return sk;
637}
638
639/* Find socket with psm and source bdaddr.
640 * Returns closest match.
641 */
Al Viro8e036fc2007-07-29 00:16:36 -0700642static struct sock *__l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700643{
644 struct sock *sk = NULL, *sk1 = NULL;
645 struct hlist_node *node;
646
647 sk_for_each(sk, node, &l2cap_sk_list.head) {
648 if (state && sk->sk_state != state)
649 continue;
650
651 if (l2cap_pi(sk)->psm == psm) {
652 /* Exact match. */
653 if (!bacmp(&bt_sk(sk)->src, src))
654 break;
655
656 /* Closest match */
657 if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY))
658 sk1 = sk;
659 }
660 }
661 return node ? sk : sk1;
662}
663
664/* Find socket with given address (psm, src).
665 * Returns locked socket */
Al Viro8e036fc2007-07-29 00:16:36 -0700666static inline struct sock *l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700667{
668 struct sock *s;
669 read_lock(&l2cap_sk_list.lock);
670 s = __l2cap_get_sock_by_psm(state, psm, src);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300671 if (s)
672 bh_lock_sock(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700673 read_unlock(&l2cap_sk_list.lock);
674 return s;
675}
676
677static void l2cap_sock_destruct(struct sock *sk)
678{
679 BT_DBG("sk %p", sk);
680
681 skb_queue_purge(&sk->sk_receive_queue);
682 skb_queue_purge(&sk->sk_write_queue);
683}
684
685static void l2cap_sock_cleanup_listen(struct sock *parent)
686{
687 struct sock *sk;
688
689 BT_DBG("parent %p", parent);
690
691 /* Close not yet accepted channels */
692 while ((sk = bt_accept_dequeue(parent, NULL)))
693 l2cap_sock_close(sk);
694
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200695 parent->sk_state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700696 sock_set_flag(parent, SOCK_ZAPPED);
697}
698
699/* Kill socket (only if zapped and orphan)
700 * Must be called on unlocked socket.
701 */
702static void l2cap_sock_kill(struct sock *sk)
703{
704 if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket)
705 return;
706
707 BT_DBG("sk %p state %d", sk, sk->sk_state);
708
709 /* Kill poor orphan */
710 bt_sock_unlink(&l2cap_sk_list, sk);
711 sock_set_flag(sk, SOCK_DEAD);
712 sock_put(sk);
713}
714
715static void __l2cap_sock_close(struct sock *sk, int reason)
716{
717 BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket);
718
719 switch (sk->sk_state) {
720 case BT_LISTEN:
721 l2cap_sock_cleanup_listen(sk);
722 break;
723
724 case BT_CONNECTED:
725 case BT_CONFIG:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300726 if (sk->sk_type == SOCK_SEQPACKET ||
727 sk->sk_type == SOCK_STREAM) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700728 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700729
730 sk->sk_state = BT_DISCONN;
731 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300732 l2cap_send_disconn_req(conn, sk);
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200733 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -0700734 l2cap_chan_del(sk, reason);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700735 break;
736
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100737 case BT_CONNECT2:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300738 if (sk->sk_type == SOCK_SEQPACKET ||
739 sk->sk_type == SOCK_STREAM) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100740 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
741 struct l2cap_conn_rsp rsp;
742 __u16 result;
743
744 if (bt_sk(sk)->defer_setup)
745 result = L2CAP_CR_SEC_BLOCK;
746 else
747 result = L2CAP_CR_BAD_PSM;
748
749 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
750 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
751 rsp.result = cpu_to_le16(result);
752 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
753 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
754 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
755 } else
756 l2cap_chan_del(sk, reason);
757 break;
758
Linus Torvalds1da177e2005-04-16 15:20:36 -0700759 case BT_CONNECT:
760 case BT_DISCONN:
761 l2cap_chan_del(sk, reason);
762 break;
763
764 default:
765 sock_set_flag(sk, SOCK_ZAPPED);
766 break;
767 }
768}
769
770/* Must be called on unlocked socket. */
771static void l2cap_sock_close(struct sock *sk)
772{
773 l2cap_sock_clear_timer(sk);
774 lock_sock(sk);
775 __l2cap_sock_close(sk, ECONNRESET);
776 release_sock(sk);
777 l2cap_sock_kill(sk);
778}
779
780static void l2cap_sock_init(struct sock *sk, struct sock *parent)
781{
782 struct l2cap_pinfo *pi = l2cap_pi(sk);
783
784 BT_DBG("sk %p", sk);
785
786 if (parent) {
787 sk->sk_type = parent->sk_type;
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100788 bt_sk(sk)->defer_setup = bt_sk(parent)->defer_setup;
789
Linus Torvalds1da177e2005-04-16 15:20:36 -0700790 pi->imtu = l2cap_pi(parent)->imtu;
791 pi->omtu = l2cap_pi(parent)->omtu;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -0700792 pi->mode = l2cap_pi(parent)->mode;
793 pi->fcs = l2cap_pi(parent)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -0300794 pi->max_tx = l2cap_pi(parent)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -0300795 pi->tx_win = l2cap_pi(parent)->tx_win;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100796 pi->sec_level = l2cap_pi(parent)->sec_level;
797 pi->role_switch = l2cap_pi(parent)->role_switch;
798 pi->force_reliable = l2cap_pi(parent)->force_reliable;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700799 } else {
800 pi->imtu = L2CAP_DEFAULT_MTU;
801 pi->omtu = 0;
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300802 if (enable_ertm && sk->sk_type == SOCK_STREAM)
803 pi->mode = L2CAP_MODE_ERTM;
804 else
805 pi->mode = L2CAP_MODE_BASIC;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -0300806 pi->max_tx = max_transmit;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -0700807 pi->fcs = L2CAP_FCS_CRC16;
Gustavo F. Padovan369ba302010-05-01 16:15:41 -0300808 pi->tx_win = tx_window;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100809 pi->sec_level = BT_SECURITY_LOW;
810 pi->role_switch = 0;
811 pi->force_reliable = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700812 }
813
814 /* Default config options */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +0200815 pi->conf_len = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700816 pi->flush_to = L2CAP_DEFAULT_FLUSH_TO;
Dave Young45054dc2009-10-18 20:28:30 +0000817 skb_queue_head_init(TX_QUEUE(sk));
818 skb_queue_head_init(SREJ_QUEUE(sk));
819 INIT_LIST_HEAD(SREJ_LIST(sk));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700820}
821
822static struct proto l2cap_proto = {
823 .name = "L2CAP",
824 .owner = THIS_MODULE,
825 .obj_size = sizeof(struct l2cap_pinfo)
826};
827
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700828static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700829{
830 struct sock *sk;
831
Pavel Emelyanov6257ff22007-11-01 00:39:31 -0700832 sk = sk_alloc(net, PF_BLUETOOTH, prio, &l2cap_proto);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700833 if (!sk)
834 return NULL;
835
836 sock_init_data(sock, sk);
837 INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
838
839 sk->sk_destruct = l2cap_sock_destruct;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200840 sk->sk_sndtimeo = msecs_to_jiffies(L2CAP_CONN_TIMEOUT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700841
842 sock_reset_flag(sk, SOCK_ZAPPED);
843
844 sk->sk_protocol = proto;
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200845 sk->sk_state = BT_OPEN;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700846
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200847 setup_timer(&sk->sk_timer, l2cap_sock_timeout, (unsigned long) sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700848
849 bt_sock_link(&l2cap_sk_list, sk);
850 return sk;
851}
852
Eric Paris3f378b62009-11-05 22:18:14 -0800853static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol,
854 int kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700855{
856 struct sock *sk;
857
858 BT_DBG("sock %p", sock);
859
860 sock->state = SS_UNCONNECTED;
861
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -0300862 if (sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM &&
Linus Torvalds1da177e2005-04-16 15:20:36 -0700863 sock->type != SOCK_DGRAM && sock->type != SOCK_RAW)
864 return -ESOCKTNOSUPPORT;
865
Eric Parisc84b3262009-11-05 20:45:52 -0800866 if (sock->type == SOCK_RAW && !kern && !capable(CAP_NET_RAW))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700867 return -EPERM;
868
869 sock->ops = &l2cap_sock_ops;
870
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700871 sk = l2cap_sock_alloc(net, sock, protocol, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700872 if (!sk)
873 return -ENOMEM;
874
875 l2cap_sock_init(sk, NULL);
876 return 0;
877}
878
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100879static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700880{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700881 struct sock *sk = sock->sk;
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100882 struct sockaddr_l2 la;
883 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700884
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100885 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700886
887 if (!addr || addr->sa_family != AF_BLUETOOTH)
888 return -EINVAL;
889
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100890 memset(&la, 0, sizeof(la));
891 len = min_t(unsigned int, sizeof(la), alen);
892 memcpy(&la, addr, len);
893
Marcel Holtmann2a517ca2009-02-16 03:20:31 +0100894 if (la.l2_cid)
895 return -EINVAL;
896
Linus Torvalds1da177e2005-04-16 15:20:36 -0700897 lock_sock(sk);
898
899 if (sk->sk_state != BT_OPEN) {
900 err = -EBADFD;
901 goto done;
902 }
903
Marcel Holtmannb4324b52009-06-07 18:06:51 +0200904 if (la.l2_psm && __le16_to_cpu(la.l2_psm) < 0x1001 &&
Marcel Holtmann847641d2007-01-22 22:00:45 +0100905 !capable(CAP_NET_BIND_SERVICE)) {
906 err = -EACCES;
907 goto done;
908 }
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900909
Linus Torvalds1da177e2005-04-16 15:20:36 -0700910 write_lock_bh(&l2cap_sk_list.lock);
911
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100912 if (la.l2_psm && __l2cap_get_sock_by_addr(la.l2_psm, &la.l2_bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700913 err = -EADDRINUSE;
914 } else {
915 /* Save source address */
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100916 bacpy(&bt_sk(sk)->src, &la.l2_bdaddr);
917 l2cap_pi(sk)->psm = la.l2_psm;
918 l2cap_pi(sk)->sport = la.l2_psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700919 sk->sk_state = BT_BOUND;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100920
Marcel Holtmannb4324b52009-06-07 18:06:51 +0200921 if (__le16_to_cpu(la.l2_psm) == 0x0001 ||
922 __le16_to_cpu(la.l2_psm) == 0x0003)
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100923 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700924 }
925
926 write_unlock_bh(&l2cap_sk_list.lock);
927
928done:
929 release_sock(sk);
930 return err;
931}
932
933static int l2cap_do_connect(struct sock *sk)
934{
935 bdaddr_t *src = &bt_sk(sk)->src;
936 bdaddr_t *dst = &bt_sk(sk)->dst;
937 struct l2cap_conn *conn;
938 struct hci_conn *hcon;
939 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200940 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +0200941 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700942
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100943 BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst),
944 l2cap_pi(sk)->psm);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700945
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300946 hdev = hci_get_route(dst, src);
947 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700948 return -EHOSTUNREACH;
949
950 hci_dev_lock_bh(hdev);
951
952 err = -ENOMEM;
953
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100954 if (sk->sk_type == SOCK_RAW) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100955 switch (l2cap_pi(sk)->sec_level) {
956 case BT_SECURITY_HIGH:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100957 auth_type = HCI_AT_DEDICATED_BONDING_MITM;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100958 break;
959 case BT_SECURITY_MEDIUM:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100960 auth_type = HCI_AT_DEDICATED_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100961 break;
962 default:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100963 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100964 break;
965 }
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100966 } else if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100967 if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200968 auth_type = HCI_AT_NO_BONDING_MITM;
969 else
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200970 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann435fef22009-02-09 03:55:28 +0100971
972 if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW)
973 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100974 } else {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100975 switch (l2cap_pi(sk)->sec_level) {
976 case BT_SECURITY_HIGH:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100977 auth_type = HCI_AT_GENERAL_BONDING_MITM;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100978 break;
979 case BT_SECURITY_MEDIUM:
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200980 auth_type = HCI_AT_GENERAL_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100981 break;
982 default:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100983 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100984 break;
985 }
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200986 }
987
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100988 hcon = hci_connect(hdev, ACL_LINK, dst,
989 l2cap_pi(sk)->sec_level, auth_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700990 if (!hcon)
991 goto done;
992
993 conn = l2cap_conn_add(hcon, 0);
994 if (!conn) {
995 hci_conn_put(hcon);
996 goto done;
997 }
998
999 err = 0;
1000
1001 /* Update source addr of the socket */
1002 bacpy(src, conn->src);
1003
1004 l2cap_chan_add(conn, sk, NULL);
1005
1006 sk->sk_state = BT_CONNECT;
1007 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
1008
1009 if (hcon->state == BT_CONNECTED) {
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001010 if (sk->sk_type != SOCK_SEQPACKET &&
1011 sk->sk_type != SOCK_STREAM) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001012 l2cap_sock_clear_timer(sk);
1013 sk->sk_state = BT_CONNECTED;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001014 } else
1015 l2cap_do_start(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001016 }
1017
1018done:
1019 hci_dev_unlock_bh(hdev);
1020 hci_dev_put(hdev);
1021 return err;
1022}
1023
1024static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
1025{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001026 struct sock *sk = sock->sk;
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001027 struct sockaddr_l2 la;
1028 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001029
Linus Torvalds1da177e2005-04-16 15:20:36 -07001030 BT_DBG("sk %p", sk);
1031
Changli Gao6503d962010-03-31 22:58:26 +00001032 if (!addr || alen < sizeof(addr->sa_family) ||
1033 addr->sa_family != AF_BLUETOOTH)
Marcel Holtmann2a517ca2009-02-16 03:20:31 +01001034 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001035
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001036 memset(&la, 0, sizeof(la));
1037 len = min_t(unsigned int, sizeof(la), alen);
1038 memcpy(&la, addr, len);
1039
Marcel Holtmann2a517ca2009-02-16 03:20:31 +01001040 if (la.l2_cid)
1041 return -EINVAL;
1042
1043 lock_sock(sk);
1044
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001045 if ((sk->sk_type == SOCK_SEQPACKET || sk->sk_type == SOCK_STREAM)
1046 && !la.l2_psm) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001047 err = -EINVAL;
1048 goto done;
1049 }
1050
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001051 switch (l2cap_pi(sk)->mode) {
1052 case L2CAP_MODE_BASIC:
1053 break;
1054 case L2CAP_MODE_ERTM:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001055 case L2CAP_MODE_STREAMING:
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001056 if (enable_ertm)
1057 break;
1058 /* fall through */
1059 default:
1060 err = -ENOTSUPP;
1061 goto done;
1062 }
1063
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001064 switch (sk->sk_state) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001065 case BT_CONNECT:
1066 case BT_CONNECT2:
1067 case BT_CONFIG:
1068 /* Already connecting */
1069 goto wait;
1070
1071 case BT_CONNECTED:
1072 /* Already connected */
1073 goto done;
1074
1075 case BT_OPEN:
1076 case BT_BOUND:
1077 /* Can connect */
1078 break;
1079
1080 default:
1081 err = -EBADFD;
1082 goto done;
1083 }
1084
1085 /* Set destination address and psm */
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001086 bacpy(&bt_sk(sk)->dst, &la.l2_bdaddr);
1087 l2cap_pi(sk)->psm = la.l2_psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001088
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001089 err = l2cap_do_connect(sk);
1090 if (err)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001091 goto done;
1092
1093wait:
1094 err = bt_sock_wait_state(sk, BT_CONNECTED,
1095 sock_sndtimeo(sk, flags & O_NONBLOCK));
1096done:
1097 release_sock(sk);
1098 return err;
1099}
1100
1101static int l2cap_sock_listen(struct socket *sock, int backlog)
1102{
1103 struct sock *sk = sock->sk;
1104 int err = 0;
1105
1106 BT_DBG("sk %p backlog %d", sk, backlog);
1107
1108 lock_sock(sk);
1109
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001110 if ((sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM)
1111 || sk->sk_state != BT_BOUND) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001112 err = -EBADFD;
1113 goto done;
1114 }
1115
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001116 switch (l2cap_pi(sk)->mode) {
1117 case L2CAP_MODE_BASIC:
1118 break;
1119 case L2CAP_MODE_ERTM:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001120 case L2CAP_MODE_STREAMING:
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001121 if (enable_ertm)
1122 break;
1123 /* fall through */
1124 default:
1125 err = -ENOTSUPP;
1126 goto done;
1127 }
1128
Linus Torvalds1da177e2005-04-16 15:20:36 -07001129 if (!l2cap_pi(sk)->psm) {
1130 bdaddr_t *src = &bt_sk(sk)->src;
1131 u16 psm;
1132
1133 err = -EINVAL;
1134
1135 write_lock_bh(&l2cap_sk_list.lock);
1136
1137 for (psm = 0x1001; psm < 0x1100; psm += 2)
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001138 if (!__l2cap_get_sock_by_addr(cpu_to_le16(psm), src)) {
1139 l2cap_pi(sk)->psm = cpu_to_le16(psm);
1140 l2cap_pi(sk)->sport = cpu_to_le16(psm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001141 err = 0;
1142 break;
1143 }
1144
1145 write_unlock_bh(&l2cap_sk_list.lock);
1146
1147 if (err < 0)
1148 goto done;
1149 }
1150
1151 sk->sk_max_ack_backlog = backlog;
1152 sk->sk_ack_backlog = 0;
1153 sk->sk_state = BT_LISTEN;
1154
1155done:
1156 release_sock(sk);
1157 return err;
1158}
1159
1160static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int flags)
1161{
1162 DECLARE_WAITQUEUE(wait, current);
1163 struct sock *sk = sock->sk, *nsk;
1164 long timeo;
1165 int err = 0;
1166
Peter Zijlstrafcc70d52006-11-08 22:44:35 -08001167 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001168
1169 if (sk->sk_state != BT_LISTEN) {
1170 err = -EBADFD;
1171 goto done;
1172 }
1173
1174 timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
1175
1176 BT_DBG("sk %p timeo %ld", sk, timeo);
1177
1178 /* Wait for an incoming connection. (wake-one). */
Eric Dumazetaa395142010-04-20 13:03:51 +00001179 add_wait_queue_exclusive(sk_sleep(sk), &wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001180 while (!(nsk = bt_accept_dequeue(sk, newsock))) {
1181 set_current_state(TASK_INTERRUPTIBLE);
1182 if (!timeo) {
1183 err = -EAGAIN;
1184 break;
1185 }
1186
1187 release_sock(sk);
1188 timeo = schedule_timeout(timeo);
Peter Zijlstrafcc70d52006-11-08 22:44:35 -08001189 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001190
1191 if (sk->sk_state != BT_LISTEN) {
1192 err = -EBADFD;
1193 break;
1194 }
1195
1196 if (signal_pending(current)) {
1197 err = sock_intr_errno(timeo);
1198 break;
1199 }
1200 }
1201 set_current_state(TASK_RUNNING);
Eric Dumazetaa395142010-04-20 13:03:51 +00001202 remove_wait_queue(sk_sleep(sk), &wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001203
1204 if (err)
1205 goto done;
1206
1207 newsock->state = SS_CONNECTED;
1208
1209 BT_DBG("new socket %p", nsk);
1210
1211done:
1212 release_sock(sk);
1213 return err;
1214}
1215
1216static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
1217{
1218 struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
1219 struct sock *sk = sock->sk;
1220
1221 BT_DBG("sock %p, sk %p", sock, sk);
1222
1223 addr->sa_family = AF_BLUETOOTH;
1224 *len = sizeof(struct sockaddr_l2);
1225
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001226 if (peer) {
1227 la->l2_psm = l2cap_pi(sk)->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001228 bacpy(&la->l2_bdaddr, &bt_sk(sk)->dst);
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001229 la->l2_cid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001230 } else {
1231 la->l2_psm = l2cap_pi(sk)->sport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001232 bacpy(&la->l2_bdaddr, &bt_sk(sk)->src);
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001233 la->l2_cid = cpu_to_le16(l2cap_pi(sk)->scid);
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001234 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001235
Linus Torvalds1da177e2005-04-16 15:20:36 -07001236 return 0;
1237}
1238
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001239static void l2cap_monitor_timeout(unsigned long arg)
1240{
1241 struct sock *sk = (void *) arg;
1242 u16 control;
1243
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001244 bh_lock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001245 if (l2cap_pi(sk)->retry_count >= l2cap_pi(sk)->remote_max_tx) {
1246 l2cap_send_disconn_req(l2cap_pi(sk)->conn, sk);
Andrei Emeltchenkob13f5862009-12-15 11:38:04 +02001247 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001248 return;
1249 }
1250
1251 l2cap_pi(sk)->retry_count++;
1252 __mod_monitor_timer();
1253
1254 control = L2CAP_CTRL_POLL;
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001255 l2cap_send_rr_or_rnr(l2cap_pi(sk), control);
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001256 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001257}
1258
1259static void l2cap_retrans_timeout(unsigned long arg)
1260{
1261 struct sock *sk = (void *) arg;
1262 u16 control;
1263
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001264 bh_lock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001265 l2cap_pi(sk)->retry_count = 1;
1266 __mod_monitor_timer();
1267
1268 l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
1269
1270 control = L2CAP_CTRL_POLL;
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001271 l2cap_send_rr_or_rnr(l2cap_pi(sk), control);
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001272 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001273}
1274
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001275static void l2cap_drop_acked_frames(struct sock *sk)
1276{
1277 struct sk_buff *skb;
1278
Gustavo F. Padovan812e7372010-05-01 16:15:42 -03001279 while ((skb = skb_peek(TX_QUEUE(sk))) &&
1280 l2cap_pi(sk)->unacked_frames) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001281 if (bt_cb(skb)->tx_seq == l2cap_pi(sk)->expected_ack_seq)
1282 break;
1283
1284 skb = skb_dequeue(TX_QUEUE(sk));
1285 kfree_skb(skb);
1286
1287 l2cap_pi(sk)->unacked_frames--;
1288 }
1289
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001290 if (!l2cap_pi(sk)->unacked_frames)
1291 del_timer(&l2cap_pi(sk)->retrans_timer);
1292
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001293 return;
1294}
1295
1296static inline int l2cap_do_send(struct sock *sk, struct sk_buff *skb)
1297{
1298 struct l2cap_pinfo *pi = l2cap_pi(sk);
1299 int err;
1300
1301 BT_DBG("sk %p, skb %p len %d", sk, skb, skb->len);
1302
1303 err = hci_send_acl(pi->conn->hcon, skb, 0);
1304 if (err < 0)
1305 kfree_skb(skb);
1306
1307 return err;
1308}
1309
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001310static int l2cap_streaming_send(struct sock *sk)
1311{
1312 struct sk_buff *skb, *tx_skb;
1313 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001314 u16 control, fcs;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001315 int err;
1316
1317 while ((skb = sk->sk_send_head)) {
1318 tx_skb = skb_clone(skb, GFP_ATOMIC);
1319
1320 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
1321 control |= pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT;
1322 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1323
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001324 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001325 fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
1326 put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
1327 }
1328
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001329 err = l2cap_do_send(sk, tx_skb);
1330 if (err < 0) {
1331 l2cap_send_disconn_req(pi->conn, sk);
1332 return err;
1333 }
1334
1335 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
1336
1337 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1338 sk->sk_send_head = NULL;
1339 else
1340 sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
1341
1342 skb = skb_dequeue(TX_QUEUE(sk));
1343 kfree_skb(skb);
1344 }
1345 return 0;
1346}
1347
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001348static int l2cap_retransmit_frame(struct sock *sk, u8 tx_seq)
1349{
1350 struct l2cap_pinfo *pi = l2cap_pi(sk);
1351 struct sk_buff *skb, *tx_skb;
1352 u16 control, fcs;
1353 int err;
1354
1355 skb = skb_peek(TX_QUEUE(sk));
1356 do {
1357 if (bt_cb(skb)->tx_seq != tx_seq) {
1358 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1359 break;
1360 skb = skb_queue_next(TX_QUEUE(sk), skb);
1361 continue;
1362 }
1363
1364 if (pi->remote_max_tx &&
1365 bt_cb(skb)->retries == pi->remote_max_tx) {
1366 l2cap_send_disconn_req(pi->conn, sk);
1367 break;
1368 }
1369
1370 tx_skb = skb_clone(skb, GFP_ATOMIC);
1371 bt_cb(skb)->retries++;
1372 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03001373 control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001374 | (tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
1375 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1376
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001377 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001378 fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
1379 put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
1380 }
1381
1382 err = l2cap_do_send(sk, tx_skb);
1383 if (err < 0) {
1384 l2cap_send_disconn_req(pi->conn, sk);
1385 return err;
1386 }
1387 break;
1388 } while(1);
1389 return 0;
1390}
1391
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001392static int l2cap_ertm_send(struct sock *sk)
1393{
1394 struct sk_buff *skb, *tx_skb;
1395 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001396 u16 control, fcs;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001397 int err, nsent = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001398
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001399 if (pi->conn_state & L2CAP_CONN_WAIT_F)
1400 return 0;
1401
Joe Perchesf64f9e72009-11-29 16:55:45 -08001402 while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(sk)) &&
1403 !(pi->conn_state & L2CAP_CONN_REMOTE_BUSY)) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001404
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001405 if (pi->remote_max_tx &&
1406 bt_cb(skb)->retries == pi->remote_max_tx) {
1407 l2cap_send_disconn_req(pi->conn, sk);
1408 break;
1409 }
1410
Andrei Emeltchenkoe420aba2009-12-23 13:07:14 +02001411 tx_skb = skb_clone(skb, GFP_ATOMIC);
1412
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001413 bt_cb(skb)->retries++;
1414
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001415 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001416 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
1417 control |= L2CAP_CTRL_FINAL;
1418 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
1419 }
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03001420 control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001421 | (pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
1422 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1423
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001424
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001425 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001426 fcs = crc16(0, (u8 *)skb->data, tx_skb->len - 2);
1427 put_unaligned_le16(fcs, skb->data + tx_skb->len - 2);
1428 }
1429
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001430 err = l2cap_do_send(sk, tx_skb);
1431 if (err < 0) {
1432 l2cap_send_disconn_req(pi->conn, sk);
1433 return err;
1434 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001435 __mod_retrans_timer();
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001436
1437 bt_cb(skb)->tx_seq = pi->next_tx_seq;
1438 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
1439
1440 pi->unacked_frames++;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001441 pi->frames_sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001442
1443 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1444 sk->sk_send_head = NULL;
1445 else
1446 sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001447
1448 nsent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001449 }
1450
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001451 return nsent;
1452}
1453
1454static int l2cap_send_ack(struct l2cap_pinfo *pi)
1455{
1456 struct sock *sk = (struct sock *)pi;
1457 u16 control = 0;
1458
1459 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1460
1461 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
1462 control |= L2CAP_SUPER_RCV_NOT_READY;
1463 return l2cap_send_sframe(pi, control);
1464 } else if (l2cap_ertm_send(sk) == 0) {
1465 control |= L2CAP_SUPER_RCV_READY;
1466 return l2cap_send_sframe(pi, control);
1467 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001468 return 0;
1469}
1470
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03001471static int l2cap_send_srejtail(struct sock *sk)
1472{
1473 struct srej_list *tail;
1474 u16 control;
1475
1476 control = L2CAP_SUPER_SELECT_REJECT;
1477 control |= L2CAP_CTRL_FINAL;
1478
1479 tail = list_entry(SREJ_LIST(sk)->prev, struct srej_list, list);
1480 control |= tail->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1481
1482 l2cap_send_sframe(l2cap_pi(sk), control);
1483
1484 return 0;
1485}
1486
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001487static inline int l2cap_skbuff_fromiovec(struct sock *sk, struct msghdr *msg, int len, int count, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001488{
1489 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001490 struct sk_buff **frag;
1491 int err, sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001492
1493 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count)) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001494 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001495 }
1496
1497 sent += count;
1498 len -= count;
1499
1500 /* Continuation fragments (no L2CAP header) */
1501 frag = &skb_shinfo(skb)->frag_list;
1502 while (len) {
1503 count = min_t(unsigned int, conn->mtu, len);
1504
1505 *frag = bt_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err);
1506 if (!*frag)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001507 return -EFAULT;
1508 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
1509 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001510
1511 sent += count;
1512 len -= count;
1513
1514 frag = &(*frag)->next;
1515 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001516
1517 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001518}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001519
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001520static struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, size_t len)
1521{
1522 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1523 struct sk_buff *skb;
1524 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1525 struct l2cap_hdr *lh;
1526
1527 BT_DBG("sk %p len %d", sk, (int)len);
1528
1529 count = min_t(unsigned int, (conn->mtu - hlen), len);
1530 skb = bt_skb_send_alloc(sk, count + hlen,
1531 msg->msg_flags & MSG_DONTWAIT, &err);
1532 if (!skb)
1533 return ERR_PTR(-ENOMEM);
1534
1535 /* Create L2CAP header */
1536 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1537 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1538 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1539 put_unaligned_le16(l2cap_pi(sk)->psm, skb_put(skb, 2));
1540
1541 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1542 if (unlikely(err < 0)) {
1543 kfree_skb(skb);
1544 return ERR_PTR(err);
1545 }
1546 return skb;
1547}
1548
1549static struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *msg, size_t len)
1550{
1551 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1552 struct sk_buff *skb;
1553 int err, count, hlen = L2CAP_HDR_SIZE;
1554 struct l2cap_hdr *lh;
1555
1556 BT_DBG("sk %p len %d", sk, (int)len);
1557
1558 count = min_t(unsigned int, (conn->mtu - hlen), len);
1559 skb = bt_skb_send_alloc(sk, count + hlen,
1560 msg->msg_flags & MSG_DONTWAIT, &err);
1561 if (!skb)
1562 return ERR_PTR(-ENOMEM);
1563
1564 /* Create L2CAP header */
1565 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1566 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1567 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1568
1569 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1570 if (unlikely(err < 0)) {
1571 kfree_skb(skb);
1572 return ERR_PTR(err);
1573 }
1574 return skb;
1575}
1576
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001577static 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 -03001578{
1579 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1580 struct sk_buff *skb;
1581 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1582 struct l2cap_hdr *lh;
1583
1584 BT_DBG("sk %p len %d", sk, (int)len);
1585
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03001586 if (!conn)
1587 return ERR_PTR(-ENOTCONN);
1588
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001589 if (sdulen)
1590 hlen += 2;
1591
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001592 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1593 hlen += 2;
1594
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001595 count = min_t(unsigned int, (conn->mtu - hlen), len);
1596 skb = bt_skb_send_alloc(sk, count + hlen,
1597 msg->msg_flags & MSG_DONTWAIT, &err);
1598 if (!skb)
1599 return ERR_PTR(-ENOMEM);
1600
1601 /* Create L2CAP header */
1602 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1603 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1604 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1605 put_unaligned_le16(control, skb_put(skb, 2));
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001606 if (sdulen)
1607 put_unaligned_le16(sdulen, skb_put(skb, 2));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001608
1609 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1610 if (unlikely(err < 0)) {
1611 kfree_skb(skb);
1612 return ERR_PTR(err);
1613 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001614
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001615 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1616 put_unaligned_le16(0, skb_put(skb, 2));
1617
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001618 bt_cb(skb)->retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001619 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001620}
1621
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001622static inline int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len)
1623{
1624 struct l2cap_pinfo *pi = l2cap_pi(sk);
1625 struct sk_buff *skb;
1626 struct sk_buff_head sar_queue;
1627 u16 control;
1628 size_t size = 0;
1629
1630 __skb_queue_head_init(&sar_queue);
1631 control = L2CAP_SDU_START;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001632 skb = l2cap_create_iframe_pdu(sk, msg, pi->remote_mps, control, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001633 if (IS_ERR(skb))
1634 return PTR_ERR(skb);
1635
1636 __skb_queue_tail(&sar_queue, skb);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001637 len -= pi->remote_mps;
1638 size += pi->remote_mps;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001639
1640 while (len > 0) {
1641 size_t buflen;
1642
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001643 if (len > pi->remote_mps) {
Gustavo F. Padovan44651b82010-05-01 16:15:43 -03001644 control = L2CAP_SDU_CONTINUE;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001645 buflen = pi->remote_mps;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001646 } else {
Gustavo F. Padovan44651b82010-05-01 16:15:43 -03001647 control = L2CAP_SDU_END;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001648 buflen = len;
1649 }
1650
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001651 skb = l2cap_create_iframe_pdu(sk, msg, buflen, control, 0);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001652 if (IS_ERR(skb)) {
1653 skb_queue_purge(&sar_queue);
1654 return PTR_ERR(skb);
1655 }
1656
1657 __skb_queue_tail(&sar_queue, skb);
1658 len -= buflen;
1659 size += buflen;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001660 }
1661 skb_queue_splice_tail(&sar_queue, TX_QUEUE(sk));
1662 if (sk->sk_send_head == NULL)
1663 sk->sk_send_head = sar_queue.next;
1664
1665 return size;
1666}
1667
Linus Torvalds1da177e2005-04-16 15:20:36 -07001668static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len)
1669{
1670 struct sock *sk = sock->sk;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001671 struct l2cap_pinfo *pi = l2cap_pi(sk);
1672 struct sk_buff *skb;
1673 u16 control;
1674 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001675
1676 BT_DBG("sock %p, sk %p", sock, sk);
1677
Benjamin LaHaisec1cbe4b2005-12-13 23:22:19 -08001678 err = sock_error(sk);
1679 if (err)
1680 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001681
1682 if (msg->msg_flags & MSG_OOB)
1683 return -EOPNOTSUPP;
1684
Linus Torvalds1da177e2005-04-16 15:20:36 -07001685 lock_sock(sk);
1686
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001687 if (sk->sk_state != BT_CONNECTED) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001688 err = -ENOTCONN;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001689 goto done;
1690 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001691
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001692 /* Connectionless channel */
1693 if (sk->sk_type == SOCK_DGRAM) {
1694 skb = l2cap_create_connless_pdu(sk, msg, len);
Dan Carpenter477fffb2010-04-21 23:52:01 +00001695 if (IS_ERR(skb))
1696 err = PTR_ERR(skb);
1697 else
1698 err = l2cap_do_send(sk, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001699 goto done;
1700 }
1701
1702 switch (pi->mode) {
1703 case L2CAP_MODE_BASIC:
Gustavo F. Padovanc69163e2010-05-01 16:15:35 -03001704 /* Check outgoing MTU */
1705 if (len > pi->omtu) {
1706 err = -EINVAL;
1707 goto done;
1708 }
1709
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001710 /* Create a basic PDU */
1711 skb = l2cap_create_basic_pdu(sk, msg, len);
1712 if (IS_ERR(skb)) {
1713 err = PTR_ERR(skb);
1714 goto done;
1715 }
1716
1717 err = l2cap_do_send(sk, skb);
1718 if (!err)
1719 err = len;
1720 break;
1721
1722 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001723 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001724 /* Entire SDU fits into one PDU */
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001725 if (len <= pi->remote_mps) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001726 control = L2CAP_SDU_UNSEGMENTED;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001727 skb = l2cap_create_iframe_pdu(sk, msg, len, control, 0);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001728 if (IS_ERR(skb)) {
1729 err = PTR_ERR(skb);
1730 goto done;
1731 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001732 __skb_queue_tail(TX_QUEUE(sk), skb);
1733 if (sk->sk_send_head == NULL)
1734 sk->sk_send_head = skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001735 } else {
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001736 /* Segment SDU into multiples PDUs */
1737 err = l2cap_sar_segment_sdu(sk, msg, len);
1738 if (err < 0)
1739 goto done;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001740 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001741
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001742 if (pi->mode == L2CAP_MODE_STREAMING)
1743 err = l2cap_streaming_send(sk);
1744 else
1745 err = l2cap_ertm_send(sk);
1746
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001747 if (err >= 0)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001748 err = len;
1749 break;
1750
1751 default:
1752 BT_DBG("bad state %1.1x", pi->mode);
1753 err = -EINVAL;
1754 }
1755
1756done:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001757 release_sock(sk);
1758 return err;
1759}
1760
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001761static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags)
1762{
1763 struct sock *sk = sock->sk;
1764
1765 lock_sock(sk);
1766
1767 if (sk->sk_state == BT_CONNECT2 && bt_sk(sk)->defer_setup) {
1768 struct l2cap_conn_rsp rsp;
1769
1770 sk->sk_state = BT_CONFIG;
1771
1772 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
1773 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
1774 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
1775 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
1776 l2cap_send_cmd(l2cap_pi(sk)->conn, l2cap_pi(sk)->ident,
1777 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
1778
1779 release_sock(sk);
1780 return 0;
1781 }
1782
1783 release_sock(sk);
1784
1785 return bt_sock_recvmsg(iocb, sock, msg, len, flags);
1786}
1787
David S. Millerb7058842009-09-30 16:12:20 -07001788static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001789{
1790 struct sock *sk = sock->sk;
1791 struct l2cap_options opts;
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001792 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001793 u32 opt;
1794
1795 BT_DBG("sk %p", sk);
1796
1797 lock_sock(sk);
1798
1799 switch (optname) {
1800 case L2CAP_OPTIONS:
Marcel Holtmann0878b662007-05-05 00:35:59 +02001801 opts.imtu = l2cap_pi(sk)->imtu;
1802 opts.omtu = l2cap_pi(sk)->omtu;
1803 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001804 opts.mode = l2cap_pi(sk)->mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001805 opts.fcs = l2cap_pi(sk)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03001806 opts.max_tx = l2cap_pi(sk)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03001807 opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
Marcel Holtmann0878b662007-05-05 00:35:59 +02001808
Linus Torvalds1da177e2005-04-16 15:20:36 -07001809 len = min_t(unsigned int, sizeof(opts), optlen);
1810 if (copy_from_user((char *) &opts, optval, len)) {
1811 err = -EFAULT;
1812 break;
1813 }
Marcel Holtmann0878b662007-05-05 00:35:59 +02001814
João Paulo Rechi Vita0041ecf2010-05-01 16:15:42 -03001815 l2cap_pi(sk)->mode = opts.mode;
1816 switch (l2cap_pi(sk)->mode) {
1817 case L2CAP_MODE_BASIC:
1818 break;
1819 case L2CAP_MODE_ERTM:
1820 case L2CAP_MODE_STREAMING:
1821 if (enable_ertm)
1822 break;
1823 /* fall through */
1824 default:
1825 err = -EINVAL;
1826 break;
1827 }
1828
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001829 l2cap_pi(sk)->imtu = opts.imtu;
1830 l2cap_pi(sk)->omtu = opts.omtu;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001831 l2cap_pi(sk)->fcs = opts.fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03001832 l2cap_pi(sk)->max_tx = opts.max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03001833 l2cap_pi(sk)->tx_win = (__u8)opts.txwin_size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001834 break;
1835
1836 case L2CAP_LM:
1837 if (get_user(opt, (u32 __user *) optval)) {
1838 err = -EFAULT;
1839 break;
1840 }
1841
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001842 if (opt & L2CAP_LM_AUTH)
1843 l2cap_pi(sk)->sec_level = BT_SECURITY_LOW;
1844 if (opt & L2CAP_LM_ENCRYPT)
1845 l2cap_pi(sk)->sec_level = BT_SECURITY_MEDIUM;
1846 if (opt & L2CAP_LM_SECURE)
1847 l2cap_pi(sk)->sec_level = BT_SECURITY_HIGH;
1848
1849 l2cap_pi(sk)->role_switch = (opt & L2CAP_LM_MASTER);
1850 l2cap_pi(sk)->force_reliable = (opt & L2CAP_LM_RELIABLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001851 break;
1852
1853 default:
1854 err = -ENOPROTOOPT;
1855 break;
1856 }
1857
1858 release_sock(sk);
1859 return err;
1860}
1861
David S. Millerb7058842009-09-30 16:12:20 -07001862static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001863{
1864 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001865 struct bt_security sec;
1866 int len, err = 0;
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001867 u32 opt;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001868
1869 BT_DBG("sk %p", sk);
1870
1871 if (level == SOL_L2CAP)
1872 return l2cap_sock_setsockopt_old(sock, optname, optval, optlen);
1873
Marcel Holtmann0588d942009-01-16 10:06:13 +01001874 if (level != SOL_BLUETOOTH)
1875 return -ENOPROTOOPT;
1876
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001877 lock_sock(sk);
1878
1879 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001880 case BT_SECURITY:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001881 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
1882 && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01001883 err = -EINVAL;
1884 break;
1885 }
1886
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001887 sec.level = BT_SECURITY_LOW;
1888
1889 len = min_t(unsigned int, sizeof(sec), optlen);
1890 if (copy_from_user((char *) &sec, optval, len)) {
1891 err = -EFAULT;
1892 break;
1893 }
1894
1895 if (sec.level < BT_SECURITY_LOW ||
1896 sec.level > BT_SECURITY_HIGH) {
1897 err = -EINVAL;
1898 break;
1899 }
1900
1901 l2cap_pi(sk)->sec_level = sec.level;
1902 break;
1903
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001904 case BT_DEFER_SETUP:
1905 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
1906 err = -EINVAL;
1907 break;
1908 }
1909
1910 if (get_user(opt, (u32 __user *) optval)) {
1911 err = -EFAULT;
1912 break;
1913 }
1914
1915 bt_sk(sk)->defer_setup = opt;
1916 break;
1917
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001918 default:
1919 err = -ENOPROTOOPT;
1920 break;
1921 }
1922
1923 release_sock(sk);
1924 return err;
1925}
1926
1927static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001928{
1929 struct sock *sk = sock->sk;
1930 struct l2cap_options opts;
1931 struct l2cap_conninfo cinfo;
1932 int len, err = 0;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001933 u32 opt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001934
1935 BT_DBG("sk %p", sk);
1936
1937 if (get_user(len, optlen))
1938 return -EFAULT;
1939
1940 lock_sock(sk);
1941
1942 switch (optname) {
1943 case L2CAP_OPTIONS:
1944 opts.imtu = l2cap_pi(sk)->imtu;
1945 opts.omtu = l2cap_pi(sk)->omtu;
1946 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001947 opts.mode = l2cap_pi(sk)->mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001948 opts.fcs = l2cap_pi(sk)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03001949 opts.max_tx = l2cap_pi(sk)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03001950 opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001951
1952 len = min_t(unsigned int, len, sizeof(opts));
1953 if (copy_to_user(optval, (char *) &opts, len))
1954 err = -EFAULT;
1955
1956 break;
1957
1958 case L2CAP_LM:
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001959 switch (l2cap_pi(sk)->sec_level) {
1960 case BT_SECURITY_LOW:
1961 opt = L2CAP_LM_AUTH;
1962 break;
1963 case BT_SECURITY_MEDIUM:
1964 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT;
1965 break;
1966 case BT_SECURITY_HIGH:
1967 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT |
1968 L2CAP_LM_SECURE;
1969 break;
1970 default:
1971 opt = 0;
1972 break;
1973 }
1974
1975 if (l2cap_pi(sk)->role_switch)
1976 opt |= L2CAP_LM_MASTER;
1977
1978 if (l2cap_pi(sk)->force_reliable)
1979 opt |= L2CAP_LM_RELIABLE;
1980
1981 if (put_user(opt, (u32 __user *) optval))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001982 err = -EFAULT;
1983 break;
1984
1985 case L2CAP_CONNINFO:
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001986 if (sk->sk_state != BT_CONNECTED &&
1987 !(sk->sk_state == BT_CONNECT2 &&
1988 bt_sk(sk)->defer_setup)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001989 err = -ENOTCONN;
1990 break;
1991 }
1992
1993 cinfo.hci_handle = l2cap_pi(sk)->conn->hcon->handle;
1994 memcpy(cinfo.dev_class, l2cap_pi(sk)->conn->hcon->dev_class, 3);
1995
1996 len = min_t(unsigned int, len, sizeof(cinfo));
1997 if (copy_to_user(optval, (char *) &cinfo, len))
1998 err = -EFAULT;
1999
2000 break;
2001
2002 default:
2003 err = -ENOPROTOOPT;
2004 break;
2005 }
2006
2007 release_sock(sk);
2008 return err;
2009}
2010
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002011static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
2012{
2013 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002014 struct bt_security sec;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002015 int len, err = 0;
2016
2017 BT_DBG("sk %p", sk);
2018
2019 if (level == SOL_L2CAP)
2020 return l2cap_sock_getsockopt_old(sock, optname, optval, optlen);
2021
Marcel Holtmann0588d942009-01-16 10:06:13 +01002022 if (level != SOL_BLUETOOTH)
2023 return -ENOPROTOOPT;
2024
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002025 if (get_user(len, optlen))
2026 return -EFAULT;
2027
2028 lock_sock(sk);
2029
2030 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002031 case BT_SECURITY:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03002032 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
2033 && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01002034 err = -EINVAL;
2035 break;
2036 }
2037
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002038 sec.level = l2cap_pi(sk)->sec_level;
2039
2040 len = min_t(unsigned int, len, sizeof(sec));
2041 if (copy_to_user(optval, (char *) &sec, len))
2042 err = -EFAULT;
2043
2044 break;
2045
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002046 case BT_DEFER_SETUP:
2047 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
2048 err = -EINVAL;
2049 break;
2050 }
2051
2052 if (put_user(bt_sk(sk)->defer_setup, (u32 __user *) optval))
2053 err = -EFAULT;
2054
2055 break;
2056
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002057 default:
2058 err = -ENOPROTOOPT;
2059 break;
2060 }
2061
2062 release_sock(sk);
2063 return err;
2064}
2065
Linus Torvalds1da177e2005-04-16 15:20:36 -07002066static int l2cap_sock_shutdown(struct socket *sock, int how)
2067{
2068 struct sock *sk = sock->sk;
2069 int err = 0;
2070
2071 BT_DBG("sock %p, sk %p", sock, sk);
2072
2073 if (!sk)
2074 return 0;
2075
2076 lock_sock(sk);
2077 if (!sk->sk_shutdown) {
2078 sk->sk_shutdown = SHUTDOWN_MASK;
2079 l2cap_sock_clear_timer(sk);
2080 __l2cap_sock_close(sk, 0);
2081
2082 if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
Marcel Holtmannb1235d72008-07-14 20:13:54 +02002083 err = bt_sock_wait_state(sk, BT_CLOSED,
2084 sk->sk_lingertime);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002085 }
2086 release_sock(sk);
2087 return err;
2088}
2089
2090static int l2cap_sock_release(struct socket *sock)
2091{
2092 struct sock *sk = sock->sk;
2093 int err;
2094
2095 BT_DBG("sock %p, sk %p", sock, sk);
2096
2097 if (!sk)
2098 return 0;
2099
2100 err = l2cap_sock_shutdown(sock, 2);
2101
2102 sock_orphan(sk);
2103 l2cap_sock_kill(sk);
2104 return err;
2105}
2106
Linus Torvalds1da177e2005-04-16 15:20:36 -07002107static void l2cap_chan_ready(struct sock *sk)
2108{
2109 struct sock *parent = bt_sk(sk)->parent;
2110
2111 BT_DBG("sk %p, parent %p", sk, parent);
2112
2113 l2cap_pi(sk)->conf_state = 0;
2114 l2cap_sock_clear_timer(sk);
2115
2116 if (!parent) {
2117 /* Outgoing channel.
2118 * Wake up socket sleeping on connect.
2119 */
2120 sk->sk_state = BT_CONNECTED;
2121 sk->sk_state_change(sk);
2122 } else {
2123 /* Incoming channel.
2124 * Wake up socket sleeping on accept.
2125 */
2126 parent->sk_data_ready(parent, 0);
2127 }
2128}
2129
2130/* Copy frame to all raw sockets on that connection */
2131static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2132{
2133 struct l2cap_chan_list *l = &conn->chan_list;
2134 struct sk_buff *nskb;
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002135 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002136
2137 BT_DBG("conn %p", conn);
2138
2139 read_lock(&l->lock);
2140 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
2141 if (sk->sk_type != SOCK_RAW)
2142 continue;
2143
2144 /* Don't send frame to the socket it came from */
2145 if (skb->sk == sk)
2146 continue;
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002147 nskb = skb_clone(skb, GFP_ATOMIC);
2148 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002149 continue;
2150
2151 if (sock_queue_rcv_skb(sk, nskb))
2152 kfree_skb(nskb);
2153 }
2154 read_unlock(&l->lock);
2155}
2156
2157/* ---- L2CAP signalling commands ---- */
2158static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
2159 u8 code, u8 ident, u16 dlen, void *data)
2160{
2161 struct sk_buff *skb, **frag;
2162 struct l2cap_cmd_hdr *cmd;
2163 struct l2cap_hdr *lh;
2164 int len, count;
2165
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002166 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d",
2167 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002168
2169 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2170 count = min_t(unsigned int, conn->mtu, len);
2171
2172 skb = bt_skb_alloc(count, GFP_ATOMIC);
2173 if (!skb)
2174 return NULL;
2175
2176 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002177 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03002178 lh->cid = cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002179
2180 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2181 cmd->code = code;
2182 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002183 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002184
2185 if (dlen) {
2186 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2187 memcpy(skb_put(skb, count), data, count);
2188 data += count;
2189 }
2190
2191 len -= skb->len;
2192
2193 /* Continuation fragments (no L2CAP header) */
2194 frag = &skb_shinfo(skb)->frag_list;
2195 while (len) {
2196 count = min_t(unsigned int, conn->mtu, len);
2197
2198 *frag = bt_skb_alloc(count, GFP_ATOMIC);
2199 if (!*frag)
2200 goto fail;
2201
2202 memcpy(skb_put(*frag, count), data, count);
2203
2204 len -= count;
2205 data += count;
2206
2207 frag = &(*frag)->next;
2208 }
2209
2210 return skb;
2211
2212fail:
2213 kfree_skb(skb);
2214 return NULL;
2215}
2216
2217static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned long *val)
2218{
2219 struct l2cap_conf_opt *opt = *ptr;
2220 int len;
2221
2222 len = L2CAP_CONF_OPT_SIZE + opt->len;
2223 *ptr += len;
2224
2225 *type = opt->type;
2226 *olen = opt->len;
2227
2228 switch (opt->len) {
2229 case 1:
2230 *val = *((u8 *) opt->val);
2231 break;
2232
2233 case 2:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002234 *val = __le16_to_cpu(*((__le16 *) opt->val));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002235 break;
2236
2237 case 4:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002238 *val = __le32_to_cpu(*((__le32 *) opt->val));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002239 break;
2240
2241 default:
2242 *val = (unsigned long) opt->val;
2243 break;
2244 }
2245
2246 BT_DBG("type 0x%2.2x len %d val 0x%lx", *type, opt->len, *val);
2247 return len;
2248}
2249
Linus Torvalds1da177e2005-04-16 15:20:36 -07002250static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2251{
2252 struct l2cap_conf_opt *opt = *ptr;
2253
2254 BT_DBG("type 0x%2.2x len %d val 0x%lx", type, len, val);
2255
2256 opt->type = type;
2257 opt->len = len;
2258
2259 switch (len) {
2260 case 1:
2261 *((u8 *) opt->val) = val;
2262 break;
2263
2264 case 2:
Al Viro8e036fc2007-07-29 00:16:36 -07002265 *((__le16 *) opt->val) = cpu_to_le16(val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002266 break;
2267
2268 case 4:
Al Viro8e036fc2007-07-29 00:16:36 -07002269 *((__le32 *) opt->val) = cpu_to_le32(val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002270 break;
2271
2272 default:
2273 memcpy(opt->val, (void *) val, len);
2274 break;
2275 }
2276
2277 *ptr += L2CAP_CONF_OPT_SIZE + len;
2278}
2279
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002280static void l2cap_ack_timeout(unsigned long arg)
2281{
2282 struct sock *sk = (void *) arg;
2283
2284 bh_lock_sock(sk);
2285 l2cap_send_ack(l2cap_pi(sk));
2286 bh_unlock_sock(sk);
2287}
2288
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002289static inline void l2cap_ertm_init(struct sock *sk)
2290{
2291 l2cap_pi(sk)->expected_ack_seq = 0;
2292 l2cap_pi(sk)->unacked_frames = 0;
2293 l2cap_pi(sk)->buffer_seq = 0;
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03002294 l2cap_pi(sk)->num_acked = 0;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03002295 l2cap_pi(sk)->frames_sent = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002296
2297 setup_timer(&l2cap_pi(sk)->retrans_timer,
2298 l2cap_retrans_timeout, (unsigned long) sk);
2299 setup_timer(&l2cap_pi(sk)->monitor_timer,
2300 l2cap_monitor_timeout, (unsigned long) sk);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002301 setup_timer(&l2cap_pi(sk)->ack_timer,
2302 l2cap_ack_timeout, (unsigned long) sk);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002303
2304 __skb_queue_head_init(SREJ_QUEUE(sk));
2305}
2306
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002307static int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
2308{
2309 u32 local_feat_mask = l2cap_feat_mask;
2310 if (enable_ertm)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002311 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002312
2313 switch (mode) {
2314 case L2CAP_MODE_ERTM:
2315 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
2316 case L2CAP_MODE_STREAMING:
2317 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
2318 default:
2319 return 0x00;
2320 }
2321}
2322
2323static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
2324{
2325 switch (mode) {
2326 case L2CAP_MODE_STREAMING:
2327 case L2CAP_MODE_ERTM:
2328 if (l2cap_mode_supported(mode, remote_feat_mask))
2329 return mode;
2330 /* fall through */
2331 default:
2332 return L2CAP_MODE_BASIC;
2333 }
2334}
2335
Linus Torvalds1da177e2005-04-16 15:20:36 -07002336static int l2cap_build_conf_req(struct sock *sk, void *data)
2337{
2338 struct l2cap_pinfo *pi = l2cap_pi(sk);
2339 struct l2cap_conf_req *req = data;
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03002340 struct l2cap_conf_rfc rfc = { .mode = pi->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07002341 void *ptr = req->data;
2342
2343 BT_DBG("sk %p", sk);
2344
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002345 if (pi->num_conf_req || pi->num_conf_rsp)
2346 goto done;
2347
2348 switch (pi->mode) {
2349 case L2CAP_MODE_STREAMING:
2350 case L2CAP_MODE_ERTM:
2351 pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002352 if (!l2cap_mode_supported(pi->mode, pi->conn->feat_mask))
2353 l2cap_send_disconn_req(pi->conn, sk);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002354 break;
2355 default:
2356 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
2357 break;
2358 }
2359
2360done:
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002361 switch (pi->mode) {
2362 case L2CAP_MODE_BASIC:
2363 if (pi->imtu != L2CAP_DEFAULT_MTU)
2364 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
2365 break;
2366
2367 case L2CAP_MODE_ERTM:
2368 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03002369 rfc.txwin_size = pi->tx_win;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03002370 rfc.max_transmit = pi->max_tx;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002371 rfc.retrans_timeout = 0;
2372 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002373 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03002374 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002375 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002376
2377 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2378 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002379
2380 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2381 break;
2382
2383 if (pi->fcs == L2CAP_FCS_NONE ||
2384 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
2385 pi->fcs = L2CAP_FCS_NONE;
2386 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
2387 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002388 break;
2389
2390 case L2CAP_MODE_STREAMING:
2391 rfc.mode = L2CAP_MODE_STREAMING;
2392 rfc.txwin_size = 0;
2393 rfc.max_transmit = 0;
2394 rfc.retrans_timeout = 0;
2395 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002396 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03002397 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002398 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002399
2400 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2401 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002402
2403 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2404 break;
2405
2406 if (pi->fcs == L2CAP_FCS_NONE ||
2407 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
2408 pi->fcs = L2CAP_FCS_NONE;
2409 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
2410 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002411 break;
2412 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002413
2414 /* FIXME: Need actual value of the flush timeout */
2415 //if (flush_to != L2CAP_DEFAULT_FLUSH_TO)
2416 // l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2, pi->flush_to);
2417
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002418 req->dcid = cpu_to_le16(pi->dcid);
2419 req->flags = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002420
2421 return ptr - data;
2422}
2423
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002424static int l2cap_parse_conf_req(struct sock *sk, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002425{
2426 struct l2cap_pinfo *pi = l2cap_pi(sk);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002427 struct l2cap_conf_rsp *rsp = data;
2428 void *ptr = rsp->data;
2429 void *req = pi->conf_req;
2430 int len = pi->conf_len;
2431 int type, hint, olen;
2432 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002433 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Marcel Holtmann861d6882007-10-20 13:37:06 +02002434 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002435 u16 result = L2CAP_CONF_SUCCESS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002436
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002437 BT_DBG("sk %p", sk);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01002438
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002439 while (len >= L2CAP_CONF_OPT_SIZE) {
2440 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002441
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03002442 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07002443 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002444
2445 switch (type) {
2446 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002447 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002448 break;
2449
2450 case L2CAP_CONF_FLUSH_TO:
2451 pi->flush_to = val;
2452 break;
2453
2454 case L2CAP_CONF_QOS:
2455 break;
2456
Marcel Holtmann6464f352007-10-20 13:39:51 +02002457 case L2CAP_CONF_RFC:
2458 if (olen == sizeof(rfc))
2459 memcpy(&rfc, (void *) val, olen);
2460 break;
2461
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002462 case L2CAP_CONF_FCS:
2463 if (val == L2CAP_FCS_NONE)
2464 pi->conf_state |= L2CAP_CONF_NO_FCS_RECV;
2465
2466 break;
2467
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002468 default:
2469 if (hint)
2470 break;
2471
2472 result = L2CAP_CONF_UNKNOWN;
2473 *((u8 *) ptr++) = type;
2474 break;
2475 }
2476 }
2477
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002478 if (pi->num_conf_rsp || pi->num_conf_req)
2479 goto done;
2480
2481 switch (pi->mode) {
2482 case L2CAP_MODE_STREAMING:
2483 case L2CAP_MODE_ERTM:
2484 pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
2485 if (!l2cap_mode_supported(pi->mode, pi->conn->feat_mask))
2486 return -ECONNREFUSED;
2487 break;
2488 default:
2489 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
2490 break;
2491 }
2492
2493done:
2494 if (pi->mode != rfc.mode) {
2495 result = L2CAP_CONF_UNACCEPT;
2496 rfc.mode = pi->mode;
2497
2498 if (pi->num_conf_rsp == 1)
2499 return -ECONNREFUSED;
2500
2501 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2502 sizeof(rfc), (unsigned long) &rfc);
2503 }
2504
2505
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002506 if (result == L2CAP_CONF_SUCCESS) {
2507 /* Configure output options and let the other side know
2508 * which ones we don't like. */
2509
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002510 if (mtu < L2CAP_DEFAULT_MIN_MTU)
2511 result = L2CAP_CONF_UNACCEPT;
2512 else {
2513 pi->omtu = mtu;
2514 pi->conf_state |= L2CAP_CONF_MTU_DONE;
2515 }
2516 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002517
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002518 switch (rfc.mode) {
2519 case L2CAP_MODE_BASIC:
2520 pi->fcs = L2CAP_FCS_NONE;
2521 pi->conf_state |= L2CAP_CONF_MODE_DONE;
2522 break;
2523
2524 case L2CAP_MODE_ERTM:
2525 pi->remote_tx_win = rfc.txwin_size;
2526 pi->remote_max_tx = rfc.max_transmit;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002527 if (rfc.max_pdu_size > pi->conn->mtu - 10)
2528 rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10);
2529
2530 pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002531
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002532 rfc.retrans_timeout =
2533 le16_to_cpu(L2CAP_DEFAULT_RETRANS_TO);
2534 rfc.monitor_timeout =
2535 le16_to_cpu(L2CAP_DEFAULT_MONITOR_TO);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002536
2537 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03002538
2539 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2540 sizeof(rfc), (unsigned long) &rfc);
2541
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002542 break;
2543
2544 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002545 if (rfc.max_pdu_size > pi->conn->mtu - 10)
2546 rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10);
2547
2548 pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002549
2550 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03002551
2552 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2553 sizeof(rfc), (unsigned long) &rfc);
2554
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002555 break;
2556
2557 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02002558 result = L2CAP_CONF_UNACCEPT;
2559
2560 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002561 rfc.mode = pi->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002562 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002563
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002564 if (result == L2CAP_CONF_SUCCESS)
2565 pi->conf_state |= L2CAP_CONF_OUTPUT_DONE;
2566 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002567 rsp->scid = cpu_to_le16(pi->dcid);
2568 rsp->result = cpu_to_le16(result);
2569 rsp->flags = cpu_to_le16(0x0000);
2570
2571 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002572}
2573
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002574static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data, u16 *result)
2575{
2576 struct l2cap_pinfo *pi = l2cap_pi(sk);
2577 struct l2cap_conf_req *req = data;
2578 void *ptr = req->data;
2579 int type, olen;
2580 unsigned long val;
2581 struct l2cap_conf_rfc rfc;
2582
2583 BT_DBG("sk %p, rsp %p, len %d, req %p", sk, rsp, len, data);
2584
2585 while (len >= L2CAP_CONF_OPT_SIZE) {
2586 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
2587
2588 switch (type) {
2589 case L2CAP_CONF_MTU:
2590 if (val < L2CAP_DEFAULT_MIN_MTU) {
2591 *result = L2CAP_CONF_UNACCEPT;
2592 pi->omtu = L2CAP_DEFAULT_MIN_MTU;
2593 } else
2594 pi->omtu = val;
2595 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
2596 break;
2597
2598 case L2CAP_CONF_FLUSH_TO:
2599 pi->flush_to = val;
2600 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
2601 2, pi->flush_to);
2602 break;
2603
2604 case L2CAP_CONF_RFC:
2605 if (olen == sizeof(rfc))
2606 memcpy(&rfc, (void *)val, olen);
2607
2608 if ((pi->conf_state & L2CAP_CONF_STATE2_DEVICE) &&
2609 rfc.mode != pi->mode)
2610 return -ECONNREFUSED;
2611
2612 pi->mode = rfc.mode;
2613 pi->fcs = 0;
2614
2615 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2616 sizeof(rfc), (unsigned long) &rfc);
2617 break;
2618 }
2619 }
2620
2621 if (*result == L2CAP_CONF_SUCCESS) {
2622 switch (rfc.mode) {
2623 case L2CAP_MODE_ERTM:
2624 pi->remote_tx_win = rfc.txwin_size;
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002625 pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
2626 pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002627 pi->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002628 break;
2629 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002630 pi->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002631 }
2632 }
2633
2634 req->dcid = cpu_to_le16(pi->dcid);
2635 req->flags = cpu_to_le16(0x0000);
2636
2637 return ptr - data;
2638}
2639
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002640static int l2cap_build_conf_rsp(struct sock *sk, void *data, u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002641{
2642 struct l2cap_conf_rsp *rsp = data;
2643 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002644
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002645 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002646
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002647 rsp->scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002648 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002649 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002650
2651 return ptr - data;
2652}
2653
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002654static void l2cap_conf_rfc_get(struct sock *sk, void *rsp, int len)
2655{
2656 struct l2cap_pinfo *pi = l2cap_pi(sk);
2657 int type, olen;
2658 unsigned long val;
2659 struct l2cap_conf_rfc rfc;
2660
2661 BT_DBG("sk %p, rsp %p, len %d", sk, rsp, len);
2662
2663 if ((pi->mode != L2CAP_MODE_ERTM) && (pi->mode != L2CAP_MODE_STREAMING))
2664 return;
2665
2666 while (len >= L2CAP_CONF_OPT_SIZE) {
2667 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
2668
2669 switch (type) {
2670 case L2CAP_CONF_RFC:
2671 if (olen == sizeof(rfc))
2672 memcpy(&rfc, (void *)val, olen);
2673 goto done;
2674 }
2675 }
2676
2677done:
2678 switch (rfc.mode) {
2679 case L2CAP_MODE_ERTM:
2680 pi->remote_tx_win = rfc.txwin_size;
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002681 pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
2682 pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002683 pi->mps = le16_to_cpu(rfc.max_pdu_size);
2684 break;
2685 case L2CAP_MODE_STREAMING:
2686 pi->mps = le16_to_cpu(rfc.max_pdu_size);
2687 }
2688}
2689
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002690static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2691{
2692 struct l2cap_cmd_rej *rej = (struct l2cap_cmd_rej *) data;
2693
2694 if (rej->reason != 0x0000)
2695 return 0;
2696
2697 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
2698 cmd->ident == conn->info_ident) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002699 del_timer(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01002700
2701 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002702 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01002703
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002704 l2cap_conn_start(conn);
2705 }
2706
2707 return 0;
2708}
2709
Linus Torvalds1da177e2005-04-16 15:20:36 -07002710static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2711{
2712 struct l2cap_chan_list *list = &conn->chan_list;
2713 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
2714 struct l2cap_conn_rsp rsp;
2715 struct sock *sk, *parent;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002716 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002717
2718 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002719 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002720
2721 BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
2722
2723 /* Check if we have socket listening on psm */
2724 parent = l2cap_get_sock_by_psm(BT_LISTEN, psm, conn->src);
2725 if (!parent) {
2726 result = L2CAP_CR_BAD_PSM;
2727 goto sendresp;
2728 }
2729
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002730 /* Check if the ACL is secure enough (if not SDP) */
2731 if (psm != cpu_to_le16(0x0001) &&
2732 !hci_conn_check_link_mode(conn->hcon)) {
Marcel Holtmann2950f212009-02-12 14:02:50 +01002733 conn->disc_reason = 0x05;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002734 result = L2CAP_CR_SEC_BLOCK;
2735 goto response;
2736 }
2737
Linus Torvalds1da177e2005-04-16 15:20:36 -07002738 result = L2CAP_CR_NO_MEM;
2739
2740 /* Check for backlog size */
2741 if (sk_acceptq_is_full(parent)) {
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09002742 BT_DBG("backlog full %d", parent->sk_ack_backlog);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002743 goto response;
2744 }
2745
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09002746 sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002747 if (!sk)
2748 goto response;
2749
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002750 write_lock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002751
2752 /* Check if we already have channel with that dcid */
2753 if (__l2cap_get_chan_by_dcid(list, scid)) {
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002754 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002755 sock_set_flag(sk, SOCK_ZAPPED);
2756 l2cap_sock_kill(sk);
2757 goto response;
2758 }
2759
2760 hci_conn_hold(conn->hcon);
2761
2762 l2cap_sock_init(sk, parent);
2763 bacpy(&bt_sk(sk)->src, conn->src);
2764 bacpy(&bt_sk(sk)->dst, conn->dst);
2765 l2cap_pi(sk)->psm = psm;
2766 l2cap_pi(sk)->dcid = scid;
2767
2768 __l2cap_chan_add(conn, sk, parent);
2769 dcid = l2cap_pi(sk)->scid;
2770
2771 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
2772
Linus Torvalds1da177e2005-04-16 15:20:36 -07002773 l2cap_pi(sk)->ident = cmd->ident;
2774
Marcel Holtmann984947d2009-02-06 23:35:19 +01002775 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002776 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002777 if (bt_sk(sk)->defer_setup) {
2778 sk->sk_state = BT_CONNECT2;
2779 result = L2CAP_CR_PEND;
2780 status = L2CAP_CS_AUTHOR_PEND;
2781 parent->sk_data_ready(parent, 0);
2782 } else {
2783 sk->sk_state = BT_CONFIG;
2784 result = L2CAP_CR_SUCCESS;
2785 status = L2CAP_CS_NO_INFO;
2786 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002787 } else {
2788 sk->sk_state = BT_CONNECT2;
2789 result = L2CAP_CR_PEND;
2790 status = L2CAP_CS_AUTHEN_PEND;
2791 }
2792 } else {
2793 sk->sk_state = BT_CONNECT2;
2794 result = L2CAP_CR_PEND;
2795 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002796 }
2797
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002798 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002799
2800response:
2801 bh_unlock_sock(parent);
2802
2803sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002804 rsp.scid = cpu_to_le16(scid);
2805 rsp.dcid = cpu_to_le16(dcid);
2806 rsp.result = cpu_to_le16(result);
2807 rsp.status = cpu_to_le16(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002808 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002809
2810 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
2811 struct l2cap_info_req info;
2812 info.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
2813
2814 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
2815 conn->info_ident = l2cap_get_ident(conn);
2816
2817 mod_timer(&conn->info_timer, jiffies +
2818 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
2819
2820 l2cap_send_cmd(conn, conn->info_ident,
2821 L2CAP_INFO_REQ, sizeof(info), &info);
2822 }
2823
Linus Torvalds1da177e2005-04-16 15:20:36 -07002824 return 0;
2825}
2826
2827static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2828{
2829 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
2830 u16 scid, dcid, result, status;
2831 struct sock *sk;
2832 u8 req[128];
2833
2834 scid = __le16_to_cpu(rsp->scid);
2835 dcid = __le16_to_cpu(rsp->dcid);
2836 result = __le16_to_cpu(rsp->result);
2837 status = __le16_to_cpu(rsp->status);
2838
2839 BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
2840
2841 if (scid) {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002842 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2843 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002844 return 0;
2845 } else {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002846 sk = l2cap_get_chan_by_ident(&conn->chan_list, cmd->ident);
2847 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002848 return 0;
2849 }
2850
2851 switch (result) {
2852 case L2CAP_CR_SUCCESS:
2853 sk->sk_state = BT_CONFIG;
2854 l2cap_pi(sk)->ident = 0;
2855 l2cap_pi(sk)->dcid = dcid;
2856 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
2857
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002858 l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_CONNECT_PEND;
2859
Linus Torvalds1da177e2005-04-16 15:20:36 -07002860 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
2861 l2cap_build_conf_req(sk, req), req);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002862 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002863 break;
2864
2865 case L2CAP_CR_PEND:
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002866 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002867 break;
2868
2869 default:
2870 l2cap_chan_del(sk, ECONNREFUSED);
2871 break;
2872 }
2873
2874 bh_unlock_sock(sk);
2875 return 0;
2876}
2877
Al Viro88219a02007-07-29 00:17:25 -07002878static 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 -07002879{
2880 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
2881 u16 dcid, flags;
2882 u8 rsp[64];
2883 struct sock *sk;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002884 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002885
2886 dcid = __le16_to_cpu(req->dcid);
2887 flags = __le16_to_cpu(req->flags);
2888
2889 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
2890
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002891 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
2892 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002893 return -ENOENT;
2894
Marcel Holtmann354f60a2006-11-18 22:15:20 +01002895 if (sk->sk_state == BT_DISCONN)
2896 goto unlock;
2897
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002898 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07002899 len = cmd_len - sizeof(*req);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002900 if (l2cap_pi(sk)->conf_len + len > sizeof(l2cap_pi(sk)->conf_req)) {
2901 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
2902 l2cap_build_conf_rsp(sk, rsp,
2903 L2CAP_CONF_REJECT, flags), rsp);
2904 goto unlock;
2905 }
2906
2907 /* Store config. */
2908 memcpy(l2cap_pi(sk)->conf_req + l2cap_pi(sk)->conf_len, req->data, len);
2909 l2cap_pi(sk)->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002910
2911 if (flags & 0x0001) {
2912 /* Incomplete config. Send empty response. */
2913 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002914 l2cap_build_conf_rsp(sk, rsp,
2915 L2CAP_CONF_SUCCESS, 0x0001), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002916 goto unlock;
2917 }
2918
2919 /* Complete config. */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002920 len = l2cap_parse_conf_req(sk, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002921 if (len < 0) {
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002922 l2cap_send_disconn_req(conn, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002923 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002924 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002925
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002926 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002927 l2cap_pi(sk)->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002928
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002929 /* Reset config buffer. */
2930 l2cap_pi(sk)->conf_len = 0;
2931
Marcel Holtmann876d9482007-10-20 13:35:42 +02002932 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE))
2933 goto unlock;
2934
Linus Torvalds1da177e2005-04-16 15:20:36 -07002935 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) {
Joe Perchesf64f9e72009-11-29 16:55:45 -08002936 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) ||
2937 l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002938 l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
2939
Linus Torvalds1da177e2005-04-16 15:20:36 -07002940 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002941
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002942 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002943 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002944 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002945 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
2946 l2cap_ertm_init(sk);
2947
Linus Torvalds1da177e2005-04-16 15:20:36 -07002948 l2cap_chan_ready(sk);
Marcel Holtmann876d9482007-10-20 13:35:42 +02002949 goto unlock;
2950 }
2951
2952 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002953 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002954 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002955 l2cap_build_conf_req(sk, buf), buf);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002956 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002957 }
2958
2959unlock:
2960 bh_unlock_sock(sk);
2961 return 0;
2962}
2963
2964static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2965{
2966 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
2967 u16 scid, flags, result;
2968 struct sock *sk;
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002969 int len = cmd->len - sizeof(*rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002970
2971 scid = __le16_to_cpu(rsp->scid);
2972 flags = __le16_to_cpu(rsp->flags);
2973 result = __le16_to_cpu(rsp->result);
2974
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002975 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x",
2976 scid, flags, result);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002977
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002978 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2979 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002980 return 0;
2981
2982 switch (result) {
2983 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002984 l2cap_conf_rfc_get(sk, rsp->data, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002985 break;
2986
2987 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002988 if (l2cap_pi(sk)->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002989 char req[64];
2990
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02002991 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
2992 l2cap_send_disconn_req(conn, sk);
2993 goto done;
2994 }
2995
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002996 /* throw out any old stored conf requests */
2997 result = L2CAP_CONF_SUCCESS;
2998 len = l2cap_parse_conf_rsp(sk, rsp->data,
2999 len, req, &result);
3000 if (len < 0) {
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03003001 l2cap_send_disconn_req(conn, sk);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003002 goto done;
3003 }
3004
3005 l2cap_send_cmd(conn, l2cap_get_ident(conn),
3006 L2CAP_CONF_REQ, len, req);
3007 l2cap_pi(sk)->num_conf_req++;
3008 if (result != L2CAP_CONF_SUCCESS)
3009 goto done;
3010 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003011 }
3012
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09003013 default:
Linus Torvalds1da177e2005-04-16 15:20:36 -07003014 sk->sk_state = BT_DISCONN;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02003015 sk->sk_err = ECONNRESET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003016 l2cap_sock_set_timer(sk, HZ * 5);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03003017 l2cap_send_disconn_req(conn, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003018 goto done;
3019 }
3020
3021 if (flags & 0x01)
3022 goto done;
3023
Linus Torvalds1da177e2005-04-16 15:20:36 -07003024 l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE;
3025
3026 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) {
Joe Perchesf64f9e72009-11-29 16:55:45 -08003027 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) ||
3028 l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003029 l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
3030
Linus Torvalds1da177e2005-04-16 15:20:36 -07003031 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003032 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003033 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003034 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003035 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
3036 l2cap_ertm_init(sk);
3037
Linus Torvalds1da177e2005-04-16 15:20:36 -07003038 l2cap_chan_ready(sk);
3039 }
3040
3041done:
3042 bh_unlock_sock(sk);
3043 return 0;
3044}
3045
3046static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3047{
3048 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
3049 struct l2cap_disconn_rsp rsp;
3050 u16 dcid, scid;
3051 struct sock *sk;
3052
3053 scid = __le16_to_cpu(req->scid);
3054 dcid = __le16_to_cpu(req->dcid);
3055
3056 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
3057
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003058 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
3059 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003060 return 0;
3061
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003062 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
3063 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003064 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
3065
3066 sk->sk_shutdown = SHUTDOWN_MASK;
3067
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003068 skb_queue_purge(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003069
3070 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
3071 skb_queue_purge(SREJ_QUEUE(sk));
3072 del_timer(&l2cap_pi(sk)->retrans_timer);
3073 del_timer(&l2cap_pi(sk)->monitor_timer);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003074 del_timer(&l2cap_pi(sk)->ack_timer);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003075 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003076
Linus Torvalds1da177e2005-04-16 15:20:36 -07003077 l2cap_chan_del(sk, ECONNRESET);
3078 bh_unlock_sock(sk);
3079
3080 l2cap_sock_kill(sk);
3081 return 0;
3082}
3083
3084static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3085{
3086 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
3087 u16 dcid, scid;
3088 struct sock *sk;
3089
3090 scid = __le16_to_cpu(rsp->scid);
3091 dcid = __le16_to_cpu(rsp->dcid);
3092
3093 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
3094
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003095 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
3096 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003097 return 0;
3098
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003099 skb_queue_purge(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003100
3101 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
3102 skb_queue_purge(SREJ_QUEUE(sk));
3103 del_timer(&l2cap_pi(sk)->retrans_timer);
3104 del_timer(&l2cap_pi(sk)->monitor_timer);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003105 del_timer(&l2cap_pi(sk)->ack_timer);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003106 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003107
Linus Torvalds1da177e2005-04-16 15:20:36 -07003108 l2cap_chan_del(sk, 0);
3109 bh_unlock_sock(sk);
3110
3111 l2cap_sock_kill(sk);
3112 return 0;
3113}
3114
3115static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3116{
3117 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003118 u16 type;
3119
3120 type = __le16_to_cpu(req->type);
3121
3122 BT_DBG("type 0x%4.4x", type);
3123
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003124 if (type == L2CAP_IT_FEAT_MASK) {
3125 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003126 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003127 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
3128 rsp->type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
3129 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003130 if (enable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003131 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
3132 | L2CAP_FEAT_FCS;
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03003133 put_unaligned_le32(feat_mask, rsp->data);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003134 l2cap_send_cmd(conn, cmd->ident,
3135 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003136 } else if (type == L2CAP_IT_FIXED_CHAN) {
3137 u8 buf[12];
3138 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
3139 rsp->type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3140 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
3141 memcpy(buf + 4, l2cap_fixed_chan, 8);
3142 l2cap_send_cmd(conn, cmd->ident,
3143 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003144 } else {
3145 struct l2cap_info_rsp rsp;
3146 rsp.type = cpu_to_le16(type);
3147 rsp.result = cpu_to_le16(L2CAP_IR_NOTSUPP);
3148 l2cap_send_cmd(conn, cmd->ident,
3149 L2CAP_INFO_RSP, sizeof(rsp), &rsp);
3150 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003151
3152 return 0;
3153}
3154
3155static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3156{
3157 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
3158 u16 type, result;
3159
3160 type = __le16_to_cpu(rsp->type);
3161 result = __le16_to_cpu(rsp->result);
3162
3163 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
3164
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003165 del_timer(&conn->info_timer);
3166
Marcel Holtmann984947d2009-02-06 23:35:19 +01003167 if (type == L2CAP_IT_FEAT_MASK) {
Harvey Harrison83985312008-05-02 16:25:46 -07003168 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003169
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003170 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003171 struct l2cap_info_req req;
3172 req.type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3173
3174 conn->info_ident = l2cap_get_ident(conn);
3175
3176 l2cap_send_cmd(conn, conn->info_ident,
3177 L2CAP_INFO_REQ, sizeof(req), &req);
3178 } else {
3179 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
3180 conn->info_ident = 0;
3181
3182 l2cap_conn_start(conn);
3183 }
3184 } else if (type == L2CAP_IT_FIXED_CHAN) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01003185 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003186 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003187
3188 l2cap_conn_start(conn);
3189 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003190
Linus Torvalds1da177e2005-04-16 15:20:36 -07003191 return 0;
3192}
3193
3194static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
3195{
3196 u8 *data = skb->data;
3197 int len = skb->len;
3198 struct l2cap_cmd_hdr cmd;
3199 int err = 0;
3200
3201 l2cap_raw_recv(conn, skb);
3202
3203 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07003204 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003205 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
3206 data += L2CAP_CMD_HDR_SIZE;
3207 len -= L2CAP_CMD_HDR_SIZE;
3208
Al Viro88219a02007-07-29 00:17:25 -07003209 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003210
Al Viro88219a02007-07-29 00:17:25 -07003211 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 -07003212
Al Viro88219a02007-07-29 00:17:25 -07003213 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003214 BT_DBG("corrupted command");
3215 break;
3216 }
3217
3218 switch (cmd.code) {
3219 case L2CAP_COMMAND_REJ:
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003220 l2cap_command_rej(conn, &cmd, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003221 break;
3222
3223 case L2CAP_CONN_REQ:
3224 err = l2cap_connect_req(conn, &cmd, data);
3225 break;
3226
3227 case L2CAP_CONN_RSP:
3228 err = l2cap_connect_rsp(conn, &cmd, data);
3229 break;
3230
3231 case L2CAP_CONF_REQ:
Al Viro88219a02007-07-29 00:17:25 -07003232 err = l2cap_config_req(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003233 break;
3234
3235 case L2CAP_CONF_RSP:
3236 err = l2cap_config_rsp(conn, &cmd, data);
3237 break;
3238
3239 case L2CAP_DISCONN_REQ:
3240 err = l2cap_disconnect_req(conn, &cmd, data);
3241 break;
3242
3243 case L2CAP_DISCONN_RSP:
3244 err = l2cap_disconnect_rsp(conn, &cmd, data);
3245 break;
3246
3247 case L2CAP_ECHO_REQ:
Al Viro88219a02007-07-29 00:17:25 -07003248 l2cap_send_cmd(conn, cmd.ident, L2CAP_ECHO_RSP, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003249 break;
3250
3251 case L2CAP_ECHO_RSP:
3252 break;
3253
3254 case L2CAP_INFO_REQ:
3255 err = l2cap_information_req(conn, &cmd, data);
3256 break;
3257
3258 case L2CAP_INFO_RSP:
3259 err = l2cap_information_rsp(conn, &cmd, data);
3260 break;
3261
3262 default:
3263 BT_ERR("Unknown signaling command 0x%2.2x", cmd.code);
3264 err = -EINVAL;
3265 break;
3266 }
3267
3268 if (err) {
3269 struct l2cap_cmd_rej rej;
3270 BT_DBG("error %d", err);
3271
3272 /* FIXME: Map err to a valid reason */
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003273 rej.reason = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003274 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
3275 }
3276
Al Viro88219a02007-07-29 00:17:25 -07003277 data += cmd_len;
3278 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003279 }
3280
3281 kfree_skb(skb);
3282}
3283
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003284static int l2cap_check_fcs(struct l2cap_pinfo *pi, struct sk_buff *skb)
3285{
3286 u16 our_fcs, rcv_fcs;
3287 int hdr_size = L2CAP_HDR_SIZE + 2;
3288
3289 if (pi->fcs == L2CAP_FCS_CRC16) {
3290 skb_trim(skb, skb->len - 2);
3291 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
3292 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
3293
3294 if (our_fcs != rcv_fcs)
3295 return -EINVAL;
3296 }
3297 return 0;
3298}
3299
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003300static inline void l2cap_send_i_or_rr_or_rnr(struct sock *sk)
3301{
3302 struct l2cap_pinfo *pi = l2cap_pi(sk);
3303 u16 control = 0;
3304
3305 pi->frames_sent = 0;
3306 pi->conn_state |= L2CAP_CONN_SEND_FBIT;
3307
3308 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3309
3310 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
3311 control |= L2CAP_SUPER_RCV_NOT_READY | L2CAP_CTRL_FINAL;
3312 l2cap_send_sframe(pi, control);
3313 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
3314 }
3315
3316 if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY && pi->unacked_frames > 0)
3317 __mod_retrans_timer();
3318
3319 l2cap_ertm_send(sk);
3320
3321 if (!(pi->conn_state & L2CAP_CONN_LOCAL_BUSY) &&
3322 pi->frames_sent == 0) {
3323 control |= L2CAP_SUPER_RCV_READY;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003324 l2cap_send_sframe(pi, control);
3325 }
3326}
3327
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003328static void l2cap_add_to_srej_queue(struct sock *sk, struct sk_buff *skb, u8 tx_seq, u8 sar)
3329{
3330 struct sk_buff *next_skb;
3331
3332 bt_cb(skb)->tx_seq = tx_seq;
3333 bt_cb(skb)->sar = sar;
3334
3335 next_skb = skb_peek(SREJ_QUEUE(sk));
3336 if (!next_skb) {
3337 __skb_queue_tail(SREJ_QUEUE(sk), skb);
3338 return;
3339 }
3340
3341 do {
3342 if (bt_cb(next_skb)->tx_seq > tx_seq) {
3343 __skb_queue_before(SREJ_QUEUE(sk), next_skb, skb);
3344 return;
3345 }
3346
3347 if (skb_queue_is_last(SREJ_QUEUE(sk), next_skb))
3348 break;
3349
3350 } while((next_skb = skb_queue_next(SREJ_QUEUE(sk), next_skb)));
3351
3352 __skb_queue_tail(SREJ_QUEUE(sk), skb);
3353}
3354
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003355static int l2cap_sar_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
3356{
3357 struct l2cap_pinfo *pi = l2cap_pi(sk);
3358 struct sk_buff *_skb;
3359 int err = -EINVAL;
3360
3361 switch (control & L2CAP_CTRL_SAR) {
3362 case L2CAP_SDU_UNSEGMENTED:
3363 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3364 kfree_skb(pi->sdu);
3365 break;
3366 }
3367
3368 err = sock_queue_rcv_skb(sk, skb);
3369 if (!err)
3370 return 0;
3371
3372 break;
3373
3374 case L2CAP_SDU_START:
3375 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3376 kfree_skb(pi->sdu);
3377 break;
3378 }
3379
3380 pi->sdu_len = get_unaligned_le16(skb->data);
3381 skb_pull(skb, 2);
3382
Gustavo F. Padovan052897c2010-05-01 16:15:40 -03003383 if (pi->sdu_len > pi->imtu) {
3384 err = -EMSGSIZE;
3385 break;
3386 }
3387
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003388 pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
3389 if (!pi->sdu) {
3390 err = -ENOMEM;
3391 break;
3392 }
3393
3394 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3395
3396 pi->conn_state |= L2CAP_CONN_SAR_SDU;
3397 pi->partial_sdu_len = skb->len;
3398 err = 0;
3399 break;
3400
3401 case L2CAP_SDU_CONTINUE:
3402 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3403 break;
3404
3405 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3406
3407 pi->partial_sdu_len += skb->len;
3408 if (pi->partial_sdu_len > pi->sdu_len)
3409 kfree_skb(pi->sdu);
3410 else
3411 err = 0;
3412
3413 break;
3414
3415 case L2CAP_SDU_END:
3416 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3417 break;
3418
3419 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3420
3421 pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
3422 pi->partial_sdu_len += skb->len;
3423
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003424 if (pi->partial_sdu_len > pi->imtu)
3425 goto drop;
3426
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003427 if (pi->partial_sdu_len == pi->sdu_len) {
3428 _skb = skb_clone(pi->sdu, GFP_ATOMIC);
3429 err = sock_queue_rcv_skb(sk, _skb);
3430 if (err < 0)
3431 kfree_skb(_skb);
3432 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003433 err = 0;
3434
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003435drop:
3436 kfree_skb(pi->sdu);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003437 break;
3438 }
3439
3440 kfree_skb(skb);
3441 return err;
3442}
3443
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003444static void l2cap_check_srej_gap(struct sock *sk, u8 tx_seq)
3445{
3446 struct sk_buff *skb;
Gustavo F. Padovanafefdbc2010-05-01 16:15:43 -03003447 u16 control;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003448
3449 while((skb = skb_peek(SREJ_QUEUE(sk)))) {
3450 if (bt_cb(skb)->tx_seq != tx_seq)
3451 break;
3452
3453 skb = skb_dequeue(SREJ_QUEUE(sk));
Gustavo F. Padovanafefdbc2010-05-01 16:15:43 -03003454 control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003455 l2cap_sar_reassembly_sdu(sk, skb, control);
3456 l2cap_pi(sk)->buffer_seq_srej =
3457 (l2cap_pi(sk)->buffer_seq_srej + 1) % 64;
3458 tx_seq++;
3459 }
3460}
3461
3462static void l2cap_resend_srejframe(struct sock *sk, u8 tx_seq)
3463{
3464 struct l2cap_pinfo *pi = l2cap_pi(sk);
3465 struct srej_list *l, *tmp;
3466 u16 control;
3467
3468 list_for_each_entry_safe(l,tmp, SREJ_LIST(sk), list) {
3469 if (l->tx_seq == tx_seq) {
3470 list_del(&l->list);
3471 kfree(l);
3472 return;
3473 }
3474 control = L2CAP_SUPER_SELECT_REJECT;
3475 control |= l->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3476 l2cap_send_sframe(pi, control);
3477 list_del(&l->list);
3478 list_add_tail(&l->list, SREJ_LIST(sk));
3479 }
3480}
3481
3482static void l2cap_send_srejframe(struct sock *sk, u8 tx_seq)
3483{
3484 struct l2cap_pinfo *pi = l2cap_pi(sk);
3485 struct srej_list *new;
3486 u16 control;
3487
3488 while (tx_seq != pi->expected_tx_seq) {
3489 control = L2CAP_SUPER_SELECT_REJECT;
3490 control |= pi->expected_tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3491 l2cap_send_sframe(pi, control);
3492
3493 new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC);
3494 new->tx_seq = pi->expected_tx_seq++;
3495 list_add_tail(&new->list, SREJ_LIST(sk));
3496 }
3497 pi->expected_tx_seq++;
3498}
3499
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003500static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
3501{
3502 struct l2cap_pinfo *pi = l2cap_pi(sk);
3503 u8 tx_seq = __get_txseq(rx_control);
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003504 u8 req_seq = __get_reqseq(rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003505 u8 sar = rx_control >> L2CAP_CTRL_SAR_SHIFT;
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03003506 int num_to_ack = (pi->tx_win/6) + 1;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003507 int err = 0;
3508
3509 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
3510
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003511 if (L2CAP_CTRL_FINAL & rx_control) {
3512 del_timer(&pi->monitor_timer);
3513 if (pi->unacked_frames > 0)
3514 __mod_retrans_timer();
3515 pi->conn_state &= ~L2CAP_CONN_WAIT_F;
3516 }
3517
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003518 pi->expected_ack_seq = req_seq;
3519 l2cap_drop_acked_frames(sk);
3520
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003521 if (tx_seq == pi->expected_tx_seq)
3522 goto expected;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003523
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003524 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3525 struct srej_list *first;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003526
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003527 first = list_first_entry(SREJ_LIST(sk),
3528 struct srej_list, list);
3529 if (tx_seq == first->tx_seq) {
3530 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3531 l2cap_check_srej_gap(sk, tx_seq);
3532
3533 list_del(&first->list);
3534 kfree(first);
3535
3536 if (list_empty(SREJ_LIST(sk))) {
3537 pi->buffer_seq = pi->buffer_seq_srej;
3538 pi->conn_state &= ~L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan855666cc2010-05-01 16:15:40 -03003539 l2cap_send_ack(pi);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003540 }
3541 } else {
3542 struct srej_list *l;
3543 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3544
3545 list_for_each_entry(l, SREJ_LIST(sk), list) {
3546 if (l->tx_seq == tx_seq) {
3547 l2cap_resend_srejframe(sk, tx_seq);
3548 return 0;
3549 }
3550 }
3551 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003552 }
3553 } else {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003554 pi->conn_state |= L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003555
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003556 INIT_LIST_HEAD(SREJ_LIST(sk));
3557 pi->buffer_seq_srej = pi->buffer_seq;
3558
3559 __skb_queue_head_init(SREJ_QUEUE(sk));
3560 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3561
Gustavo F. Padovanef54fd92009-08-20 22:26:04 -03003562 pi->conn_state |= L2CAP_CONN_SEND_PBIT;
3563
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003564 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003565 }
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003566 return 0;
3567
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003568expected:
3569 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
3570
3571 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
Gustavo F. Padovan3b1a9f32010-05-01 16:15:42 -03003572 bt_cb(skb)->tx_seq = tx_seq;
3573 bt_cb(skb)->sar = sar;
3574 __skb_queue_tail(SREJ_QUEUE(sk), skb);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003575 return 0;
3576 }
3577
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03003578 if (rx_control & L2CAP_CTRL_FINAL) {
3579 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3580 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
3581 else {
Gustavo F. Padovanf6e6b162010-05-01 16:15:41 -03003582 if (!skb_queue_empty(TX_QUEUE(sk)))
3583 sk->sk_send_head = TX_QUEUE(sk)->next;
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03003584 pi->next_tx_seq = pi->expected_ack_seq;
3585 l2cap_ertm_send(sk);
3586 }
3587 }
3588
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003589 pi->buffer_seq = (pi->buffer_seq + 1) % 64;
3590
3591 err = l2cap_sar_reassembly_sdu(sk, skb, rx_control);
3592 if (err < 0)
3593 return err;
3594
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003595 __mod_ack_timer();
3596
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03003597 pi->num_acked = (pi->num_acked + 1) % num_to_ack;
3598 if (pi->num_acked == num_to_ack - 1)
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03003599 l2cap_send_ack(pi);
3600
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003601 return 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003602}
3603
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003604static inline void l2cap_data_channel_rrframe(struct sock *sk, u16 rx_control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003605{
3606 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan6e3a5982010-05-01 16:15:38 -03003607
3608 pi->expected_ack_seq = __get_reqseq(rx_control);
3609 l2cap_drop_acked_frames(sk);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003610
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003611 if (rx_control & L2CAP_CTRL_POLL) {
Gustavo F. Padovan05fbd892010-05-01 16:15:39 -03003612 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3613 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
3614 (pi->unacked_frames > 0))
3615 __mod_retrans_timer();
3616
3617 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3618 l2cap_send_srejtail(sk);
3619 } else {
3620 l2cap_send_i_or_rr_or_rnr(sk);
3621 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3622 }
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003623
3624 } else if (rx_control & L2CAP_CTRL_FINAL) {
3625 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003626
3627 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3628 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
3629 else {
Gustavo F. Padovanf6e6b162010-05-01 16:15:41 -03003630 if (!skb_queue_empty(TX_QUEUE(sk)))
3631 sk->sk_send_head = TX_QUEUE(sk)->next;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003632 pi->next_tx_seq = pi->expected_ack_seq;
3633 l2cap_ertm_send(sk);
3634 }
3635
3636 } else {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003637 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
3638 (pi->unacked_frames > 0))
3639 __mod_retrans_timer();
3640
3641 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3642 if (pi->conn_state & L2CAP_CONN_SREJ_SENT)
3643 l2cap_send_ack(pi);
3644 else
3645 l2cap_ertm_send(sk);
3646 }
3647}
3648
3649static inline void l2cap_data_channel_rejframe(struct sock *sk, u16 rx_control)
3650{
3651 struct l2cap_pinfo *pi = l2cap_pi(sk);
3652 u8 tx_seq = __get_reqseq(rx_control);
3653
3654 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3655
Gustavo F. Padovan8abb52e2010-05-01 16:15:38 -03003656 pi->expected_ack_seq = tx_seq;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003657 l2cap_drop_acked_frames(sk);
3658
3659 if (rx_control & L2CAP_CTRL_FINAL) {
3660 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3661 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
3662 else {
Gustavo F. Padovanf6e6b162010-05-01 16:15:41 -03003663 if (!skb_queue_empty(TX_QUEUE(sk)))
3664 sk->sk_send_head = TX_QUEUE(sk)->next;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003665 pi->next_tx_seq = pi->expected_ack_seq;
3666 l2cap_ertm_send(sk);
3667 }
3668 } else {
Gustavo F. Padovanf6e6b162010-05-01 16:15:41 -03003669 if (!skb_queue_empty(TX_QUEUE(sk)))
3670 sk->sk_send_head = TX_QUEUE(sk)->next;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003671 pi->next_tx_seq = pi->expected_ack_seq;
3672 l2cap_ertm_send(sk);
3673
3674 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
3675 pi->srej_save_reqseq = tx_seq;
3676 pi->conn_state |= L2CAP_CONN_REJ_ACT;
3677 }
3678 }
3679}
3680static inline void l2cap_data_channel_srejframe(struct sock *sk, u16 rx_control)
3681{
3682 struct l2cap_pinfo *pi = l2cap_pi(sk);
3683 u8 tx_seq = __get_reqseq(rx_control);
3684
3685 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3686
3687 if (rx_control & L2CAP_CTRL_POLL) {
3688 pi->expected_ack_seq = tx_seq;
3689 l2cap_drop_acked_frames(sk);
3690 l2cap_retransmit_frame(sk, tx_seq);
3691 l2cap_ertm_send(sk);
3692 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
3693 pi->srej_save_reqseq = tx_seq;
3694 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
3695 }
3696 } else if (rx_control & L2CAP_CTRL_FINAL) {
3697 if ((pi->conn_state & L2CAP_CONN_SREJ_ACT) &&
3698 pi->srej_save_reqseq == tx_seq)
3699 pi->conn_state &= ~L2CAP_CONN_SREJ_ACT;
3700 else
3701 l2cap_retransmit_frame(sk, tx_seq);
3702 } else {
3703 l2cap_retransmit_frame(sk, tx_seq);
3704 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
3705 pi->srej_save_reqseq = tx_seq;
3706 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
3707 }
3708 }
3709}
3710
3711static inline void l2cap_data_channel_rnrframe(struct sock *sk, u16 rx_control)
3712{
3713 struct l2cap_pinfo *pi = l2cap_pi(sk);
3714 u8 tx_seq = __get_reqseq(rx_control);
3715
3716 pi->conn_state |= L2CAP_CONN_REMOTE_BUSY;
3717 pi->expected_ack_seq = tx_seq;
3718 l2cap_drop_acked_frames(sk);
3719
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03003720 if (!(pi->conn_state & L2CAP_CONN_SREJ_SENT)) {
3721 del_timer(&pi->retrans_timer);
3722 if (rx_control & L2CAP_CTRL_POLL) {
3723 u16 control = L2CAP_CTRL_FINAL;
3724 l2cap_send_rr_or_rnr(pi, control);
3725 }
3726 return;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003727 }
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03003728
3729 if (rx_control & L2CAP_CTRL_POLL)
3730 l2cap_send_srejtail(sk);
3731 else
3732 l2cap_send_sframe(pi, L2CAP_SUPER_RCV_READY);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003733}
3734
3735static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
3736{
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003737 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
3738
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003739 if (L2CAP_CTRL_FINAL & rx_control) {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003740 del_timer(&l2cap_pi(sk)->monitor_timer);
3741 if (l2cap_pi(sk)->unacked_frames > 0)
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003742 __mod_retrans_timer();
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003743 l2cap_pi(sk)->conn_state &= ~L2CAP_CONN_WAIT_F;
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003744 }
3745
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003746 switch (rx_control & L2CAP_CTRL_SUPERVISE) {
3747 case L2CAP_SUPER_RCV_READY:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003748 l2cap_data_channel_rrframe(sk, rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003749 break;
3750
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003751 case L2CAP_SUPER_REJECT:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003752 l2cap_data_channel_rejframe(sk, rx_control);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003753 break;
3754
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003755 case L2CAP_SUPER_SELECT_REJECT:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003756 l2cap_data_channel_srejframe(sk, rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003757 break;
3758
3759 case L2CAP_SUPER_RCV_NOT_READY:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003760 l2cap_data_channel_rnrframe(sk, rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003761 break;
3762 }
3763
Gustavo F. Padovanfaaebd12010-05-01 16:15:35 -03003764 kfree_skb(skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003765 return 0;
3766}
3767
Linus Torvalds1da177e2005-04-16 15:20:36 -07003768static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk_buff *skb)
3769{
3770 struct sock *sk;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003771 struct l2cap_pinfo *pi;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003772 u16 control, len;
João Paulo Rechi Vita01760bd2010-05-01 16:15:43 -03003773 u8 tx_seq, req_seq, next_tx_seq_offset, req_seq_offset;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003774
3775 sk = l2cap_get_chan_by_scid(&conn->chan_list, cid);
3776 if (!sk) {
3777 BT_DBG("unknown cid 0x%4.4x", cid);
3778 goto drop;
3779 }
3780
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003781 pi = l2cap_pi(sk);
3782
Linus Torvalds1da177e2005-04-16 15:20:36 -07003783 BT_DBG("sk %p, len %d", sk, skb->len);
3784
3785 if (sk->sk_state != BT_CONNECTED)
3786 goto drop;
3787
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003788 switch (pi->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003789 case L2CAP_MODE_BASIC:
3790 /* If socket recv buffers overflows we drop data here
3791 * which is *bad* because L2CAP has to be reliable.
3792 * But we don't have any other choice. L2CAP doesn't
3793 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003794
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003795 if (pi->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003796 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003797
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003798 if (!sock_queue_rcv_skb(sk, skb))
3799 goto done;
3800 break;
3801
3802 case L2CAP_MODE_ERTM:
3803 control = get_unaligned_le16(skb->data);
3804 skb_pull(skb, 2);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003805 len = skb->len;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003806
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003807 if (__is_sar_start(control))
3808 len -= 2;
3809
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003810 if (pi->fcs == L2CAP_FCS_CRC16)
3811 len -= 2;
3812
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003813 /*
3814 * We can just drop the corrupted I-frame here.
3815 * Receiver will miss it and start proper recovery
3816 * procedures and ask retransmission.
3817 */
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03003818 if (len > pi->mps)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003819 goto drop;
3820
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003821 if (l2cap_check_fcs(pi, skb))
3822 goto drop;
3823
João Paulo Rechi Vita01760bd2010-05-01 16:15:43 -03003824 req_seq = __get_reqseq(control);
3825 req_seq_offset = (req_seq - pi->expected_ack_seq) % 64;
3826 if (req_seq_offset < 0)
3827 req_seq_offset += 64;
3828
3829 next_tx_seq_offset =
3830 (pi->next_tx_seq - pi->expected_ack_seq) % 64;
3831 if (next_tx_seq_offset < 0)
3832 next_tx_seq_offset += 64;
3833
3834 /* check for invalid req-seq */
3835 if (req_seq_offset > next_tx_seq_offset) {
3836 l2cap_send_disconn_req(pi->conn, sk);
3837 goto drop;
3838 }
3839
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03003840 if (__is_iframe(control)) {
3841 if (len < 4)
3842 goto drop;
3843
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02003844 l2cap_data_channel_iframe(sk, control, skb);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03003845 } else {
3846 if (len != 0)
3847 goto drop;
3848
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02003849 l2cap_data_channel_sframe(sk, control, skb);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03003850 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003851
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02003852 goto done;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003853
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003854 case L2CAP_MODE_STREAMING:
3855 control = get_unaligned_le16(skb->data);
3856 skb_pull(skb, 2);
3857 len = skb->len;
3858
3859 if (__is_sar_start(control))
3860 len -= 2;
3861
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003862 if (pi->fcs == L2CAP_FCS_CRC16)
3863 len -= 2;
3864
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03003865 if (len > pi->mps || len < 4 || __is_sframe(control))
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003866 goto drop;
3867
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003868 if (l2cap_check_fcs(pi, skb))
3869 goto drop;
3870
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003871 tx_seq = __get_txseq(control);
3872
3873 if (pi->expected_tx_seq == tx_seq)
3874 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
3875 else
Gustavo F. Padovan7dffe422010-05-01 16:15:36 -03003876 pi->expected_tx_seq = (tx_seq + 1) % 64;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003877
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02003878 l2cap_sar_reassembly_sdu(sk, skb, control);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003879
3880 goto done;
3881
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003882 default:
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03003883 BT_DBG("sk %p: bad mode 0x%2.2x", sk, pi->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003884 break;
3885 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003886
3887drop:
3888 kfree_skb(skb);
3889
3890done:
Marcel Holtmann01394182006-07-03 10:02:46 +02003891 if (sk)
3892 bh_unlock_sock(sk);
3893
Linus Torvalds1da177e2005-04-16 15:20:36 -07003894 return 0;
3895}
3896
Al Viro8e036fc2007-07-29 00:16:36 -07003897static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003898{
3899 struct sock *sk;
3900
3901 sk = l2cap_get_sock_by_psm(0, psm, conn->src);
3902 if (!sk)
3903 goto drop;
3904
3905 BT_DBG("sk %p, len %d", sk, skb->len);
3906
3907 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_CONNECTED)
3908 goto drop;
3909
3910 if (l2cap_pi(sk)->imtu < skb->len)
3911 goto drop;
3912
3913 if (!sock_queue_rcv_skb(sk, skb))
3914 goto done;
3915
3916drop:
3917 kfree_skb(skb);
3918
3919done:
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003920 if (sk)
3921 bh_unlock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003922 return 0;
3923}
3924
3925static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
3926{
3927 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07003928 u16 cid, len;
3929 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003930
3931 skb_pull(skb, L2CAP_HDR_SIZE);
3932 cid = __le16_to_cpu(lh->cid);
3933 len = __le16_to_cpu(lh->len);
3934
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003935 if (len != skb->len) {
3936 kfree_skb(skb);
3937 return;
3938 }
3939
Linus Torvalds1da177e2005-04-16 15:20:36 -07003940 BT_DBG("len %d, cid 0x%4.4x", len, cid);
3941
3942 switch (cid) {
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03003943 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07003944 l2cap_sig_channel(conn, skb);
3945 break;
3946
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03003947 case L2CAP_CID_CONN_LESS:
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03003948 psm = get_unaligned_le16(skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003949 skb_pull(skb, 2);
3950 l2cap_conless_channel(conn, psm, skb);
3951 break;
3952
3953 default:
3954 l2cap_data_channel(conn, cid, skb);
3955 break;
3956 }
3957}
3958
3959/* ---- L2CAP interface with lower layer (HCI) ---- */
3960
3961static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
3962{
3963 int exact = 0, lm1 = 0, lm2 = 0;
3964 register struct sock *sk;
3965 struct hlist_node *node;
3966
3967 if (type != ACL_LINK)
3968 return 0;
3969
3970 BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
3971
3972 /* Find listening sockets and check their link_mode */
3973 read_lock(&l2cap_sk_list.lock);
3974 sk_for_each(sk, node, &l2cap_sk_list.head) {
3975 if (sk->sk_state != BT_LISTEN)
3976 continue;
3977
3978 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01003979 lm1 |= HCI_LM_ACCEPT;
3980 if (l2cap_pi(sk)->role_switch)
3981 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003982 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01003983 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
3984 lm2 |= HCI_LM_ACCEPT;
3985 if (l2cap_pi(sk)->role_switch)
3986 lm2 |= HCI_LM_MASTER;
3987 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003988 }
3989 read_unlock(&l2cap_sk_list.lock);
3990
3991 return exact ? lm1 : lm2;
3992}
3993
3994static int l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
3995{
Marcel Holtmann01394182006-07-03 10:02:46 +02003996 struct l2cap_conn *conn;
3997
Linus Torvalds1da177e2005-04-16 15:20:36 -07003998 BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
3999
4000 if (hcon->type != ACL_LINK)
4001 return 0;
4002
4003 if (!status) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004004 conn = l2cap_conn_add(hcon, status);
4005 if (conn)
4006 l2cap_conn_ready(conn);
Marcel Holtmann01394182006-07-03 10:02:46 +02004007 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -07004008 l2cap_conn_del(hcon, bt_err(status));
4009
4010 return 0;
4011}
4012
Marcel Holtmann2950f212009-02-12 14:02:50 +01004013static int l2cap_disconn_ind(struct hci_conn *hcon)
4014{
4015 struct l2cap_conn *conn = hcon->l2cap_data;
4016
4017 BT_DBG("hcon %p", hcon);
4018
4019 if (hcon->type != ACL_LINK || !conn)
4020 return 0x13;
4021
4022 return conn->disc_reason;
4023}
4024
4025static int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004026{
4027 BT_DBG("hcon %p reason %d", hcon, reason);
4028
4029 if (hcon->type != ACL_LINK)
4030 return 0;
4031
4032 l2cap_conn_del(hcon, bt_err(reason));
Marcel Holtmann01394182006-07-03 10:02:46 +02004033
Linus Torvalds1da177e2005-04-16 15:20:36 -07004034 return 0;
4035}
4036
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004037static inline void l2cap_check_encryption(struct sock *sk, u8 encrypt)
4038{
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03004039 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM)
Marcel Holtmann255c7602009-02-04 21:07:19 +01004040 return;
4041
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004042 if (encrypt == 0x00) {
4043 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM) {
4044 l2cap_sock_clear_timer(sk);
4045 l2cap_sock_set_timer(sk, HZ * 5);
4046 } else if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
4047 __l2cap_sock_close(sk, ECONNREFUSED);
4048 } else {
4049 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM)
4050 l2cap_sock_clear_timer(sk);
4051 }
4052}
4053
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004054static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004055{
4056 struct l2cap_chan_list *l;
Marcel Holtmann40be4922008-07-14 20:13:50 +02004057 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004058 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004059
Marcel Holtmann01394182006-07-03 10:02:46 +02004060 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004061 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02004062
Linus Torvalds1da177e2005-04-16 15:20:36 -07004063 l = &conn->chan_list;
4064
4065 BT_DBG("conn %p", conn);
4066
4067 read_lock(&l->lock);
4068
4069 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
4070 bh_lock_sock(sk);
4071
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01004072 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND) {
4073 bh_unlock_sock(sk);
4074 continue;
4075 }
4076
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004077 if (!status && (sk->sk_state == BT_CONNECTED ||
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004078 sk->sk_state == BT_CONFIG)) {
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004079 l2cap_check_encryption(sk, encrypt);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02004080 bh_unlock_sock(sk);
4081 continue;
4082 }
4083
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004084 if (sk->sk_state == BT_CONNECT) {
4085 if (!status) {
4086 struct l2cap_conn_req req;
4087 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
4088 req.psm = l2cap_pi(sk)->psm;
4089
4090 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
4091
4092 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
4093 L2CAP_CONN_REQ, sizeof(req), &req);
4094 } else {
4095 l2cap_sock_clear_timer(sk);
4096 l2cap_sock_set_timer(sk, HZ / 10);
4097 }
4098 } else if (sk->sk_state == BT_CONNECT2) {
4099 struct l2cap_conn_rsp rsp;
4100 __u16 result;
4101
4102 if (!status) {
4103 sk->sk_state = BT_CONFIG;
4104 result = L2CAP_CR_SUCCESS;
4105 } else {
4106 sk->sk_state = BT_DISCONN;
4107 l2cap_sock_set_timer(sk, HZ / 10);
4108 result = L2CAP_CR_SEC_BLOCK;
4109 }
4110
4111 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
4112 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
4113 rsp.result = cpu_to_le16(result);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02004114 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004115 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
4116 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004117 }
4118
Linus Torvalds1da177e2005-04-16 15:20:36 -07004119 bh_unlock_sock(sk);
4120 }
4121
4122 read_unlock(&l->lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004123
Linus Torvalds1da177e2005-04-16 15:20:36 -07004124 return 0;
4125}
4126
4127static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
4128{
4129 struct l2cap_conn *conn = hcon->l2cap_data;
4130
4131 if (!conn && !(conn = l2cap_conn_add(hcon, 0)))
4132 goto drop;
4133
4134 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
4135
4136 if (flags & ACL_START) {
4137 struct l2cap_hdr *hdr;
4138 int len;
4139
4140 if (conn->rx_len) {
4141 BT_ERR("Unexpected start frame (len %d)", skb->len);
4142 kfree_skb(conn->rx_skb);
4143 conn->rx_skb = NULL;
4144 conn->rx_len = 0;
4145 l2cap_conn_unreliable(conn, ECOMM);
4146 }
4147
4148 if (skb->len < 2) {
4149 BT_ERR("Frame is too short (len %d)", skb->len);
4150 l2cap_conn_unreliable(conn, ECOMM);
4151 goto drop;
4152 }
4153
4154 hdr = (struct l2cap_hdr *) skb->data;
4155 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
4156
4157 if (len == skb->len) {
4158 /* Complete frame received */
4159 l2cap_recv_frame(conn, skb);
4160 return 0;
4161 }
4162
4163 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
4164
4165 if (skb->len > len) {
4166 BT_ERR("Frame is too long (len %d, expected len %d)",
4167 skb->len, len);
4168 l2cap_conn_unreliable(conn, ECOMM);
4169 goto drop;
4170 }
4171
4172 /* Allocate skb for the complete frame (with header) */
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03004173 conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC);
4174 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004175 goto drop;
4176
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03004177 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004178 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004179 conn->rx_len = len - skb->len;
4180 } else {
4181 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
4182
4183 if (!conn->rx_len) {
4184 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
4185 l2cap_conn_unreliable(conn, ECOMM);
4186 goto drop;
4187 }
4188
4189 if (skb->len > conn->rx_len) {
4190 BT_ERR("Fragment is too long (len %d, expected %d)",
4191 skb->len, conn->rx_len);
4192 kfree_skb(conn->rx_skb);
4193 conn->rx_skb = NULL;
4194 conn->rx_len = 0;
4195 l2cap_conn_unreliable(conn, ECOMM);
4196 goto drop;
4197 }
4198
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03004199 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004200 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004201 conn->rx_len -= skb->len;
4202
4203 if (!conn->rx_len) {
4204 /* Complete frame received */
4205 l2cap_recv_frame(conn, conn->rx_skb);
4206 conn->rx_skb = NULL;
4207 }
4208 }
4209
4210drop:
4211 kfree_skb(skb);
4212 return 0;
4213}
4214
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004215static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004216{
4217 struct sock *sk;
4218 struct hlist_node *node;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004219
4220 read_lock_bh(&l2cap_sk_list.lock);
4221
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004222 sk_for_each(sk, node, &l2cap_sk_list.head) {
4223 struct l2cap_pinfo *pi = l2cap_pi(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004224
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004225 seq_printf(f, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d\n",
4226 batostr(&bt_sk(sk)->src),
4227 batostr(&bt_sk(sk)->dst),
4228 sk->sk_state, __le16_to_cpu(pi->psm),
4229 pi->scid, pi->dcid,
4230 pi->imtu, pi->omtu, pi->sec_level);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004231 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004232
Linus Torvalds1da177e2005-04-16 15:20:36 -07004233 read_unlock_bh(&l2cap_sk_list.lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004234
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004235 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004236}
4237
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004238static int l2cap_debugfs_open(struct inode *inode, struct file *file)
4239{
4240 return single_open(file, l2cap_debugfs_show, inode->i_private);
4241}
4242
4243static const struct file_operations l2cap_debugfs_fops = {
4244 .open = l2cap_debugfs_open,
4245 .read = seq_read,
4246 .llseek = seq_lseek,
4247 .release = single_release,
4248};
4249
4250static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004251
Eric Dumazet90ddc4f2005-12-22 12:49:22 -08004252static const struct proto_ops l2cap_sock_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004253 .family = PF_BLUETOOTH,
4254 .owner = THIS_MODULE,
4255 .release = l2cap_sock_release,
4256 .bind = l2cap_sock_bind,
4257 .connect = l2cap_sock_connect,
4258 .listen = l2cap_sock_listen,
4259 .accept = l2cap_sock_accept,
4260 .getname = l2cap_sock_getname,
4261 .sendmsg = l2cap_sock_sendmsg,
Marcel Holtmannf66dc812009-01-15 21:57:00 +01004262 .recvmsg = l2cap_sock_recvmsg,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004263 .poll = bt_sock_poll,
Marcel Holtmann3241ad82008-07-14 20:13:50 +02004264 .ioctl = bt_sock_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004265 .mmap = sock_no_mmap,
4266 .socketpair = sock_no_socketpair,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004267 .shutdown = l2cap_sock_shutdown,
4268 .setsockopt = l2cap_sock_setsockopt,
4269 .getsockopt = l2cap_sock_getsockopt
4270};
4271
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +00004272static const struct net_proto_family l2cap_sock_family_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004273 .family = PF_BLUETOOTH,
4274 .owner = THIS_MODULE,
4275 .create = l2cap_sock_create,
4276};
4277
4278static struct hci_proto l2cap_hci_proto = {
4279 .name = "L2CAP",
4280 .id = HCI_PROTO_L2CAP,
4281 .connect_ind = l2cap_connect_ind,
4282 .connect_cfm = l2cap_connect_cfm,
4283 .disconn_ind = l2cap_disconn_ind,
Marcel Holtmann2950f212009-02-12 14:02:50 +01004284 .disconn_cfm = l2cap_disconn_cfm,
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004285 .security_cfm = l2cap_security_cfm,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004286 .recv_acldata = l2cap_recv_acldata
4287};
4288
4289static int __init l2cap_init(void)
4290{
4291 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004292
Linus Torvalds1da177e2005-04-16 15:20:36 -07004293 err = proto_register(&l2cap_proto, 0);
4294 if (err < 0)
4295 return err;
4296
4297 err = bt_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops);
4298 if (err < 0) {
4299 BT_ERR("L2CAP socket registration failed");
4300 goto error;
4301 }
4302
4303 err = hci_register_proto(&l2cap_hci_proto);
4304 if (err < 0) {
4305 BT_ERR("L2CAP protocol registration failed");
4306 bt_sock_unregister(BTPROTO_L2CAP);
4307 goto error;
4308 }
4309
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004310 if (bt_debugfs) {
4311 l2cap_debugfs = debugfs_create_file("l2cap", 0444,
4312 bt_debugfs, NULL, &l2cap_debugfs_fops);
4313 if (!l2cap_debugfs)
4314 BT_ERR("Failed to create L2CAP debug file");
4315 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004316
4317 BT_INFO("L2CAP ver %s", VERSION);
4318 BT_INFO("L2CAP socket layer initialized");
4319
4320 return 0;
4321
4322error:
4323 proto_unregister(&l2cap_proto);
4324 return err;
4325}
4326
4327static void __exit l2cap_exit(void)
4328{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004329 debugfs_remove(l2cap_debugfs);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004330
4331 if (bt_sock_unregister(BTPROTO_L2CAP) < 0)
4332 BT_ERR("L2CAP socket unregistration failed");
4333
4334 if (hci_unregister_proto(&l2cap_hci_proto) < 0)
4335 BT_ERR("L2CAP protocol unregistration failed");
4336
4337 proto_unregister(&l2cap_proto);
4338}
4339
4340void l2cap_load(void)
4341{
4342 /* Dummy function to trigger automatic L2CAP module loading by
4343 * other modules that use L2CAP sockets but don't use any other
4344 * symbols from it. */
4345 return;
4346}
4347EXPORT_SYMBOL(l2cap_load);
4348
4349module_init(l2cap_init);
4350module_exit(l2cap_exit);
4351
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07004352module_param(enable_ertm, bool, 0644);
4353MODULE_PARM_DESC(enable_ertm, "Enable enhanced retransmission mode");
4354
Marcel Holtmann5fbcd3d2009-10-05 11:35:43 +02004355module_param(max_transmit, uint, 0644);
4356MODULE_PARM_DESC(max_transmit, "Max transmit value (default = 3)");
4357
Gustavo F. Padovan369ba302010-05-01 16:15:41 -03004358module_param(tx_window, uint, 0644);
4359MODULE_PARM_DESC(tx_window, "Transmission window size value (default = 63)");
4360
Marcel Holtmann63fbd242008-08-18 13:23:53 +02004361MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004362MODULE_DESCRIPTION("Bluetooth L2CAP ver " VERSION);
4363MODULE_VERSION(VERSION);
4364MODULE_LICENSE("GPL");
4365MODULE_ALIAS("bt-proto-0");