blob: 31514d8faa6621b8aaadd438448aecace166c4f9 [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 control = 0;
1640
1641 while (len > 0) {
1642 size_t buflen;
1643
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001644 if (len > pi->remote_mps) {
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001645 control |= L2CAP_SDU_CONTINUE;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001646 buflen = pi->remote_mps;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001647 } else {
1648 control |= L2CAP_SDU_END;
1649 buflen = len;
1650 }
1651
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001652 skb = l2cap_create_iframe_pdu(sk, msg, buflen, control, 0);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001653 if (IS_ERR(skb)) {
1654 skb_queue_purge(&sar_queue);
1655 return PTR_ERR(skb);
1656 }
1657
1658 __skb_queue_tail(&sar_queue, skb);
1659 len -= buflen;
1660 size += buflen;
1661 control = 0;
1662 }
1663 skb_queue_splice_tail(&sar_queue, TX_QUEUE(sk));
1664 if (sk->sk_send_head == NULL)
1665 sk->sk_send_head = sar_queue.next;
1666
1667 return size;
1668}
1669
Linus Torvalds1da177e2005-04-16 15:20:36 -07001670static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len)
1671{
1672 struct sock *sk = sock->sk;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001673 struct l2cap_pinfo *pi = l2cap_pi(sk);
1674 struct sk_buff *skb;
1675 u16 control;
1676 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001677
1678 BT_DBG("sock %p, sk %p", sock, sk);
1679
Benjamin LaHaisec1cbe4b2005-12-13 23:22:19 -08001680 err = sock_error(sk);
1681 if (err)
1682 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001683
1684 if (msg->msg_flags & MSG_OOB)
1685 return -EOPNOTSUPP;
1686
Linus Torvalds1da177e2005-04-16 15:20:36 -07001687 lock_sock(sk);
1688
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001689 if (sk->sk_state != BT_CONNECTED) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001690 err = -ENOTCONN;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001691 goto done;
1692 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001693
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001694 /* Connectionless channel */
1695 if (sk->sk_type == SOCK_DGRAM) {
1696 skb = l2cap_create_connless_pdu(sk, msg, len);
Dan Carpenter477fffb2010-04-21 23:52:01 +00001697 if (IS_ERR(skb))
1698 err = PTR_ERR(skb);
1699 else
1700 err = l2cap_do_send(sk, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001701 goto done;
1702 }
1703
1704 switch (pi->mode) {
1705 case L2CAP_MODE_BASIC:
Gustavo F. Padovanc69163e2010-05-01 16:15:35 -03001706 /* Check outgoing MTU */
1707 if (len > pi->omtu) {
1708 err = -EINVAL;
1709 goto done;
1710 }
1711
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001712 /* Create a basic PDU */
1713 skb = l2cap_create_basic_pdu(sk, msg, len);
1714 if (IS_ERR(skb)) {
1715 err = PTR_ERR(skb);
1716 goto done;
1717 }
1718
1719 err = l2cap_do_send(sk, skb);
1720 if (!err)
1721 err = len;
1722 break;
1723
1724 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001725 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001726 /* Entire SDU fits into one PDU */
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001727 if (len <= pi->remote_mps) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001728 control = L2CAP_SDU_UNSEGMENTED;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001729 skb = l2cap_create_iframe_pdu(sk, msg, len, control, 0);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001730 if (IS_ERR(skb)) {
1731 err = PTR_ERR(skb);
1732 goto done;
1733 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001734 __skb_queue_tail(TX_QUEUE(sk), skb);
1735 if (sk->sk_send_head == NULL)
1736 sk->sk_send_head = skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001737 } else {
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001738 /* Segment SDU into multiples PDUs */
1739 err = l2cap_sar_segment_sdu(sk, msg, len);
1740 if (err < 0)
1741 goto done;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001742 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001743
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001744 if (pi->mode == L2CAP_MODE_STREAMING)
1745 err = l2cap_streaming_send(sk);
1746 else
1747 err = l2cap_ertm_send(sk);
1748
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001749 if (err >= 0)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001750 err = len;
1751 break;
1752
1753 default:
1754 BT_DBG("bad state %1.1x", pi->mode);
1755 err = -EINVAL;
1756 }
1757
1758done:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001759 release_sock(sk);
1760 return err;
1761}
1762
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001763static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags)
1764{
1765 struct sock *sk = sock->sk;
1766
1767 lock_sock(sk);
1768
1769 if (sk->sk_state == BT_CONNECT2 && bt_sk(sk)->defer_setup) {
1770 struct l2cap_conn_rsp rsp;
1771
1772 sk->sk_state = BT_CONFIG;
1773
1774 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
1775 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
1776 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
1777 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
1778 l2cap_send_cmd(l2cap_pi(sk)->conn, l2cap_pi(sk)->ident,
1779 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
1780
1781 release_sock(sk);
1782 return 0;
1783 }
1784
1785 release_sock(sk);
1786
1787 return bt_sock_recvmsg(iocb, sock, msg, len, flags);
1788}
1789
David S. Millerb7058842009-09-30 16:12:20 -07001790static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001791{
1792 struct sock *sk = sock->sk;
1793 struct l2cap_options opts;
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001794 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001795 u32 opt;
1796
1797 BT_DBG("sk %p", sk);
1798
1799 lock_sock(sk);
1800
1801 switch (optname) {
1802 case L2CAP_OPTIONS:
Marcel Holtmann0878b662007-05-05 00:35:59 +02001803 opts.imtu = l2cap_pi(sk)->imtu;
1804 opts.omtu = l2cap_pi(sk)->omtu;
1805 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001806 opts.mode = l2cap_pi(sk)->mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001807 opts.fcs = l2cap_pi(sk)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03001808 opts.max_tx = l2cap_pi(sk)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03001809 opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
Marcel Holtmann0878b662007-05-05 00:35:59 +02001810
Linus Torvalds1da177e2005-04-16 15:20:36 -07001811 len = min_t(unsigned int, sizeof(opts), optlen);
1812 if (copy_from_user((char *) &opts, optval, len)) {
1813 err = -EFAULT;
1814 break;
1815 }
Marcel Holtmann0878b662007-05-05 00:35:59 +02001816
João Paulo Rechi Vita0041ecf2010-05-01 16:15:42 -03001817 l2cap_pi(sk)->mode = opts.mode;
1818 switch (l2cap_pi(sk)->mode) {
1819 case L2CAP_MODE_BASIC:
1820 break;
1821 case L2CAP_MODE_ERTM:
1822 case L2CAP_MODE_STREAMING:
1823 if (enable_ertm)
1824 break;
1825 /* fall through */
1826 default:
1827 err = -EINVAL;
1828 break;
1829 }
1830
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001831 l2cap_pi(sk)->imtu = opts.imtu;
1832 l2cap_pi(sk)->omtu = opts.omtu;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001833 l2cap_pi(sk)->fcs = opts.fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03001834 l2cap_pi(sk)->max_tx = opts.max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03001835 l2cap_pi(sk)->tx_win = (__u8)opts.txwin_size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001836 break;
1837
1838 case L2CAP_LM:
1839 if (get_user(opt, (u32 __user *) optval)) {
1840 err = -EFAULT;
1841 break;
1842 }
1843
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001844 if (opt & L2CAP_LM_AUTH)
1845 l2cap_pi(sk)->sec_level = BT_SECURITY_LOW;
1846 if (opt & L2CAP_LM_ENCRYPT)
1847 l2cap_pi(sk)->sec_level = BT_SECURITY_MEDIUM;
1848 if (opt & L2CAP_LM_SECURE)
1849 l2cap_pi(sk)->sec_level = BT_SECURITY_HIGH;
1850
1851 l2cap_pi(sk)->role_switch = (opt & L2CAP_LM_MASTER);
1852 l2cap_pi(sk)->force_reliable = (opt & L2CAP_LM_RELIABLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001853 break;
1854
1855 default:
1856 err = -ENOPROTOOPT;
1857 break;
1858 }
1859
1860 release_sock(sk);
1861 return err;
1862}
1863
David S. Millerb7058842009-09-30 16:12:20 -07001864static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001865{
1866 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001867 struct bt_security sec;
1868 int len, err = 0;
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001869 u32 opt;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001870
1871 BT_DBG("sk %p", sk);
1872
1873 if (level == SOL_L2CAP)
1874 return l2cap_sock_setsockopt_old(sock, optname, optval, optlen);
1875
Marcel Holtmann0588d942009-01-16 10:06:13 +01001876 if (level != SOL_BLUETOOTH)
1877 return -ENOPROTOOPT;
1878
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001879 lock_sock(sk);
1880
1881 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001882 case BT_SECURITY:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001883 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
1884 && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01001885 err = -EINVAL;
1886 break;
1887 }
1888
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001889 sec.level = BT_SECURITY_LOW;
1890
1891 len = min_t(unsigned int, sizeof(sec), optlen);
1892 if (copy_from_user((char *) &sec, optval, len)) {
1893 err = -EFAULT;
1894 break;
1895 }
1896
1897 if (sec.level < BT_SECURITY_LOW ||
1898 sec.level > BT_SECURITY_HIGH) {
1899 err = -EINVAL;
1900 break;
1901 }
1902
1903 l2cap_pi(sk)->sec_level = sec.level;
1904 break;
1905
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001906 case BT_DEFER_SETUP:
1907 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
1908 err = -EINVAL;
1909 break;
1910 }
1911
1912 if (get_user(opt, (u32 __user *) optval)) {
1913 err = -EFAULT;
1914 break;
1915 }
1916
1917 bt_sk(sk)->defer_setup = opt;
1918 break;
1919
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001920 default:
1921 err = -ENOPROTOOPT;
1922 break;
1923 }
1924
1925 release_sock(sk);
1926 return err;
1927}
1928
1929static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001930{
1931 struct sock *sk = sock->sk;
1932 struct l2cap_options opts;
1933 struct l2cap_conninfo cinfo;
1934 int len, err = 0;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001935 u32 opt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001936
1937 BT_DBG("sk %p", sk);
1938
1939 if (get_user(len, optlen))
1940 return -EFAULT;
1941
1942 lock_sock(sk);
1943
1944 switch (optname) {
1945 case L2CAP_OPTIONS:
1946 opts.imtu = l2cap_pi(sk)->imtu;
1947 opts.omtu = l2cap_pi(sk)->omtu;
1948 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001949 opts.mode = l2cap_pi(sk)->mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001950 opts.fcs = l2cap_pi(sk)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03001951 opts.max_tx = l2cap_pi(sk)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03001952 opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001953
1954 len = min_t(unsigned int, len, sizeof(opts));
1955 if (copy_to_user(optval, (char *) &opts, len))
1956 err = -EFAULT;
1957
1958 break;
1959
1960 case L2CAP_LM:
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001961 switch (l2cap_pi(sk)->sec_level) {
1962 case BT_SECURITY_LOW:
1963 opt = L2CAP_LM_AUTH;
1964 break;
1965 case BT_SECURITY_MEDIUM:
1966 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT;
1967 break;
1968 case BT_SECURITY_HIGH:
1969 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT |
1970 L2CAP_LM_SECURE;
1971 break;
1972 default:
1973 opt = 0;
1974 break;
1975 }
1976
1977 if (l2cap_pi(sk)->role_switch)
1978 opt |= L2CAP_LM_MASTER;
1979
1980 if (l2cap_pi(sk)->force_reliable)
1981 opt |= L2CAP_LM_RELIABLE;
1982
1983 if (put_user(opt, (u32 __user *) optval))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001984 err = -EFAULT;
1985 break;
1986
1987 case L2CAP_CONNINFO:
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001988 if (sk->sk_state != BT_CONNECTED &&
1989 !(sk->sk_state == BT_CONNECT2 &&
1990 bt_sk(sk)->defer_setup)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001991 err = -ENOTCONN;
1992 break;
1993 }
1994
1995 cinfo.hci_handle = l2cap_pi(sk)->conn->hcon->handle;
1996 memcpy(cinfo.dev_class, l2cap_pi(sk)->conn->hcon->dev_class, 3);
1997
1998 len = min_t(unsigned int, len, sizeof(cinfo));
1999 if (copy_to_user(optval, (char *) &cinfo, len))
2000 err = -EFAULT;
2001
2002 break;
2003
2004 default:
2005 err = -ENOPROTOOPT;
2006 break;
2007 }
2008
2009 release_sock(sk);
2010 return err;
2011}
2012
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002013static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
2014{
2015 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002016 struct bt_security sec;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002017 int len, err = 0;
2018
2019 BT_DBG("sk %p", sk);
2020
2021 if (level == SOL_L2CAP)
2022 return l2cap_sock_getsockopt_old(sock, optname, optval, optlen);
2023
Marcel Holtmann0588d942009-01-16 10:06:13 +01002024 if (level != SOL_BLUETOOTH)
2025 return -ENOPROTOOPT;
2026
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002027 if (get_user(len, optlen))
2028 return -EFAULT;
2029
2030 lock_sock(sk);
2031
2032 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002033 case BT_SECURITY:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03002034 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
2035 && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01002036 err = -EINVAL;
2037 break;
2038 }
2039
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002040 sec.level = l2cap_pi(sk)->sec_level;
2041
2042 len = min_t(unsigned int, len, sizeof(sec));
2043 if (copy_to_user(optval, (char *) &sec, len))
2044 err = -EFAULT;
2045
2046 break;
2047
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002048 case BT_DEFER_SETUP:
2049 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
2050 err = -EINVAL;
2051 break;
2052 }
2053
2054 if (put_user(bt_sk(sk)->defer_setup, (u32 __user *) optval))
2055 err = -EFAULT;
2056
2057 break;
2058
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002059 default:
2060 err = -ENOPROTOOPT;
2061 break;
2062 }
2063
2064 release_sock(sk);
2065 return err;
2066}
2067
Linus Torvalds1da177e2005-04-16 15:20:36 -07002068static int l2cap_sock_shutdown(struct socket *sock, int how)
2069{
2070 struct sock *sk = sock->sk;
2071 int err = 0;
2072
2073 BT_DBG("sock %p, sk %p", sock, sk);
2074
2075 if (!sk)
2076 return 0;
2077
2078 lock_sock(sk);
2079 if (!sk->sk_shutdown) {
2080 sk->sk_shutdown = SHUTDOWN_MASK;
2081 l2cap_sock_clear_timer(sk);
2082 __l2cap_sock_close(sk, 0);
2083
2084 if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
Marcel Holtmannb1235d72008-07-14 20:13:54 +02002085 err = bt_sock_wait_state(sk, BT_CLOSED,
2086 sk->sk_lingertime);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002087 }
2088 release_sock(sk);
2089 return err;
2090}
2091
2092static int l2cap_sock_release(struct socket *sock)
2093{
2094 struct sock *sk = sock->sk;
2095 int err;
2096
2097 BT_DBG("sock %p, sk %p", sock, sk);
2098
2099 if (!sk)
2100 return 0;
2101
2102 err = l2cap_sock_shutdown(sock, 2);
2103
2104 sock_orphan(sk);
2105 l2cap_sock_kill(sk);
2106 return err;
2107}
2108
Linus Torvalds1da177e2005-04-16 15:20:36 -07002109static void l2cap_chan_ready(struct sock *sk)
2110{
2111 struct sock *parent = bt_sk(sk)->parent;
2112
2113 BT_DBG("sk %p, parent %p", sk, parent);
2114
2115 l2cap_pi(sk)->conf_state = 0;
2116 l2cap_sock_clear_timer(sk);
2117
2118 if (!parent) {
2119 /* Outgoing channel.
2120 * Wake up socket sleeping on connect.
2121 */
2122 sk->sk_state = BT_CONNECTED;
2123 sk->sk_state_change(sk);
2124 } else {
2125 /* Incoming channel.
2126 * Wake up socket sleeping on accept.
2127 */
2128 parent->sk_data_ready(parent, 0);
2129 }
2130}
2131
2132/* Copy frame to all raw sockets on that connection */
2133static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2134{
2135 struct l2cap_chan_list *l = &conn->chan_list;
2136 struct sk_buff *nskb;
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002137 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002138
2139 BT_DBG("conn %p", conn);
2140
2141 read_lock(&l->lock);
2142 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
2143 if (sk->sk_type != SOCK_RAW)
2144 continue;
2145
2146 /* Don't send frame to the socket it came from */
2147 if (skb->sk == sk)
2148 continue;
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002149 nskb = skb_clone(skb, GFP_ATOMIC);
2150 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002151 continue;
2152
2153 if (sock_queue_rcv_skb(sk, nskb))
2154 kfree_skb(nskb);
2155 }
2156 read_unlock(&l->lock);
2157}
2158
2159/* ---- L2CAP signalling commands ---- */
2160static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
2161 u8 code, u8 ident, u16 dlen, void *data)
2162{
2163 struct sk_buff *skb, **frag;
2164 struct l2cap_cmd_hdr *cmd;
2165 struct l2cap_hdr *lh;
2166 int len, count;
2167
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002168 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d",
2169 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002170
2171 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2172 count = min_t(unsigned int, conn->mtu, len);
2173
2174 skb = bt_skb_alloc(count, GFP_ATOMIC);
2175 if (!skb)
2176 return NULL;
2177
2178 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002179 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03002180 lh->cid = cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002181
2182 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2183 cmd->code = code;
2184 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002185 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002186
2187 if (dlen) {
2188 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2189 memcpy(skb_put(skb, count), data, count);
2190 data += count;
2191 }
2192
2193 len -= skb->len;
2194
2195 /* Continuation fragments (no L2CAP header) */
2196 frag = &skb_shinfo(skb)->frag_list;
2197 while (len) {
2198 count = min_t(unsigned int, conn->mtu, len);
2199
2200 *frag = bt_skb_alloc(count, GFP_ATOMIC);
2201 if (!*frag)
2202 goto fail;
2203
2204 memcpy(skb_put(*frag, count), data, count);
2205
2206 len -= count;
2207 data += count;
2208
2209 frag = &(*frag)->next;
2210 }
2211
2212 return skb;
2213
2214fail:
2215 kfree_skb(skb);
2216 return NULL;
2217}
2218
2219static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned long *val)
2220{
2221 struct l2cap_conf_opt *opt = *ptr;
2222 int len;
2223
2224 len = L2CAP_CONF_OPT_SIZE + opt->len;
2225 *ptr += len;
2226
2227 *type = opt->type;
2228 *olen = opt->len;
2229
2230 switch (opt->len) {
2231 case 1:
2232 *val = *((u8 *) opt->val);
2233 break;
2234
2235 case 2:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002236 *val = __le16_to_cpu(*((__le16 *) opt->val));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002237 break;
2238
2239 case 4:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002240 *val = __le32_to_cpu(*((__le32 *) opt->val));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002241 break;
2242
2243 default:
2244 *val = (unsigned long) opt->val;
2245 break;
2246 }
2247
2248 BT_DBG("type 0x%2.2x len %d val 0x%lx", *type, opt->len, *val);
2249 return len;
2250}
2251
Linus Torvalds1da177e2005-04-16 15:20:36 -07002252static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2253{
2254 struct l2cap_conf_opt *opt = *ptr;
2255
2256 BT_DBG("type 0x%2.2x len %d val 0x%lx", type, len, val);
2257
2258 opt->type = type;
2259 opt->len = len;
2260
2261 switch (len) {
2262 case 1:
2263 *((u8 *) opt->val) = val;
2264 break;
2265
2266 case 2:
Al Viro8e036fc2007-07-29 00:16:36 -07002267 *((__le16 *) opt->val) = cpu_to_le16(val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002268 break;
2269
2270 case 4:
Al Viro8e036fc2007-07-29 00:16:36 -07002271 *((__le32 *) opt->val) = cpu_to_le32(val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002272 break;
2273
2274 default:
2275 memcpy(opt->val, (void *) val, len);
2276 break;
2277 }
2278
2279 *ptr += L2CAP_CONF_OPT_SIZE + len;
2280}
2281
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002282static void l2cap_ack_timeout(unsigned long arg)
2283{
2284 struct sock *sk = (void *) arg;
2285
2286 bh_lock_sock(sk);
2287 l2cap_send_ack(l2cap_pi(sk));
2288 bh_unlock_sock(sk);
2289}
2290
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002291static inline void l2cap_ertm_init(struct sock *sk)
2292{
2293 l2cap_pi(sk)->expected_ack_seq = 0;
2294 l2cap_pi(sk)->unacked_frames = 0;
2295 l2cap_pi(sk)->buffer_seq = 0;
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03002296 l2cap_pi(sk)->num_acked = 0;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03002297 l2cap_pi(sk)->frames_sent = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002298
2299 setup_timer(&l2cap_pi(sk)->retrans_timer,
2300 l2cap_retrans_timeout, (unsigned long) sk);
2301 setup_timer(&l2cap_pi(sk)->monitor_timer,
2302 l2cap_monitor_timeout, (unsigned long) sk);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002303 setup_timer(&l2cap_pi(sk)->ack_timer,
2304 l2cap_ack_timeout, (unsigned long) sk);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002305
2306 __skb_queue_head_init(SREJ_QUEUE(sk));
2307}
2308
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002309static int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
2310{
2311 u32 local_feat_mask = l2cap_feat_mask;
2312 if (enable_ertm)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002313 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002314
2315 switch (mode) {
2316 case L2CAP_MODE_ERTM:
2317 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
2318 case L2CAP_MODE_STREAMING:
2319 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
2320 default:
2321 return 0x00;
2322 }
2323}
2324
2325static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
2326{
2327 switch (mode) {
2328 case L2CAP_MODE_STREAMING:
2329 case L2CAP_MODE_ERTM:
2330 if (l2cap_mode_supported(mode, remote_feat_mask))
2331 return mode;
2332 /* fall through */
2333 default:
2334 return L2CAP_MODE_BASIC;
2335 }
2336}
2337
Linus Torvalds1da177e2005-04-16 15:20:36 -07002338static int l2cap_build_conf_req(struct sock *sk, void *data)
2339{
2340 struct l2cap_pinfo *pi = l2cap_pi(sk);
2341 struct l2cap_conf_req *req = data;
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03002342 struct l2cap_conf_rfc rfc = { .mode = pi->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07002343 void *ptr = req->data;
2344
2345 BT_DBG("sk %p", sk);
2346
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002347 if (pi->num_conf_req || pi->num_conf_rsp)
2348 goto done;
2349
2350 switch (pi->mode) {
2351 case L2CAP_MODE_STREAMING:
2352 case L2CAP_MODE_ERTM:
2353 pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002354 if (!l2cap_mode_supported(pi->mode, pi->conn->feat_mask))
2355 l2cap_send_disconn_req(pi->conn, sk);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002356 break;
2357 default:
2358 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
2359 break;
2360 }
2361
2362done:
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002363 switch (pi->mode) {
2364 case L2CAP_MODE_BASIC:
2365 if (pi->imtu != L2CAP_DEFAULT_MTU)
2366 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
2367 break;
2368
2369 case L2CAP_MODE_ERTM:
2370 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03002371 rfc.txwin_size = pi->tx_win;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03002372 rfc.max_transmit = pi->max_tx;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002373 rfc.retrans_timeout = 0;
2374 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002375 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03002376 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002377 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002378
2379 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2380 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002381
2382 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2383 break;
2384
2385 if (pi->fcs == L2CAP_FCS_NONE ||
2386 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
2387 pi->fcs = L2CAP_FCS_NONE;
2388 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
2389 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002390 break;
2391
2392 case L2CAP_MODE_STREAMING:
2393 rfc.mode = L2CAP_MODE_STREAMING;
2394 rfc.txwin_size = 0;
2395 rfc.max_transmit = 0;
2396 rfc.retrans_timeout = 0;
2397 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002398 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03002399 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002400 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002401
2402 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2403 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002404
2405 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2406 break;
2407
2408 if (pi->fcs == L2CAP_FCS_NONE ||
2409 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
2410 pi->fcs = L2CAP_FCS_NONE;
2411 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
2412 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002413 break;
2414 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002415
2416 /* FIXME: Need actual value of the flush timeout */
2417 //if (flush_to != L2CAP_DEFAULT_FLUSH_TO)
2418 // l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2, pi->flush_to);
2419
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002420 req->dcid = cpu_to_le16(pi->dcid);
2421 req->flags = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002422
2423 return ptr - data;
2424}
2425
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002426static int l2cap_parse_conf_req(struct sock *sk, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002427{
2428 struct l2cap_pinfo *pi = l2cap_pi(sk);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002429 struct l2cap_conf_rsp *rsp = data;
2430 void *ptr = rsp->data;
2431 void *req = pi->conf_req;
2432 int len = pi->conf_len;
2433 int type, hint, olen;
2434 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002435 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Marcel Holtmann861d6882007-10-20 13:37:06 +02002436 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002437 u16 result = L2CAP_CONF_SUCCESS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002438
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002439 BT_DBG("sk %p", sk);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01002440
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002441 while (len >= L2CAP_CONF_OPT_SIZE) {
2442 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002443
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03002444 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07002445 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002446
2447 switch (type) {
2448 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002449 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002450 break;
2451
2452 case L2CAP_CONF_FLUSH_TO:
2453 pi->flush_to = val;
2454 break;
2455
2456 case L2CAP_CONF_QOS:
2457 break;
2458
Marcel Holtmann6464f352007-10-20 13:39:51 +02002459 case L2CAP_CONF_RFC:
2460 if (olen == sizeof(rfc))
2461 memcpy(&rfc, (void *) val, olen);
2462 break;
2463
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002464 case L2CAP_CONF_FCS:
2465 if (val == L2CAP_FCS_NONE)
2466 pi->conf_state |= L2CAP_CONF_NO_FCS_RECV;
2467
2468 break;
2469
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002470 default:
2471 if (hint)
2472 break;
2473
2474 result = L2CAP_CONF_UNKNOWN;
2475 *((u8 *) ptr++) = type;
2476 break;
2477 }
2478 }
2479
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002480 if (pi->num_conf_rsp || pi->num_conf_req)
2481 goto done;
2482
2483 switch (pi->mode) {
2484 case L2CAP_MODE_STREAMING:
2485 case L2CAP_MODE_ERTM:
2486 pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
2487 if (!l2cap_mode_supported(pi->mode, pi->conn->feat_mask))
2488 return -ECONNREFUSED;
2489 break;
2490 default:
2491 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
2492 break;
2493 }
2494
2495done:
2496 if (pi->mode != rfc.mode) {
2497 result = L2CAP_CONF_UNACCEPT;
2498 rfc.mode = pi->mode;
2499
2500 if (pi->num_conf_rsp == 1)
2501 return -ECONNREFUSED;
2502
2503 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2504 sizeof(rfc), (unsigned long) &rfc);
2505 }
2506
2507
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002508 if (result == L2CAP_CONF_SUCCESS) {
2509 /* Configure output options and let the other side know
2510 * which ones we don't like. */
2511
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002512 if (mtu < L2CAP_DEFAULT_MIN_MTU)
2513 result = L2CAP_CONF_UNACCEPT;
2514 else {
2515 pi->omtu = mtu;
2516 pi->conf_state |= L2CAP_CONF_MTU_DONE;
2517 }
2518 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002519
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002520 switch (rfc.mode) {
2521 case L2CAP_MODE_BASIC:
2522 pi->fcs = L2CAP_FCS_NONE;
2523 pi->conf_state |= L2CAP_CONF_MODE_DONE;
2524 break;
2525
2526 case L2CAP_MODE_ERTM:
2527 pi->remote_tx_win = rfc.txwin_size;
2528 pi->remote_max_tx = rfc.max_transmit;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002529 if (rfc.max_pdu_size > pi->conn->mtu - 10)
2530 rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10);
2531
2532 pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002533
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002534 rfc.retrans_timeout =
2535 le16_to_cpu(L2CAP_DEFAULT_RETRANS_TO);
2536 rfc.monitor_timeout =
2537 le16_to_cpu(L2CAP_DEFAULT_MONITOR_TO);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002538
2539 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03002540
2541 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2542 sizeof(rfc), (unsigned long) &rfc);
2543
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002544 break;
2545
2546 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002547 if (rfc.max_pdu_size > pi->conn->mtu - 10)
2548 rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10);
2549
2550 pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002551
2552 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03002553
2554 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2555 sizeof(rfc), (unsigned long) &rfc);
2556
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002557 break;
2558
2559 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02002560 result = L2CAP_CONF_UNACCEPT;
2561
2562 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002563 rfc.mode = pi->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002564 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002565
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002566 if (result == L2CAP_CONF_SUCCESS)
2567 pi->conf_state |= L2CAP_CONF_OUTPUT_DONE;
2568 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002569 rsp->scid = cpu_to_le16(pi->dcid);
2570 rsp->result = cpu_to_le16(result);
2571 rsp->flags = cpu_to_le16(0x0000);
2572
2573 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002574}
2575
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002576static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data, u16 *result)
2577{
2578 struct l2cap_pinfo *pi = l2cap_pi(sk);
2579 struct l2cap_conf_req *req = data;
2580 void *ptr = req->data;
2581 int type, olen;
2582 unsigned long val;
2583 struct l2cap_conf_rfc rfc;
2584
2585 BT_DBG("sk %p, rsp %p, len %d, req %p", sk, rsp, len, data);
2586
2587 while (len >= L2CAP_CONF_OPT_SIZE) {
2588 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
2589
2590 switch (type) {
2591 case L2CAP_CONF_MTU:
2592 if (val < L2CAP_DEFAULT_MIN_MTU) {
2593 *result = L2CAP_CONF_UNACCEPT;
2594 pi->omtu = L2CAP_DEFAULT_MIN_MTU;
2595 } else
2596 pi->omtu = val;
2597 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
2598 break;
2599
2600 case L2CAP_CONF_FLUSH_TO:
2601 pi->flush_to = val;
2602 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
2603 2, pi->flush_to);
2604 break;
2605
2606 case L2CAP_CONF_RFC:
2607 if (olen == sizeof(rfc))
2608 memcpy(&rfc, (void *)val, olen);
2609
2610 if ((pi->conf_state & L2CAP_CONF_STATE2_DEVICE) &&
2611 rfc.mode != pi->mode)
2612 return -ECONNREFUSED;
2613
2614 pi->mode = rfc.mode;
2615 pi->fcs = 0;
2616
2617 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2618 sizeof(rfc), (unsigned long) &rfc);
2619 break;
2620 }
2621 }
2622
2623 if (*result == L2CAP_CONF_SUCCESS) {
2624 switch (rfc.mode) {
2625 case L2CAP_MODE_ERTM:
2626 pi->remote_tx_win = rfc.txwin_size;
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002627 pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
2628 pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002629 pi->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002630 break;
2631 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002632 pi->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002633 }
2634 }
2635
2636 req->dcid = cpu_to_le16(pi->dcid);
2637 req->flags = cpu_to_le16(0x0000);
2638
2639 return ptr - data;
2640}
2641
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002642static int l2cap_build_conf_rsp(struct sock *sk, void *data, u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002643{
2644 struct l2cap_conf_rsp *rsp = data;
2645 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002646
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002647 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002648
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002649 rsp->scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002650 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002651 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002652
2653 return ptr - data;
2654}
2655
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002656static void l2cap_conf_rfc_get(struct sock *sk, void *rsp, int len)
2657{
2658 struct l2cap_pinfo *pi = l2cap_pi(sk);
2659 int type, olen;
2660 unsigned long val;
2661 struct l2cap_conf_rfc rfc;
2662
2663 BT_DBG("sk %p, rsp %p, len %d", sk, rsp, len);
2664
2665 if ((pi->mode != L2CAP_MODE_ERTM) && (pi->mode != L2CAP_MODE_STREAMING))
2666 return;
2667
2668 while (len >= L2CAP_CONF_OPT_SIZE) {
2669 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
2670
2671 switch (type) {
2672 case L2CAP_CONF_RFC:
2673 if (olen == sizeof(rfc))
2674 memcpy(&rfc, (void *)val, olen);
2675 goto done;
2676 }
2677 }
2678
2679done:
2680 switch (rfc.mode) {
2681 case L2CAP_MODE_ERTM:
2682 pi->remote_tx_win = rfc.txwin_size;
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002683 pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
2684 pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002685 pi->mps = le16_to_cpu(rfc.max_pdu_size);
2686 break;
2687 case L2CAP_MODE_STREAMING:
2688 pi->mps = le16_to_cpu(rfc.max_pdu_size);
2689 }
2690}
2691
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002692static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2693{
2694 struct l2cap_cmd_rej *rej = (struct l2cap_cmd_rej *) data;
2695
2696 if (rej->reason != 0x0000)
2697 return 0;
2698
2699 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
2700 cmd->ident == conn->info_ident) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002701 del_timer(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01002702
2703 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002704 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01002705
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002706 l2cap_conn_start(conn);
2707 }
2708
2709 return 0;
2710}
2711
Linus Torvalds1da177e2005-04-16 15:20:36 -07002712static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2713{
2714 struct l2cap_chan_list *list = &conn->chan_list;
2715 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
2716 struct l2cap_conn_rsp rsp;
2717 struct sock *sk, *parent;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002718 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002719
2720 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002721 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002722
2723 BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
2724
2725 /* Check if we have socket listening on psm */
2726 parent = l2cap_get_sock_by_psm(BT_LISTEN, psm, conn->src);
2727 if (!parent) {
2728 result = L2CAP_CR_BAD_PSM;
2729 goto sendresp;
2730 }
2731
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002732 /* Check if the ACL is secure enough (if not SDP) */
2733 if (psm != cpu_to_le16(0x0001) &&
2734 !hci_conn_check_link_mode(conn->hcon)) {
Marcel Holtmann2950f212009-02-12 14:02:50 +01002735 conn->disc_reason = 0x05;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002736 result = L2CAP_CR_SEC_BLOCK;
2737 goto response;
2738 }
2739
Linus Torvalds1da177e2005-04-16 15:20:36 -07002740 result = L2CAP_CR_NO_MEM;
2741
2742 /* Check for backlog size */
2743 if (sk_acceptq_is_full(parent)) {
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09002744 BT_DBG("backlog full %d", parent->sk_ack_backlog);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002745 goto response;
2746 }
2747
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09002748 sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002749 if (!sk)
2750 goto response;
2751
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002752 write_lock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002753
2754 /* Check if we already have channel with that dcid */
2755 if (__l2cap_get_chan_by_dcid(list, scid)) {
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002756 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002757 sock_set_flag(sk, SOCK_ZAPPED);
2758 l2cap_sock_kill(sk);
2759 goto response;
2760 }
2761
2762 hci_conn_hold(conn->hcon);
2763
2764 l2cap_sock_init(sk, parent);
2765 bacpy(&bt_sk(sk)->src, conn->src);
2766 bacpy(&bt_sk(sk)->dst, conn->dst);
2767 l2cap_pi(sk)->psm = psm;
2768 l2cap_pi(sk)->dcid = scid;
2769
2770 __l2cap_chan_add(conn, sk, parent);
2771 dcid = l2cap_pi(sk)->scid;
2772
2773 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
2774
Linus Torvalds1da177e2005-04-16 15:20:36 -07002775 l2cap_pi(sk)->ident = cmd->ident;
2776
Marcel Holtmann984947d2009-02-06 23:35:19 +01002777 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002778 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002779 if (bt_sk(sk)->defer_setup) {
2780 sk->sk_state = BT_CONNECT2;
2781 result = L2CAP_CR_PEND;
2782 status = L2CAP_CS_AUTHOR_PEND;
2783 parent->sk_data_ready(parent, 0);
2784 } else {
2785 sk->sk_state = BT_CONFIG;
2786 result = L2CAP_CR_SUCCESS;
2787 status = L2CAP_CS_NO_INFO;
2788 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002789 } else {
2790 sk->sk_state = BT_CONNECT2;
2791 result = L2CAP_CR_PEND;
2792 status = L2CAP_CS_AUTHEN_PEND;
2793 }
2794 } else {
2795 sk->sk_state = BT_CONNECT2;
2796 result = L2CAP_CR_PEND;
2797 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002798 }
2799
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002800 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002801
2802response:
2803 bh_unlock_sock(parent);
2804
2805sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002806 rsp.scid = cpu_to_le16(scid);
2807 rsp.dcid = cpu_to_le16(dcid);
2808 rsp.result = cpu_to_le16(result);
2809 rsp.status = cpu_to_le16(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002810 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002811
2812 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
2813 struct l2cap_info_req info;
2814 info.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
2815
2816 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
2817 conn->info_ident = l2cap_get_ident(conn);
2818
2819 mod_timer(&conn->info_timer, jiffies +
2820 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
2821
2822 l2cap_send_cmd(conn, conn->info_ident,
2823 L2CAP_INFO_REQ, sizeof(info), &info);
2824 }
2825
Linus Torvalds1da177e2005-04-16 15:20:36 -07002826 return 0;
2827}
2828
2829static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2830{
2831 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
2832 u16 scid, dcid, result, status;
2833 struct sock *sk;
2834 u8 req[128];
2835
2836 scid = __le16_to_cpu(rsp->scid);
2837 dcid = __le16_to_cpu(rsp->dcid);
2838 result = __le16_to_cpu(rsp->result);
2839 status = __le16_to_cpu(rsp->status);
2840
2841 BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
2842
2843 if (scid) {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002844 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2845 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002846 return 0;
2847 } else {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002848 sk = l2cap_get_chan_by_ident(&conn->chan_list, cmd->ident);
2849 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002850 return 0;
2851 }
2852
2853 switch (result) {
2854 case L2CAP_CR_SUCCESS:
2855 sk->sk_state = BT_CONFIG;
2856 l2cap_pi(sk)->ident = 0;
2857 l2cap_pi(sk)->dcid = dcid;
2858 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
2859
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002860 l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_CONNECT_PEND;
2861
Linus Torvalds1da177e2005-04-16 15:20:36 -07002862 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
2863 l2cap_build_conf_req(sk, req), req);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002864 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002865 break;
2866
2867 case L2CAP_CR_PEND:
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002868 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002869 break;
2870
2871 default:
2872 l2cap_chan_del(sk, ECONNREFUSED);
2873 break;
2874 }
2875
2876 bh_unlock_sock(sk);
2877 return 0;
2878}
2879
Al Viro88219a02007-07-29 00:17:25 -07002880static 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 -07002881{
2882 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
2883 u16 dcid, flags;
2884 u8 rsp[64];
2885 struct sock *sk;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002886 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002887
2888 dcid = __le16_to_cpu(req->dcid);
2889 flags = __le16_to_cpu(req->flags);
2890
2891 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
2892
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002893 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
2894 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002895 return -ENOENT;
2896
Marcel Holtmann354f60a2006-11-18 22:15:20 +01002897 if (sk->sk_state == BT_DISCONN)
2898 goto unlock;
2899
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002900 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07002901 len = cmd_len - sizeof(*req);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002902 if (l2cap_pi(sk)->conf_len + len > sizeof(l2cap_pi(sk)->conf_req)) {
2903 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
2904 l2cap_build_conf_rsp(sk, rsp,
2905 L2CAP_CONF_REJECT, flags), rsp);
2906 goto unlock;
2907 }
2908
2909 /* Store config. */
2910 memcpy(l2cap_pi(sk)->conf_req + l2cap_pi(sk)->conf_len, req->data, len);
2911 l2cap_pi(sk)->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002912
2913 if (flags & 0x0001) {
2914 /* Incomplete config. Send empty response. */
2915 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002916 l2cap_build_conf_rsp(sk, rsp,
2917 L2CAP_CONF_SUCCESS, 0x0001), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002918 goto unlock;
2919 }
2920
2921 /* Complete config. */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002922 len = l2cap_parse_conf_req(sk, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002923 if (len < 0) {
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002924 l2cap_send_disconn_req(conn, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002925 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002926 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002927
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002928 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002929 l2cap_pi(sk)->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002930
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002931 /* Reset config buffer. */
2932 l2cap_pi(sk)->conf_len = 0;
2933
Marcel Holtmann876d9482007-10-20 13:35:42 +02002934 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE))
2935 goto unlock;
2936
Linus Torvalds1da177e2005-04-16 15:20:36 -07002937 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) {
Joe Perchesf64f9e72009-11-29 16:55:45 -08002938 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) ||
2939 l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002940 l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
2941
Linus Torvalds1da177e2005-04-16 15:20:36 -07002942 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002943
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002944 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002945 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002946 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002947 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
2948 l2cap_ertm_init(sk);
2949
Linus Torvalds1da177e2005-04-16 15:20:36 -07002950 l2cap_chan_ready(sk);
Marcel Holtmann876d9482007-10-20 13:35:42 +02002951 goto unlock;
2952 }
2953
2954 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002955 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002956 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002957 l2cap_build_conf_req(sk, buf), buf);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002958 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002959 }
2960
2961unlock:
2962 bh_unlock_sock(sk);
2963 return 0;
2964}
2965
2966static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2967{
2968 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
2969 u16 scid, flags, result;
2970 struct sock *sk;
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002971 int len = cmd->len - sizeof(*rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002972
2973 scid = __le16_to_cpu(rsp->scid);
2974 flags = __le16_to_cpu(rsp->flags);
2975 result = __le16_to_cpu(rsp->result);
2976
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002977 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x",
2978 scid, flags, result);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002979
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002980 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2981 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002982 return 0;
2983
2984 switch (result) {
2985 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002986 l2cap_conf_rfc_get(sk, rsp->data, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002987 break;
2988
2989 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002990 if (l2cap_pi(sk)->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002991 char req[64];
2992
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02002993 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
2994 l2cap_send_disconn_req(conn, sk);
2995 goto done;
2996 }
2997
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002998 /* throw out any old stored conf requests */
2999 result = L2CAP_CONF_SUCCESS;
3000 len = l2cap_parse_conf_rsp(sk, rsp->data,
3001 len, req, &result);
3002 if (len < 0) {
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03003003 l2cap_send_disconn_req(conn, sk);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003004 goto done;
3005 }
3006
3007 l2cap_send_cmd(conn, l2cap_get_ident(conn),
3008 L2CAP_CONF_REQ, len, req);
3009 l2cap_pi(sk)->num_conf_req++;
3010 if (result != L2CAP_CONF_SUCCESS)
3011 goto done;
3012 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003013 }
3014
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09003015 default:
Linus Torvalds1da177e2005-04-16 15:20:36 -07003016 sk->sk_state = BT_DISCONN;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02003017 sk->sk_err = ECONNRESET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003018 l2cap_sock_set_timer(sk, HZ * 5);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03003019 l2cap_send_disconn_req(conn, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003020 goto done;
3021 }
3022
3023 if (flags & 0x01)
3024 goto done;
3025
Linus Torvalds1da177e2005-04-16 15:20:36 -07003026 l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE;
3027
3028 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) {
Joe Perchesf64f9e72009-11-29 16:55:45 -08003029 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) ||
3030 l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003031 l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
3032
Linus Torvalds1da177e2005-04-16 15:20:36 -07003033 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003034 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003035 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003036 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003037 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
3038 l2cap_ertm_init(sk);
3039
Linus Torvalds1da177e2005-04-16 15:20:36 -07003040 l2cap_chan_ready(sk);
3041 }
3042
3043done:
3044 bh_unlock_sock(sk);
3045 return 0;
3046}
3047
3048static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3049{
3050 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
3051 struct l2cap_disconn_rsp rsp;
3052 u16 dcid, scid;
3053 struct sock *sk;
3054
3055 scid = __le16_to_cpu(req->scid);
3056 dcid = __le16_to_cpu(req->dcid);
3057
3058 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
3059
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003060 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
3061 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003062 return 0;
3063
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003064 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
3065 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003066 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
3067
3068 sk->sk_shutdown = SHUTDOWN_MASK;
3069
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003070 skb_queue_purge(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003071
3072 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
3073 skb_queue_purge(SREJ_QUEUE(sk));
3074 del_timer(&l2cap_pi(sk)->retrans_timer);
3075 del_timer(&l2cap_pi(sk)->monitor_timer);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003076 del_timer(&l2cap_pi(sk)->ack_timer);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003077 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003078
Linus Torvalds1da177e2005-04-16 15:20:36 -07003079 l2cap_chan_del(sk, ECONNRESET);
3080 bh_unlock_sock(sk);
3081
3082 l2cap_sock_kill(sk);
3083 return 0;
3084}
3085
3086static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3087{
3088 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
3089 u16 dcid, scid;
3090 struct sock *sk;
3091
3092 scid = __le16_to_cpu(rsp->scid);
3093 dcid = __le16_to_cpu(rsp->dcid);
3094
3095 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
3096
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003097 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
3098 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003099 return 0;
3100
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003101 skb_queue_purge(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003102
3103 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
3104 skb_queue_purge(SREJ_QUEUE(sk));
3105 del_timer(&l2cap_pi(sk)->retrans_timer);
3106 del_timer(&l2cap_pi(sk)->monitor_timer);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003107 del_timer(&l2cap_pi(sk)->ack_timer);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003108 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003109
Linus Torvalds1da177e2005-04-16 15:20:36 -07003110 l2cap_chan_del(sk, 0);
3111 bh_unlock_sock(sk);
3112
3113 l2cap_sock_kill(sk);
3114 return 0;
3115}
3116
3117static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3118{
3119 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003120 u16 type;
3121
3122 type = __le16_to_cpu(req->type);
3123
3124 BT_DBG("type 0x%4.4x", type);
3125
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003126 if (type == L2CAP_IT_FEAT_MASK) {
3127 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003128 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003129 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
3130 rsp->type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
3131 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003132 if (enable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003133 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
3134 | L2CAP_FEAT_FCS;
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03003135 put_unaligned_le32(feat_mask, rsp->data);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003136 l2cap_send_cmd(conn, cmd->ident,
3137 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003138 } else if (type == L2CAP_IT_FIXED_CHAN) {
3139 u8 buf[12];
3140 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
3141 rsp->type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3142 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
3143 memcpy(buf + 4, l2cap_fixed_chan, 8);
3144 l2cap_send_cmd(conn, cmd->ident,
3145 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003146 } else {
3147 struct l2cap_info_rsp rsp;
3148 rsp.type = cpu_to_le16(type);
3149 rsp.result = cpu_to_le16(L2CAP_IR_NOTSUPP);
3150 l2cap_send_cmd(conn, cmd->ident,
3151 L2CAP_INFO_RSP, sizeof(rsp), &rsp);
3152 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003153
3154 return 0;
3155}
3156
3157static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3158{
3159 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
3160 u16 type, result;
3161
3162 type = __le16_to_cpu(rsp->type);
3163 result = __le16_to_cpu(rsp->result);
3164
3165 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
3166
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003167 del_timer(&conn->info_timer);
3168
Marcel Holtmann984947d2009-02-06 23:35:19 +01003169 if (type == L2CAP_IT_FEAT_MASK) {
Harvey Harrison83985312008-05-02 16:25:46 -07003170 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003171
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003172 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003173 struct l2cap_info_req req;
3174 req.type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3175
3176 conn->info_ident = l2cap_get_ident(conn);
3177
3178 l2cap_send_cmd(conn, conn->info_ident,
3179 L2CAP_INFO_REQ, sizeof(req), &req);
3180 } else {
3181 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
3182 conn->info_ident = 0;
3183
3184 l2cap_conn_start(conn);
3185 }
3186 } else if (type == L2CAP_IT_FIXED_CHAN) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01003187 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003188 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003189
3190 l2cap_conn_start(conn);
3191 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003192
Linus Torvalds1da177e2005-04-16 15:20:36 -07003193 return 0;
3194}
3195
3196static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
3197{
3198 u8 *data = skb->data;
3199 int len = skb->len;
3200 struct l2cap_cmd_hdr cmd;
3201 int err = 0;
3202
3203 l2cap_raw_recv(conn, skb);
3204
3205 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07003206 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003207 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
3208 data += L2CAP_CMD_HDR_SIZE;
3209 len -= L2CAP_CMD_HDR_SIZE;
3210
Al Viro88219a02007-07-29 00:17:25 -07003211 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003212
Al Viro88219a02007-07-29 00:17:25 -07003213 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 -07003214
Al Viro88219a02007-07-29 00:17:25 -07003215 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003216 BT_DBG("corrupted command");
3217 break;
3218 }
3219
3220 switch (cmd.code) {
3221 case L2CAP_COMMAND_REJ:
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003222 l2cap_command_rej(conn, &cmd, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003223 break;
3224
3225 case L2CAP_CONN_REQ:
3226 err = l2cap_connect_req(conn, &cmd, data);
3227 break;
3228
3229 case L2CAP_CONN_RSP:
3230 err = l2cap_connect_rsp(conn, &cmd, data);
3231 break;
3232
3233 case L2CAP_CONF_REQ:
Al Viro88219a02007-07-29 00:17:25 -07003234 err = l2cap_config_req(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003235 break;
3236
3237 case L2CAP_CONF_RSP:
3238 err = l2cap_config_rsp(conn, &cmd, data);
3239 break;
3240
3241 case L2CAP_DISCONN_REQ:
3242 err = l2cap_disconnect_req(conn, &cmd, data);
3243 break;
3244
3245 case L2CAP_DISCONN_RSP:
3246 err = l2cap_disconnect_rsp(conn, &cmd, data);
3247 break;
3248
3249 case L2CAP_ECHO_REQ:
Al Viro88219a02007-07-29 00:17:25 -07003250 l2cap_send_cmd(conn, cmd.ident, L2CAP_ECHO_RSP, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003251 break;
3252
3253 case L2CAP_ECHO_RSP:
3254 break;
3255
3256 case L2CAP_INFO_REQ:
3257 err = l2cap_information_req(conn, &cmd, data);
3258 break;
3259
3260 case L2CAP_INFO_RSP:
3261 err = l2cap_information_rsp(conn, &cmd, data);
3262 break;
3263
3264 default:
3265 BT_ERR("Unknown signaling command 0x%2.2x", cmd.code);
3266 err = -EINVAL;
3267 break;
3268 }
3269
3270 if (err) {
3271 struct l2cap_cmd_rej rej;
3272 BT_DBG("error %d", err);
3273
3274 /* FIXME: Map err to a valid reason */
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003275 rej.reason = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003276 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
3277 }
3278
Al Viro88219a02007-07-29 00:17:25 -07003279 data += cmd_len;
3280 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003281 }
3282
3283 kfree_skb(skb);
3284}
3285
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003286static int l2cap_check_fcs(struct l2cap_pinfo *pi, struct sk_buff *skb)
3287{
3288 u16 our_fcs, rcv_fcs;
3289 int hdr_size = L2CAP_HDR_SIZE + 2;
3290
3291 if (pi->fcs == L2CAP_FCS_CRC16) {
3292 skb_trim(skb, skb->len - 2);
3293 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
3294 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
3295
3296 if (our_fcs != rcv_fcs)
3297 return -EINVAL;
3298 }
3299 return 0;
3300}
3301
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003302static inline void l2cap_send_i_or_rr_or_rnr(struct sock *sk)
3303{
3304 struct l2cap_pinfo *pi = l2cap_pi(sk);
3305 u16 control = 0;
3306
3307 pi->frames_sent = 0;
3308 pi->conn_state |= L2CAP_CONN_SEND_FBIT;
3309
3310 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3311
3312 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
3313 control |= L2CAP_SUPER_RCV_NOT_READY | L2CAP_CTRL_FINAL;
3314 l2cap_send_sframe(pi, control);
3315 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
3316 }
3317
3318 if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY && pi->unacked_frames > 0)
3319 __mod_retrans_timer();
3320
3321 l2cap_ertm_send(sk);
3322
3323 if (!(pi->conn_state & L2CAP_CONN_LOCAL_BUSY) &&
3324 pi->frames_sent == 0) {
3325 control |= L2CAP_SUPER_RCV_READY;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003326 l2cap_send_sframe(pi, control);
3327 }
3328}
3329
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003330static void l2cap_add_to_srej_queue(struct sock *sk, struct sk_buff *skb, u8 tx_seq, u8 sar)
3331{
3332 struct sk_buff *next_skb;
3333
3334 bt_cb(skb)->tx_seq = tx_seq;
3335 bt_cb(skb)->sar = sar;
3336
3337 next_skb = skb_peek(SREJ_QUEUE(sk));
3338 if (!next_skb) {
3339 __skb_queue_tail(SREJ_QUEUE(sk), skb);
3340 return;
3341 }
3342
3343 do {
3344 if (bt_cb(next_skb)->tx_seq > tx_seq) {
3345 __skb_queue_before(SREJ_QUEUE(sk), next_skb, skb);
3346 return;
3347 }
3348
3349 if (skb_queue_is_last(SREJ_QUEUE(sk), next_skb))
3350 break;
3351
3352 } while((next_skb = skb_queue_next(SREJ_QUEUE(sk), next_skb)));
3353
3354 __skb_queue_tail(SREJ_QUEUE(sk), skb);
3355}
3356
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003357static int l2cap_sar_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
3358{
3359 struct l2cap_pinfo *pi = l2cap_pi(sk);
3360 struct sk_buff *_skb;
3361 int err = -EINVAL;
3362
3363 switch (control & L2CAP_CTRL_SAR) {
3364 case L2CAP_SDU_UNSEGMENTED:
3365 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3366 kfree_skb(pi->sdu);
3367 break;
3368 }
3369
3370 err = sock_queue_rcv_skb(sk, skb);
3371 if (!err)
3372 return 0;
3373
3374 break;
3375
3376 case L2CAP_SDU_START:
3377 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3378 kfree_skb(pi->sdu);
3379 break;
3380 }
3381
3382 pi->sdu_len = get_unaligned_le16(skb->data);
3383 skb_pull(skb, 2);
3384
Gustavo F. Padovan052897c2010-05-01 16:15:40 -03003385 if (pi->sdu_len > pi->imtu) {
3386 err = -EMSGSIZE;
3387 break;
3388 }
3389
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003390 pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
3391 if (!pi->sdu) {
3392 err = -ENOMEM;
3393 break;
3394 }
3395
3396 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3397
3398 pi->conn_state |= L2CAP_CONN_SAR_SDU;
3399 pi->partial_sdu_len = skb->len;
3400 err = 0;
3401 break;
3402
3403 case L2CAP_SDU_CONTINUE:
3404 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3405 break;
3406
3407 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3408
3409 pi->partial_sdu_len += skb->len;
3410 if (pi->partial_sdu_len > pi->sdu_len)
3411 kfree_skb(pi->sdu);
3412 else
3413 err = 0;
3414
3415 break;
3416
3417 case L2CAP_SDU_END:
3418 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3419 break;
3420
3421 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3422
3423 pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
3424 pi->partial_sdu_len += skb->len;
3425
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003426 if (pi->partial_sdu_len > pi->imtu)
3427 goto drop;
3428
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003429 if (pi->partial_sdu_len == pi->sdu_len) {
3430 _skb = skb_clone(pi->sdu, GFP_ATOMIC);
3431 err = sock_queue_rcv_skb(sk, _skb);
3432 if (err < 0)
3433 kfree_skb(_skb);
3434 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003435 err = 0;
3436
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003437drop:
3438 kfree_skb(pi->sdu);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003439 break;
3440 }
3441
3442 kfree_skb(skb);
3443 return err;
3444}
3445
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003446static void l2cap_check_srej_gap(struct sock *sk, u8 tx_seq)
3447{
3448 struct sk_buff *skb;
Gustavo F. Padovanafefdbc2010-05-01 16:15:43 -03003449 u16 control;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003450
3451 while((skb = skb_peek(SREJ_QUEUE(sk)))) {
3452 if (bt_cb(skb)->tx_seq != tx_seq)
3453 break;
3454
3455 skb = skb_dequeue(SREJ_QUEUE(sk));
Gustavo F. Padovanafefdbc2010-05-01 16:15:43 -03003456 control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003457 l2cap_sar_reassembly_sdu(sk, skb, control);
3458 l2cap_pi(sk)->buffer_seq_srej =
3459 (l2cap_pi(sk)->buffer_seq_srej + 1) % 64;
3460 tx_seq++;
3461 }
3462}
3463
3464static void l2cap_resend_srejframe(struct sock *sk, u8 tx_seq)
3465{
3466 struct l2cap_pinfo *pi = l2cap_pi(sk);
3467 struct srej_list *l, *tmp;
3468 u16 control;
3469
3470 list_for_each_entry_safe(l,tmp, SREJ_LIST(sk), list) {
3471 if (l->tx_seq == tx_seq) {
3472 list_del(&l->list);
3473 kfree(l);
3474 return;
3475 }
3476 control = L2CAP_SUPER_SELECT_REJECT;
3477 control |= l->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3478 l2cap_send_sframe(pi, control);
3479 list_del(&l->list);
3480 list_add_tail(&l->list, SREJ_LIST(sk));
3481 }
3482}
3483
3484static void l2cap_send_srejframe(struct sock *sk, u8 tx_seq)
3485{
3486 struct l2cap_pinfo *pi = l2cap_pi(sk);
3487 struct srej_list *new;
3488 u16 control;
3489
3490 while (tx_seq != pi->expected_tx_seq) {
3491 control = L2CAP_SUPER_SELECT_REJECT;
3492 control |= pi->expected_tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3493 l2cap_send_sframe(pi, control);
3494
3495 new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC);
3496 new->tx_seq = pi->expected_tx_seq++;
3497 list_add_tail(&new->list, SREJ_LIST(sk));
3498 }
3499 pi->expected_tx_seq++;
3500}
3501
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003502static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
3503{
3504 struct l2cap_pinfo *pi = l2cap_pi(sk);
3505 u8 tx_seq = __get_txseq(rx_control);
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003506 u8 req_seq = __get_reqseq(rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003507 u8 sar = rx_control >> L2CAP_CTRL_SAR_SHIFT;
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03003508 int num_to_ack = (pi->tx_win/6) + 1;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003509 int err = 0;
3510
3511 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
3512
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003513 if (L2CAP_CTRL_FINAL & rx_control) {
3514 del_timer(&pi->monitor_timer);
3515 if (pi->unacked_frames > 0)
3516 __mod_retrans_timer();
3517 pi->conn_state &= ~L2CAP_CONN_WAIT_F;
3518 }
3519
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003520 pi->expected_ack_seq = req_seq;
3521 l2cap_drop_acked_frames(sk);
3522
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003523 if (tx_seq == pi->expected_tx_seq)
3524 goto expected;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003525
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003526 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3527 struct srej_list *first;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003528
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003529 first = list_first_entry(SREJ_LIST(sk),
3530 struct srej_list, list);
3531 if (tx_seq == first->tx_seq) {
3532 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3533 l2cap_check_srej_gap(sk, tx_seq);
3534
3535 list_del(&first->list);
3536 kfree(first);
3537
3538 if (list_empty(SREJ_LIST(sk))) {
3539 pi->buffer_seq = pi->buffer_seq_srej;
3540 pi->conn_state &= ~L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan855666cc2010-05-01 16:15:40 -03003541 l2cap_send_ack(pi);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003542 }
3543 } else {
3544 struct srej_list *l;
3545 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3546
3547 list_for_each_entry(l, SREJ_LIST(sk), list) {
3548 if (l->tx_seq == tx_seq) {
3549 l2cap_resend_srejframe(sk, tx_seq);
3550 return 0;
3551 }
3552 }
3553 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003554 }
3555 } else {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003556 pi->conn_state |= L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003557
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003558 INIT_LIST_HEAD(SREJ_LIST(sk));
3559 pi->buffer_seq_srej = pi->buffer_seq;
3560
3561 __skb_queue_head_init(SREJ_QUEUE(sk));
3562 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3563
Gustavo F. Padovanef54fd92009-08-20 22:26:04 -03003564 pi->conn_state |= L2CAP_CONN_SEND_PBIT;
3565
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003566 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003567 }
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003568 return 0;
3569
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003570expected:
3571 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
3572
3573 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
Gustavo F. Padovan3b1a9f32010-05-01 16:15:42 -03003574 bt_cb(skb)->tx_seq = tx_seq;
3575 bt_cb(skb)->sar = sar;
3576 __skb_queue_tail(SREJ_QUEUE(sk), skb);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003577 return 0;
3578 }
3579
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03003580 if (rx_control & L2CAP_CTRL_FINAL) {
3581 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3582 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
3583 else {
Gustavo F. Padovanf6e6b162010-05-01 16:15:41 -03003584 if (!skb_queue_empty(TX_QUEUE(sk)))
3585 sk->sk_send_head = TX_QUEUE(sk)->next;
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03003586 pi->next_tx_seq = pi->expected_ack_seq;
3587 l2cap_ertm_send(sk);
3588 }
3589 }
3590
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003591 pi->buffer_seq = (pi->buffer_seq + 1) % 64;
3592
3593 err = l2cap_sar_reassembly_sdu(sk, skb, rx_control);
3594 if (err < 0)
3595 return err;
3596
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003597 __mod_ack_timer();
3598
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03003599 pi->num_acked = (pi->num_acked + 1) % num_to_ack;
3600 if (pi->num_acked == num_to_ack - 1)
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03003601 l2cap_send_ack(pi);
3602
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003603 return 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003604}
3605
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003606static inline void l2cap_data_channel_rrframe(struct sock *sk, u16 rx_control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003607{
3608 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan6e3a5982010-05-01 16:15:38 -03003609
3610 pi->expected_ack_seq = __get_reqseq(rx_control);
3611 l2cap_drop_acked_frames(sk);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003612
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003613 if (rx_control & L2CAP_CTRL_POLL) {
Gustavo F. Padovan05fbd892010-05-01 16:15:39 -03003614 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3615 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
3616 (pi->unacked_frames > 0))
3617 __mod_retrans_timer();
3618
3619 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3620 l2cap_send_srejtail(sk);
3621 } else {
3622 l2cap_send_i_or_rr_or_rnr(sk);
3623 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3624 }
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003625
3626 } else if (rx_control & L2CAP_CTRL_FINAL) {
3627 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003628
3629 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3630 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
3631 else {
Gustavo F. Padovanf6e6b162010-05-01 16:15:41 -03003632 if (!skb_queue_empty(TX_QUEUE(sk)))
3633 sk->sk_send_head = TX_QUEUE(sk)->next;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003634 pi->next_tx_seq = pi->expected_ack_seq;
3635 l2cap_ertm_send(sk);
3636 }
3637
3638 } else {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003639 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
3640 (pi->unacked_frames > 0))
3641 __mod_retrans_timer();
3642
3643 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3644 if (pi->conn_state & L2CAP_CONN_SREJ_SENT)
3645 l2cap_send_ack(pi);
3646 else
3647 l2cap_ertm_send(sk);
3648 }
3649}
3650
3651static inline void l2cap_data_channel_rejframe(struct sock *sk, u16 rx_control)
3652{
3653 struct l2cap_pinfo *pi = l2cap_pi(sk);
3654 u8 tx_seq = __get_reqseq(rx_control);
3655
3656 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3657
Gustavo F. Padovan8abb52e2010-05-01 16:15:38 -03003658 pi->expected_ack_seq = tx_seq;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003659 l2cap_drop_acked_frames(sk);
3660
3661 if (rx_control & L2CAP_CTRL_FINAL) {
3662 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3663 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
3664 else {
Gustavo F. Padovanf6e6b162010-05-01 16:15:41 -03003665 if (!skb_queue_empty(TX_QUEUE(sk)))
3666 sk->sk_send_head = TX_QUEUE(sk)->next;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003667 pi->next_tx_seq = pi->expected_ack_seq;
3668 l2cap_ertm_send(sk);
3669 }
3670 } else {
Gustavo F. Padovanf6e6b162010-05-01 16:15:41 -03003671 if (!skb_queue_empty(TX_QUEUE(sk)))
3672 sk->sk_send_head = TX_QUEUE(sk)->next;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003673 pi->next_tx_seq = pi->expected_ack_seq;
3674 l2cap_ertm_send(sk);
3675
3676 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
3677 pi->srej_save_reqseq = tx_seq;
3678 pi->conn_state |= L2CAP_CONN_REJ_ACT;
3679 }
3680 }
3681}
3682static inline void l2cap_data_channel_srejframe(struct sock *sk, u16 rx_control)
3683{
3684 struct l2cap_pinfo *pi = l2cap_pi(sk);
3685 u8 tx_seq = __get_reqseq(rx_control);
3686
3687 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3688
3689 if (rx_control & L2CAP_CTRL_POLL) {
3690 pi->expected_ack_seq = tx_seq;
3691 l2cap_drop_acked_frames(sk);
3692 l2cap_retransmit_frame(sk, tx_seq);
3693 l2cap_ertm_send(sk);
3694 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
3695 pi->srej_save_reqseq = tx_seq;
3696 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
3697 }
3698 } else if (rx_control & L2CAP_CTRL_FINAL) {
3699 if ((pi->conn_state & L2CAP_CONN_SREJ_ACT) &&
3700 pi->srej_save_reqseq == tx_seq)
3701 pi->conn_state &= ~L2CAP_CONN_SREJ_ACT;
3702 else
3703 l2cap_retransmit_frame(sk, tx_seq);
3704 } else {
3705 l2cap_retransmit_frame(sk, tx_seq);
3706 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
3707 pi->srej_save_reqseq = tx_seq;
3708 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
3709 }
3710 }
3711}
3712
3713static inline void l2cap_data_channel_rnrframe(struct sock *sk, u16 rx_control)
3714{
3715 struct l2cap_pinfo *pi = l2cap_pi(sk);
3716 u8 tx_seq = __get_reqseq(rx_control);
3717
3718 pi->conn_state |= L2CAP_CONN_REMOTE_BUSY;
3719 pi->expected_ack_seq = tx_seq;
3720 l2cap_drop_acked_frames(sk);
3721
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03003722 if (!(pi->conn_state & L2CAP_CONN_SREJ_SENT)) {
3723 del_timer(&pi->retrans_timer);
3724 if (rx_control & L2CAP_CTRL_POLL) {
3725 u16 control = L2CAP_CTRL_FINAL;
3726 l2cap_send_rr_or_rnr(pi, control);
3727 }
3728 return;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003729 }
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03003730
3731 if (rx_control & L2CAP_CTRL_POLL)
3732 l2cap_send_srejtail(sk);
3733 else
3734 l2cap_send_sframe(pi, L2CAP_SUPER_RCV_READY);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003735}
3736
3737static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
3738{
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003739 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
3740
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003741 if (L2CAP_CTRL_FINAL & rx_control) {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003742 del_timer(&l2cap_pi(sk)->monitor_timer);
3743 if (l2cap_pi(sk)->unacked_frames > 0)
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003744 __mod_retrans_timer();
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003745 l2cap_pi(sk)->conn_state &= ~L2CAP_CONN_WAIT_F;
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003746 }
3747
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003748 switch (rx_control & L2CAP_CTRL_SUPERVISE) {
3749 case L2CAP_SUPER_RCV_READY:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003750 l2cap_data_channel_rrframe(sk, rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003751 break;
3752
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003753 case L2CAP_SUPER_REJECT:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003754 l2cap_data_channel_rejframe(sk, rx_control);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003755 break;
3756
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003757 case L2CAP_SUPER_SELECT_REJECT:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003758 l2cap_data_channel_srejframe(sk, rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003759 break;
3760
3761 case L2CAP_SUPER_RCV_NOT_READY:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003762 l2cap_data_channel_rnrframe(sk, rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003763 break;
3764 }
3765
Gustavo F. Padovanfaaebd12010-05-01 16:15:35 -03003766 kfree_skb(skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003767 return 0;
3768}
3769
Linus Torvalds1da177e2005-04-16 15:20:36 -07003770static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk_buff *skb)
3771{
3772 struct sock *sk;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003773 struct l2cap_pinfo *pi;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003774 u16 control, len;
João Paulo Rechi Vita01760bd2010-05-01 16:15:43 -03003775 u8 tx_seq, req_seq, next_tx_seq_offset, req_seq_offset;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003776
3777 sk = l2cap_get_chan_by_scid(&conn->chan_list, cid);
3778 if (!sk) {
3779 BT_DBG("unknown cid 0x%4.4x", cid);
3780 goto drop;
3781 }
3782
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003783 pi = l2cap_pi(sk);
3784
Linus Torvalds1da177e2005-04-16 15:20:36 -07003785 BT_DBG("sk %p, len %d", sk, skb->len);
3786
3787 if (sk->sk_state != BT_CONNECTED)
3788 goto drop;
3789
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003790 switch (pi->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003791 case L2CAP_MODE_BASIC:
3792 /* If socket recv buffers overflows we drop data here
3793 * which is *bad* because L2CAP has to be reliable.
3794 * But we don't have any other choice. L2CAP doesn't
3795 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003796
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003797 if (pi->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003798 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003799
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003800 if (!sock_queue_rcv_skb(sk, skb))
3801 goto done;
3802 break;
3803
3804 case L2CAP_MODE_ERTM:
3805 control = get_unaligned_le16(skb->data);
3806 skb_pull(skb, 2);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003807 len = skb->len;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003808
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003809 if (__is_sar_start(control))
3810 len -= 2;
3811
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003812 if (pi->fcs == L2CAP_FCS_CRC16)
3813 len -= 2;
3814
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003815 /*
3816 * We can just drop the corrupted I-frame here.
3817 * Receiver will miss it and start proper recovery
3818 * procedures and ask retransmission.
3819 */
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03003820 if (len > pi->mps)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003821 goto drop;
3822
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003823 if (l2cap_check_fcs(pi, skb))
3824 goto drop;
3825
João Paulo Rechi Vita01760bd2010-05-01 16:15:43 -03003826 req_seq = __get_reqseq(control);
3827 req_seq_offset = (req_seq - pi->expected_ack_seq) % 64;
3828 if (req_seq_offset < 0)
3829 req_seq_offset += 64;
3830
3831 next_tx_seq_offset =
3832 (pi->next_tx_seq - pi->expected_ack_seq) % 64;
3833 if (next_tx_seq_offset < 0)
3834 next_tx_seq_offset += 64;
3835
3836 /* check for invalid req-seq */
3837 if (req_seq_offset > next_tx_seq_offset) {
3838 l2cap_send_disconn_req(pi->conn, sk);
3839 goto drop;
3840 }
3841
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03003842 if (__is_iframe(control)) {
3843 if (len < 4)
3844 goto drop;
3845
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02003846 l2cap_data_channel_iframe(sk, control, skb);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03003847 } else {
3848 if (len != 0)
3849 goto drop;
3850
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02003851 l2cap_data_channel_sframe(sk, control, skb);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03003852 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003853
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02003854 goto done;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003855
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003856 case L2CAP_MODE_STREAMING:
3857 control = get_unaligned_le16(skb->data);
3858 skb_pull(skb, 2);
3859 len = skb->len;
3860
3861 if (__is_sar_start(control))
3862 len -= 2;
3863
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003864 if (pi->fcs == L2CAP_FCS_CRC16)
3865 len -= 2;
3866
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03003867 if (len > pi->mps || len < 4 || __is_sframe(control))
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003868 goto drop;
3869
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003870 if (l2cap_check_fcs(pi, skb))
3871 goto drop;
3872
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003873 tx_seq = __get_txseq(control);
3874
3875 if (pi->expected_tx_seq == tx_seq)
3876 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
3877 else
Gustavo F. Padovan7dffe422010-05-01 16:15:36 -03003878 pi->expected_tx_seq = (tx_seq + 1) % 64;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003879
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02003880 l2cap_sar_reassembly_sdu(sk, skb, control);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003881
3882 goto done;
3883
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003884 default:
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03003885 BT_DBG("sk %p: bad mode 0x%2.2x", sk, pi->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003886 break;
3887 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003888
3889drop:
3890 kfree_skb(skb);
3891
3892done:
Marcel Holtmann01394182006-07-03 10:02:46 +02003893 if (sk)
3894 bh_unlock_sock(sk);
3895
Linus Torvalds1da177e2005-04-16 15:20:36 -07003896 return 0;
3897}
3898
Al Viro8e036fc2007-07-29 00:16:36 -07003899static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003900{
3901 struct sock *sk;
3902
3903 sk = l2cap_get_sock_by_psm(0, psm, conn->src);
3904 if (!sk)
3905 goto drop;
3906
3907 BT_DBG("sk %p, len %d", sk, skb->len);
3908
3909 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_CONNECTED)
3910 goto drop;
3911
3912 if (l2cap_pi(sk)->imtu < skb->len)
3913 goto drop;
3914
3915 if (!sock_queue_rcv_skb(sk, skb))
3916 goto done;
3917
3918drop:
3919 kfree_skb(skb);
3920
3921done:
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003922 if (sk)
3923 bh_unlock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003924 return 0;
3925}
3926
3927static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
3928{
3929 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07003930 u16 cid, len;
3931 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003932
3933 skb_pull(skb, L2CAP_HDR_SIZE);
3934 cid = __le16_to_cpu(lh->cid);
3935 len = __le16_to_cpu(lh->len);
3936
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003937 if (len != skb->len) {
3938 kfree_skb(skb);
3939 return;
3940 }
3941
Linus Torvalds1da177e2005-04-16 15:20:36 -07003942 BT_DBG("len %d, cid 0x%4.4x", len, cid);
3943
3944 switch (cid) {
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03003945 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07003946 l2cap_sig_channel(conn, skb);
3947 break;
3948
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03003949 case L2CAP_CID_CONN_LESS:
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03003950 psm = get_unaligned_le16(skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003951 skb_pull(skb, 2);
3952 l2cap_conless_channel(conn, psm, skb);
3953 break;
3954
3955 default:
3956 l2cap_data_channel(conn, cid, skb);
3957 break;
3958 }
3959}
3960
3961/* ---- L2CAP interface with lower layer (HCI) ---- */
3962
3963static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
3964{
3965 int exact = 0, lm1 = 0, lm2 = 0;
3966 register struct sock *sk;
3967 struct hlist_node *node;
3968
3969 if (type != ACL_LINK)
3970 return 0;
3971
3972 BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
3973
3974 /* Find listening sockets and check their link_mode */
3975 read_lock(&l2cap_sk_list.lock);
3976 sk_for_each(sk, node, &l2cap_sk_list.head) {
3977 if (sk->sk_state != BT_LISTEN)
3978 continue;
3979
3980 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01003981 lm1 |= HCI_LM_ACCEPT;
3982 if (l2cap_pi(sk)->role_switch)
3983 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003984 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01003985 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
3986 lm2 |= HCI_LM_ACCEPT;
3987 if (l2cap_pi(sk)->role_switch)
3988 lm2 |= HCI_LM_MASTER;
3989 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003990 }
3991 read_unlock(&l2cap_sk_list.lock);
3992
3993 return exact ? lm1 : lm2;
3994}
3995
3996static int l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
3997{
Marcel Holtmann01394182006-07-03 10:02:46 +02003998 struct l2cap_conn *conn;
3999
Linus Torvalds1da177e2005-04-16 15:20:36 -07004000 BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
4001
4002 if (hcon->type != ACL_LINK)
4003 return 0;
4004
4005 if (!status) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004006 conn = l2cap_conn_add(hcon, status);
4007 if (conn)
4008 l2cap_conn_ready(conn);
Marcel Holtmann01394182006-07-03 10:02:46 +02004009 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -07004010 l2cap_conn_del(hcon, bt_err(status));
4011
4012 return 0;
4013}
4014
Marcel Holtmann2950f212009-02-12 14:02:50 +01004015static int l2cap_disconn_ind(struct hci_conn *hcon)
4016{
4017 struct l2cap_conn *conn = hcon->l2cap_data;
4018
4019 BT_DBG("hcon %p", hcon);
4020
4021 if (hcon->type != ACL_LINK || !conn)
4022 return 0x13;
4023
4024 return conn->disc_reason;
4025}
4026
4027static int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004028{
4029 BT_DBG("hcon %p reason %d", hcon, reason);
4030
4031 if (hcon->type != ACL_LINK)
4032 return 0;
4033
4034 l2cap_conn_del(hcon, bt_err(reason));
Marcel Holtmann01394182006-07-03 10:02:46 +02004035
Linus Torvalds1da177e2005-04-16 15:20:36 -07004036 return 0;
4037}
4038
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004039static inline void l2cap_check_encryption(struct sock *sk, u8 encrypt)
4040{
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03004041 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM)
Marcel Holtmann255c7602009-02-04 21:07:19 +01004042 return;
4043
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004044 if (encrypt == 0x00) {
4045 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM) {
4046 l2cap_sock_clear_timer(sk);
4047 l2cap_sock_set_timer(sk, HZ * 5);
4048 } else if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
4049 __l2cap_sock_close(sk, ECONNREFUSED);
4050 } else {
4051 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM)
4052 l2cap_sock_clear_timer(sk);
4053 }
4054}
4055
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004056static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004057{
4058 struct l2cap_chan_list *l;
Marcel Holtmann40be4922008-07-14 20:13:50 +02004059 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004060 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004061
Marcel Holtmann01394182006-07-03 10:02:46 +02004062 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004063 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02004064
Linus Torvalds1da177e2005-04-16 15:20:36 -07004065 l = &conn->chan_list;
4066
4067 BT_DBG("conn %p", conn);
4068
4069 read_lock(&l->lock);
4070
4071 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
4072 bh_lock_sock(sk);
4073
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01004074 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND) {
4075 bh_unlock_sock(sk);
4076 continue;
4077 }
4078
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004079 if (!status && (sk->sk_state == BT_CONNECTED ||
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004080 sk->sk_state == BT_CONFIG)) {
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004081 l2cap_check_encryption(sk, encrypt);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02004082 bh_unlock_sock(sk);
4083 continue;
4084 }
4085
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004086 if (sk->sk_state == BT_CONNECT) {
4087 if (!status) {
4088 struct l2cap_conn_req req;
4089 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
4090 req.psm = l2cap_pi(sk)->psm;
4091
4092 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
4093
4094 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
4095 L2CAP_CONN_REQ, sizeof(req), &req);
4096 } else {
4097 l2cap_sock_clear_timer(sk);
4098 l2cap_sock_set_timer(sk, HZ / 10);
4099 }
4100 } else if (sk->sk_state == BT_CONNECT2) {
4101 struct l2cap_conn_rsp rsp;
4102 __u16 result;
4103
4104 if (!status) {
4105 sk->sk_state = BT_CONFIG;
4106 result = L2CAP_CR_SUCCESS;
4107 } else {
4108 sk->sk_state = BT_DISCONN;
4109 l2cap_sock_set_timer(sk, HZ / 10);
4110 result = L2CAP_CR_SEC_BLOCK;
4111 }
4112
4113 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
4114 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
4115 rsp.result = cpu_to_le16(result);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02004116 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004117 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
4118 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004119 }
4120
Linus Torvalds1da177e2005-04-16 15:20:36 -07004121 bh_unlock_sock(sk);
4122 }
4123
4124 read_unlock(&l->lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004125
Linus Torvalds1da177e2005-04-16 15:20:36 -07004126 return 0;
4127}
4128
4129static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
4130{
4131 struct l2cap_conn *conn = hcon->l2cap_data;
4132
4133 if (!conn && !(conn = l2cap_conn_add(hcon, 0)))
4134 goto drop;
4135
4136 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
4137
4138 if (flags & ACL_START) {
4139 struct l2cap_hdr *hdr;
4140 int len;
4141
4142 if (conn->rx_len) {
4143 BT_ERR("Unexpected start frame (len %d)", skb->len);
4144 kfree_skb(conn->rx_skb);
4145 conn->rx_skb = NULL;
4146 conn->rx_len = 0;
4147 l2cap_conn_unreliable(conn, ECOMM);
4148 }
4149
4150 if (skb->len < 2) {
4151 BT_ERR("Frame is too short (len %d)", skb->len);
4152 l2cap_conn_unreliable(conn, ECOMM);
4153 goto drop;
4154 }
4155
4156 hdr = (struct l2cap_hdr *) skb->data;
4157 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
4158
4159 if (len == skb->len) {
4160 /* Complete frame received */
4161 l2cap_recv_frame(conn, skb);
4162 return 0;
4163 }
4164
4165 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
4166
4167 if (skb->len > len) {
4168 BT_ERR("Frame is too long (len %d, expected len %d)",
4169 skb->len, len);
4170 l2cap_conn_unreliable(conn, ECOMM);
4171 goto drop;
4172 }
4173
4174 /* Allocate skb for the complete frame (with header) */
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03004175 conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC);
4176 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004177 goto drop;
4178
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03004179 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004180 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004181 conn->rx_len = len - skb->len;
4182 } else {
4183 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
4184
4185 if (!conn->rx_len) {
4186 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
4187 l2cap_conn_unreliable(conn, ECOMM);
4188 goto drop;
4189 }
4190
4191 if (skb->len > conn->rx_len) {
4192 BT_ERR("Fragment is too long (len %d, expected %d)",
4193 skb->len, conn->rx_len);
4194 kfree_skb(conn->rx_skb);
4195 conn->rx_skb = NULL;
4196 conn->rx_len = 0;
4197 l2cap_conn_unreliable(conn, ECOMM);
4198 goto drop;
4199 }
4200
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03004201 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004202 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004203 conn->rx_len -= skb->len;
4204
4205 if (!conn->rx_len) {
4206 /* Complete frame received */
4207 l2cap_recv_frame(conn, conn->rx_skb);
4208 conn->rx_skb = NULL;
4209 }
4210 }
4211
4212drop:
4213 kfree_skb(skb);
4214 return 0;
4215}
4216
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004217static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004218{
4219 struct sock *sk;
4220 struct hlist_node *node;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004221
4222 read_lock_bh(&l2cap_sk_list.lock);
4223
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004224 sk_for_each(sk, node, &l2cap_sk_list.head) {
4225 struct l2cap_pinfo *pi = l2cap_pi(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004226
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004227 seq_printf(f, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d\n",
4228 batostr(&bt_sk(sk)->src),
4229 batostr(&bt_sk(sk)->dst),
4230 sk->sk_state, __le16_to_cpu(pi->psm),
4231 pi->scid, pi->dcid,
4232 pi->imtu, pi->omtu, pi->sec_level);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004233 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004234
Linus Torvalds1da177e2005-04-16 15:20:36 -07004235 read_unlock_bh(&l2cap_sk_list.lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004236
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004237 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004238}
4239
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004240static int l2cap_debugfs_open(struct inode *inode, struct file *file)
4241{
4242 return single_open(file, l2cap_debugfs_show, inode->i_private);
4243}
4244
4245static const struct file_operations l2cap_debugfs_fops = {
4246 .open = l2cap_debugfs_open,
4247 .read = seq_read,
4248 .llseek = seq_lseek,
4249 .release = single_release,
4250};
4251
4252static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004253
Eric Dumazet90ddc4f2005-12-22 12:49:22 -08004254static const struct proto_ops l2cap_sock_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004255 .family = PF_BLUETOOTH,
4256 .owner = THIS_MODULE,
4257 .release = l2cap_sock_release,
4258 .bind = l2cap_sock_bind,
4259 .connect = l2cap_sock_connect,
4260 .listen = l2cap_sock_listen,
4261 .accept = l2cap_sock_accept,
4262 .getname = l2cap_sock_getname,
4263 .sendmsg = l2cap_sock_sendmsg,
Marcel Holtmannf66dc812009-01-15 21:57:00 +01004264 .recvmsg = l2cap_sock_recvmsg,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004265 .poll = bt_sock_poll,
Marcel Holtmann3241ad82008-07-14 20:13:50 +02004266 .ioctl = bt_sock_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004267 .mmap = sock_no_mmap,
4268 .socketpair = sock_no_socketpair,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004269 .shutdown = l2cap_sock_shutdown,
4270 .setsockopt = l2cap_sock_setsockopt,
4271 .getsockopt = l2cap_sock_getsockopt
4272};
4273
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +00004274static const struct net_proto_family l2cap_sock_family_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004275 .family = PF_BLUETOOTH,
4276 .owner = THIS_MODULE,
4277 .create = l2cap_sock_create,
4278};
4279
4280static struct hci_proto l2cap_hci_proto = {
4281 .name = "L2CAP",
4282 .id = HCI_PROTO_L2CAP,
4283 .connect_ind = l2cap_connect_ind,
4284 .connect_cfm = l2cap_connect_cfm,
4285 .disconn_ind = l2cap_disconn_ind,
Marcel Holtmann2950f212009-02-12 14:02:50 +01004286 .disconn_cfm = l2cap_disconn_cfm,
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004287 .security_cfm = l2cap_security_cfm,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004288 .recv_acldata = l2cap_recv_acldata
4289};
4290
4291static int __init l2cap_init(void)
4292{
4293 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004294
Linus Torvalds1da177e2005-04-16 15:20:36 -07004295 err = proto_register(&l2cap_proto, 0);
4296 if (err < 0)
4297 return err;
4298
4299 err = bt_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops);
4300 if (err < 0) {
4301 BT_ERR("L2CAP socket registration failed");
4302 goto error;
4303 }
4304
4305 err = hci_register_proto(&l2cap_hci_proto);
4306 if (err < 0) {
4307 BT_ERR("L2CAP protocol registration failed");
4308 bt_sock_unregister(BTPROTO_L2CAP);
4309 goto error;
4310 }
4311
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004312 if (bt_debugfs) {
4313 l2cap_debugfs = debugfs_create_file("l2cap", 0444,
4314 bt_debugfs, NULL, &l2cap_debugfs_fops);
4315 if (!l2cap_debugfs)
4316 BT_ERR("Failed to create L2CAP debug file");
4317 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004318
4319 BT_INFO("L2CAP ver %s", VERSION);
4320 BT_INFO("L2CAP socket layer initialized");
4321
4322 return 0;
4323
4324error:
4325 proto_unregister(&l2cap_proto);
4326 return err;
4327}
4328
4329static void __exit l2cap_exit(void)
4330{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004331 debugfs_remove(l2cap_debugfs);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004332
4333 if (bt_sock_unregister(BTPROTO_L2CAP) < 0)
4334 BT_ERR("L2CAP socket unregistration failed");
4335
4336 if (hci_unregister_proto(&l2cap_hci_proto) < 0)
4337 BT_ERR("L2CAP protocol unregistration failed");
4338
4339 proto_unregister(&l2cap_proto);
4340}
4341
4342void l2cap_load(void)
4343{
4344 /* Dummy function to trigger automatic L2CAP module loading by
4345 * other modules that use L2CAP sockets but don't use any other
4346 * symbols from it. */
4347 return;
4348}
4349EXPORT_SYMBOL(l2cap_load);
4350
4351module_init(l2cap_init);
4352module_exit(l2cap_exit);
4353
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07004354module_param(enable_ertm, bool, 0644);
4355MODULE_PARM_DESC(enable_ertm, "Enable enhanced retransmission mode");
4356
Marcel Holtmann5fbcd3d2009-10-05 11:35:43 +02004357module_param(max_transmit, uint, 0644);
4358MODULE_PARM_DESC(max_transmit, "Max transmit value (default = 3)");
4359
Gustavo F. Padovan369ba302010-05-01 16:15:41 -03004360module_param(tx_window, uint, 0644);
4361MODULE_PARM_DESC(tx_window, "Transmission window size value (default = 63)");
4362
Marcel Holtmann63fbd242008-08-18 13:23:53 +02004363MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004364MODULE_DESCRIPTION("Bluetooth L2CAP ver " VERSION);
4365MODULE_VERSION(VERSION);
4366MODULE_LICENSE("GPL");
4367MODULE_ALIAS("bt-proto-0");