blob: 7e74d5be16e3ade91f9717aaa8387d8a3649e3ed [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. Padovanaf05b302009-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. Padovanaf05b302009-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. Padovanaf05b302009-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. Padovanaf05b302009-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. Padovanaf05b302009-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. Padovanaf05b302009-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
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300333static inline void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200334{
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)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300340 return;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200341
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300342 hci_send_acl(conn->hcon, skb, 0);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200343}
344
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300345static inline void l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300346{
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)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300372 return;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300373
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. Padovan9a9c6a32010-05-01 16:15:43 -0300384 hci_send_acl(pi->conn->hcon, skb, 0);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300385}
386
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300387static inline void l2cap_send_rr_or_rnr(struct l2cap_pinfo *pi, u16 control)
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300388{
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. Padovan9a9c6a32010-05-01 16:15:43 -0300396 l2cap_send_sframe(pi, control);
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300397}
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. Padovanaf05b302009-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. Padovanaf05b302009-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. Padovanaf05b302009-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. Padovanaf05b302009-04-20 01:31:08 -03001089 err = l2cap_do_connect(sk);
1090 if (err)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001091 goto done;
1092
1093wait:
1094 err = bt_sock_wait_state(sk, BT_CONNECTED,
1095 sock_sndtimeo(sk, flags & O_NONBLOCK));
1096done:
1097 release_sock(sk);
1098 return err;
1099}
1100
1101static int l2cap_sock_listen(struct socket *sock, int backlog)
1102{
1103 struct sock *sk = sock->sk;
1104 int err = 0;
1105
1106 BT_DBG("sk %p backlog %d", sk, backlog);
1107
1108 lock_sock(sk);
1109
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001110 if ((sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM)
1111 || sk->sk_state != BT_BOUND) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001112 err = -EBADFD;
1113 goto done;
1114 }
1115
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001116 switch (l2cap_pi(sk)->mode) {
1117 case L2CAP_MODE_BASIC:
1118 break;
1119 case L2CAP_MODE_ERTM:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001120 case L2CAP_MODE_STREAMING:
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001121 if (enable_ertm)
1122 break;
1123 /* fall through */
1124 default:
1125 err = -ENOTSUPP;
1126 goto done;
1127 }
1128
Linus Torvalds1da177e2005-04-16 15:20:36 -07001129 if (!l2cap_pi(sk)->psm) {
1130 bdaddr_t *src = &bt_sk(sk)->src;
1131 u16 psm;
1132
1133 err = -EINVAL;
1134
1135 write_lock_bh(&l2cap_sk_list.lock);
1136
1137 for (psm = 0x1001; psm < 0x1100; psm += 2)
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001138 if (!__l2cap_get_sock_by_addr(cpu_to_le16(psm), src)) {
1139 l2cap_pi(sk)->psm = cpu_to_le16(psm);
1140 l2cap_pi(sk)->sport = cpu_to_le16(psm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001141 err = 0;
1142 break;
1143 }
1144
1145 write_unlock_bh(&l2cap_sk_list.lock);
1146
1147 if (err < 0)
1148 goto done;
1149 }
1150
1151 sk->sk_max_ack_backlog = backlog;
1152 sk->sk_ack_backlog = 0;
1153 sk->sk_state = BT_LISTEN;
1154
1155done:
1156 release_sock(sk);
1157 return err;
1158}
1159
1160static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int flags)
1161{
1162 DECLARE_WAITQUEUE(wait, current);
1163 struct sock *sk = sock->sk, *nsk;
1164 long timeo;
1165 int err = 0;
1166
Peter Zijlstrafcc70d52006-11-08 22:44:35 -08001167 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001168
1169 if (sk->sk_state != BT_LISTEN) {
1170 err = -EBADFD;
1171 goto done;
1172 }
1173
1174 timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
1175
1176 BT_DBG("sk %p timeo %ld", sk, timeo);
1177
1178 /* Wait for an incoming connection. (wake-one). */
Eric Dumazetaa395142010-04-20 13:03:51 +00001179 add_wait_queue_exclusive(sk_sleep(sk), &wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001180 while (!(nsk = bt_accept_dequeue(sk, newsock))) {
1181 set_current_state(TASK_INTERRUPTIBLE);
1182 if (!timeo) {
1183 err = -EAGAIN;
1184 break;
1185 }
1186
1187 release_sock(sk);
1188 timeo = schedule_timeout(timeo);
Peter Zijlstrafcc70d52006-11-08 22:44:35 -08001189 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001190
1191 if (sk->sk_state != BT_LISTEN) {
1192 err = -EBADFD;
1193 break;
1194 }
1195
1196 if (signal_pending(current)) {
1197 err = sock_intr_errno(timeo);
1198 break;
1199 }
1200 }
1201 set_current_state(TASK_RUNNING);
Eric Dumazetaa395142010-04-20 13:03:51 +00001202 remove_wait_queue(sk_sleep(sk), &wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001203
1204 if (err)
1205 goto done;
1206
1207 newsock->state = SS_CONNECTED;
1208
1209 BT_DBG("new socket %p", nsk);
1210
1211done:
1212 release_sock(sk);
1213 return err;
1214}
1215
1216static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
1217{
1218 struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
1219 struct sock *sk = sock->sk;
1220
1221 BT_DBG("sock %p, sk %p", sock, sk);
1222
1223 addr->sa_family = AF_BLUETOOTH;
1224 *len = sizeof(struct sockaddr_l2);
1225
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001226 if (peer) {
1227 la->l2_psm = l2cap_pi(sk)->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001228 bacpy(&la->l2_bdaddr, &bt_sk(sk)->dst);
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001229 la->l2_cid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001230 } else {
1231 la->l2_psm = l2cap_pi(sk)->sport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001232 bacpy(&la->l2_bdaddr, &bt_sk(sk)->src);
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001233 la->l2_cid = cpu_to_le16(l2cap_pi(sk)->scid);
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001234 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001235
Linus Torvalds1da177e2005-04-16 15:20:36 -07001236 return 0;
1237}
1238
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001239static void l2cap_monitor_timeout(unsigned long arg)
1240{
1241 struct sock *sk = (void *) arg;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001242
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001243 bh_lock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001244 if (l2cap_pi(sk)->retry_count >= l2cap_pi(sk)->remote_max_tx) {
1245 l2cap_send_disconn_req(l2cap_pi(sk)->conn, sk);
Andrei Emeltchenkob13f5862009-12-15 11:38:04 +02001246 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001247 return;
1248 }
1249
1250 l2cap_pi(sk)->retry_count++;
1251 __mod_monitor_timer();
1252
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -03001253 l2cap_send_rr_or_rnr(l2cap_pi(sk), L2CAP_CTRL_POLL);
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001254 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001255}
1256
1257static void l2cap_retrans_timeout(unsigned long arg)
1258{
1259 struct sock *sk = (void *) arg;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001260
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001261 bh_lock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001262 l2cap_pi(sk)->retry_count = 1;
1263 __mod_monitor_timer();
1264
1265 l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
1266
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -03001267 l2cap_send_rr_or_rnr(l2cap_pi(sk), L2CAP_CTRL_POLL);
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001268 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001269}
1270
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001271static void l2cap_drop_acked_frames(struct sock *sk)
1272{
1273 struct sk_buff *skb;
1274
Gustavo F. Padovan812e7372010-05-01 16:15:42 -03001275 while ((skb = skb_peek(TX_QUEUE(sk))) &&
1276 l2cap_pi(sk)->unacked_frames) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001277 if (bt_cb(skb)->tx_seq == l2cap_pi(sk)->expected_ack_seq)
1278 break;
1279
1280 skb = skb_dequeue(TX_QUEUE(sk));
1281 kfree_skb(skb);
1282
1283 l2cap_pi(sk)->unacked_frames--;
1284 }
1285
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001286 if (!l2cap_pi(sk)->unacked_frames)
1287 del_timer(&l2cap_pi(sk)->retrans_timer);
1288
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001289 return;
1290}
1291
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001292static inline void l2cap_do_send(struct sock *sk, struct sk_buff *skb)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001293{
1294 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001295
1296 BT_DBG("sk %p, skb %p len %d", sk, skb, skb->len);
1297
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001298 hci_send_acl(pi->conn->hcon, skb, 0);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001299}
1300
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001301static int l2cap_streaming_send(struct sock *sk)
1302{
1303 struct sk_buff *skb, *tx_skb;
1304 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001305 u16 control, fcs;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001306
1307 while ((skb = sk->sk_send_head)) {
1308 tx_skb = skb_clone(skb, GFP_ATOMIC);
1309
1310 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
1311 control |= pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT;
1312 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1313
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001314 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001315 fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
1316 put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
1317 }
1318
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001319 l2cap_do_send(sk, tx_skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001320
1321 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
1322
1323 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1324 sk->sk_send_head = NULL;
1325 else
1326 sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
1327
1328 skb = skb_dequeue(TX_QUEUE(sk));
1329 kfree_skb(skb);
1330 }
1331 return 0;
1332}
1333
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001334static int l2cap_retransmit_frame(struct sock *sk, u8 tx_seq)
1335{
1336 struct l2cap_pinfo *pi = l2cap_pi(sk);
1337 struct sk_buff *skb, *tx_skb;
1338 u16 control, fcs;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001339
1340 skb = skb_peek(TX_QUEUE(sk));
1341 do {
1342 if (bt_cb(skb)->tx_seq != tx_seq) {
1343 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1344 break;
1345 skb = skb_queue_next(TX_QUEUE(sk), skb);
1346 continue;
1347 }
1348
1349 if (pi->remote_max_tx &&
1350 bt_cb(skb)->retries == pi->remote_max_tx) {
1351 l2cap_send_disconn_req(pi->conn, sk);
1352 break;
1353 }
1354
1355 tx_skb = skb_clone(skb, GFP_ATOMIC);
1356 bt_cb(skb)->retries++;
1357 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03001358 control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001359 | (tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
1360 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1361
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001362 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001363 fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
1364 put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
1365 }
1366
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001367 l2cap_do_send(sk, tx_skb);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001368 break;
1369 } while(1);
1370 return 0;
1371}
1372
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001373static int l2cap_ertm_send(struct sock *sk)
1374{
1375 struct sk_buff *skb, *tx_skb;
1376 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001377 u16 control, fcs;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001378 int nsent = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001379
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001380 if (pi->conn_state & L2CAP_CONN_WAIT_F)
1381 return 0;
1382
Joe Perchesf64f9e72009-11-29 16:55:45 -08001383 while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(sk)) &&
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03001384 !(pi->conn_state & L2CAP_CONN_REMOTE_BUSY)) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001385
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001386 if (pi->remote_max_tx &&
1387 bt_cb(skb)->retries == pi->remote_max_tx) {
1388 l2cap_send_disconn_req(pi->conn, sk);
1389 break;
1390 }
1391
Andrei Emeltchenkoe420aba2009-12-23 13:07:14 +02001392 tx_skb = skb_clone(skb, GFP_ATOMIC);
1393
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001394 bt_cb(skb)->retries++;
1395
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001396 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001397 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
1398 control |= L2CAP_CTRL_FINAL;
1399 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
1400 }
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03001401 control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001402 | (pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
1403 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1404
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001405
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03001406 if (pi->fcs == L2CAP_FCS_CRC16) {
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001407 fcs = crc16(0, (u8 *)skb->data, tx_skb->len - 2);
1408 put_unaligned_le16(fcs, skb->data + tx_skb->len - 2);
1409 }
1410
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001411 l2cap_do_send(sk, tx_skb);
1412
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001413 __mod_retrans_timer();
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001414
1415 bt_cb(skb)->tx_seq = pi->next_tx_seq;
1416 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
1417
1418 pi->unacked_frames++;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03001419 pi->frames_sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001420
1421 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1422 sk->sk_send_head = NULL;
1423 else
1424 sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001425
1426 nsent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001427 }
1428
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001429 return nsent;
1430}
1431
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001432static void l2cap_send_ack(struct l2cap_pinfo *pi)
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001433{
1434 struct sock *sk = (struct sock *)pi;
1435 u16 control = 0;
1436
1437 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1438
1439 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
1440 control |= L2CAP_SUPER_RCV_NOT_READY;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001441 l2cap_send_sframe(pi, control);
1442 return;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001443 } else if (l2cap_ertm_send(sk) == 0) {
1444 control |= L2CAP_SUPER_RCV_READY;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001445 l2cap_send_sframe(pi, control);
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001446 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001447}
1448
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001449static void l2cap_send_srejtail(struct sock *sk)
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03001450{
1451 struct srej_list *tail;
1452 u16 control;
1453
1454 control = L2CAP_SUPER_SELECT_REJECT;
1455 control |= L2CAP_CTRL_FINAL;
1456
1457 tail = list_entry(SREJ_LIST(sk)->prev, struct srej_list, list);
1458 control |= tail->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1459
1460 l2cap_send_sframe(l2cap_pi(sk), control);
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03001461}
1462
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001463static 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 -07001464{
1465 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001466 struct sk_buff **frag;
1467 int err, sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001468
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03001469 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001470 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001471
1472 sent += count;
1473 len -= count;
1474
1475 /* Continuation fragments (no L2CAP header) */
1476 frag = &skb_shinfo(skb)->frag_list;
1477 while (len) {
1478 count = min_t(unsigned int, conn->mtu, len);
1479
1480 *frag = bt_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err);
1481 if (!*frag)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001482 return -EFAULT;
1483 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
1484 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001485
1486 sent += count;
1487 len -= count;
1488
1489 frag = &(*frag)->next;
1490 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001491
1492 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001493}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001494
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001495static struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, size_t len)
1496{
1497 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1498 struct sk_buff *skb;
1499 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1500 struct l2cap_hdr *lh;
1501
1502 BT_DBG("sk %p len %d", sk, (int)len);
1503
1504 count = min_t(unsigned int, (conn->mtu - hlen), len);
1505 skb = bt_skb_send_alloc(sk, count + hlen,
1506 msg->msg_flags & MSG_DONTWAIT, &err);
1507 if (!skb)
1508 return ERR_PTR(-ENOMEM);
1509
1510 /* Create L2CAP header */
1511 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1512 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1513 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1514 put_unaligned_le16(l2cap_pi(sk)->psm, skb_put(skb, 2));
1515
1516 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1517 if (unlikely(err < 0)) {
1518 kfree_skb(skb);
1519 return ERR_PTR(err);
1520 }
1521 return skb;
1522}
1523
1524static struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *msg, size_t len)
1525{
1526 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1527 struct sk_buff *skb;
1528 int err, count, hlen = L2CAP_HDR_SIZE;
1529 struct l2cap_hdr *lh;
1530
1531 BT_DBG("sk %p len %d", sk, (int)len);
1532
1533 count = min_t(unsigned int, (conn->mtu - hlen), len);
1534 skb = bt_skb_send_alloc(sk, count + hlen,
1535 msg->msg_flags & MSG_DONTWAIT, &err);
1536 if (!skb)
1537 return ERR_PTR(-ENOMEM);
1538
1539 /* Create L2CAP header */
1540 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1541 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1542 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1543
1544 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1545 if (unlikely(err < 0)) {
1546 kfree_skb(skb);
1547 return ERR_PTR(err);
1548 }
1549 return skb;
1550}
1551
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001552static 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 -03001553{
1554 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1555 struct sk_buff *skb;
1556 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1557 struct l2cap_hdr *lh;
1558
1559 BT_DBG("sk %p len %d", sk, (int)len);
1560
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03001561 if (!conn)
1562 return ERR_PTR(-ENOTCONN);
1563
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001564 if (sdulen)
1565 hlen += 2;
1566
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001567 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1568 hlen += 2;
1569
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001570 count = min_t(unsigned int, (conn->mtu - hlen), len);
1571 skb = bt_skb_send_alloc(sk, count + hlen,
1572 msg->msg_flags & MSG_DONTWAIT, &err);
1573 if (!skb)
1574 return ERR_PTR(-ENOMEM);
1575
1576 /* Create L2CAP header */
1577 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1578 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1579 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1580 put_unaligned_le16(control, skb_put(skb, 2));
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001581 if (sdulen)
1582 put_unaligned_le16(sdulen, skb_put(skb, 2));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001583
1584 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1585 if (unlikely(err < 0)) {
1586 kfree_skb(skb);
1587 return ERR_PTR(err);
1588 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001589
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001590 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1591 put_unaligned_le16(0, skb_put(skb, 2));
1592
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001593 bt_cb(skb)->retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001594 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001595}
1596
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001597static inline int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len)
1598{
1599 struct l2cap_pinfo *pi = l2cap_pi(sk);
1600 struct sk_buff *skb;
1601 struct sk_buff_head sar_queue;
1602 u16 control;
1603 size_t size = 0;
1604
Gustavo F. Padovanff12fd62010-05-05 22:09:15 -03001605 skb_queue_head_init(&sar_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001606 control = L2CAP_SDU_START;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001607 skb = l2cap_create_iframe_pdu(sk, msg, pi->remote_mps, control, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001608 if (IS_ERR(skb))
1609 return PTR_ERR(skb);
1610
1611 __skb_queue_tail(&sar_queue, skb);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001612 len -= pi->remote_mps;
1613 size += pi->remote_mps;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001614
1615 while (len > 0) {
1616 size_t buflen;
1617
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001618 if (len > pi->remote_mps) {
Gustavo F. Padovan44651b82010-05-01 16:15:43 -03001619 control = L2CAP_SDU_CONTINUE;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001620 buflen = pi->remote_mps;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001621 } else {
Gustavo F. Padovan44651b82010-05-01 16:15:43 -03001622 control = L2CAP_SDU_END;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001623 buflen = len;
1624 }
1625
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001626 skb = l2cap_create_iframe_pdu(sk, msg, buflen, control, 0);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001627 if (IS_ERR(skb)) {
1628 skb_queue_purge(&sar_queue);
1629 return PTR_ERR(skb);
1630 }
1631
1632 __skb_queue_tail(&sar_queue, skb);
1633 len -= buflen;
1634 size += buflen;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001635 }
1636 skb_queue_splice_tail(&sar_queue, TX_QUEUE(sk));
1637 if (sk->sk_send_head == NULL)
1638 sk->sk_send_head = sar_queue.next;
1639
1640 return size;
1641}
1642
Linus Torvalds1da177e2005-04-16 15:20:36 -07001643static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len)
1644{
1645 struct sock *sk = sock->sk;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001646 struct l2cap_pinfo *pi = l2cap_pi(sk);
1647 struct sk_buff *skb;
1648 u16 control;
1649 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001650
1651 BT_DBG("sock %p, sk %p", sock, sk);
1652
Benjamin LaHaisec1cbe4b2005-12-13 23:22:19 -08001653 err = sock_error(sk);
1654 if (err)
1655 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001656
1657 if (msg->msg_flags & MSG_OOB)
1658 return -EOPNOTSUPP;
1659
Linus Torvalds1da177e2005-04-16 15:20:36 -07001660 lock_sock(sk);
1661
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001662 if (sk->sk_state != BT_CONNECTED) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001663 err = -ENOTCONN;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001664 goto done;
1665 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001666
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001667 /* Connectionless channel */
1668 if (sk->sk_type == SOCK_DGRAM) {
1669 skb = l2cap_create_connless_pdu(sk, msg, len);
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001670 if (IS_ERR(skb)) {
Dan Carpenter477fffb2010-04-21 23:52:01 +00001671 err = PTR_ERR(skb);
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001672 } else {
1673 l2cap_do_send(sk, skb);
1674 err = len;
1675 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001676 goto done;
1677 }
1678
1679 switch (pi->mode) {
1680 case L2CAP_MODE_BASIC:
Gustavo F. Padovanc69163e2010-05-01 16:15:35 -03001681 /* Check outgoing MTU */
1682 if (len > pi->omtu) {
1683 err = -EINVAL;
1684 goto done;
1685 }
1686
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001687 /* Create a basic PDU */
1688 skb = l2cap_create_basic_pdu(sk, msg, len);
1689 if (IS_ERR(skb)) {
1690 err = PTR_ERR(skb);
1691 goto done;
1692 }
1693
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001694 l2cap_do_send(sk, skb);
1695 err = len;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001696 break;
1697
1698 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001699 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001700 /* Entire SDU fits into one PDU */
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03001701 if (len <= pi->remote_mps) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001702 control = L2CAP_SDU_UNSEGMENTED;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001703 skb = l2cap_create_iframe_pdu(sk, msg, len, control, 0);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001704 if (IS_ERR(skb)) {
1705 err = PTR_ERR(skb);
1706 goto done;
1707 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001708 __skb_queue_tail(TX_QUEUE(sk), skb);
1709 if (sk->sk_send_head == NULL)
1710 sk->sk_send_head = skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001711 } else {
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001712 /* Segment SDU into multiples PDUs */
1713 err = l2cap_sar_segment_sdu(sk, msg, len);
1714 if (err < 0)
1715 goto done;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001716 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001717
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001718 if (pi->mode == L2CAP_MODE_STREAMING)
1719 err = l2cap_streaming_send(sk);
1720 else
1721 err = l2cap_ertm_send(sk);
1722
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001723 if (err >= 0)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001724 err = len;
1725 break;
1726
1727 default:
1728 BT_DBG("bad state %1.1x", pi->mode);
1729 err = -EINVAL;
1730 }
1731
1732done:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001733 release_sock(sk);
1734 return err;
1735}
1736
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001737static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags)
1738{
1739 struct sock *sk = sock->sk;
1740
1741 lock_sock(sk);
1742
1743 if (sk->sk_state == BT_CONNECT2 && bt_sk(sk)->defer_setup) {
1744 struct l2cap_conn_rsp rsp;
1745
1746 sk->sk_state = BT_CONFIG;
1747
1748 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
1749 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
1750 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
1751 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
1752 l2cap_send_cmd(l2cap_pi(sk)->conn, l2cap_pi(sk)->ident,
1753 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
1754
1755 release_sock(sk);
1756 return 0;
1757 }
1758
1759 release_sock(sk);
1760
1761 return bt_sock_recvmsg(iocb, sock, msg, len, flags);
1762}
1763
David S. Millerb7058842009-09-30 16:12:20 -07001764static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001765{
1766 struct sock *sk = sock->sk;
1767 struct l2cap_options opts;
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001768 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001769 u32 opt;
1770
1771 BT_DBG("sk %p", sk);
1772
1773 lock_sock(sk);
1774
1775 switch (optname) {
1776 case L2CAP_OPTIONS:
Marcel Holtmann0878b662007-05-05 00:35:59 +02001777 opts.imtu = l2cap_pi(sk)->imtu;
1778 opts.omtu = l2cap_pi(sk)->omtu;
1779 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001780 opts.mode = l2cap_pi(sk)->mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001781 opts.fcs = l2cap_pi(sk)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03001782 opts.max_tx = l2cap_pi(sk)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03001783 opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
Marcel Holtmann0878b662007-05-05 00:35:59 +02001784
Linus Torvalds1da177e2005-04-16 15:20:36 -07001785 len = min_t(unsigned int, sizeof(opts), optlen);
1786 if (copy_from_user((char *) &opts, optval, len)) {
1787 err = -EFAULT;
1788 break;
1789 }
Marcel Holtmann0878b662007-05-05 00:35:59 +02001790
João Paulo Rechi Vita0041ecf2010-05-01 16:15:42 -03001791 l2cap_pi(sk)->mode = opts.mode;
1792 switch (l2cap_pi(sk)->mode) {
1793 case L2CAP_MODE_BASIC:
1794 break;
1795 case L2CAP_MODE_ERTM:
1796 case L2CAP_MODE_STREAMING:
1797 if (enable_ertm)
1798 break;
1799 /* fall through */
1800 default:
1801 err = -EINVAL;
1802 break;
1803 }
1804
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001805 l2cap_pi(sk)->imtu = opts.imtu;
1806 l2cap_pi(sk)->omtu = opts.omtu;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001807 l2cap_pi(sk)->fcs = opts.fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03001808 l2cap_pi(sk)->max_tx = opts.max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03001809 l2cap_pi(sk)->tx_win = (__u8)opts.txwin_size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001810 break;
1811
1812 case L2CAP_LM:
1813 if (get_user(opt, (u32 __user *) optval)) {
1814 err = -EFAULT;
1815 break;
1816 }
1817
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001818 if (opt & L2CAP_LM_AUTH)
1819 l2cap_pi(sk)->sec_level = BT_SECURITY_LOW;
1820 if (opt & L2CAP_LM_ENCRYPT)
1821 l2cap_pi(sk)->sec_level = BT_SECURITY_MEDIUM;
1822 if (opt & L2CAP_LM_SECURE)
1823 l2cap_pi(sk)->sec_level = BT_SECURITY_HIGH;
1824
1825 l2cap_pi(sk)->role_switch = (opt & L2CAP_LM_MASTER);
1826 l2cap_pi(sk)->force_reliable = (opt & L2CAP_LM_RELIABLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001827 break;
1828
1829 default:
1830 err = -ENOPROTOOPT;
1831 break;
1832 }
1833
1834 release_sock(sk);
1835 return err;
1836}
1837
David S. Millerb7058842009-09-30 16:12:20 -07001838static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001839{
1840 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001841 struct bt_security sec;
1842 int len, err = 0;
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001843 u32 opt;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001844
1845 BT_DBG("sk %p", sk);
1846
1847 if (level == SOL_L2CAP)
1848 return l2cap_sock_setsockopt_old(sock, optname, optval, optlen);
1849
Marcel Holtmann0588d942009-01-16 10:06:13 +01001850 if (level != SOL_BLUETOOTH)
1851 return -ENOPROTOOPT;
1852
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001853 lock_sock(sk);
1854
1855 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001856 case BT_SECURITY:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03001857 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
1858 && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01001859 err = -EINVAL;
1860 break;
1861 }
1862
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001863 sec.level = BT_SECURITY_LOW;
1864
1865 len = min_t(unsigned int, sizeof(sec), optlen);
1866 if (copy_from_user((char *) &sec, optval, len)) {
1867 err = -EFAULT;
1868 break;
1869 }
1870
1871 if (sec.level < BT_SECURITY_LOW ||
1872 sec.level > BT_SECURITY_HIGH) {
1873 err = -EINVAL;
1874 break;
1875 }
1876
1877 l2cap_pi(sk)->sec_level = sec.level;
1878 break;
1879
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001880 case BT_DEFER_SETUP:
1881 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
1882 err = -EINVAL;
1883 break;
1884 }
1885
1886 if (get_user(opt, (u32 __user *) optval)) {
1887 err = -EFAULT;
1888 break;
1889 }
1890
1891 bt_sk(sk)->defer_setup = opt;
1892 break;
1893
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001894 default:
1895 err = -ENOPROTOOPT;
1896 break;
1897 }
1898
1899 release_sock(sk);
1900 return err;
1901}
1902
1903static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001904{
1905 struct sock *sk = sock->sk;
1906 struct l2cap_options opts;
1907 struct l2cap_conninfo cinfo;
1908 int len, err = 0;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001909 u32 opt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001910
1911 BT_DBG("sk %p", sk);
1912
1913 if (get_user(len, optlen))
1914 return -EFAULT;
1915
1916 lock_sock(sk);
1917
1918 switch (optname) {
1919 case L2CAP_OPTIONS:
1920 opts.imtu = l2cap_pi(sk)->imtu;
1921 opts.omtu = l2cap_pi(sk)->omtu;
1922 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001923 opts.mode = l2cap_pi(sk)->mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001924 opts.fcs = l2cap_pi(sk)->fcs;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03001925 opts.max_tx = l2cap_pi(sk)->max_tx;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03001926 opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001927
1928 len = min_t(unsigned int, len, sizeof(opts));
1929 if (copy_to_user(optval, (char *) &opts, len))
1930 err = -EFAULT;
1931
1932 break;
1933
1934 case L2CAP_LM:
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001935 switch (l2cap_pi(sk)->sec_level) {
1936 case BT_SECURITY_LOW:
1937 opt = L2CAP_LM_AUTH;
1938 break;
1939 case BT_SECURITY_MEDIUM:
1940 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT;
1941 break;
1942 case BT_SECURITY_HIGH:
1943 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT |
1944 L2CAP_LM_SECURE;
1945 break;
1946 default:
1947 opt = 0;
1948 break;
1949 }
1950
1951 if (l2cap_pi(sk)->role_switch)
1952 opt |= L2CAP_LM_MASTER;
1953
1954 if (l2cap_pi(sk)->force_reliable)
1955 opt |= L2CAP_LM_RELIABLE;
1956
1957 if (put_user(opt, (u32 __user *) optval))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001958 err = -EFAULT;
1959 break;
1960
1961 case L2CAP_CONNINFO:
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001962 if (sk->sk_state != BT_CONNECTED &&
1963 !(sk->sk_state == BT_CONNECT2 &&
1964 bt_sk(sk)->defer_setup)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001965 err = -ENOTCONN;
1966 break;
1967 }
1968
1969 cinfo.hci_handle = l2cap_pi(sk)->conn->hcon->handle;
1970 memcpy(cinfo.dev_class, l2cap_pi(sk)->conn->hcon->dev_class, 3);
1971
1972 len = min_t(unsigned int, len, sizeof(cinfo));
1973 if (copy_to_user(optval, (char *) &cinfo, len))
1974 err = -EFAULT;
1975
1976 break;
1977
1978 default:
1979 err = -ENOPROTOOPT;
1980 break;
1981 }
1982
1983 release_sock(sk);
1984 return err;
1985}
1986
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001987static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
1988{
1989 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001990 struct bt_security sec;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001991 int len, err = 0;
1992
1993 BT_DBG("sk %p", sk);
1994
1995 if (level == SOL_L2CAP)
1996 return l2cap_sock_getsockopt_old(sock, optname, optval, optlen);
1997
Marcel Holtmann0588d942009-01-16 10:06:13 +01001998 if (level != SOL_BLUETOOTH)
1999 return -ENOPROTOOPT;
2000
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002001 if (get_user(len, optlen))
2002 return -EFAULT;
2003
2004 lock_sock(sk);
2005
2006 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002007 case BT_SECURITY:
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03002008 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
2009 && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01002010 err = -EINVAL;
2011 break;
2012 }
2013
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002014 sec.level = l2cap_pi(sk)->sec_level;
2015
2016 len = min_t(unsigned int, len, sizeof(sec));
2017 if (copy_to_user(optval, (char *) &sec, len))
2018 err = -EFAULT;
2019
2020 break;
2021
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002022 case BT_DEFER_SETUP:
2023 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
2024 err = -EINVAL;
2025 break;
2026 }
2027
2028 if (put_user(bt_sk(sk)->defer_setup, (u32 __user *) optval))
2029 err = -EFAULT;
2030
2031 break;
2032
Marcel Holtmannd58daf42009-01-15 21:52:14 +01002033 default:
2034 err = -ENOPROTOOPT;
2035 break;
2036 }
2037
2038 release_sock(sk);
2039 return err;
2040}
2041
Linus Torvalds1da177e2005-04-16 15:20:36 -07002042static int l2cap_sock_shutdown(struct socket *sock, int how)
2043{
2044 struct sock *sk = sock->sk;
2045 int err = 0;
2046
2047 BT_DBG("sock %p, sk %p", sock, sk);
2048
2049 if (!sk)
2050 return 0;
2051
2052 lock_sock(sk);
2053 if (!sk->sk_shutdown) {
2054 sk->sk_shutdown = SHUTDOWN_MASK;
2055 l2cap_sock_clear_timer(sk);
2056 __l2cap_sock_close(sk, 0);
2057
2058 if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
Marcel Holtmannb1235d72008-07-14 20:13:54 +02002059 err = bt_sock_wait_state(sk, BT_CLOSED,
2060 sk->sk_lingertime);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002061 }
2062 release_sock(sk);
2063 return err;
2064}
2065
2066static int l2cap_sock_release(struct socket *sock)
2067{
2068 struct sock *sk = sock->sk;
2069 int err;
2070
2071 BT_DBG("sock %p, sk %p", sock, sk);
2072
2073 if (!sk)
2074 return 0;
2075
2076 err = l2cap_sock_shutdown(sock, 2);
2077
2078 sock_orphan(sk);
2079 l2cap_sock_kill(sk);
2080 return err;
2081}
2082
Linus Torvalds1da177e2005-04-16 15:20:36 -07002083static void l2cap_chan_ready(struct sock *sk)
2084{
2085 struct sock *parent = bt_sk(sk)->parent;
2086
2087 BT_DBG("sk %p, parent %p", sk, parent);
2088
2089 l2cap_pi(sk)->conf_state = 0;
2090 l2cap_sock_clear_timer(sk);
2091
2092 if (!parent) {
2093 /* Outgoing channel.
2094 * Wake up socket sleeping on connect.
2095 */
2096 sk->sk_state = BT_CONNECTED;
2097 sk->sk_state_change(sk);
2098 } else {
2099 /* Incoming channel.
2100 * Wake up socket sleeping on accept.
2101 */
2102 parent->sk_data_ready(parent, 0);
2103 }
2104}
2105
2106/* Copy frame to all raw sockets on that connection */
2107static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2108{
2109 struct l2cap_chan_list *l = &conn->chan_list;
2110 struct sk_buff *nskb;
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002111 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002112
2113 BT_DBG("conn %p", conn);
2114
2115 read_lock(&l->lock);
2116 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
2117 if (sk->sk_type != SOCK_RAW)
2118 continue;
2119
2120 /* Don't send frame to the socket it came from */
2121 if (skb->sk == sk)
2122 continue;
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002123 nskb = skb_clone(skb, GFP_ATOMIC);
2124 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002125 continue;
2126
2127 if (sock_queue_rcv_skb(sk, nskb))
2128 kfree_skb(nskb);
2129 }
2130 read_unlock(&l->lock);
2131}
2132
2133/* ---- L2CAP signalling commands ---- */
2134static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
2135 u8 code, u8 ident, u16 dlen, void *data)
2136{
2137 struct sk_buff *skb, **frag;
2138 struct l2cap_cmd_hdr *cmd;
2139 struct l2cap_hdr *lh;
2140 int len, count;
2141
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002142 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d",
2143 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002144
2145 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2146 count = min_t(unsigned int, conn->mtu, len);
2147
2148 skb = bt_skb_alloc(count, GFP_ATOMIC);
2149 if (!skb)
2150 return NULL;
2151
2152 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002153 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03002154 lh->cid = cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002155
2156 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2157 cmd->code = code;
2158 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002159 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002160
2161 if (dlen) {
2162 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2163 memcpy(skb_put(skb, count), data, count);
2164 data += count;
2165 }
2166
2167 len -= skb->len;
2168
2169 /* Continuation fragments (no L2CAP header) */
2170 frag = &skb_shinfo(skb)->frag_list;
2171 while (len) {
2172 count = min_t(unsigned int, conn->mtu, len);
2173
2174 *frag = bt_skb_alloc(count, GFP_ATOMIC);
2175 if (!*frag)
2176 goto fail;
2177
2178 memcpy(skb_put(*frag, count), data, count);
2179
2180 len -= count;
2181 data += count;
2182
2183 frag = &(*frag)->next;
2184 }
2185
2186 return skb;
2187
2188fail:
2189 kfree_skb(skb);
2190 return NULL;
2191}
2192
2193static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned long *val)
2194{
2195 struct l2cap_conf_opt *opt = *ptr;
2196 int len;
2197
2198 len = L2CAP_CONF_OPT_SIZE + opt->len;
2199 *ptr += len;
2200
2201 *type = opt->type;
2202 *olen = opt->len;
2203
2204 switch (opt->len) {
2205 case 1:
2206 *val = *((u8 *) opt->val);
2207 break;
2208
2209 case 2:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002210 *val = __le16_to_cpu(*((__le16 *) opt->val));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002211 break;
2212
2213 case 4:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002214 *val = __le32_to_cpu(*((__le32 *) opt->val));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002215 break;
2216
2217 default:
2218 *val = (unsigned long) opt->val;
2219 break;
2220 }
2221
2222 BT_DBG("type 0x%2.2x len %d val 0x%lx", *type, opt->len, *val);
2223 return len;
2224}
2225
Linus Torvalds1da177e2005-04-16 15:20:36 -07002226static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2227{
2228 struct l2cap_conf_opt *opt = *ptr;
2229
2230 BT_DBG("type 0x%2.2x len %d val 0x%lx", type, len, val);
2231
2232 opt->type = type;
2233 opt->len = len;
2234
2235 switch (len) {
2236 case 1:
2237 *((u8 *) opt->val) = val;
2238 break;
2239
2240 case 2:
Al Viro8e036fc2007-07-29 00:16:36 -07002241 *((__le16 *) opt->val) = cpu_to_le16(val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002242 break;
2243
2244 case 4:
Al Viro8e036fc2007-07-29 00:16:36 -07002245 *((__le32 *) opt->val) = cpu_to_le32(val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002246 break;
2247
2248 default:
2249 memcpy(opt->val, (void *) val, len);
2250 break;
2251 }
2252
2253 *ptr += L2CAP_CONF_OPT_SIZE + len;
2254}
2255
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002256static void l2cap_ack_timeout(unsigned long arg)
2257{
2258 struct sock *sk = (void *) arg;
2259
2260 bh_lock_sock(sk);
2261 l2cap_send_ack(l2cap_pi(sk));
2262 bh_unlock_sock(sk);
2263}
2264
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002265static inline void l2cap_ertm_init(struct sock *sk)
2266{
2267 l2cap_pi(sk)->expected_ack_seq = 0;
2268 l2cap_pi(sk)->unacked_frames = 0;
2269 l2cap_pi(sk)->buffer_seq = 0;
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03002270 l2cap_pi(sk)->num_acked = 0;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03002271 l2cap_pi(sk)->frames_sent = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002272
2273 setup_timer(&l2cap_pi(sk)->retrans_timer,
2274 l2cap_retrans_timeout, (unsigned long) sk);
2275 setup_timer(&l2cap_pi(sk)->monitor_timer,
2276 l2cap_monitor_timeout, (unsigned long) sk);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002277 setup_timer(&l2cap_pi(sk)->ack_timer,
2278 l2cap_ack_timeout, (unsigned long) sk);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002279
2280 __skb_queue_head_init(SREJ_QUEUE(sk));
2281}
2282
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002283static int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
2284{
2285 u32 local_feat_mask = l2cap_feat_mask;
2286 if (enable_ertm)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002287 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002288
2289 switch (mode) {
2290 case L2CAP_MODE_ERTM:
2291 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
2292 case L2CAP_MODE_STREAMING:
2293 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
2294 default:
2295 return 0x00;
2296 }
2297}
2298
2299static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
2300{
2301 switch (mode) {
2302 case L2CAP_MODE_STREAMING:
2303 case L2CAP_MODE_ERTM:
2304 if (l2cap_mode_supported(mode, remote_feat_mask))
2305 return mode;
2306 /* fall through */
2307 default:
2308 return L2CAP_MODE_BASIC;
2309 }
2310}
2311
Linus Torvalds1da177e2005-04-16 15:20:36 -07002312static int l2cap_build_conf_req(struct sock *sk, void *data)
2313{
2314 struct l2cap_pinfo *pi = l2cap_pi(sk);
2315 struct l2cap_conf_req *req = data;
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03002316 struct l2cap_conf_rfc rfc = { .mode = pi->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07002317 void *ptr = req->data;
2318
2319 BT_DBG("sk %p", sk);
2320
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002321 if (pi->num_conf_req || pi->num_conf_rsp)
2322 goto done;
2323
2324 switch (pi->mode) {
2325 case L2CAP_MODE_STREAMING:
2326 case L2CAP_MODE_ERTM:
2327 pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002328 if (!l2cap_mode_supported(pi->mode, pi->conn->feat_mask))
2329 l2cap_send_disconn_req(pi->conn, sk);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002330 break;
2331 default:
2332 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
2333 break;
2334 }
2335
2336done:
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002337 switch (pi->mode) {
2338 case L2CAP_MODE_BASIC:
2339 if (pi->imtu != L2CAP_DEFAULT_MTU)
2340 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
2341 break;
2342
2343 case L2CAP_MODE_ERTM:
2344 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan14b5aa72010-05-01 16:15:40 -03002345 rfc.txwin_size = pi->tx_win;
Gustavo F. Padovan68d7f0c2010-05-01 16:15:41 -03002346 rfc.max_transmit = pi->max_tx;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002347 rfc.retrans_timeout = 0;
2348 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002349 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03002350 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002351 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002352
2353 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2354 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002355
2356 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2357 break;
2358
2359 if (pi->fcs == L2CAP_FCS_NONE ||
2360 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
2361 pi->fcs = L2CAP_FCS_NONE;
2362 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
2363 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002364 break;
2365
2366 case L2CAP_MODE_STREAMING:
2367 rfc.mode = L2CAP_MODE_STREAMING;
2368 rfc.txwin_size = 0;
2369 rfc.max_transmit = 0;
2370 rfc.retrans_timeout = 0;
2371 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002372 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03002373 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002374 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002375
2376 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2377 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002378
2379 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2380 break;
2381
2382 if (pi->fcs == L2CAP_FCS_NONE ||
2383 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
2384 pi->fcs = L2CAP_FCS_NONE;
2385 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
2386 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002387 break;
2388 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002389
2390 /* FIXME: Need actual value of the flush timeout */
2391 //if (flush_to != L2CAP_DEFAULT_FLUSH_TO)
2392 // l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2, pi->flush_to);
2393
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002394 req->dcid = cpu_to_le16(pi->dcid);
2395 req->flags = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002396
2397 return ptr - data;
2398}
2399
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002400static int l2cap_parse_conf_req(struct sock *sk, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002401{
2402 struct l2cap_pinfo *pi = l2cap_pi(sk);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002403 struct l2cap_conf_rsp *rsp = data;
2404 void *ptr = rsp->data;
2405 void *req = pi->conf_req;
2406 int len = pi->conf_len;
2407 int type, hint, olen;
2408 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002409 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Marcel Holtmann861d6882007-10-20 13:37:06 +02002410 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002411 u16 result = L2CAP_CONF_SUCCESS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002412
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002413 BT_DBG("sk %p", sk);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01002414
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002415 while (len >= L2CAP_CONF_OPT_SIZE) {
2416 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002417
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03002418 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07002419 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002420
2421 switch (type) {
2422 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002423 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002424 break;
2425
2426 case L2CAP_CONF_FLUSH_TO:
2427 pi->flush_to = val;
2428 break;
2429
2430 case L2CAP_CONF_QOS:
2431 break;
2432
Marcel Holtmann6464f352007-10-20 13:39:51 +02002433 case L2CAP_CONF_RFC:
2434 if (olen == sizeof(rfc))
2435 memcpy(&rfc, (void *) val, olen);
2436 break;
2437
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002438 case L2CAP_CONF_FCS:
2439 if (val == L2CAP_FCS_NONE)
2440 pi->conf_state |= L2CAP_CONF_NO_FCS_RECV;
2441
2442 break;
2443
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002444 default:
2445 if (hint)
2446 break;
2447
2448 result = L2CAP_CONF_UNKNOWN;
2449 *((u8 *) ptr++) = type;
2450 break;
2451 }
2452 }
2453
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002454 if (pi->num_conf_rsp || pi->num_conf_req)
2455 goto done;
2456
2457 switch (pi->mode) {
2458 case L2CAP_MODE_STREAMING:
2459 case L2CAP_MODE_ERTM:
2460 pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
2461 if (!l2cap_mode_supported(pi->mode, pi->conn->feat_mask))
2462 return -ECONNREFUSED;
2463 break;
2464 default:
2465 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
2466 break;
2467 }
2468
2469done:
2470 if (pi->mode != rfc.mode) {
2471 result = L2CAP_CONF_UNACCEPT;
2472 rfc.mode = pi->mode;
2473
2474 if (pi->num_conf_rsp == 1)
2475 return -ECONNREFUSED;
2476
2477 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2478 sizeof(rfc), (unsigned long) &rfc);
2479 }
2480
2481
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002482 if (result == L2CAP_CONF_SUCCESS) {
2483 /* Configure output options and let the other side know
2484 * which ones we don't like. */
2485
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002486 if (mtu < L2CAP_DEFAULT_MIN_MTU)
2487 result = L2CAP_CONF_UNACCEPT;
2488 else {
2489 pi->omtu = mtu;
2490 pi->conf_state |= L2CAP_CONF_MTU_DONE;
2491 }
2492 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002493
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002494 switch (rfc.mode) {
2495 case L2CAP_MODE_BASIC:
2496 pi->fcs = L2CAP_FCS_NONE;
2497 pi->conf_state |= L2CAP_CONF_MODE_DONE;
2498 break;
2499
2500 case L2CAP_MODE_ERTM:
2501 pi->remote_tx_win = rfc.txwin_size;
2502 pi->remote_max_tx = rfc.max_transmit;
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002503 if (rfc.max_pdu_size > pi->conn->mtu - 10)
2504 rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10);
2505
2506 pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002507
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002508 rfc.retrans_timeout =
2509 le16_to_cpu(L2CAP_DEFAULT_RETRANS_TO);
2510 rfc.monitor_timeout =
2511 le16_to_cpu(L2CAP_DEFAULT_MONITOR_TO);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002512
2513 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03002514
2515 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2516 sizeof(rfc), (unsigned long) &rfc);
2517
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002518 break;
2519
2520 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002521 if (rfc.max_pdu_size > pi->conn->mtu - 10)
2522 rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10);
2523
2524 pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002525
2526 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03002527
2528 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2529 sizeof(rfc), (unsigned long) &rfc);
2530
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002531 break;
2532
2533 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02002534 result = L2CAP_CONF_UNACCEPT;
2535
2536 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002537 rfc.mode = pi->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002538 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002539
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002540 if (result == L2CAP_CONF_SUCCESS)
2541 pi->conf_state |= L2CAP_CONF_OUTPUT_DONE;
2542 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002543 rsp->scid = cpu_to_le16(pi->dcid);
2544 rsp->result = cpu_to_le16(result);
2545 rsp->flags = cpu_to_le16(0x0000);
2546
2547 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002548}
2549
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002550static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data, u16 *result)
2551{
2552 struct l2cap_pinfo *pi = l2cap_pi(sk);
2553 struct l2cap_conf_req *req = data;
2554 void *ptr = req->data;
2555 int type, olen;
2556 unsigned long val;
2557 struct l2cap_conf_rfc rfc;
2558
2559 BT_DBG("sk %p, rsp %p, len %d, req %p", sk, rsp, len, data);
2560
2561 while (len >= L2CAP_CONF_OPT_SIZE) {
2562 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
2563
2564 switch (type) {
2565 case L2CAP_CONF_MTU:
2566 if (val < L2CAP_DEFAULT_MIN_MTU) {
2567 *result = L2CAP_CONF_UNACCEPT;
2568 pi->omtu = L2CAP_DEFAULT_MIN_MTU;
2569 } else
2570 pi->omtu = val;
2571 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
2572 break;
2573
2574 case L2CAP_CONF_FLUSH_TO:
2575 pi->flush_to = val;
2576 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
2577 2, pi->flush_to);
2578 break;
2579
2580 case L2CAP_CONF_RFC:
2581 if (olen == sizeof(rfc))
2582 memcpy(&rfc, (void *)val, olen);
2583
2584 if ((pi->conf_state & L2CAP_CONF_STATE2_DEVICE) &&
2585 rfc.mode != pi->mode)
2586 return -ECONNREFUSED;
2587
2588 pi->mode = rfc.mode;
2589 pi->fcs = 0;
2590
2591 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2592 sizeof(rfc), (unsigned long) &rfc);
2593 break;
2594 }
2595 }
2596
2597 if (*result == L2CAP_CONF_SUCCESS) {
2598 switch (rfc.mode) {
2599 case L2CAP_MODE_ERTM:
2600 pi->remote_tx_win = rfc.txwin_size;
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002601 pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
2602 pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002603 pi->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002604 break;
2605 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03002606 pi->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002607 }
2608 }
2609
2610 req->dcid = cpu_to_le16(pi->dcid);
2611 req->flags = cpu_to_le16(0x0000);
2612
2613 return ptr - data;
2614}
2615
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002616static int l2cap_build_conf_rsp(struct sock *sk, void *data, u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002617{
2618 struct l2cap_conf_rsp *rsp = data;
2619 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002620
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002621 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002622
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002623 rsp->scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002624 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002625 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002626
2627 return ptr - data;
2628}
2629
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002630static void l2cap_conf_rfc_get(struct sock *sk, void *rsp, int len)
2631{
2632 struct l2cap_pinfo *pi = l2cap_pi(sk);
2633 int type, olen;
2634 unsigned long val;
2635 struct l2cap_conf_rfc rfc;
2636
2637 BT_DBG("sk %p, rsp %p, len %d", sk, rsp, len);
2638
2639 if ((pi->mode != L2CAP_MODE_ERTM) && (pi->mode != L2CAP_MODE_STREAMING))
2640 return;
2641
2642 while (len >= L2CAP_CONF_OPT_SIZE) {
2643 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
2644
2645 switch (type) {
2646 case L2CAP_CONF_RFC:
2647 if (olen == sizeof(rfc))
2648 memcpy(&rfc, (void *)val, olen);
2649 goto done;
2650 }
2651 }
2652
2653done:
2654 switch (rfc.mode) {
2655 case L2CAP_MODE_ERTM:
2656 pi->remote_tx_win = rfc.txwin_size;
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03002657 pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
2658 pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002659 pi->mps = le16_to_cpu(rfc.max_pdu_size);
2660 break;
2661 case L2CAP_MODE_STREAMING:
2662 pi->mps = le16_to_cpu(rfc.max_pdu_size);
2663 }
2664}
2665
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002666static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2667{
2668 struct l2cap_cmd_rej *rej = (struct l2cap_cmd_rej *) data;
2669
2670 if (rej->reason != 0x0000)
2671 return 0;
2672
2673 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
2674 cmd->ident == conn->info_ident) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002675 del_timer(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01002676
2677 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002678 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01002679
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002680 l2cap_conn_start(conn);
2681 }
2682
2683 return 0;
2684}
2685
Linus Torvalds1da177e2005-04-16 15:20:36 -07002686static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2687{
2688 struct l2cap_chan_list *list = &conn->chan_list;
2689 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
2690 struct l2cap_conn_rsp rsp;
2691 struct sock *sk, *parent;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002692 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002693
2694 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002695 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002696
2697 BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
2698
2699 /* Check if we have socket listening on psm */
2700 parent = l2cap_get_sock_by_psm(BT_LISTEN, psm, conn->src);
2701 if (!parent) {
2702 result = L2CAP_CR_BAD_PSM;
2703 goto sendresp;
2704 }
2705
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002706 /* Check if the ACL is secure enough (if not SDP) */
2707 if (psm != cpu_to_le16(0x0001) &&
2708 !hci_conn_check_link_mode(conn->hcon)) {
Marcel Holtmann2950f212009-02-12 14:02:50 +01002709 conn->disc_reason = 0x05;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002710 result = L2CAP_CR_SEC_BLOCK;
2711 goto response;
2712 }
2713
Linus Torvalds1da177e2005-04-16 15:20:36 -07002714 result = L2CAP_CR_NO_MEM;
2715
2716 /* Check for backlog size */
2717 if (sk_acceptq_is_full(parent)) {
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09002718 BT_DBG("backlog full %d", parent->sk_ack_backlog);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002719 goto response;
2720 }
2721
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09002722 sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002723 if (!sk)
2724 goto response;
2725
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002726 write_lock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002727
2728 /* Check if we already have channel with that dcid */
2729 if (__l2cap_get_chan_by_dcid(list, scid)) {
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002730 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002731 sock_set_flag(sk, SOCK_ZAPPED);
2732 l2cap_sock_kill(sk);
2733 goto response;
2734 }
2735
2736 hci_conn_hold(conn->hcon);
2737
2738 l2cap_sock_init(sk, parent);
2739 bacpy(&bt_sk(sk)->src, conn->src);
2740 bacpy(&bt_sk(sk)->dst, conn->dst);
2741 l2cap_pi(sk)->psm = psm;
2742 l2cap_pi(sk)->dcid = scid;
2743
2744 __l2cap_chan_add(conn, sk, parent);
2745 dcid = l2cap_pi(sk)->scid;
2746
2747 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
2748
Linus Torvalds1da177e2005-04-16 15:20:36 -07002749 l2cap_pi(sk)->ident = cmd->ident;
2750
Marcel Holtmann984947d2009-02-06 23:35:19 +01002751 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002752 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002753 if (bt_sk(sk)->defer_setup) {
2754 sk->sk_state = BT_CONNECT2;
2755 result = L2CAP_CR_PEND;
2756 status = L2CAP_CS_AUTHOR_PEND;
2757 parent->sk_data_ready(parent, 0);
2758 } else {
2759 sk->sk_state = BT_CONFIG;
2760 result = L2CAP_CR_SUCCESS;
2761 status = L2CAP_CS_NO_INFO;
2762 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002763 } else {
2764 sk->sk_state = BT_CONNECT2;
2765 result = L2CAP_CR_PEND;
2766 status = L2CAP_CS_AUTHEN_PEND;
2767 }
2768 } else {
2769 sk->sk_state = BT_CONNECT2;
2770 result = L2CAP_CR_PEND;
2771 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002772 }
2773
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002774 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002775
2776response:
2777 bh_unlock_sock(parent);
2778
2779sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002780 rsp.scid = cpu_to_le16(scid);
2781 rsp.dcid = cpu_to_le16(dcid);
2782 rsp.result = cpu_to_le16(result);
2783 rsp.status = cpu_to_le16(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002784 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002785
2786 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
2787 struct l2cap_info_req info;
2788 info.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
2789
2790 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
2791 conn->info_ident = l2cap_get_ident(conn);
2792
2793 mod_timer(&conn->info_timer, jiffies +
2794 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
2795
2796 l2cap_send_cmd(conn, conn->info_ident,
2797 L2CAP_INFO_REQ, sizeof(info), &info);
2798 }
2799
Linus Torvalds1da177e2005-04-16 15:20:36 -07002800 return 0;
2801}
2802
2803static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2804{
2805 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
2806 u16 scid, dcid, result, status;
2807 struct sock *sk;
2808 u8 req[128];
2809
2810 scid = __le16_to_cpu(rsp->scid);
2811 dcid = __le16_to_cpu(rsp->dcid);
2812 result = __le16_to_cpu(rsp->result);
2813 status = __le16_to_cpu(rsp->status);
2814
2815 BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
2816
2817 if (scid) {
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002818 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2819 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002820 return 0;
2821 } else {
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002822 sk = l2cap_get_chan_by_ident(&conn->chan_list, cmd->ident);
2823 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002824 return 0;
2825 }
2826
2827 switch (result) {
2828 case L2CAP_CR_SUCCESS:
2829 sk->sk_state = BT_CONFIG;
2830 l2cap_pi(sk)->ident = 0;
2831 l2cap_pi(sk)->dcid = dcid;
2832 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
2833
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002834 l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_CONNECT_PEND;
2835
Linus Torvalds1da177e2005-04-16 15:20:36 -07002836 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
2837 l2cap_build_conf_req(sk, req), req);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002838 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002839 break;
2840
2841 case L2CAP_CR_PEND:
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002842 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002843 break;
2844
2845 default:
2846 l2cap_chan_del(sk, ECONNREFUSED);
2847 break;
2848 }
2849
2850 bh_unlock_sock(sk);
2851 return 0;
2852}
2853
Al Viro88219a02007-07-29 00:17:25 -07002854static 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 -07002855{
2856 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
2857 u16 dcid, flags;
2858 u8 rsp[64];
2859 struct sock *sk;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002860 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002861
2862 dcid = __le16_to_cpu(req->dcid);
2863 flags = __le16_to_cpu(req->flags);
2864
2865 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
2866
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002867 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
2868 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002869 return -ENOENT;
2870
Marcel Holtmann354f60a2006-11-18 22:15:20 +01002871 if (sk->sk_state == BT_DISCONN)
2872 goto unlock;
2873
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002874 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07002875 len = cmd_len - sizeof(*req);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002876 if (l2cap_pi(sk)->conf_len + len > sizeof(l2cap_pi(sk)->conf_req)) {
2877 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
2878 l2cap_build_conf_rsp(sk, rsp,
2879 L2CAP_CONF_REJECT, flags), rsp);
2880 goto unlock;
2881 }
2882
2883 /* Store config. */
2884 memcpy(l2cap_pi(sk)->conf_req + l2cap_pi(sk)->conf_len, req->data, len);
2885 l2cap_pi(sk)->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002886
2887 if (flags & 0x0001) {
2888 /* Incomplete config. Send empty response. */
2889 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002890 l2cap_build_conf_rsp(sk, rsp,
2891 L2CAP_CONF_SUCCESS, 0x0001), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002892 goto unlock;
2893 }
2894
2895 /* Complete config. */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002896 len = l2cap_parse_conf_req(sk, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002897 if (len < 0) {
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002898 l2cap_send_disconn_req(conn, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002899 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002900 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002901
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002902 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002903 l2cap_pi(sk)->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002904
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002905 /* Reset config buffer. */
2906 l2cap_pi(sk)->conf_len = 0;
2907
Marcel Holtmann876d9482007-10-20 13:35:42 +02002908 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE))
2909 goto unlock;
2910
Linus Torvalds1da177e2005-04-16 15:20:36 -07002911 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) {
Joe Perchesf64f9e72009-11-29 16:55:45 -08002912 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) ||
2913 l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002914 l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
2915
Linus Torvalds1da177e2005-04-16 15:20:36 -07002916 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002917
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002918 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002919 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002920 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002921 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
2922 l2cap_ertm_init(sk);
2923
Linus Torvalds1da177e2005-04-16 15:20:36 -07002924 l2cap_chan_ready(sk);
Marcel Holtmann876d9482007-10-20 13:35:42 +02002925 goto unlock;
2926 }
2927
2928 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002929 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002930 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002931 l2cap_build_conf_req(sk, buf), buf);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002932 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002933 }
2934
2935unlock:
2936 bh_unlock_sock(sk);
2937 return 0;
2938}
2939
2940static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2941{
2942 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
2943 u16 scid, flags, result;
2944 struct sock *sk;
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002945 int len = cmd->len - sizeof(*rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002946
2947 scid = __le16_to_cpu(rsp->scid);
2948 flags = __le16_to_cpu(rsp->flags);
2949 result = __le16_to_cpu(rsp->result);
2950
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002951 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x",
2952 scid, flags, result);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002953
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002954 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2955 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002956 return 0;
2957
2958 switch (result) {
2959 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03002960 l2cap_conf_rfc_get(sk, rsp->data, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002961 break;
2962
2963 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002964 if (l2cap_pi(sk)->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002965 char req[64];
2966
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02002967 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
2968 l2cap_send_disconn_req(conn, sk);
2969 goto done;
2970 }
2971
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002972 /* throw out any old stored conf requests */
2973 result = L2CAP_CONF_SUCCESS;
2974 len = l2cap_parse_conf_rsp(sk, rsp->data,
2975 len, req, &result);
2976 if (len < 0) {
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002977 l2cap_send_disconn_req(conn, sk);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002978 goto done;
2979 }
2980
2981 l2cap_send_cmd(conn, l2cap_get_ident(conn),
2982 L2CAP_CONF_REQ, len, req);
2983 l2cap_pi(sk)->num_conf_req++;
2984 if (result != L2CAP_CONF_SUCCESS)
2985 goto done;
2986 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002987 }
2988
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09002989 default:
Linus Torvalds1da177e2005-04-16 15:20:36 -07002990 sk->sk_state = BT_DISCONN;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02002991 sk->sk_err = ECONNRESET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002992 l2cap_sock_set_timer(sk, HZ * 5);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002993 l2cap_send_disconn_req(conn, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002994 goto done;
2995 }
2996
2997 if (flags & 0x01)
2998 goto done;
2999
Linus Torvalds1da177e2005-04-16 15:20:36 -07003000 l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE;
3001
3002 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) {
Joe Perchesf64f9e72009-11-29 16:55:45 -08003003 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) ||
3004 l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003005 l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
3006
Linus Torvalds1da177e2005-04-16 15:20:36 -07003007 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003008 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003009 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003010 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003011 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
3012 l2cap_ertm_init(sk);
3013
Linus Torvalds1da177e2005-04-16 15:20:36 -07003014 l2cap_chan_ready(sk);
3015 }
3016
3017done:
3018 bh_unlock_sock(sk);
3019 return 0;
3020}
3021
3022static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3023{
3024 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
3025 struct l2cap_disconn_rsp rsp;
3026 u16 dcid, scid;
3027 struct sock *sk;
3028
3029 scid = __le16_to_cpu(req->scid);
3030 dcid = __le16_to_cpu(req->dcid);
3031
3032 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
3033
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03003034 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
3035 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003036 return 0;
3037
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003038 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
3039 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003040 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
3041
3042 sk->sk_shutdown = SHUTDOWN_MASK;
3043
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003044 skb_queue_purge(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003045
3046 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
3047 skb_queue_purge(SREJ_QUEUE(sk));
3048 del_timer(&l2cap_pi(sk)->retrans_timer);
3049 del_timer(&l2cap_pi(sk)->monitor_timer);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003050 del_timer(&l2cap_pi(sk)->ack_timer);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003051 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003052
Linus Torvalds1da177e2005-04-16 15:20:36 -07003053 l2cap_chan_del(sk, ECONNRESET);
3054 bh_unlock_sock(sk);
3055
3056 l2cap_sock_kill(sk);
3057 return 0;
3058}
3059
3060static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3061{
3062 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
3063 u16 dcid, scid;
3064 struct sock *sk;
3065
3066 scid = __le16_to_cpu(rsp->scid);
3067 dcid = __le16_to_cpu(rsp->dcid);
3068
3069 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
3070
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03003071 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
3072 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003073 return 0;
3074
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003075 skb_queue_purge(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003076
3077 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
3078 skb_queue_purge(SREJ_QUEUE(sk));
3079 del_timer(&l2cap_pi(sk)->retrans_timer);
3080 del_timer(&l2cap_pi(sk)->monitor_timer);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003081 del_timer(&l2cap_pi(sk)->ack_timer);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003082 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003083
Linus Torvalds1da177e2005-04-16 15:20:36 -07003084 l2cap_chan_del(sk, 0);
3085 bh_unlock_sock(sk);
3086
3087 l2cap_sock_kill(sk);
3088 return 0;
3089}
3090
3091static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3092{
3093 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003094 u16 type;
3095
3096 type = __le16_to_cpu(req->type);
3097
3098 BT_DBG("type 0x%4.4x", type);
3099
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003100 if (type == L2CAP_IT_FEAT_MASK) {
3101 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003102 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003103 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
3104 rsp->type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
3105 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003106 if (enable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003107 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
3108 | L2CAP_FEAT_FCS;
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03003109 put_unaligned_le32(feat_mask, rsp->data);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003110 l2cap_send_cmd(conn, cmd->ident,
3111 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003112 } else if (type == L2CAP_IT_FIXED_CHAN) {
3113 u8 buf[12];
3114 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
3115 rsp->type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3116 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
3117 memcpy(buf + 4, l2cap_fixed_chan, 8);
3118 l2cap_send_cmd(conn, cmd->ident,
3119 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003120 } else {
3121 struct l2cap_info_rsp rsp;
3122 rsp.type = cpu_to_le16(type);
3123 rsp.result = cpu_to_le16(L2CAP_IR_NOTSUPP);
3124 l2cap_send_cmd(conn, cmd->ident,
3125 L2CAP_INFO_RSP, sizeof(rsp), &rsp);
3126 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003127
3128 return 0;
3129}
3130
3131static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3132{
3133 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
3134 u16 type, result;
3135
3136 type = __le16_to_cpu(rsp->type);
3137 result = __le16_to_cpu(rsp->result);
3138
3139 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
3140
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003141 del_timer(&conn->info_timer);
3142
Marcel Holtmann984947d2009-02-06 23:35:19 +01003143 if (type == L2CAP_IT_FEAT_MASK) {
Harvey Harrison83985312008-05-02 16:25:46 -07003144 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003145
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003146 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003147 struct l2cap_info_req req;
3148 req.type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3149
3150 conn->info_ident = l2cap_get_ident(conn);
3151
3152 l2cap_send_cmd(conn, conn->info_ident,
3153 L2CAP_INFO_REQ, sizeof(req), &req);
3154 } else {
3155 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
3156 conn->info_ident = 0;
3157
3158 l2cap_conn_start(conn);
3159 }
3160 } else if (type == L2CAP_IT_FIXED_CHAN) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01003161 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003162 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003163
3164 l2cap_conn_start(conn);
3165 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003166
Linus Torvalds1da177e2005-04-16 15:20:36 -07003167 return 0;
3168}
3169
3170static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
3171{
3172 u8 *data = skb->data;
3173 int len = skb->len;
3174 struct l2cap_cmd_hdr cmd;
3175 int err = 0;
3176
3177 l2cap_raw_recv(conn, skb);
3178
3179 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07003180 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003181 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
3182 data += L2CAP_CMD_HDR_SIZE;
3183 len -= L2CAP_CMD_HDR_SIZE;
3184
Al Viro88219a02007-07-29 00:17:25 -07003185 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003186
Al Viro88219a02007-07-29 00:17:25 -07003187 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 -07003188
Al Viro88219a02007-07-29 00:17:25 -07003189 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003190 BT_DBG("corrupted command");
3191 break;
3192 }
3193
3194 switch (cmd.code) {
3195 case L2CAP_COMMAND_REJ:
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003196 l2cap_command_rej(conn, &cmd, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003197 break;
3198
3199 case L2CAP_CONN_REQ:
3200 err = l2cap_connect_req(conn, &cmd, data);
3201 break;
3202
3203 case L2CAP_CONN_RSP:
3204 err = l2cap_connect_rsp(conn, &cmd, data);
3205 break;
3206
3207 case L2CAP_CONF_REQ:
Al Viro88219a02007-07-29 00:17:25 -07003208 err = l2cap_config_req(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003209 break;
3210
3211 case L2CAP_CONF_RSP:
3212 err = l2cap_config_rsp(conn, &cmd, data);
3213 break;
3214
3215 case L2CAP_DISCONN_REQ:
3216 err = l2cap_disconnect_req(conn, &cmd, data);
3217 break;
3218
3219 case L2CAP_DISCONN_RSP:
3220 err = l2cap_disconnect_rsp(conn, &cmd, data);
3221 break;
3222
3223 case L2CAP_ECHO_REQ:
Al Viro88219a02007-07-29 00:17:25 -07003224 l2cap_send_cmd(conn, cmd.ident, L2CAP_ECHO_RSP, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003225 break;
3226
3227 case L2CAP_ECHO_RSP:
3228 break;
3229
3230 case L2CAP_INFO_REQ:
3231 err = l2cap_information_req(conn, &cmd, data);
3232 break;
3233
3234 case L2CAP_INFO_RSP:
3235 err = l2cap_information_rsp(conn, &cmd, data);
3236 break;
3237
3238 default:
3239 BT_ERR("Unknown signaling command 0x%2.2x", cmd.code);
3240 err = -EINVAL;
3241 break;
3242 }
3243
3244 if (err) {
3245 struct l2cap_cmd_rej rej;
3246 BT_DBG("error %d", err);
3247
3248 /* FIXME: Map err to a valid reason */
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003249 rej.reason = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003250 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
3251 }
3252
Al Viro88219a02007-07-29 00:17:25 -07003253 data += cmd_len;
3254 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003255 }
3256
3257 kfree_skb(skb);
3258}
3259
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003260static int l2cap_check_fcs(struct l2cap_pinfo *pi, struct sk_buff *skb)
3261{
3262 u16 our_fcs, rcv_fcs;
3263 int hdr_size = L2CAP_HDR_SIZE + 2;
3264
3265 if (pi->fcs == L2CAP_FCS_CRC16) {
3266 skb_trim(skb, skb->len - 2);
3267 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
3268 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
3269
3270 if (our_fcs != rcv_fcs)
3271 return -EINVAL;
3272 }
3273 return 0;
3274}
3275
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003276static inline void l2cap_send_i_or_rr_or_rnr(struct sock *sk)
3277{
3278 struct l2cap_pinfo *pi = l2cap_pi(sk);
3279 u16 control = 0;
3280
3281 pi->frames_sent = 0;
3282 pi->conn_state |= L2CAP_CONN_SEND_FBIT;
3283
3284 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3285
3286 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
3287 control |= L2CAP_SUPER_RCV_NOT_READY | L2CAP_CTRL_FINAL;
3288 l2cap_send_sframe(pi, control);
3289 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
3290 }
3291
3292 if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY && pi->unacked_frames > 0)
3293 __mod_retrans_timer();
3294
3295 l2cap_ertm_send(sk);
3296
3297 if (!(pi->conn_state & L2CAP_CONN_LOCAL_BUSY) &&
3298 pi->frames_sent == 0) {
3299 control |= L2CAP_SUPER_RCV_READY;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03003300 l2cap_send_sframe(pi, control);
3301 }
3302}
3303
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003304static void l2cap_add_to_srej_queue(struct sock *sk, struct sk_buff *skb, u8 tx_seq, u8 sar)
3305{
3306 struct sk_buff *next_skb;
3307
3308 bt_cb(skb)->tx_seq = tx_seq;
3309 bt_cb(skb)->sar = sar;
3310
3311 next_skb = skb_peek(SREJ_QUEUE(sk));
3312 if (!next_skb) {
3313 __skb_queue_tail(SREJ_QUEUE(sk), skb);
3314 return;
3315 }
3316
3317 do {
3318 if (bt_cb(next_skb)->tx_seq > tx_seq) {
3319 __skb_queue_before(SREJ_QUEUE(sk), next_skb, skb);
3320 return;
3321 }
3322
3323 if (skb_queue_is_last(SREJ_QUEUE(sk), next_skb))
3324 break;
3325
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003326 } while ((next_skb = skb_queue_next(SREJ_QUEUE(sk), next_skb)));
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003327
3328 __skb_queue_tail(SREJ_QUEUE(sk), skb);
3329}
3330
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003331static int l2cap_sar_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
3332{
3333 struct l2cap_pinfo *pi = l2cap_pi(sk);
3334 struct sk_buff *_skb;
3335 int err = -EINVAL;
3336
3337 switch (control & L2CAP_CTRL_SAR) {
3338 case L2CAP_SDU_UNSEGMENTED:
3339 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3340 kfree_skb(pi->sdu);
3341 break;
3342 }
3343
3344 err = sock_queue_rcv_skb(sk, skb);
3345 if (!err)
3346 return 0;
3347
3348 break;
3349
3350 case L2CAP_SDU_START:
3351 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3352 kfree_skb(pi->sdu);
3353 break;
3354 }
3355
3356 pi->sdu_len = get_unaligned_le16(skb->data);
3357 skb_pull(skb, 2);
3358
Gustavo F. Padovan052897c2010-05-01 16:15:40 -03003359 if (pi->sdu_len > pi->imtu) {
3360 err = -EMSGSIZE;
3361 break;
3362 }
3363
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003364 pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
3365 if (!pi->sdu) {
3366 err = -ENOMEM;
3367 break;
3368 }
3369
3370 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3371
3372 pi->conn_state |= L2CAP_CONN_SAR_SDU;
3373 pi->partial_sdu_len = skb->len;
3374 err = 0;
3375 break;
3376
3377 case L2CAP_SDU_CONTINUE:
3378 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3379 break;
3380
3381 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3382
3383 pi->partial_sdu_len += skb->len;
3384 if (pi->partial_sdu_len > pi->sdu_len)
3385 kfree_skb(pi->sdu);
3386 else
3387 err = 0;
3388
3389 break;
3390
3391 case L2CAP_SDU_END:
3392 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3393 break;
3394
3395 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3396
3397 pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
3398 pi->partial_sdu_len += skb->len;
3399
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003400 if (pi->partial_sdu_len > pi->imtu)
3401 goto drop;
3402
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003403 if (pi->partial_sdu_len == pi->sdu_len) {
3404 _skb = skb_clone(pi->sdu, GFP_ATOMIC);
3405 err = sock_queue_rcv_skb(sk, _skb);
3406 if (err < 0)
3407 kfree_skb(_skb);
3408 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003409 err = 0;
3410
Gustavo F. Padovan36f2fd52010-05-01 16:15:37 -03003411drop:
3412 kfree_skb(pi->sdu);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003413 break;
3414 }
3415
3416 kfree_skb(skb);
3417 return err;
3418}
3419
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003420static void l2cap_check_srej_gap(struct sock *sk, u8 tx_seq)
3421{
3422 struct sk_buff *skb;
Gustavo F. Padovanafefdbc2010-05-01 16:15:43 -03003423 u16 control;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003424
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003425 while ((skb = skb_peek(SREJ_QUEUE(sk)))) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003426 if (bt_cb(skb)->tx_seq != tx_seq)
3427 break;
3428
3429 skb = skb_dequeue(SREJ_QUEUE(sk));
Gustavo F. Padovanafefdbc2010-05-01 16:15:43 -03003430 control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003431 l2cap_sar_reassembly_sdu(sk, skb, control);
3432 l2cap_pi(sk)->buffer_seq_srej =
3433 (l2cap_pi(sk)->buffer_seq_srej + 1) % 64;
3434 tx_seq++;
3435 }
3436}
3437
3438static void l2cap_resend_srejframe(struct sock *sk, u8 tx_seq)
3439{
3440 struct l2cap_pinfo *pi = l2cap_pi(sk);
3441 struct srej_list *l, *tmp;
3442 u16 control;
3443
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03003444 list_for_each_entry_safe(l, tmp, SREJ_LIST(sk), list) {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003445 if (l->tx_seq == tx_seq) {
3446 list_del(&l->list);
3447 kfree(l);
3448 return;
3449 }
3450 control = L2CAP_SUPER_SELECT_REJECT;
3451 control |= l->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3452 l2cap_send_sframe(pi, control);
3453 list_del(&l->list);
3454 list_add_tail(&l->list, SREJ_LIST(sk));
3455 }
3456}
3457
3458static void l2cap_send_srejframe(struct sock *sk, u8 tx_seq)
3459{
3460 struct l2cap_pinfo *pi = l2cap_pi(sk);
3461 struct srej_list *new;
3462 u16 control;
3463
3464 while (tx_seq != pi->expected_tx_seq) {
3465 control = L2CAP_SUPER_SELECT_REJECT;
3466 control |= pi->expected_tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3467 l2cap_send_sframe(pi, control);
3468
3469 new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC);
3470 new->tx_seq = pi->expected_tx_seq++;
3471 list_add_tail(&new->list, SREJ_LIST(sk));
3472 }
3473 pi->expected_tx_seq++;
3474}
3475
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003476static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
3477{
3478 struct l2cap_pinfo *pi = l2cap_pi(sk);
3479 u8 tx_seq = __get_txseq(rx_control);
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003480 u8 req_seq = __get_reqseq(rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003481 u8 sar = rx_control >> L2CAP_CTRL_SAR_SHIFT;
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03003482 int num_to_ack = (pi->tx_win/6) + 1;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003483 int err = 0;
3484
3485 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
3486
Gustavo F. Padovan9b16dc62010-05-05 20:05:57 -03003487 if (L2CAP_CTRL_FINAL & rx_control &&
3488 l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) {
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003489 del_timer(&pi->monitor_timer);
3490 if (pi->unacked_frames > 0)
3491 __mod_retrans_timer();
3492 pi->conn_state &= ~L2CAP_CONN_WAIT_F;
3493 }
3494
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003495 pi->expected_ack_seq = req_seq;
3496 l2cap_drop_acked_frames(sk);
3497
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003498 if (tx_seq == pi->expected_tx_seq)
3499 goto expected;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003500
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003501 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3502 struct srej_list *first;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003503
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003504 first = list_first_entry(SREJ_LIST(sk),
3505 struct srej_list, list);
3506 if (tx_seq == first->tx_seq) {
3507 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3508 l2cap_check_srej_gap(sk, tx_seq);
3509
3510 list_del(&first->list);
3511 kfree(first);
3512
3513 if (list_empty(SREJ_LIST(sk))) {
3514 pi->buffer_seq = pi->buffer_seq_srej;
3515 pi->conn_state &= ~L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan855666c2010-05-01 16:15:40 -03003516 l2cap_send_ack(pi);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003517 }
3518 } else {
3519 struct srej_list *l;
3520 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3521
3522 list_for_each_entry(l, SREJ_LIST(sk), list) {
3523 if (l->tx_seq == tx_seq) {
3524 l2cap_resend_srejframe(sk, tx_seq);
3525 return 0;
3526 }
3527 }
3528 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003529 }
3530 } else {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003531 pi->conn_state |= L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003532
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003533 INIT_LIST_HEAD(SREJ_LIST(sk));
3534 pi->buffer_seq_srej = pi->buffer_seq;
3535
3536 __skb_queue_head_init(SREJ_QUEUE(sk));
3537 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3538
Gustavo F. Padovanef54fd92009-08-20 22:26:04 -03003539 pi->conn_state |= L2CAP_CONN_SEND_PBIT;
3540
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003541 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003542 }
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003543 return 0;
3544
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003545expected:
3546 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
3547
3548 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
Gustavo F. Padovan3b1a9f32010-05-01 16:15:42 -03003549 bt_cb(skb)->tx_seq = tx_seq;
3550 bt_cb(skb)->sar = sar;
3551 __skb_queue_tail(SREJ_QUEUE(sk), skb);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003552 return 0;
3553 }
3554
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03003555 if (rx_control & L2CAP_CTRL_FINAL) {
3556 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3557 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
3558 else {
Gustavo F. Padovanf6e6b162010-05-01 16:15:41 -03003559 if (!skb_queue_empty(TX_QUEUE(sk)))
3560 sk->sk_send_head = TX_QUEUE(sk)->next;
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03003561 pi->next_tx_seq = pi->expected_ack_seq;
3562 l2cap_ertm_send(sk);
3563 }
3564 }
3565
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003566 pi->buffer_seq = (pi->buffer_seq + 1) % 64;
3567
3568 err = l2cap_sar_reassembly_sdu(sk, skb, rx_control);
3569 if (err < 0)
3570 return err;
3571
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003572 __mod_ack_timer();
3573
Gustavo F. Padovan803020c2010-05-01 16:15:41 -03003574 pi->num_acked = (pi->num_acked + 1) % num_to_ack;
3575 if (pi->num_acked == num_to_ack - 1)
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03003576 l2cap_send_ack(pi);
3577
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003578 return 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003579}
3580
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003581static inline void l2cap_data_channel_rrframe(struct sock *sk, u16 rx_control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003582{
3583 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan6e3a5982010-05-01 16:15:38 -03003584
3585 pi->expected_ack_seq = __get_reqseq(rx_control);
3586 l2cap_drop_acked_frames(sk);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003587
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003588 if (rx_control & L2CAP_CTRL_POLL) {
Gustavo F. Padovan05fbd892010-05-01 16:15:39 -03003589 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3590 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
3591 (pi->unacked_frames > 0))
3592 __mod_retrans_timer();
3593
3594 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3595 l2cap_send_srejtail(sk);
3596 } else {
3597 l2cap_send_i_or_rr_or_rnr(sk);
3598 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3599 }
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003600
3601 } else if (rx_control & L2CAP_CTRL_FINAL) {
3602 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003603
3604 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3605 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
3606 else {
Gustavo F. Padovanf6e6b162010-05-01 16:15:41 -03003607 if (!skb_queue_empty(TX_QUEUE(sk)))
3608 sk->sk_send_head = TX_QUEUE(sk)->next;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003609 pi->next_tx_seq = pi->expected_ack_seq;
3610 l2cap_ertm_send(sk);
3611 }
3612
3613 } else {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003614 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
3615 (pi->unacked_frames > 0))
3616 __mod_retrans_timer();
3617
3618 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3619 if (pi->conn_state & L2CAP_CONN_SREJ_SENT)
3620 l2cap_send_ack(pi);
3621 else
3622 l2cap_ertm_send(sk);
3623 }
3624}
3625
3626static inline void l2cap_data_channel_rejframe(struct sock *sk, u16 rx_control)
3627{
3628 struct l2cap_pinfo *pi = l2cap_pi(sk);
3629 u8 tx_seq = __get_reqseq(rx_control);
3630
3631 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3632
Gustavo F. Padovan8abb52e2010-05-01 16:15:38 -03003633 pi->expected_ack_seq = tx_seq;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003634 l2cap_drop_acked_frames(sk);
3635
3636 if (rx_control & L2CAP_CTRL_FINAL) {
3637 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3638 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
3639 else {
Gustavo F. Padovanf6e6b162010-05-01 16:15:41 -03003640 if (!skb_queue_empty(TX_QUEUE(sk)))
3641 sk->sk_send_head = TX_QUEUE(sk)->next;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003642 pi->next_tx_seq = pi->expected_ack_seq;
3643 l2cap_ertm_send(sk);
3644 }
3645 } else {
Gustavo F. Padovanf6e6b162010-05-01 16:15:41 -03003646 if (!skb_queue_empty(TX_QUEUE(sk)))
3647 sk->sk_send_head = TX_QUEUE(sk)->next;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003648 pi->next_tx_seq = pi->expected_ack_seq;
3649 l2cap_ertm_send(sk);
3650
Gustavo F. Padovan0301ef02010-05-05 20:56:43 -03003651 if (pi->conn_state & L2CAP_CONN_WAIT_F)
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003652 pi->conn_state |= L2CAP_CONN_REJ_ACT;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003653 }
3654}
3655static inline void l2cap_data_channel_srejframe(struct sock *sk, u16 rx_control)
3656{
3657 struct l2cap_pinfo *pi = l2cap_pi(sk);
3658 u8 tx_seq = __get_reqseq(rx_control);
3659
3660 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3661
3662 if (rx_control & L2CAP_CTRL_POLL) {
3663 pi->expected_ack_seq = tx_seq;
3664 l2cap_drop_acked_frames(sk);
3665 l2cap_retransmit_frame(sk, tx_seq);
3666 l2cap_ertm_send(sk);
3667 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
3668 pi->srej_save_reqseq = tx_seq;
3669 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
3670 }
3671 } else if (rx_control & L2CAP_CTRL_FINAL) {
3672 if ((pi->conn_state & L2CAP_CONN_SREJ_ACT) &&
3673 pi->srej_save_reqseq == tx_seq)
3674 pi->conn_state &= ~L2CAP_CONN_SREJ_ACT;
3675 else
3676 l2cap_retransmit_frame(sk, tx_seq);
3677 } else {
3678 l2cap_retransmit_frame(sk, tx_seq);
3679 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
3680 pi->srej_save_reqseq = tx_seq;
3681 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
3682 }
3683 }
3684}
3685
3686static inline void l2cap_data_channel_rnrframe(struct sock *sk, u16 rx_control)
3687{
3688 struct l2cap_pinfo *pi = l2cap_pi(sk);
3689 u8 tx_seq = __get_reqseq(rx_control);
3690
3691 pi->conn_state |= L2CAP_CONN_REMOTE_BUSY;
3692 pi->expected_ack_seq = tx_seq;
3693 l2cap_drop_acked_frames(sk);
3694
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03003695 if (!(pi->conn_state & L2CAP_CONN_SREJ_SENT)) {
3696 del_timer(&pi->retrans_timer);
Gustavo F. Padovana2e12a22010-05-05 19:58:27 -03003697 if (rx_control & L2CAP_CTRL_POLL)
3698 l2cap_send_rr_or_rnr(pi, L2CAP_CTRL_FINAL);
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03003699 return;
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003700 }
Gustavo F. Padovan99b0d4b2010-05-01 16:15:38 -03003701
3702 if (rx_control & L2CAP_CTRL_POLL)
3703 l2cap_send_srejtail(sk);
3704 else
3705 l2cap_send_sframe(pi, L2CAP_SUPER_RCV_READY);
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003706}
3707
3708static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
3709{
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003710 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
3711
Gustavo F. Padovan9b16dc62010-05-05 20:05:57 -03003712 if (L2CAP_CTRL_FINAL & rx_control &&
3713 l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) {
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003714 del_timer(&l2cap_pi(sk)->monitor_timer);
3715 if (l2cap_pi(sk)->unacked_frames > 0)
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003716 __mod_retrans_timer();
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003717 l2cap_pi(sk)->conn_state &= ~L2CAP_CONN_WAIT_F;
Gustavo F. Padovan1d8f5d12010-05-01 16:15:37 -03003718 }
3719
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003720 switch (rx_control & L2CAP_CTRL_SUPERVISE) {
3721 case L2CAP_SUPER_RCV_READY:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003722 l2cap_data_channel_rrframe(sk, rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003723 break;
3724
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003725 case L2CAP_SUPER_REJECT:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003726 l2cap_data_channel_rejframe(sk, rx_control);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003727 break;
3728
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003729 case L2CAP_SUPER_SELECT_REJECT:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003730 l2cap_data_channel_srejframe(sk, rx_control);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003731 break;
3732
3733 case L2CAP_SUPER_RCV_NOT_READY:
Gustavo F. Padovane0727452010-05-01 16:15:38 -03003734 l2cap_data_channel_rnrframe(sk, rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003735 break;
3736 }
3737
Gustavo F. Padovanfaaebd12010-05-01 16:15:35 -03003738 kfree_skb(skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003739 return 0;
3740}
3741
Linus Torvalds1da177e2005-04-16 15:20:36 -07003742static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk_buff *skb)
3743{
3744 struct sock *sk;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003745 struct l2cap_pinfo *pi;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003746 u16 control, len;
João Paulo Rechi Vita01760bd2010-05-01 16:15:43 -03003747 u8 tx_seq, req_seq, next_tx_seq_offset, req_seq_offset;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003748
3749 sk = l2cap_get_chan_by_scid(&conn->chan_list, cid);
3750 if (!sk) {
3751 BT_DBG("unknown cid 0x%4.4x", cid);
3752 goto drop;
3753 }
3754
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003755 pi = l2cap_pi(sk);
3756
Linus Torvalds1da177e2005-04-16 15:20:36 -07003757 BT_DBG("sk %p, len %d", sk, skb->len);
3758
3759 if (sk->sk_state != BT_CONNECTED)
3760 goto drop;
3761
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003762 switch (pi->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003763 case L2CAP_MODE_BASIC:
3764 /* If socket recv buffers overflows we drop data here
3765 * which is *bad* because L2CAP has to be reliable.
3766 * But we don't have any other choice. L2CAP doesn't
3767 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003768
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003769 if (pi->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003770 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003771
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003772 if (!sock_queue_rcv_skb(sk, skb))
3773 goto done;
3774 break;
3775
3776 case L2CAP_MODE_ERTM:
3777 control = get_unaligned_le16(skb->data);
3778 skb_pull(skb, 2);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003779 len = skb->len;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003780
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003781 if (__is_sar_start(control))
3782 len -= 2;
3783
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003784 if (pi->fcs == L2CAP_FCS_CRC16)
3785 len -= 2;
3786
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003787 /*
3788 * We can just drop the corrupted I-frame here.
3789 * Receiver will miss it and start proper recovery
3790 * procedures and ask retransmission.
3791 */
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03003792 if (len > pi->mps)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003793 goto drop;
3794
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003795 if (l2cap_check_fcs(pi, skb))
3796 goto drop;
3797
João Paulo Rechi Vita01760bd2010-05-01 16:15:43 -03003798 req_seq = __get_reqseq(control);
3799 req_seq_offset = (req_seq - pi->expected_ack_seq) % 64;
3800 if (req_seq_offset < 0)
3801 req_seq_offset += 64;
3802
3803 next_tx_seq_offset =
3804 (pi->next_tx_seq - pi->expected_ack_seq) % 64;
3805 if (next_tx_seq_offset < 0)
3806 next_tx_seq_offset += 64;
3807
3808 /* check for invalid req-seq */
3809 if (req_seq_offset > next_tx_seq_offset) {
3810 l2cap_send_disconn_req(pi->conn, sk);
3811 goto drop;
3812 }
3813
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03003814 if (__is_iframe(control)) {
3815 if (len < 4)
3816 goto drop;
3817
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02003818 l2cap_data_channel_iframe(sk, control, skb);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03003819 } else {
3820 if (len != 0)
3821 goto drop;
3822
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02003823 l2cap_data_channel_sframe(sk, control, skb);
Gustavo F. Padovan277ffbe2010-05-01 16:15:37 -03003824 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003825
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02003826 goto done;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003827
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003828 case L2CAP_MODE_STREAMING:
3829 control = get_unaligned_le16(skb->data);
3830 skb_pull(skb, 2);
3831 len = skb->len;
3832
3833 if (__is_sar_start(control))
3834 len -= 2;
3835
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003836 if (pi->fcs == L2CAP_FCS_CRC16)
3837 len -= 2;
3838
Gustavo F. Padovan1c762152010-05-01 16:15:40 -03003839 if (len > pi->mps || len < 4 || __is_sframe(control))
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003840 goto drop;
3841
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003842 if (l2cap_check_fcs(pi, skb))
3843 goto drop;
3844
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003845 tx_seq = __get_txseq(control);
3846
3847 if (pi->expected_tx_seq == tx_seq)
3848 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
3849 else
Gustavo F. Padovan7dffe422010-05-01 16:15:36 -03003850 pi->expected_tx_seq = (tx_seq + 1) % 64;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003851
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02003852 l2cap_sar_reassembly_sdu(sk, skb, control);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003853
3854 goto done;
3855
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003856 default:
Gustavo F. Padovane8235c62010-05-01 16:15:36 -03003857 BT_DBG("sk %p: bad mode 0x%2.2x", sk, pi->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003858 break;
3859 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003860
3861drop:
3862 kfree_skb(skb);
3863
3864done:
Marcel Holtmann01394182006-07-03 10:02:46 +02003865 if (sk)
3866 bh_unlock_sock(sk);
3867
Linus Torvalds1da177e2005-04-16 15:20:36 -07003868 return 0;
3869}
3870
Al Viro8e036fc2007-07-29 00:16:36 -07003871static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003872{
3873 struct sock *sk;
3874
3875 sk = l2cap_get_sock_by_psm(0, psm, conn->src);
3876 if (!sk)
3877 goto drop;
3878
3879 BT_DBG("sk %p, len %d", sk, skb->len);
3880
3881 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_CONNECTED)
3882 goto drop;
3883
3884 if (l2cap_pi(sk)->imtu < skb->len)
3885 goto drop;
3886
3887 if (!sock_queue_rcv_skb(sk, skb))
3888 goto done;
3889
3890drop:
3891 kfree_skb(skb);
3892
3893done:
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03003894 if (sk)
3895 bh_unlock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003896 return 0;
3897}
3898
3899static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
3900{
3901 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07003902 u16 cid, len;
3903 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003904
3905 skb_pull(skb, L2CAP_HDR_SIZE);
3906 cid = __le16_to_cpu(lh->cid);
3907 len = __le16_to_cpu(lh->len);
3908
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003909 if (len != skb->len) {
3910 kfree_skb(skb);
3911 return;
3912 }
3913
Linus Torvalds1da177e2005-04-16 15:20:36 -07003914 BT_DBG("len %d, cid 0x%4.4x", len, cid);
3915
3916 switch (cid) {
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03003917 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07003918 l2cap_sig_channel(conn, skb);
3919 break;
3920
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03003921 case L2CAP_CID_CONN_LESS:
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03003922 psm = get_unaligned_le16(skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003923 skb_pull(skb, 2);
3924 l2cap_conless_channel(conn, psm, skb);
3925 break;
3926
3927 default:
3928 l2cap_data_channel(conn, cid, skb);
3929 break;
3930 }
3931}
3932
3933/* ---- L2CAP interface with lower layer (HCI) ---- */
3934
3935static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
3936{
3937 int exact = 0, lm1 = 0, lm2 = 0;
3938 register struct sock *sk;
3939 struct hlist_node *node;
3940
3941 if (type != ACL_LINK)
3942 return 0;
3943
3944 BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
3945
3946 /* Find listening sockets and check their link_mode */
3947 read_lock(&l2cap_sk_list.lock);
3948 sk_for_each(sk, node, &l2cap_sk_list.head) {
3949 if (sk->sk_state != BT_LISTEN)
3950 continue;
3951
3952 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01003953 lm1 |= HCI_LM_ACCEPT;
3954 if (l2cap_pi(sk)->role_switch)
3955 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003956 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01003957 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
3958 lm2 |= HCI_LM_ACCEPT;
3959 if (l2cap_pi(sk)->role_switch)
3960 lm2 |= HCI_LM_MASTER;
3961 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003962 }
3963 read_unlock(&l2cap_sk_list.lock);
3964
3965 return exact ? lm1 : lm2;
3966}
3967
3968static int l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
3969{
Marcel Holtmann01394182006-07-03 10:02:46 +02003970 struct l2cap_conn *conn;
3971
Linus Torvalds1da177e2005-04-16 15:20:36 -07003972 BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
3973
3974 if (hcon->type != ACL_LINK)
3975 return 0;
3976
3977 if (!status) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003978 conn = l2cap_conn_add(hcon, status);
3979 if (conn)
3980 l2cap_conn_ready(conn);
Marcel Holtmann01394182006-07-03 10:02:46 +02003981 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -07003982 l2cap_conn_del(hcon, bt_err(status));
3983
3984 return 0;
3985}
3986
Marcel Holtmann2950f212009-02-12 14:02:50 +01003987static int l2cap_disconn_ind(struct hci_conn *hcon)
3988{
3989 struct l2cap_conn *conn = hcon->l2cap_data;
3990
3991 BT_DBG("hcon %p", hcon);
3992
3993 if (hcon->type != ACL_LINK || !conn)
3994 return 0x13;
3995
3996 return conn->disc_reason;
3997}
3998
3999static int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004000{
4001 BT_DBG("hcon %p reason %d", hcon, reason);
4002
4003 if (hcon->type != ACL_LINK)
4004 return 0;
4005
4006 l2cap_conn_del(hcon, bt_err(reason));
Marcel Holtmann01394182006-07-03 10:02:46 +02004007
Linus Torvalds1da177e2005-04-16 15:20:36 -07004008 return 0;
4009}
4010
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004011static inline void l2cap_check_encryption(struct sock *sk, u8 encrypt)
4012{
Gustavo F. Padovanbd3c9e22010-05-01 16:15:42 -03004013 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM)
Marcel Holtmann255c7602009-02-04 21:07:19 +01004014 return;
4015
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004016 if (encrypt == 0x00) {
4017 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM) {
4018 l2cap_sock_clear_timer(sk);
4019 l2cap_sock_set_timer(sk, HZ * 5);
4020 } else if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
4021 __l2cap_sock_close(sk, ECONNREFUSED);
4022 } else {
4023 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM)
4024 l2cap_sock_clear_timer(sk);
4025 }
4026}
4027
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004028static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004029{
4030 struct l2cap_chan_list *l;
Marcel Holtmann40be4922008-07-14 20:13:50 +02004031 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004032 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004033
Marcel Holtmann01394182006-07-03 10:02:46 +02004034 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004035 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02004036
Linus Torvalds1da177e2005-04-16 15:20:36 -07004037 l = &conn->chan_list;
4038
4039 BT_DBG("conn %p", conn);
4040
4041 read_lock(&l->lock);
4042
4043 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
4044 bh_lock_sock(sk);
4045
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01004046 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND) {
4047 bh_unlock_sock(sk);
4048 continue;
4049 }
4050
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004051 if (!status && (sk->sk_state == BT_CONNECTED ||
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004052 sk->sk_state == BT_CONFIG)) {
Marcel Holtmannf62e4322009-01-15 21:58:44 +01004053 l2cap_check_encryption(sk, encrypt);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02004054 bh_unlock_sock(sk);
4055 continue;
4056 }
4057
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004058 if (sk->sk_state == BT_CONNECT) {
4059 if (!status) {
4060 struct l2cap_conn_req req;
4061 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
4062 req.psm = l2cap_pi(sk)->psm;
4063
4064 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
4065
4066 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
4067 L2CAP_CONN_REQ, sizeof(req), &req);
4068 } else {
4069 l2cap_sock_clear_timer(sk);
4070 l2cap_sock_set_timer(sk, HZ / 10);
4071 }
4072 } else if (sk->sk_state == BT_CONNECT2) {
4073 struct l2cap_conn_rsp rsp;
4074 __u16 result;
4075
4076 if (!status) {
4077 sk->sk_state = BT_CONFIG;
4078 result = L2CAP_CR_SUCCESS;
4079 } else {
4080 sk->sk_state = BT_DISCONN;
4081 l2cap_sock_set_timer(sk, HZ / 10);
4082 result = L2CAP_CR_SEC_BLOCK;
4083 }
4084
4085 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
4086 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
4087 rsp.result = cpu_to_le16(result);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02004088 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004089 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
4090 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004091 }
4092
Linus Torvalds1da177e2005-04-16 15:20:36 -07004093 bh_unlock_sock(sk);
4094 }
4095
4096 read_unlock(&l->lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02004097
Linus Torvalds1da177e2005-04-16 15:20:36 -07004098 return 0;
4099}
4100
4101static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
4102{
4103 struct l2cap_conn *conn = hcon->l2cap_data;
4104
4105 if (!conn && !(conn = l2cap_conn_add(hcon, 0)))
4106 goto drop;
4107
4108 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
4109
4110 if (flags & ACL_START) {
4111 struct l2cap_hdr *hdr;
4112 int len;
4113
4114 if (conn->rx_len) {
4115 BT_ERR("Unexpected start frame (len %d)", skb->len);
4116 kfree_skb(conn->rx_skb);
4117 conn->rx_skb = NULL;
4118 conn->rx_len = 0;
4119 l2cap_conn_unreliable(conn, ECOMM);
4120 }
4121
4122 if (skb->len < 2) {
4123 BT_ERR("Frame is too short (len %d)", skb->len);
4124 l2cap_conn_unreliable(conn, ECOMM);
4125 goto drop;
4126 }
4127
4128 hdr = (struct l2cap_hdr *) skb->data;
4129 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
4130
4131 if (len == skb->len) {
4132 /* Complete frame received */
4133 l2cap_recv_frame(conn, skb);
4134 return 0;
4135 }
4136
4137 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
4138
4139 if (skb->len > len) {
4140 BT_ERR("Frame is too long (len %d, expected len %d)",
4141 skb->len, len);
4142 l2cap_conn_unreliable(conn, ECOMM);
4143 goto drop;
4144 }
4145
4146 /* Allocate skb for the complete frame (with header) */
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03004147 conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC);
4148 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004149 goto drop;
4150
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03004151 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004152 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004153 conn->rx_len = len - skb->len;
4154 } else {
4155 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
4156
4157 if (!conn->rx_len) {
4158 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
4159 l2cap_conn_unreliable(conn, ECOMM);
4160 goto drop;
4161 }
4162
4163 if (skb->len > conn->rx_len) {
4164 BT_ERR("Fragment is too long (len %d, expected %d)",
4165 skb->len, conn->rx_len);
4166 kfree_skb(conn->rx_skb);
4167 conn->rx_skb = NULL;
4168 conn->rx_len = 0;
4169 l2cap_conn_unreliable(conn, ECOMM);
4170 goto drop;
4171 }
4172
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03004173 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004174 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004175 conn->rx_len -= skb->len;
4176
4177 if (!conn->rx_len) {
4178 /* Complete frame received */
4179 l2cap_recv_frame(conn, conn->rx_skb);
4180 conn->rx_skb = NULL;
4181 }
4182 }
4183
4184drop:
4185 kfree_skb(skb);
4186 return 0;
4187}
4188
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004189static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004190{
4191 struct sock *sk;
4192 struct hlist_node *node;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004193
4194 read_lock_bh(&l2cap_sk_list.lock);
4195
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004196 sk_for_each(sk, node, &l2cap_sk_list.head) {
4197 struct l2cap_pinfo *pi = l2cap_pi(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004198
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004199 seq_printf(f, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d\n",
4200 batostr(&bt_sk(sk)->src),
4201 batostr(&bt_sk(sk)->dst),
4202 sk->sk_state, __le16_to_cpu(pi->psm),
4203 pi->scid, pi->dcid,
4204 pi->imtu, pi->omtu, pi->sec_level);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004205 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004206
Linus Torvalds1da177e2005-04-16 15:20:36 -07004207 read_unlock_bh(&l2cap_sk_list.lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004208
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004209 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004210}
4211
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004212static int l2cap_debugfs_open(struct inode *inode, struct file *file)
4213{
4214 return single_open(file, l2cap_debugfs_show, inode->i_private);
4215}
4216
4217static const struct file_operations l2cap_debugfs_fops = {
4218 .open = l2cap_debugfs_open,
4219 .read = seq_read,
4220 .llseek = seq_lseek,
4221 .release = single_release,
4222};
4223
4224static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004225
Eric Dumazet90ddc4f2005-12-22 12:49:22 -08004226static const struct proto_ops l2cap_sock_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004227 .family = PF_BLUETOOTH,
4228 .owner = THIS_MODULE,
4229 .release = l2cap_sock_release,
4230 .bind = l2cap_sock_bind,
4231 .connect = l2cap_sock_connect,
4232 .listen = l2cap_sock_listen,
4233 .accept = l2cap_sock_accept,
4234 .getname = l2cap_sock_getname,
4235 .sendmsg = l2cap_sock_sendmsg,
Marcel Holtmannf66dc812009-01-15 21:57:00 +01004236 .recvmsg = l2cap_sock_recvmsg,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004237 .poll = bt_sock_poll,
Marcel Holtmann3241ad82008-07-14 20:13:50 +02004238 .ioctl = bt_sock_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004239 .mmap = sock_no_mmap,
4240 .socketpair = sock_no_socketpair,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004241 .shutdown = l2cap_sock_shutdown,
4242 .setsockopt = l2cap_sock_setsockopt,
4243 .getsockopt = l2cap_sock_getsockopt
4244};
4245
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +00004246static const struct net_proto_family l2cap_sock_family_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004247 .family = PF_BLUETOOTH,
4248 .owner = THIS_MODULE,
4249 .create = l2cap_sock_create,
4250};
4251
4252static struct hci_proto l2cap_hci_proto = {
4253 .name = "L2CAP",
4254 .id = HCI_PROTO_L2CAP,
4255 .connect_ind = l2cap_connect_ind,
4256 .connect_cfm = l2cap_connect_cfm,
4257 .disconn_ind = l2cap_disconn_ind,
Marcel Holtmann2950f212009-02-12 14:02:50 +01004258 .disconn_cfm = l2cap_disconn_cfm,
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004259 .security_cfm = l2cap_security_cfm,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004260 .recv_acldata = l2cap_recv_acldata
4261};
4262
4263static int __init l2cap_init(void)
4264{
4265 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004266
Linus Torvalds1da177e2005-04-16 15:20:36 -07004267 err = proto_register(&l2cap_proto, 0);
4268 if (err < 0)
4269 return err;
4270
4271 err = bt_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops);
4272 if (err < 0) {
4273 BT_ERR("L2CAP socket registration failed");
4274 goto error;
4275 }
4276
4277 err = hci_register_proto(&l2cap_hci_proto);
4278 if (err < 0) {
4279 BT_ERR("L2CAP protocol registration failed");
4280 bt_sock_unregister(BTPROTO_L2CAP);
4281 goto error;
4282 }
4283
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004284 if (bt_debugfs) {
4285 l2cap_debugfs = debugfs_create_file("l2cap", 0444,
4286 bt_debugfs, NULL, &l2cap_debugfs_fops);
4287 if (!l2cap_debugfs)
4288 BT_ERR("Failed to create L2CAP debug file");
4289 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004290
4291 BT_INFO("L2CAP ver %s", VERSION);
4292 BT_INFO("L2CAP socket layer initialized");
4293
4294 return 0;
4295
4296error:
4297 proto_unregister(&l2cap_proto);
4298 return err;
4299}
4300
4301static void __exit l2cap_exit(void)
4302{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004303 debugfs_remove(l2cap_debugfs);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004304
4305 if (bt_sock_unregister(BTPROTO_L2CAP) < 0)
4306 BT_ERR("L2CAP socket unregistration failed");
4307
4308 if (hci_unregister_proto(&l2cap_hci_proto) < 0)
4309 BT_ERR("L2CAP protocol unregistration failed");
4310
4311 proto_unregister(&l2cap_proto);
4312}
4313
4314void l2cap_load(void)
4315{
4316 /* Dummy function to trigger automatic L2CAP module loading by
4317 * other modules that use L2CAP sockets but don't use any other
4318 * symbols from it. */
4319 return;
4320}
4321EXPORT_SYMBOL(l2cap_load);
4322
4323module_init(l2cap_init);
4324module_exit(l2cap_exit);
4325
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07004326module_param(enable_ertm, bool, 0644);
4327MODULE_PARM_DESC(enable_ertm, "Enable enhanced retransmission mode");
4328
Marcel Holtmann5fbcd3d2009-10-05 11:35:43 +02004329module_param(max_transmit, uint, 0644);
4330MODULE_PARM_DESC(max_transmit, "Max transmit value (default = 3)");
4331
Gustavo F. Padovan369ba302010-05-01 16:15:41 -03004332module_param(tx_window, uint, 0644);
4333MODULE_PARM_DESC(tx_window, "Transmission window size value (default = 63)");
4334
Marcel Holtmann63fbd242008-08-18 13:23:53 +02004335MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004336MODULE_DESCRIPTION("Bluetooth L2CAP ver " VERSION);
4337MODULE_VERSION(VERSION);
4338MODULE_LICENSE("GPL");
4339MODULE_ALIAS("bt-proto-0");