blob: 99cf1772b481896fa945741985df54bb0856aacc [file] [log] [blame]
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 BlueZ - Bluetooth protocol stack for Linux
3 Copyright (C) 2000-2001 Qualcomm Incorporated
4
5 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License version 2 as
9 published by the Free Software Foundation;
10
11 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
12 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
14 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090015 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
16 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Linus Torvalds1da177e2005-04-16 15:20:36 -070018 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090020 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
21 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
Linus Torvalds1da177e2005-04-16 15:20:36 -070022 SOFTWARE IS DISCLAIMED.
23*/
24
25/* Bluetooth L2CAP core and sockets. */
26
Linus Torvalds1da177e2005-04-16 15:20:36 -070027#include <linux/module.h>
28
29#include <linux/types.h>
Randy Dunlap4fc268d2006-01-11 12:17:47 -080030#include <linux/capability.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070031#include <linux/errno.h>
32#include <linux/kernel.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070033#include <linux/sched.h>
34#include <linux/slab.h>
35#include <linux/poll.h>
36#include <linux/fcntl.h>
37#include <linux/init.h>
38#include <linux/interrupt.h>
39#include <linux/socket.h>
40#include <linux/skbuff.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070041#include <linux/list.h>
Marcel Holtmannbe9d1222005-11-08 09:57:38 -080042#include <linux/device.h>
Marcel Holtmannaef7d972010-03-21 05:27:45 +010043#include <linux/debugfs.h>
44#include <linux/seq_file.h>
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -030045#include <linux/uaccess.h>
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -030046#include <linux/crc16.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070047#include <net/sock.h>
48
49#include <asm/system.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070050#include <asm/unaligned.h>
51
52#include <net/bluetooth/bluetooth.h>
53#include <net/bluetooth/hci_core.h>
54#include <net/bluetooth/l2cap.h>
55
Marcel Holtmann44dd46d2009-05-02 19:09:01 -070056#define VERSION "2.14"
57
58static int enable_ertm = 0;
Marcel Holtmann5fbcd3d2009-10-05 11:35:43 +020059static int max_transmit = L2CAP_DEFAULT_MAX_TX;
Marcel Holtmannf0709e02007-10-20 13:38:51 +020060
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -070061static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN;
Marcel Holtmanne1027a72009-02-09 09:18:02 +010062static u8 l2cap_fixed_chan[8] = { 0x02, };
Linus Torvalds1da177e2005-04-16 15:20:36 -070063
Eric Dumazet90ddc4f2005-12-22 12:49:22 -080064static const struct proto_ops l2cap_sock_ops;
Linus Torvalds1da177e2005-04-16 15:20:36 -070065
66static struct bt_sock_list l2cap_sk_list = {
Robert P. J. Dayd5fb2962008-03-28 16:17:38 -070067 .lock = __RW_LOCK_UNLOCKED(l2cap_sk_list.lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -070068};
69
Linus Torvalds1da177e2005-04-16 15:20:36 -070070static void __l2cap_sock_close(struct sock *sk, int reason);
71static void l2cap_sock_close(struct sock *sk);
72static void l2cap_sock_kill(struct sock *sk);
73
74static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
75 u8 code, u8 ident, u16 dlen, void *data);
76
77/* ---- L2CAP timers ---- */
78static void l2cap_sock_timeout(unsigned long arg)
79{
80 struct sock *sk = (struct sock *) arg;
Marcel Holtmannb1235d72008-07-14 20:13:54 +020081 int reason;
Linus Torvalds1da177e2005-04-16 15:20:36 -070082
83 BT_DBG("sock %p state %d", sk, sk->sk_state);
84
85 bh_lock_sock(sk);
Marcel Holtmannb1235d72008-07-14 20:13:54 +020086
Marcel Holtmannf62e4322009-01-15 21:58:44 +010087 if (sk->sk_state == BT_CONNECTED || sk->sk_state == BT_CONFIG)
88 reason = ECONNREFUSED;
89 else if (sk->sk_state == BT_CONNECT &&
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +010090 l2cap_pi(sk)->sec_level != BT_SECURITY_SDP)
Marcel Holtmannb1235d72008-07-14 20:13:54 +020091 reason = ECONNREFUSED;
92 else
93 reason = ETIMEDOUT;
94
95 __l2cap_sock_close(sk, reason);
96
Linus Torvalds1da177e2005-04-16 15:20:36 -070097 bh_unlock_sock(sk);
98
99 l2cap_sock_kill(sk);
100 sock_put(sk);
101}
102
103static void l2cap_sock_set_timer(struct sock *sk, long timeout)
104{
105 BT_DBG("sk %p state %d timeout %ld", sk, sk->sk_state, timeout);
106 sk_reset_timer(sk, &sk->sk_timer, jiffies + timeout);
107}
108
109static void l2cap_sock_clear_timer(struct sock *sk)
110{
111 BT_DBG("sock %p state %d", sk, sk->sk_state);
112 sk_stop_timer(sk, &sk->sk_timer);
113}
114
Marcel Holtmann01394182006-07-03 10:02:46 +0200115/* ---- L2CAP channels ---- */
116static struct sock *__l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, u16 cid)
117{
118 struct sock *s;
119 for (s = l->head; s; s = l2cap_pi(s)->next_c) {
120 if (l2cap_pi(s)->dcid == cid)
121 break;
122 }
123 return s;
124}
125
126static struct sock *__l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid)
127{
128 struct sock *s;
129 for (s = l->head; s; s = l2cap_pi(s)->next_c) {
130 if (l2cap_pi(s)->scid == cid)
131 break;
132 }
133 return s;
134}
135
136/* Find channel with given SCID.
137 * Returns locked socket */
138static inline struct sock *l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid)
139{
140 struct sock *s;
141 read_lock(&l->lock);
142 s = __l2cap_get_chan_by_scid(l, cid);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300143 if (s)
144 bh_lock_sock(s);
Marcel Holtmann01394182006-07-03 10:02:46 +0200145 read_unlock(&l->lock);
146 return s;
147}
148
149static struct sock *__l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 ident)
150{
151 struct sock *s;
152 for (s = l->head; s; s = l2cap_pi(s)->next_c) {
153 if (l2cap_pi(s)->ident == ident)
154 break;
155 }
156 return s;
157}
158
159static inline struct sock *l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 ident)
160{
161 struct sock *s;
162 read_lock(&l->lock);
163 s = __l2cap_get_chan_by_ident(l, ident);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300164 if (s)
165 bh_lock_sock(s);
Marcel Holtmann01394182006-07-03 10:02:46 +0200166 read_unlock(&l->lock);
167 return s;
168}
169
170static u16 l2cap_alloc_cid(struct l2cap_chan_list *l)
171{
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300172 u16 cid = L2CAP_CID_DYN_START;
Marcel Holtmann01394182006-07-03 10:02:46 +0200173
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300174 for (; cid < L2CAP_CID_DYN_END; cid++) {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300175 if (!__l2cap_get_chan_by_scid(l, cid))
Marcel Holtmann01394182006-07-03 10:02:46 +0200176 return cid;
177 }
178
179 return 0;
180}
181
182static inline void __l2cap_chan_link(struct l2cap_chan_list *l, struct sock *sk)
183{
184 sock_hold(sk);
185
186 if (l->head)
187 l2cap_pi(l->head)->prev_c = sk;
188
189 l2cap_pi(sk)->next_c = l->head;
190 l2cap_pi(sk)->prev_c = NULL;
191 l->head = sk;
192}
193
194static inline void l2cap_chan_unlink(struct l2cap_chan_list *l, struct sock *sk)
195{
196 struct sock *next = l2cap_pi(sk)->next_c, *prev = l2cap_pi(sk)->prev_c;
197
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200198 write_lock_bh(&l->lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200199 if (sk == l->head)
200 l->head = next;
201
202 if (next)
203 l2cap_pi(next)->prev_c = prev;
204 if (prev)
205 l2cap_pi(prev)->next_c = next;
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200206 write_unlock_bh(&l->lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200207
208 __sock_put(sk);
209}
210
211static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
212{
213 struct l2cap_chan_list *l = &conn->chan_list;
214
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300215 BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
216 l2cap_pi(sk)->psm, l2cap_pi(sk)->dcid);
Marcel Holtmann01394182006-07-03 10:02:46 +0200217
Marcel Holtmann2950f212009-02-12 14:02:50 +0100218 conn->disc_reason = 0x13;
219
Marcel Holtmann01394182006-07-03 10:02:46 +0200220 l2cap_pi(sk)->conn = conn;
221
222 if (sk->sk_type == SOCK_SEQPACKET) {
223 /* Alloc CID for connection-oriented socket */
224 l2cap_pi(sk)->scid = l2cap_alloc_cid(l);
225 } else if (sk->sk_type == SOCK_DGRAM) {
226 /* Connectionless socket */
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300227 l2cap_pi(sk)->scid = L2CAP_CID_CONN_LESS;
228 l2cap_pi(sk)->dcid = L2CAP_CID_CONN_LESS;
Marcel Holtmann01394182006-07-03 10:02:46 +0200229 l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
230 } else {
231 /* Raw socket can send/recv signalling messages only */
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300232 l2cap_pi(sk)->scid = L2CAP_CID_SIGNALING;
233 l2cap_pi(sk)->dcid = L2CAP_CID_SIGNALING;
Marcel Holtmann01394182006-07-03 10:02:46 +0200234 l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
235 }
236
237 __l2cap_chan_link(l, sk);
238
239 if (parent)
240 bt_accept_enqueue(parent, sk);
241}
242
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900243/* Delete channel.
Marcel Holtmann01394182006-07-03 10:02:46 +0200244 * Must be called on the locked socket. */
245static void l2cap_chan_del(struct sock *sk, int err)
246{
247 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
248 struct sock *parent = bt_sk(sk)->parent;
249
250 l2cap_sock_clear_timer(sk);
251
252 BT_DBG("sk %p, conn %p, err %d", sk, conn, err);
253
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900254 if (conn) {
Marcel Holtmann01394182006-07-03 10:02:46 +0200255 /* Unlink from channel list */
256 l2cap_chan_unlink(&conn->chan_list, sk);
257 l2cap_pi(sk)->conn = NULL;
258 hci_conn_put(conn->hcon);
259 }
260
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200261 sk->sk_state = BT_CLOSED;
Marcel Holtmann01394182006-07-03 10:02:46 +0200262 sock_set_flag(sk, SOCK_ZAPPED);
263
264 if (err)
265 sk->sk_err = err;
266
267 if (parent) {
268 bt_accept_unlink(sk);
269 parent->sk_data_ready(parent, 0);
270 } else
271 sk->sk_state_change(sk);
272}
273
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200274/* Service level security */
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100275static inline int l2cap_check_security(struct sock *sk)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200276{
277 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100278 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200279
Marcel Holtmann00ae4af2009-02-12 16:19:45 +0100280 if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) {
281 if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
282 auth_type = HCI_AT_NO_BONDING_MITM;
283 else
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300284 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann00ae4af2009-02-12 16:19:45 +0100285
286 if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW)
287 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
288 } else {
289 switch (l2cap_pi(sk)->sec_level) {
290 case BT_SECURITY_HIGH:
291 auth_type = HCI_AT_GENERAL_BONDING_MITM;
292 break;
293 case BT_SECURITY_MEDIUM:
294 auth_type = HCI_AT_GENERAL_BONDING;
295 break;
296 default:
297 auth_type = HCI_AT_NO_BONDING;
298 break;
299 }
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100300 }
301
302 return hci_conn_security(conn->hcon, l2cap_pi(sk)->sec_level,
303 auth_type);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200304}
305
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200306static inline u8 l2cap_get_ident(struct l2cap_conn *conn)
307{
308 u8 id;
309
310 /* Get next available identificator.
311 * 1 - 128 are used by kernel.
312 * 129 - 199 are reserved.
313 * 200 - 254 are used by utilities like l2ping, etc.
314 */
315
316 spin_lock_bh(&conn->lock);
317
318 if (++conn->tx_ident > 128)
319 conn->tx_ident = 1;
320
321 id = conn->tx_ident;
322
323 spin_unlock_bh(&conn->lock);
324
325 return id;
326}
327
328static inline int l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data)
329{
330 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
331
332 BT_DBG("code 0x%2.2x", code);
333
334 if (!skb)
335 return -ENOMEM;
336
337 return hci_send_acl(conn->hcon, skb, 0);
338}
339
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300340static inline int l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control)
341{
342 struct sk_buff *skb;
343 struct l2cap_hdr *lh;
344 struct l2cap_conn *conn = pi->conn;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300345 int count, hlen = L2CAP_HDR_SIZE + 2;
346
347 if (pi->fcs == L2CAP_FCS_CRC16)
348 hlen += 2;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300349
350 BT_DBG("pi %p, control 0x%2.2x", pi, control);
351
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300352 count = min_t(unsigned int, conn->mtu, hlen);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300353 control |= L2CAP_CTRL_FRAME_TYPE;
354
355 skb = bt_skb_alloc(count, GFP_ATOMIC);
356 if (!skb)
357 return -ENOMEM;
358
359 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300360 lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300361 lh->cid = cpu_to_le16(pi->dcid);
362 put_unaligned_le16(control, skb_put(skb, 2));
363
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300364 if (pi->fcs == L2CAP_FCS_CRC16) {
365 u16 fcs = crc16(0, (u8 *)lh, count - 2);
366 put_unaligned_le16(fcs, skb_put(skb, 2));
367 }
368
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300369 return hci_send_acl(pi->conn->hcon, skb, 0);
370}
371
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300372static inline int l2cap_send_rr_or_rnr(struct l2cap_pinfo *pi, u16 control)
373{
374 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY)
375 control |= L2CAP_SUPER_RCV_NOT_READY;
376 else
377 control |= L2CAP_SUPER_RCV_READY;
378
Gustavo F. Padovan2ab25cd2009-10-03 02:34:40 -0300379 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
380
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300381 return l2cap_send_sframe(pi, control);
382}
383
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200384static void l2cap_do_start(struct sock *sk)
385{
386 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
387
388 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +0100389 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
390 return;
391
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100392 if (l2cap_check_security(sk)) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200393 struct l2cap_conn_req req;
394 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
395 req.psm = l2cap_pi(sk)->psm;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200396
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200397 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200398
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200399 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200400 L2CAP_CONN_REQ, sizeof(req), &req);
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200401 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200402 } else {
403 struct l2cap_info_req req;
404 req.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
405
406 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
407 conn->info_ident = l2cap_get_ident(conn);
408
409 mod_timer(&conn->info_timer, jiffies +
410 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
411
412 l2cap_send_cmd(conn, conn->info_ident,
413 L2CAP_INFO_REQ, sizeof(req), &req);
414 }
415}
416
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300417static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct sock *sk)
418{
419 struct l2cap_disconn_req req;
420
421 req.dcid = cpu_to_le16(l2cap_pi(sk)->dcid);
422 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
423 l2cap_send_cmd(conn, l2cap_get_ident(conn),
424 L2CAP_DISCONN_REQ, sizeof(req), &req);
425}
426
Linus Torvalds1da177e2005-04-16 15:20:36 -0700427/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200428static void l2cap_conn_start(struct l2cap_conn *conn)
429{
430 struct l2cap_chan_list *l = &conn->chan_list;
431 struct sock *sk;
432
433 BT_DBG("conn %p", conn);
434
435 read_lock(&l->lock);
436
437 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
438 bh_lock_sock(sk);
439
440 if (sk->sk_type != SOCK_SEQPACKET) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200441 bh_unlock_sock(sk);
442 continue;
443 }
444
445 if (sk->sk_state == BT_CONNECT) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100446 if (l2cap_check_security(sk)) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200447 struct l2cap_conn_req req;
448 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
449 req.psm = l2cap_pi(sk)->psm;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200450
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200451 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200452
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200453 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200454 L2CAP_CONN_REQ, sizeof(req), &req);
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200455 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200456 } else if (sk->sk_state == BT_CONNECT2) {
457 struct l2cap_conn_rsp rsp;
458 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
459 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
460
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100461 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100462 if (bt_sk(sk)->defer_setup) {
463 struct sock *parent = bt_sk(sk)->parent;
464 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
465 rsp.status = cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
466 parent->sk_data_ready(parent, 0);
467
468 } else {
469 sk->sk_state = BT_CONFIG;
470 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
471 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
472 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200473 } else {
474 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
475 rsp.status = cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
476 }
477
478 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
479 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
480 }
481
482 bh_unlock_sock(sk);
483 }
484
485 read_unlock(&l->lock);
486}
487
488static void l2cap_conn_ready(struct l2cap_conn *conn)
489{
490 struct l2cap_chan_list *l = &conn->chan_list;
491 struct sock *sk;
492
493 BT_DBG("conn %p", conn);
494
495 read_lock(&l->lock);
496
497 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
498 bh_lock_sock(sk);
499
500 if (sk->sk_type != SOCK_SEQPACKET) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200501 l2cap_sock_clear_timer(sk);
502 sk->sk_state = BT_CONNECTED;
503 sk->sk_state_change(sk);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200504 } else if (sk->sk_state == BT_CONNECT)
505 l2cap_do_start(sk);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200506
507 bh_unlock_sock(sk);
508 }
509
510 read_unlock(&l->lock);
511}
512
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200513/* Notify sockets that we cannot guaranty reliability anymore */
514static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
515{
516 struct l2cap_chan_list *l = &conn->chan_list;
517 struct sock *sk;
518
519 BT_DBG("conn %p", conn);
520
521 read_lock(&l->lock);
522
523 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100524 if (l2cap_pi(sk)->force_reliable)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200525 sk->sk_err = err;
526 }
527
528 read_unlock(&l->lock);
529}
530
531static void l2cap_info_timeout(unsigned long arg)
532{
533 struct l2cap_conn *conn = (void *) arg;
534
Marcel Holtmann984947d2009-02-06 23:35:19 +0100535 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +0100536 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +0100537
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200538 l2cap_conn_start(conn);
539}
540
Linus Torvalds1da177e2005-04-16 15:20:36 -0700541static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
542{
Marcel Holtmann01394182006-07-03 10:02:46 +0200543 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700544
Marcel Holtmann01394182006-07-03 10:02:46 +0200545 if (conn || status)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700546 return conn;
547
Marcel Holtmann01394182006-07-03 10:02:46 +0200548 conn = kzalloc(sizeof(struct l2cap_conn), GFP_ATOMIC);
549 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700550 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700551
552 hcon->l2cap_data = conn;
553 conn->hcon = hcon;
554
Marcel Holtmann01394182006-07-03 10:02:46 +0200555 BT_DBG("hcon %p conn %p", hcon, conn);
556
Linus Torvalds1da177e2005-04-16 15:20:36 -0700557 conn->mtu = hcon->hdev->acl_mtu;
558 conn->src = &hcon->hdev->bdaddr;
559 conn->dst = &hcon->dst;
560
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200561 conn->feat_mask = 0;
562
Linus Torvalds1da177e2005-04-16 15:20:36 -0700563 spin_lock_init(&conn->lock);
564 rwlock_init(&conn->chan_list.lock);
565
Dave Young45054dc2009-10-18 20:28:30 +0000566 setup_timer(&conn->info_timer, l2cap_info_timeout,
567 (unsigned long) conn);
568
Marcel Holtmann2950f212009-02-12 14:02:50 +0100569 conn->disc_reason = 0x13;
570
Linus Torvalds1da177e2005-04-16 15:20:36 -0700571 return conn;
572}
573
Marcel Holtmann01394182006-07-03 10:02:46 +0200574static void l2cap_conn_del(struct hci_conn *hcon, int err)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700575{
Marcel Holtmann01394182006-07-03 10:02:46 +0200576 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700577 struct sock *sk;
578
Marcel Holtmann01394182006-07-03 10:02:46 +0200579 if (!conn)
580 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700581
582 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
583
Wei Yongjun7585b972009-02-25 18:29:52 +0800584 kfree_skb(conn->rx_skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700585
586 /* Kill channels */
587 while ((sk = conn->chan_list.head)) {
588 bh_lock_sock(sk);
589 l2cap_chan_del(sk, err);
590 bh_unlock_sock(sk);
591 l2cap_sock_kill(sk);
592 }
593
Dave Young8e8440f2008-03-03 12:18:55 -0800594 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
595 del_timer_sync(&conn->info_timer);
Thomas Gleixner3ab22732008-02-26 17:42:56 -0800596
Linus Torvalds1da177e2005-04-16 15:20:36 -0700597 hcon->l2cap_data = NULL;
598 kfree(conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700599}
600
601static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
602{
603 struct l2cap_chan_list *l = &conn->chan_list;
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200604 write_lock_bh(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700605 __l2cap_chan_add(conn, sk, parent);
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200606 write_unlock_bh(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700607}
608
Linus Torvalds1da177e2005-04-16 15:20:36 -0700609/* ---- Socket interface ---- */
Al Viro8e036fc2007-07-29 00:16:36 -0700610static struct sock *__l2cap_get_sock_by_addr(__le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700611{
612 struct sock *sk;
613 struct hlist_node *node;
614 sk_for_each(sk, node, &l2cap_sk_list.head)
615 if (l2cap_pi(sk)->sport == psm && !bacmp(&bt_sk(sk)->src, src))
616 goto found;
617 sk = NULL;
618found:
619 return sk;
620}
621
622/* Find socket with psm and source bdaddr.
623 * Returns closest match.
624 */
Al Viro8e036fc2007-07-29 00:16:36 -0700625static struct sock *__l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700626{
627 struct sock *sk = NULL, *sk1 = NULL;
628 struct hlist_node *node;
629
630 sk_for_each(sk, node, &l2cap_sk_list.head) {
631 if (state && sk->sk_state != state)
632 continue;
633
634 if (l2cap_pi(sk)->psm == psm) {
635 /* Exact match. */
636 if (!bacmp(&bt_sk(sk)->src, src))
637 break;
638
639 /* Closest match */
640 if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY))
641 sk1 = sk;
642 }
643 }
644 return node ? sk : sk1;
645}
646
647/* Find socket with given address (psm, src).
648 * Returns locked socket */
Al Viro8e036fc2007-07-29 00:16:36 -0700649static inline struct sock *l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700650{
651 struct sock *s;
652 read_lock(&l2cap_sk_list.lock);
653 s = __l2cap_get_sock_by_psm(state, psm, src);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300654 if (s)
655 bh_lock_sock(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700656 read_unlock(&l2cap_sk_list.lock);
657 return s;
658}
659
660static void l2cap_sock_destruct(struct sock *sk)
661{
662 BT_DBG("sk %p", sk);
663
664 skb_queue_purge(&sk->sk_receive_queue);
665 skb_queue_purge(&sk->sk_write_queue);
666}
667
668static void l2cap_sock_cleanup_listen(struct sock *parent)
669{
670 struct sock *sk;
671
672 BT_DBG("parent %p", parent);
673
674 /* Close not yet accepted channels */
675 while ((sk = bt_accept_dequeue(parent, NULL)))
676 l2cap_sock_close(sk);
677
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200678 parent->sk_state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700679 sock_set_flag(parent, SOCK_ZAPPED);
680}
681
682/* Kill socket (only if zapped and orphan)
683 * Must be called on unlocked socket.
684 */
685static void l2cap_sock_kill(struct sock *sk)
686{
687 if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket)
688 return;
689
690 BT_DBG("sk %p state %d", sk, sk->sk_state);
691
692 /* Kill poor orphan */
693 bt_sock_unlink(&l2cap_sk_list, sk);
694 sock_set_flag(sk, SOCK_DEAD);
695 sock_put(sk);
696}
697
698static void __l2cap_sock_close(struct sock *sk, int reason)
699{
700 BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket);
701
702 switch (sk->sk_state) {
703 case BT_LISTEN:
704 l2cap_sock_cleanup_listen(sk);
705 break;
706
707 case BT_CONNECTED:
708 case BT_CONFIG:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700709 if (sk->sk_type == SOCK_SEQPACKET) {
710 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700711
712 sk->sk_state = BT_DISCONN;
713 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300714 l2cap_send_disconn_req(conn, sk);
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200715 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -0700716 l2cap_chan_del(sk, reason);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700717 break;
718
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100719 case BT_CONNECT2:
720 if (sk->sk_type == SOCK_SEQPACKET) {
721 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
722 struct l2cap_conn_rsp rsp;
723 __u16 result;
724
725 if (bt_sk(sk)->defer_setup)
726 result = L2CAP_CR_SEC_BLOCK;
727 else
728 result = L2CAP_CR_BAD_PSM;
729
730 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
731 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
732 rsp.result = cpu_to_le16(result);
733 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
734 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
735 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
736 } else
737 l2cap_chan_del(sk, reason);
738 break;
739
Linus Torvalds1da177e2005-04-16 15:20:36 -0700740 case BT_CONNECT:
741 case BT_DISCONN:
742 l2cap_chan_del(sk, reason);
743 break;
744
745 default:
746 sock_set_flag(sk, SOCK_ZAPPED);
747 break;
748 }
749}
750
751/* Must be called on unlocked socket. */
752static void l2cap_sock_close(struct sock *sk)
753{
754 l2cap_sock_clear_timer(sk);
755 lock_sock(sk);
756 __l2cap_sock_close(sk, ECONNRESET);
757 release_sock(sk);
758 l2cap_sock_kill(sk);
759}
760
761static void l2cap_sock_init(struct sock *sk, struct sock *parent)
762{
763 struct l2cap_pinfo *pi = l2cap_pi(sk);
764
765 BT_DBG("sk %p", sk);
766
767 if (parent) {
768 sk->sk_type = parent->sk_type;
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100769 bt_sk(sk)->defer_setup = bt_sk(parent)->defer_setup;
770
Linus Torvalds1da177e2005-04-16 15:20:36 -0700771 pi->imtu = l2cap_pi(parent)->imtu;
772 pi->omtu = l2cap_pi(parent)->omtu;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -0700773 pi->mode = l2cap_pi(parent)->mode;
774 pi->fcs = l2cap_pi(parent)->fcs;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100775 pi->sec_level = l2cap_pi(parent)->sec_level;
776 pi->role_switch = l2cap_pi(parent)->role_switch;
777 pi->force_reliable = l2cap_pi(parent)->force_reliable;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700778 } else {
779 pi->imtu = L2CAP_DEFAULT_MTU;
780 pi->omtu = 0;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -0700781 pi->mode = L2CAP_MODE_BASIC;
782 pi->fcs = L2CAP_FCS_CRC16;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100783 pi->sec_level = BT_SECURITY_LOW;
784 pi->role_switch = 0;
785 pi->force_reliable = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700786 }
787
788 /* Default config options */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +0200789 pi->conf_len = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700790 pi->flush_to = L2CAP_DEFAULT_FLUSH_TO;
Dave Young45054dc2009-10-18 20:28:30 +0000791 skb_queue_head_init(TX_QUEUE(sk));
792 skb_queue_head_init(SREJ_QUEUE(sk));
793 INIT_LIST_HEAD(SREJ_LIST(sk));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700794}
795
796static struct proto l2cap_proto = {
797 .name = "L2CAP",
798 .owner = THIS_MODULE,
799 .obj_size = sizeof(struct l2cap_pinfo)
800};
801
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700802static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700803{
804 struct sock *sk;
805
Pavel Emelyanov6257ff22007-11-01 00:39:31 -0700806 sk = sk_alloc(net, PF_BLUETOOTH, prio, &l2cap_proto);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700807 if (!sk)
808 return NULL;
809
810 sock_init_data(sock, sk);
811 INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
812
813 sk->sk_destruct = l2cap_sock_destruct;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200814 sk->sk_sndtimeo = msecs_to_jiffies(L2CAP_CONN_TIMEOUT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700815
816 sock_reset_flag(sk, SOCK_ZAPPED);
817
818 sk->sk_protocol = proto;
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200819 sk->sk_state = BT_OPEN;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700820
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200821 setup_timer(&sk->sk_timer, l2cap_sock_timeout, (unsigned long) sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700822
823 bt_sock_link(&l2cap_sk_list, sk);
824 return sk;
825}
826
Eric Paris3f378b62009-11-05 22:18:14 -0800827static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol,
828 int kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700829{
830 struct sock *sk;
831
832 BT_DBG("sock %p", sock);
833
834 sock->state = SS_UNCONNECTED;
835
836 if (sock->type != SOCK_SEQPACKET &&
837 sock->type != SOCK_DGRAM && sock->type != SOCK_RAW)
838 return -ESOCKTNOSUPPORT;
839
Eric Parisc84b3262009-11-05 20:45:52 -0800840 if (sock->type == SOCK_RAW && !kern && !capable(CAP_NET_RAW))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700841 return -EPERM;
842
843 sock->ops = &l2cap_sock_ops;
844
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700845 sk = l2cap_sock_alloc(net, sock, protocol, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700846 if (!sk)
847 return -ENOMEM;
848
849 l2cap_sock_init(sk, NULL);
850 return 0;
851}
852
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100853static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700854{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700855 struct sock *sk = sock->sk;
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100856 struct sockaddr_l2 la;
857 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700858
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100859 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700860
861 if (!addr || addr->sa_family != AF_BLUETOOTH)
862 return -EINVAL;
863
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100864 memset(&la, 0, sizeof(la));
865 len = min_t(unsigned int, sizeof(la), alen);
866 memcpy(&la, addr, len);
867
Marcel Holtmann2a517ca2009-02-16 03:20:31 +0100868 if (la.l2_cid)
869 return -EINVAL;
870
Linus Torvalds1da177e2005-04-16 15:20:36 -0700871 lock_sock(sk);
872
873 if (sk->sk_state != BT_OPEN) {
874 err = -EBADFD;
875 goto done;
876 }
877
Marcel Holtmannb4324b52009-06-07 18:06:51 +0200878 if (la.l2_psm && __le16_to_cpu(la.l2_psm) < 0x1001 &&
Marcel Holtmann847641d2007-01-22 22:00:45 +0100879 !capable(CAP_NET_BIND_SERVICE)) {
880 err = -EACCES;
881 goto done;
882 }
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900883
Linus Torvalds1da177e2005-04-16 15:20:36 -0700884 write_lock_bh(&l2cap_sk_list.lock);
885
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100886 if (la.l2_psm && __l2cap_get_sock_by_addr(la.l2_psm, &la.l2_bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700887 err = -EADDRINUSE;
888 } else {
889 /* Save source address */
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100890 bacpy(&bt_sk(sk)->src, &la.l2_bdaddr);
891 l2cap_pi(sk)->psm = la.l2_psm;
892 l2cap_pi(sk)->sport = la.l2_psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700893 sk->sk_state = BT_BOUND;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100894
Marcel Holtmannb4324b52009-06-07 18:06:51 +0200895 if (__le16_to_cpu(la.l2_psm) == 0x0001 ||
896 __le16_to_cpu(la.l2_psm) == 0x0003)
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100897 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700898 }
899
900 write_unlock_bh(&l2cap_sk_list.lock);
901
902done:
903 release_sock(sk);
904 return err;
905}
906
907static int l2cap_do_connect(struct sock *sk)
908{
909 bdaddr_t *src = &bt_sk(sk)->src;
910 bdaddr_t *dst = &bt_sk(sk)->dst;
911 struct l2cap_conn *conn;
912 struct hci_conn *hcon;
913 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200914 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +0200915 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700916
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100917 BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst),
918 l2cap_pi(sk)->psm);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700919
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300920 hdev = hci_get_route(dst, src);
921 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700922 return -EHOSTUNREACH;
923
924 hci_dev_lock_bh(hdev);
925
926 err = -ENOMEM;
927
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100928 if (sk->sk_type == SOCK_RAW) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100929 switch (l2cap_pi(sk)->sec_level) {
930 case BT_SECURITY_HIGH:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100931 auth_type = HCI_AT_DEDICATED_BONDING_MITM;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100932 break;
933 case BT_SECURITY_MEDIUM:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100934 auth_type = HCI_AT_DEDICATED_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100935 break;
936 default:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100937 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100938 break;
939 }
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100940 } else if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100941 if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200942 auth_type = HCI_AT_NO_BONDING_MITM;
943 else
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200944 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann435fef22009-02-09 03:55:28 +0100945
946 if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW)
947 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100948 } else {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100949 switch (l2cap_pi(sk)->sec_level) {
950 case BT_SECURITY_HIGH:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100951 auth_type = HCI_AT_GENERAL_BONDING_MITM;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100952 break;
953 case BT_SECURITY_MEDIUM:
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200954 auth_type = HCI_AT_GENERAL_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100955 break;
956 default:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100957 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100958 break;
959 }
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200960 }
961
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100962 hcon = hci_connect(hdev, ACL_LINK, dst,
963 l2cap_pi(sk)->sec_level, auth_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700964 if (!hcon)
965 goto done;
966
967 conn = l2cap_conn_add(hcon, 0);
968 if (!conn) {
969 hci_conn_put(hcon);
970 goto done;
971 }
972
973 err = 0;
974
975 /* Update source addr of the socket */
976 bacpy(src, conn->src);
977
978 l2cap_chan_add(conn, sk, NULL);
979
980 sk->sk_state = BT_CONNECT;
981 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
982
983 if (hcon->state == BT_CONNECTED) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200984 if (sk->sk_type != SOCK_SEQPACKET) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700985 l2cap_sock_clear_timer(sk);
986 sk->sk_state = BT_CONNECTED;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200987 } else
988 l2cap_do_start(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700989 }
990
991done:
992 hci_dev_unlock_bh(hdev);
993 hci_dev_put(hdev);
994 return err;
995}
996
997static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
998{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700999 struct sock *sk = sock->sk;
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001000 struct sockaddr_l2 la;
1001 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001002
Linus Torvalds1da177e2005-04-16 15:20:36 -07001003 BT_DBG("sk %p", sk);
1004
Changli Gao6503d962010-03-31 22:58:26 +00001005 if (!addr || alen < sizeof(addr->sa_family) ||
1006 addr->sa_family != AF_BLUETOOTH)
Marcel Holtmann2a517ca2009-02-16 03:20:31 +01001007 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001008
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001009 memset(&la, 0, sizeof(la));
1010 len = min_t(unsigned int, sizeof(la), alen);
1011 memcpy(&la, addr, len);
1012
Marcel Holtmann2a517ca2009-02-16 03:20:31 +01001013 if (la.l2_cid)
1014 return -EINVAL;
1015
1016 lock_sock(sk);
1017
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001018 if (sk->sk_type == SOCK_SEQPACKET && !la.l2_psm) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001019 err = -EINVAL;
1020 goto done;
1021 }
1022
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001023 switch (l2cap_pi(sk)->mode) {
1024 case L2CAP_MODE_BASIC:
1025 break;
1026 case L2CAP_MODE_ERTM:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001027 case L2CAP_MODE_STREAMING:
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001028 if (enable_ertm)
1029 break;
1030 /* fall through */
1031 default:
1032 err = -ENOTSUPP;
1033 goto done;
1034 }
1035
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001036 switch (sk->sk_state) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001037 case BT_CONNECT:
1038 case BT_CONNECT2:
1039 case BT_CONFIG:
1040 /* Already connecting */
1041 goto wait;
1042
1043 case BT_CONNECTED:
1044 /* Already connected */
1045 goto done;
1046
1047 case BT_OPEN:
1048 case BT_BOUND:
1049 /* Can connect */
1050 break;
1051
1052 default:
1053 err = -EBADFD;
1054 goto done;
1055 }
1056
1057 /* Set destination address and psm */
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001058 bacpy(&bt_sk(sk)->dst, &la.l2_bdaddr);
1059 l2cap_pi(sk)->psm = la.l2_psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001060
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001061 err = l2cap_do_connect(sk);
1062 if (err)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001063 goto done;
1064
1065wait:
1066 err = bt_sock_wait_state(sk, BT_CONNECTED,
1067 sock_sndtimeo(sk, flags & O_NONBLOCK));
1068done:
1069 release_sock(sk);
1070 return err;
1071}
1072
1073static int l2cap_sock_listen(struct socket *sock, int backlog)
1074{
1075 struct sock *sk = sock->sk;
1076 int err = 0;
1077
1078 BT_DBG("sk %p backlog %d", sk, backlog);
1079
1080 lock_sock(sk);
1081
1082 if (sk->sk_state != BT_BOUND || sock->type != SOCK_SEQPACKET) {
1083 err = -EBADFD;
1084 goto done;
1085 }
1086
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001087 switch (l2cap_pi(sk)->mode) {
1088 case L2CAP_MODE_BASIC:
1089 break;
1090 case L2CAP_MODE_ERTM:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001091 case L2CAP_MODE_STREAMING:
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001092 if (enable_ertm)
1093 break;
1094 /* fall through */
1095 default:
1096 err = -ENOTSUPP;
1097 goto done;
1098 }
1099
Linus Torvalds1da177e2005-04-16 15:20:36 -07001100 if (!l2cap_pi(sk)->psm) {
1101 bdaddr_t *src = &bt_sk(sk)->src;
1102 u16 psm;
1103
1104 err = -EINVAL;
1105
1106 write_lock_bh(&l2cap_sk_list.lock);
1107
1108 for (psm = 0x1001; psm < 0x1100; psm += 2)
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001109 if (!__l2cap_get_sock_by_addr(cpu_to_le16(psm), src)) {
1110 l2cap_pi(sk)->psm = cpu_to_le16(psm);
1111 l2cap_pi(sk)->sport = cpu_to_le16(psm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001112 err = 0;
1113 break;
1114 }
1115
1116 write_unlock_bh(&l2cap_sk_list.lock);
1117
1118 if (err < 0)
1119 goto done;
1120 }
1121
1122 sk->sk_max_ack_backlog = backlog;
1123 sk->sk_ack_backlog = 0;
1124 sk->sk_state = BT_LISTEN;
1125
1126done:
1127 release_sock(sk);
1128 return err;
1129}
1130
1131static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int flags)
1132{
1133 DECLARE_WAITQUEUE(wait, current);
1134 struct sock *sk = sock->sk, *nsk;
1135 long timeo;
1136 int err = 0;
1137
Peter Zijlstrafcc70d52006-11-08 22:44:35 -08001138 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001139
1140 if (sk->sk_state != BT_LISTEN) {
1141 err = -EBADFD;
1142 goto done;
1143 }
1144
1145 timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
1146
1147 BT_DBG("sk %p timeo %ld", sk, timeo);
1148
1149 /* Wait for an incoming connection. (wake-one). */
Eric Dumazetaa395142010-04-20 13:03:51 +00001150 add_wait_queue_exclusive(sk_sleep(sk), &wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001151 while (!(nsk = bt_accept_dequeue(sk, newsock))) {
1152 set_current_state(TASK_INTERRUPTIBLE);
1153 if (!timeo) {
1154 err = -EAGAIN;
1155 break;
1156 }
1157
1158 release_sock(sk);
1159 timeo = schedule_timeout(timeo);
Peter Zijlstrafcc70d52006-11-08 22:44:35 -08001160 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001161
1162 if (sk->sk_state != BT_LISTEN) {
1163 err = -EBADFD;
1164 break;
1165 }
1166
1167 if (signal_pending(current)) {
1168 err = sock_intr_errno(timeo);
1169 break;
1170 }
1171 }
1172 set_current_state(TASK_RUNNING);
Eric Dumazetaa395142010-04-20 13:03:51 +00001173 remove_wait_queue(sk_sleep(sk), &wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001174
1175 if (err)
1176 goto done;
1177
1178 newsock->state = SS_CONNECTED;
1179
1180 BT_DBG("new socket %p", nsk);
1181
1182done:
1183 release_sock(sk);
1184 return err;
1185}
1186
1187static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
1188{
1189 struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
1190 struct sock *sk = sock->sk;
1191
1192 BT_DBG("sock %p, sk %p", sock, sk);
1193
1194 addr->sa_family = AF_BLUETOOTH;
1195 *len = sizeof(struct sockaddr_l2);
1196
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001197 if (peer) {
1198 la->l2_psm = l2cap_pi(sk)->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001199 bacpy(&la->l2_bdaddr, &bt_sk(sk)->dst);
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001200 la->l2_cid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001201 } else {
1202 la->l2_psm = l2cap_pi(sk)->sport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001203 bacpy(&la->l2_bdaddr, &bt_sk(sk)->src);
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001204 la->l2_cid = cpu_to_le16(l2cap_pi(sk)->scid);
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001205 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001206
Linus Torvalds1da177e2005-04-16 15:20:36 -07001207 return 0;
1208}
1209
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001210static void l2cap_monitor_timeout(unsigned long arg)
1211{
1212 struct sock *sk = (void *) arg;
1213 u16 control;
1214
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001215 bh_lock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001216 if (l2cap_pi(sk)->retry_count >= l2cap_pi(sk)->remote_max_tx) {
1217 l2cap_send_disconn_req(l2cap_pi(sk)->conn, sk);
Andrei Emeltchenkob13f5862009-12-15 11:38:04 +02001218 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001219 return;
1220 }
1221
1222 l2cap_pi(sk)->retry_count++;
1223 __mod_monitor_timer();
1224
1225 control = L2CAP_CTRL_POLL;
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001226 l2cap_send_rr_or_rnr(l2cap_pi(sk), control);
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001227 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001228}
1229
1230static void l2cap_retrans_timeout(unsigned long arg)
1231{
1232 struct sock *sk = (void *) arg;
1233 u16 control;
1234
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001235 bh_lock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001236 l2cap_pi(sk)->retry_count = 1;
1237 __mod_monitor_timer();
1238
1239 l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
1240
1241 control = L2CAP_CTRL_POLL;
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001242 l2cap_send_rr_or_rnr(l2cap_pi(sk), control);
Gustavo F. Padovane6862192009-08-24 00:45:19 -03001243 bh_unlock_sock(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001244}
1245
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001246static void l2cap_drop_acked_frames(struct sock *sk)
1247{
1248 struct sk_buff *skb;
1249
1250 while ((skb = skb_peek(TX_QUEUE(sk)))) {
1251 if (bt_cb(skb)->tx_seq == l2cap_pi(sk)->expected_ack_seq)
1252 break;
1253
1254 skb = skb_dequeue(TX_QUEUE(sk));
1255 kfree_skb(skb);
1256
1257 l2cap_pi(sk)->unacked_frames--;
1258 }
1259
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001260 if (!l2cap_pi(sk)->unacked_frames)
1261 del_timer(&l2cap_pi(sk)->retrans_timer);
1262
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001263 return;
1264}
1265
1266static inline int l2cap_do_send(struct sock *sk, struct sk_buff *skb)
1267{
1268 struct l2cap_pinfo *pi = l2cap_pi(sk);
1269 int err;
1270
1271 BT_DBG("sk %p, skb %p len %d", sk, skb, skb->len);
1272
1273 err = hci_send_acl(pi->conn->hcon, skb, 0);
1274 if (err < 0)
1275 kfree_skb(skb);
1276
1277 return err;
1278}
1279
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001280static int l2cap_streaming_send(struct sock *sk)
1281{
1282 struct sk_buff *skb, *tx_skb;
1283 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001284 u16 control, fcs;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001285 int err;
1286
1287 while ((skb = sk->sk_send_head)) {
1288 tx_skb = skb_clone(skb, GFP_ATOMIC);
1289
1290 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
1291 control |= pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT;
1292 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1293
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001294 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16) {
1295 fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
1296 put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
1297 }
1298
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001299 err = l2cap_do_send(sk, tx_skb);
1300 if (err < 0) {
1301 l2cap_send_disconn_req(pi->conn, sk);
1302 return err;
1303 }
1304
1305 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
1306
1307 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1308 sk->sk_send_head = NULL;
1309 else
1310 sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
1311
1312 skb = skb_dequeue(TX_QUEUE(sk));
1313 kfree_skb(skb);
1314 }
1315 return 0;
1316}
1317
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001318static int l2cap_retransmit_frame(struct sock *sk, u8 tx_seq)
1319{
1320 struct l2cap_pinfo *pi = l2cap_pi(sk);
1321 struct sk_buff *skb, *tx_skb;
1322 u16 control, fcs;
1323 int err;
1324
1325 skb = skb_peek(TX_QUEUE(sk));
1326 do {
1327 if (bt_cb(skb)->tx_seq != tx_seq) {
1328 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1329 break;
1330 skb = skb_queue_next(TX_QUEUE(sk), skb);
1331 continue;
1332 }
1333
1334 if (pi->remote_max_tx &&
1335 bt_cb(skb)->retries == pi->remote_max_tx) {
1336 l2cap_send_disconn_req(pi->conn, sk);
1337 break;
1338 }
1339
1340 tx_skb = skb_clone(skb, GFP_ATOMIC);
1341 bt_cb(skb)->retries++;
1342 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03001343 control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03001344 | (tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
1345 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1346
1347 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16) {
1348 fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
1349 put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
1350 }
1351
1352 err = l2cap_do_send(sk, tx_skb);
1353 if (err < 0) {
1354 l2cap_send_disconn_req(pi->conn, sk);
1355 return err;
1356 }
1357 break;
1358 } while(1);
1359 return 0;
1360}
1361
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001362static int l2cap_ertm_send(struct sock *sk)
1363{
1364 struct sk_buff *skb, *tx_skb;
1365 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001366 u16 control, fcs;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001367 int err;
1368
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001369 if (pi->conn_state & L2CAP_CONN_WAIT_F)
1370 return 0;
1371
Joe Perchesf64f9e72009-11-29 16:55:45 -08001372 while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(sk)) &&
1373 !(pi->conn_state & L2CAP_CONN_REMOTE_BUSY)) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001374
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001375 if (pi->remote_max_tx &&
1376 bt_cb(skb)->retries == pi->remote_max_tx) {
1377 l2cap_send_disconn_req(pi->conn, sk);
1378 break;
1379 }
1380
Andrei Emeltchenkoe420aba2009-12-23 13:07:14 +02001381 tx_skb = skb_clone(skb, GFP_ATOMIC);
1382
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001383 bt_cb(skb)->retries++;
1384
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001385 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03001386 control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001387 | (pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
1388 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1389
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001390
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001391 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16) {
1392 fcs = crc16(0, (u8 *)skb->data, tx_skb->len - 2);
1393 put_unaligned_le16(fcs, skb->data + tx_skb->len - 2);
1394 }
1395
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001396 err = l2cap_do_send(sk, tx_skb);
1397 if (err < 0) {
1398 l2cap_send_disconn_req(pi->conn, sk);
1399 return err;
1400 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001401 __mod_retrans_timer();
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001402
1403 bt_cb(skb)->tx_seq = pi->next_tx_seq;
1404 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
1405
1406 pi->unacked_frames++;
1407
1408 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1409 sk->sk_send_head = NULL;
1410 else
1411 sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
1412 }
1413
1414 return 0;
1415}
1416
1417static 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 -07001418{
1419 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001420 struct sk_buff **frag;
1421 int err, sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001422
1423 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count)) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001424 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001425 }
1426
1427 sent += count;
1428 len -= count;
1429
1430 /* Continuation fragments (no L2CAP header) */
1431 frag = &skb_shinfo(skb)->frag_list;
1432 while (len) {
1433 count = min_t(unsigned int, conn->mtu, len);
1434
1435 *frag = bt_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err);
1436 if (!*frag)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001437 return -EFAULT;
1438 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
1439 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001440
1441 sent += count;
1442 len -= count;
1443
1444 frag = &(*frag)->next;
1445 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001446
1447 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001448}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001449
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001450static struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, size_t len)
1451{
1452 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1453 struct sk_buff *skb;
1454 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1455 struct l2cap_hdr *lh;
1456
1457 BT_DBG("sk %p len %d", sk, (int)len);
1458
1459 count = min_t(unsigned int, (conn->mtu - hlen), len);
1460 skb = bt_skb_send_alloc(sk, count + hlen,
1461 msg->msg_flags & MSG_DONTWAIT, &err);
1462 if (!skb)
1463 return ERR_PTR(-ENOMEM);
1464
1465 /* Create L2CAP header */
1466 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1467 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1468 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1469 put_unaligned_le16(l2cap_pi(sk)->psm, skb_put(skb, 2));
1470
1471 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1472 if (unlikely(err < 0)) {
1473 kfree_skb(skb);
1474 return ERR_PTR(err);
1475 }
1476 return skb;
1477}
1478
1479static struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *msg, size_t len)
1480{
1481 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1482 struct sk_buff *skb;
1483 int err, count, hlen = L2CAP_HDR_SIZE;
1484 struct l2cap_hdr *lh;
1485
1486 BT_DBG("sk %p len %d", sk, (int)len);
1487
1488 count = min_t(unsigned int, (conn->mtu - hlen), len);
1489 skb = bt_skb_send_alloc(sk, count + hlen,
1490 msg->msg_flags & MSG_DONTWAIT, &err);
1491 if (!skb)
1492 return ERR_PTR(-ENOMEM);
1493
1494 /* Create L2CAP header */
1495 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1496 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1497 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1498
1499 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1500 if (unlikely(err < 0)) {
1501 kfree_skb(skb);
1502 return ERR_PTR(err);
1503 }
1504 return skb;
1505}
1506
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001507static 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 -03001508{
1509 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1510 struct sk_buff *skb;
1511 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1512 struct l2cap_hdr *lh;
1513
1514 BT_DBG("sk %p len %d", sk, (int)len);
1515
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001516 if (sdulen)
1517 hlen += 2;
1518
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001519 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1520 hlen += 2;
1521
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001522 count = min_t(unsigned int, (conn->mtu - hlen), len);
1523 skb = bt_skb_send_alloc(sk, count + hlen,
1524 msg->msg_flags & MSG_DONTWAIT, &err);
1525 if (!skb)
1526 return ERR_PTR(-ENOMEM);
1527
1528 /* Create L2CAP header */
1529 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1530 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1531 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1532 put_unaligned_le16(control, skb_put(skb, 2));
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001533 if (sdulen)
1534 put_unaligned_le16(sdulen, skb_put(skb, 2));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001535
1536 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1537 if (unlikely(err < 0)) {
1538 kfree_skb(skb);
1539 return ERR_PTR(err);
1540 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001541
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001542 if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
1543 put_unaligned_le16(0, skb_put(skb, 2));
1544
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001545 bt_cb(skb)->retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001546 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001547}
1548
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001549static inline int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len)
1550{
1551 struct l2cap_pinfo *pi = l2cap_pi(sk);
1552 struct sk_buff *skb;
1553 struct sk_buff_head sar_queue;
1554 u16 control;
1555 size_t size = 0;
1556
1557 __skb_queue_head_init(&sar_queue);
1558 control = L2CAP_SDU_START;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001559 skb = l2cap_create_iframe_pdu(sk, msg, pi->max_pdu_size, control, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001560 if (IS_ERR(skb))
1561 return PTR_ERR(skb);
1562
1563 __skb_queue_tail(&sar_queue, skb);
1564 len -= pi->max_pdu_size;
1565 size +=pi->max_pdu_size;
1566 control = 0;
1567
1568 while (len > 0) {
1569 size_t buflen;
1570
1571 if (len > pi->max_pdu_size) {
1572 control |= L2CAP_SDU_CONTINUE;
1573 buflen = pi->max_pdu_size;
1574 } else {
1575 control |= L2CAP_SDU_END;
1576 buflen = len;
1577 }
1578
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001579 skb = l2cap_create_iframe_pdu(sk, msg, buflen, control, 0);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001580 if (IS_ERR(skb)) {
1581 skb_queue_purge(&sar_queue);
1582 return PTR_ERR(skb);
1583 }
1584
1585 __skb_queue_tail(&sar_queue, skb);
1586 len -= buflen;
1587 size += buflen;
1588 control = 0;
1589 }
1590 skb_queue_splice_tail(&sar_queue, TX_QUEUE(sk));
1591 if (sk->sk_send_head == NULL)
1592 sk->sk_send_head = sar_queue.next;
1593
1594 return size;
1595}
1596
Linus Torvalds1da177e2005-04-16 15:20:36 -07001597static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len)
1598{
1599 struct sock *sk = sock->sk;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001600 struct l2cap_pinfo *pi = l2cap_pi(sk);
1601 struct sk_buff *skb;
1602 u16 control;
1603 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001604
1605 BT_DBG("sock %p, sk %p", sock, sk);
1606
Benjamin LaHaisec1cbe4b2005-12-13 23:22:19 -08001607 err = sock_error(sk);
1608 if (err)
1609 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001610
1611 if (msg->msg_flags & MSG_OOB)
1612 return -EOPNOTSUPP;
1613
Linus Torvalds1da177e2005-04-16 15:20:36 -07001614 lock_sock(sk);
1615
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001616 if (sk->sk_state != BT_CONNECTED) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001617 err = -ENOTCONN;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001618 goto done;
1619 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001620
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001621 /* Connectionless channel */
1622 if (sk->sk_type == SOCK_DGRAM) {
1623 skb = l2cap_create_connless_pdu(sk, msg, len);
Dan Carpenter477fffb2010-04-21 23:52:01 +00001624 if (IS_ERR(skb))
1625 err = PTR_ERR(skb);
1626 else
1627 err = l2cap_do_send(sk, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001628 goto done;
1629 }
1630
1631 switch (pi->mode) {
1632 case L2CAP_MODE_BASIC:
Gustavo F. Padovanc69163e2010-05-01 16:15:35 -03001633 /* Check outgoing MTU */
1634 if (len > pi->omtu) {
1635 err = -EINVAL;
1636 goto done;
1637 }
1638
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001639 /* Create a basic PDU */
1640 skb = l2cap_create_basic_pdu(sk, msg, len);
1641 if (IS_ERR(skb)) {
1642 err = PTR_ERR(skb);
1643 goto done;
1644 }
1645
1646 err = l2cap_do_send(sk, skb);
1647 if (!err)
1648 err = len;
1649 break;
1650
1651 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001652 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001653 /* Entire SDU fits into one PDU */
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001654 if (len <= pi->max_pdu_size) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001655 control = L2CAP_SDU_UNSEGMENTED;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001656 skb = l2cap_create_iframe_pdu(sk, msg, len, control, 0);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001657 if (IS_ERR(skb)) {
1658 err = PTR_ERR(skb);
1659 goto done;
1660 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001661 __skb_queue_tail(TX_QUEUE(sk), skb);
1662 if (sk->sk_send_head == NULL)
1663 sk->sk_send_head = skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001664 } else {
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001665 /* Segment SDU into multiples PDUs */
1666 err = l2cap_sar_segment_sdu(sk, msg, len);
1667 if (err < 0)
1668 goto done;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001669 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001670
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001671 if (pi->mode == L2CAP_MODE_STREAMING)
1672 err = l2cap_streaming_send(sk);
1673 else
1674 err = l2cap_ertm_send(sk);
1675
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001676 if (!err)
1677 err = len;
1678 break;
1679
1680 default:
1681 BT_DBG("bad state %1.1x", pi->mode);
1682 err = -EINVAL;
1683 }
1684
1685done:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001686 release_sock(sk);
1687 return err;
1688}
1689
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001690static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags)
1691{
1692 struct sock *sk = sock->sk;
1693
1694 lock_sock(sk);
1695
1696 if (sk->sk_state == BT_CONNECT2 && bt_sk(sk)->defer_setup) {
1697 struct l2cap_conn_rsp rsp;
1698
1699 sk->sk_state = BT_CONFIG;
1700
1701 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
1702 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
1703 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
1704 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
1705 l2cap_send_cmd(l2cap_pi(sk)->conn, l2cap_pi(sk)->ident,
1706 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
1707
1708 release_sock(sk);
1709 return 0;
1710 }
1711
1712 release_sock(sk);
1713
1714 return bt_sock_recvmsg(iocb, sock, msg, len, flags);
1715}
1716
David S. Millerb7058842009-09-30 16:12:20 -07001717static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001718{
1719 struct sock *sk = sock->sk;
1720 struct l2cap_options opts;
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001721 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001722 u32 opt;
1723
1724 BT_DBG("sk %p", sk);
1725
1726 lock_sock(sk);
1727
1728 switch (optname) {
1729 case L2CAP_OPTIONS:
Marcel Holtmann0878b662007-05-05 00:35:59 +02001730 opts.imtu = l2cap_pi(sk)->imtu;
1731 opts.omtu = l2cap_pi(sk)->omtu;
1732 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001733 opts.mode = l2cap_pi(sk)->mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001734 opts.fcs = l2cap_pi(sk)->fcs;
Marcel Holtmann0878b662007-05-05 00:35:59 +02001735
Linus Torvalds1da177e2005-04-16 15:20:36 -07001736 len = min_t(unsigned int, sizeof(opts), optlen);
1737 if (copy_from_user((char *) &opts, optval, len)) {
1738 err = -EFAULT;
1739 break;
1740 }
Marcel Holtmann0878b662007-05-05 00:35:59 +02001741
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001742 l2cap_pi(sk)->imtu = opts.imtu;
1743 l2cap_pi(sk)->omtu = opts.omtu;
1744 l2cap_pi(sk)->mode = opts.mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001745 l2cap_pi(sk)->fcs = opts.fcs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001746 break;
1747
1748 case L2CAP_LM:
1749 if (get_user(opt, (u32 __user *) optval)) {
1750 err = -EFAULT;
1751 break;
1752 }
1753
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001754 if (opt & L2CAP_LM_AUTH)
1755 l2cap_pi(sk)->sec_level = BT_SECURITY_LOW;
1756 if (opt & L2CAP_LM_ENCRYPT)
1757 l2cap_pi(sk)->sec_level = BT_SECURITY_MEDIUM;
1758 if (opt & L2CAP_LM_SECURE)
1759 l2cap_pi(sk)->sec_level = BT_SECURITY_HIGH;
1760
1761 l2cap_pi(sk)->role_switch = (opt & L2CAP_LM_MASTER);
1762 l2cap_pi(sk)->force_reliable = (opt & L2CAP_LM_RELIABLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001763 break;
1764
1765 default:
1766 err = -ENOPROTOOPT;
1767 break;
1768 }
1769
1770 release_sock(sk);
1771 return err;
1772}
1773
David S. Millerb7058842009-09-30 16:12:20 -07001774static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001775{
1776 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001777 struct bt_security sec;
1778 int len, err = 0;
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001779 u32 opt;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001780
1781 BT_DBG("sk %p", sk);
1782
1783 if (level == SOL_L2CAP)
1784 return l2cap_sock_setsockopt_old(sock, optname, optval, optlen);
1785
Marcel Holtmann0588d942009-01-16 10:06:13 +01001786 if (level != SOL_BLUETOOTH)
1787 return -ENOPROTOOPT;
1788
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001789 lock_sock(sk);
1790
1791 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001792 case BT_SECURITY:
Marcel Holtmann2526d3d2009-02-20 20:54:06 +01001793 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01001794 err = -EINVAL;
1795 break;
1796 }
1797
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001798 sec.level = BT_SECURITY_LOW;
1799
1800 len = min_t(unsigned int, sizeof(sec), optlen);
1801 if (copy_from_user((char *) &sec, optval, len)) {
1802 err = -EFAULT;
1803 break;
1804 }
1805
1806 if (sec.level < BT_SECURITY_LOW ||
1807 sec.level > BT_SECURITY_HIGH) {
1808 err = -EINVAL;
1809 break;
1810 }
1811
1812 l2cap_pi(sk)->sec_level = sec.level;
1813 break;
1814
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001815 case BT_DEFER_SETUP:
1816 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
1817 err = -EINVAL;
1818 break;
1819 }
1820
1821 if (get_user(opt, (u32 __user *) optval)) {
1822 err = -EFAULT;
1823 break;
1824 }
1825
1826 bt_sk(sk)->defer_setup = opt;
1827 break;
1828
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001829 default:
1830 err = -ENOPROTOOPT;
1831 break;
1832 }
1833
1834 release_sock(sk);
1835 return err;
1836}
1837
1838static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001839{
1840 struct sock *sk = sock->sk;
1841 struct l2cap_options opts;
1842 struct l2cap_conninfo cinfo;
1843 int len, err = 0;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001844 u32 opt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001845
1846 BT_DBG("sk %p", sk);
1847
1848 if (get_user(len, optlen))
1849 return -EFAULT;
1850
1851 lock_sock(sk);
1852
1853 switch (optname) {
1854 case L2CAP_OPTIONS:
1855 opts.imtu = l2cap_pi(sk)->imtu;
1856 opts.omtu = l2cap_pi(sk)->omtu;
1857 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001858 opts.mode = l2cap_pi(sk)->mode;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001859 opts.fcs = l2cap_pi(sk)->fcs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001860
1861 len = min_t(unsigned int, len, sizeof(opts));
1862 if (copy_to_user(optval, (char *) &opts, len))
1863 err = -EFAULT;
1864
1865 break;
1866
1867 case L2CAP_LM:
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001868 switch (l2cap_pi(sk)->sec_level) {
1869 case BT_SECURITY_LOW:
1870 opt = L2CAP_LM_AUTH;
1871 break;
1872 case BT_SECURITY_MEDIUM:
1873 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT;
1874 break;
1875 case BT_SECURITY_HIGH:
1876 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT |
1877 L2CAP_LM_SECURE;
1878 break;
1879 default:
1880 opt = 0;
1881 break;
1882 }
1883
1884 if (l2cap_pi(sk)->role_switch)
1885 opt |= L2CAP_LM_MASTER;
1886
1887 if (l2cap_pi(sk)->force_reliable)
1888 opt |= L2CAP_LM_RELIABLE;
1889
1890 if (put_user(opt, (u32 __user *) optval))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001891 err = -EFAULT;
1892 break;
1893
1894 case L2CAP_CONNINFO:
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001895 if (sk->sk_state != BT_CONNECTED &&
1896 !(sk->sk_state == BT_CONNECT2 &&
1897 bt_sk(sk)->defer_setup)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001898 err = -ENOTCONN;
1899 break;
1900 }
1901
1902 cinfo.hci_handle = l2cap_pi(sk)->conn->hcon->handle;
1903 memcpy(cinfo.dev_class, l2cap_pi(sk)->conn->hcon->dev_class, 3);
1904
1905 len = min_t(unsigned int, len, sizeof(cinfo));
1906 if (copy_to_user(optval, (char *) &cinfo, len))
1907 err = -EFAULT;
1908
1909 break;
1910
1911 default:
1912 err = -ENOPROTOOPT;
1913 break;
1914 }
1915
1916 release_sock(sk);
1917 return err;
1918}
1919
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001920static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
1921{
1922 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001923 struct bt_security sec;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001924 int len, err = 0;
1925
1926 BT_DBG("sk %p", sk);
1927
1928 if (level == SOL_L2CAP)
1929 return l2cap_sock_getsockopt_old(sock, optname, optval, optlen);
1930
Marcel Holtmann0588d942009-01-16 10:06:13 +01001931 if (level != SOL_BLUETOOTH)
1932 return -ENOPROTOOPT;
1933
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001934 if (get_user(len, optlen))
1935 return -EFAULT;
1936
1937 lock_sock(sk);
1938
1939 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001940 case BT_SECURITY:
Marcel Holtmann2526d3d2009-02-20 20:54:06 +01001941 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01001942 err = -EINVAL;
1943 break;
1944 }
1945
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001946 sec.level = l2cap_pi(sk)->sec_level;
1947
1948 len = min_t(unsigned int, len, sizeof(sec));
1949 if (copy_to_user(optval, (char *) &sec, len))
1950 err = -EFAULT;
1951
1952 break;
1953
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001954 case BT_DEFER_SETUP:
1955 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
1956 err = -EINVAL;
1957 break;
1958 }
1959
1960 if (put_user(bt_sk(sk)->defer_setup, (u32 __user *) optval))
1961 err = -EFAULT;
1962
1963 break;
1964
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001965 default:
1966 err = -ENOPROTOOPT;
1967 break;
1968 }
1969
1970 release_sock(sk);
1971 return err;
1972}
1973
Linus Torvalds1da177e2005-04-16 15:20:36 -07001974static int l2cap_sock_shutdown(struct socket *sock, int how)
1975{
1976 struct sock *sk = sock->sk;
1977 int err = 0;
1978
1979 BT_DBG("sock %p, sk %p", sock, sk);
1980
1981 if (!sk)
1982 return 0;
1983
1984 lock_sock(sk);
1985 if (!sk->sk_shutdown) {
1986 sk->sk_shutdown = SHUTDOWN_MASK;
1987 l2cap_sock_clear_timer(sk);
1988 __l2cap_sock_close(sk, 0);
1989
1990 if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
Marcel Holtmannb1235d72008-07-14 20:13:54 +02001991 err = bt_sock_wait_state(sk, BT_CLOSED,
1992 sk->sk_lingertime);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001993 }
1994 release_sock(sk);
1995 return err;
1996}
1997
1998static int l2cap_sock_release(struct socket *sock)
1999{
2000 struct sock *sk = sock->sk;
2001 int err;
2002
2003 BT_DBG("sock %p, sk %p", sock, sk);
2004
2005 if (!sk)
2006 return 0;
2007
2008 err = l2cap_sock_shutdown(sock, 2);
2009
2010 sock_orphan(sk);
2011 l2cap_sock_kill(sk);
2012 return err;
2013}
2014
Linus Torvalds1da177e2005-04-16 15:20:36 -07002015static void l2cap_chan_ready(struct sock *sk)
2016{
2017 struct sock *parent = bt_sk(sk)->parent;
2018
2019 BT_DBG("sk %p, parent %p", sk, parent);
2020
2021 l2cap_pi(sk)->conf_state = 0;
2022 l2cap_sock_clear_timer(sk);
2023
2024 if (!parent) {
2025 /* Outgoing channel.
2026 * Wake up socket sleeping on connect.
2027 */
2028 sk->sk_state = BT_CONNECTED;
2029 sk->sk_state_change(sk);
2030 } else {
2031 /* Incoming channel.
2032 * Wake up socket sleeping on accept.
2033 */
2034 parent->sk_data_ready(parent, 0);
2035 }
2036}
2037
2038/* Copy frame to all raw sockets on that connection */
2039static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2040{
2041 struct l2cap_chan_list *l = &conn->chan_list;
2042 struct sk_buff *nskb;
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002043 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002044
2045 BT_DBG("conn %p", conn);
2046
2047 read_lock(&l->lock);
2048 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
2049 if (sk->sk_type != SOCK_RAW)
2050 continue;
2051
2052 /* Don't send frame to the socket it came from */
2053 if (skb->sk == sk)
2054 continue;
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002055 nskb = skb_clone(skb, GFP_ATOMIC);
2056 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002057 continue;
2058
2059 if (sock_queue_rcv_skb(sk, nskb))
2060 kfree_skb(nskb);
2061 }
2062 read_unlock(&l->lock);
2063}
2064
2065/* ---- L2CAP signalling commands ---- */
2066static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
2067 u8 code, u8 ident, u16 dlen, void *data)
2068{
2069 struct sk_buff *skb, **frag;
2070 struct l2cap_cmd_hdr *cmd;
2071 struct l2cap_hdr *lh;
2072 int len, count;
2073
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002074 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d",
2075 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002076
2077 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2078 count = min_t(unsigned int, conn->mtu, len);
2079
2080 skb = bt_skb_alloc(count, GFP_ATOMIC);
2081 if (!skb)
2082 return NULL;
2083
2084 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002085 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03002086 lh->cid = cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002087
2088 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2089 cmd->code = code;
2090 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002091 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002092
2093 if (dlen) {
2094 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2095 memcpy(skb_put(skb, count), data, count);
2096 data += count;
2097 }
2098
2099 len -= skb->len;
2100
2101 /* Continuation fragments (no L2CAP header) */
2102 frag = &skb_shinfo(skb)->frag_list;
2103 while (len) {
2104 count = min_t(unsigned int, conn->mtu, len);
2105
2106 *frag = bt_skb_alloc(count, GFP_ATOMIC);
2107 if (!*frag)
2108 goto fail;
2109
2110 memcpy(skb_put(*frag, count), data, count);
2111
2112 len -= count;
2113 data += count;
2114
2115 frag = &(*frag)->next;
2116 }
2117
2118 return skb;
2119
2120fail:
2121 kfree_skb(skb);
2122 return NULL;
2123}
2124
2125static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned long *val)
2126{
2127 struct l2cap_conf_opt *opt = *ptr;
2128 int len;
2129
2130 len = L2CAP_CONF_OPT_SIZE + opt->len;
2131 *ptr += len;
2132
2133 *type = opt->type;
2134 *olen = opt->len;
2135
2136 switch (opt->len) {
2137 case 1:
2138 *val = *((u8 *) opt->val);
2139 break;
2140
2141 case 2:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002142 *val = __le16_to_cpu(*((__le16 *) opt->val));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002143 break;
2144
2145 case 4:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002146 *val = __le32_to_cpu(*((__le32 *) opt->val));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002147 break;
2148
2149 default:
2150 *val = (unsigned long) opt->val;
2151 break;
2152 }
2153
2154 BT_DBG("type 0x%2.2x len %d val 0x%lx", *type, opt->len, *val);
2155 return len;
2156}
2157
Linus Torvalds1da177e2005-04-16 15:20:36 -07002158static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2159{
2160 struct l2cap_conf_opt *opt = *ptr;
2161
2162 BT_DBG("type 0x%2.2x len %d val 0x%lx", type, len, val);
2163
2164 opt->type = type;
2165 opt->len = len;
2166
2167 switch (len) {
2168 case 1:
2169 *((u8 *) opt->val) = val;
2170 break;
2171
2172 case 2:
Al Viro8e036fc2007-07-29 00:16:36 -07002173 *((__le16 *) opt->val) = cpu_to_le16(val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002174 break;
2175
2176 case 4:
Al Viro8e036fc2007-07-29 00:16:36 -07002177 *((__le32 *) opt->val) = cpu_to_le32(val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002178 break;
2179
2180 default:
2181 memcpy(opt->val, (void *) val, len);
2182 break;
2183 }
2184
2185 *ptr += L2CAP_CONF_OPT_SIZE + len;
2186}
2187
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002188static inline void l2cap_ertm_init(struct sock *sk)
2189{
2190 l2cap_pi(sk)->expected_ack_seq = 0;
2191 l2cap_pi(sk)->unacked_frames = 0;
2192 l2cap_pi(sk)->buffer_seq = 0;
2193 l2cap_pi(sk)->num_to_ack = 0;
2194
2195 setup_timer(&l2cap_pi(sk)->retrans_timer,
2196 l2cap_retrans_timeout, (unsigned long) sk);
2197 setup_timer(&l2cap_pi(sk)->monitor_timer,
2198 l2cap_monitor_timeout, (unsigned long) sk);
2199
2200 __skb_queue_head_init(SREJ_QUEUE(sk));
2201}
2202
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002203static int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
2204{
2205 u32 local_feat_mask = l2cap_feat_mask;
2206 if (enable_ertm)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002207 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002208
2209 switch (mode) {
2210 case L2CAP_MODE_ERTM:
2211 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
2212 case L2CAP_MODE_STREAMING:
2213 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
2214 default:
2215 return 0x00;
2216 }
2217}
2218
2219static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
2220{
2221 switch (mode) {
2222 case L2CAP_MODE_STREAMING:
2223 case L2CAP_MODE_ERTM:
2224 if (l2cap_mode_supported(mode, remote_feat_mask))
2225 return mode;
2226 /* fall through */
2227 default:
2228 return L2CAP_MODE_BASIC;
2229 }
2230}
2231
Linus Torvalds1da177e2005-04-16 15:20:36 -07002232static int l2cap_build_conf_req(struct sock *sk, void *data)
2233{
2234 struct l2cap_pinfo *pi = l2cap_pi(sk);
2235 struct l2cap_conf_req *req = data;
Gustavo F. Padovana0e55a32009-09-29 01:42:23 -03002236 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Linus Torvalds1da177e2005-04-16 15:20:36 -07002237 void *ptr = req->data;
2238
2239 BT_DBG("sk %p", sk);
2240
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002241 if (pi->num_conf_req || pi->num_conf_rsp)
2242 goto done;
2243
2244 switch (pi->mode) {
2245 case L2CAP_MODE_STREAMING:
2246 case L2CAP_MODE_ERTM:
2247 pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002248 if (!l2cap_mode_supported(pi->mode, pi->conn->feat_mask))
2249 l2cap_send_disconn_req(pi->conn, sk);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002250 break;
2251 default:
2252 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
2253 break;
2254 }
2255
2256done:
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002257 switch (pi->mode) {
2258 case L2CAP_MODE_BASIC:
2259 if (pi->imtu != L2CAP_DEFAULT_MTU)
2260 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
2261 break;
2262
2263 case L2CAP_MODE_ERTM:
2264 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002265 rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW;
Marcel Holtmann5fbcd3d2009-10-05 11:35:43 +02002266 rfc.max_transmit = max_transmit;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002267 rfc.retrans_timeout = 0;
2268 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002269 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03002270 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
2271 rfc.max_pdu_size = pi->conn->mtu - 10;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002272
2273 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2274 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002275
2276 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2277 break;
2278
2279 if (pi->fcs == L2CAP_FCS_NONE ||
2280 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
2281 pi->fcs = L2CAP_FCS_NONE;
2282 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
2283 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002284 break;
2285
2286 case L2CAP_MODE_STREAMING:
2287 rfc.mode = L2CAP_MODE_STREAMING;
2288 rfc.txwin_size = 0;
2289 rfc.max_transmit = 0;
2290 rfc.retrans_timeout = 0;
2291 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002292 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovand1daa092010-05-01 16:15:36 -03002293 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
2294 rfc.max_pdu_size = pi->conn->mtu - 10;
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002295
2296 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2297 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002298
2299 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2300 break;
2301
2302 if (pi->fcs == L2CAP_FCS_NONE ||
2303 pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
2304 pi->fcs = L2CAP_FCS_NONE;
2305 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
2306 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002307 break;
2308 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002309
2310 /* FIXME: Need actual value of the flush timeout */
2311 //if (flush_to != L2CAP_DEFAULT_FLUSH_TO)
2312 // l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2, pi->flush_to);
2313
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002314 req->dcid = cpu_to_le16(pi->dcid);
2315 req->flags = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002316
2317 return ptr - data;
2318}
2319
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002320static int l2cap_parse_conf_req(struct sock *sk, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002321{
2322 struct l2cap_pinfo *pi = l2cap_pi(sk);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002323 struct l2cap_conf_rsp *rsp = data;
2324 void *ptr = rsp->data;
2325 void *req = pi->conf_req;
2326 int len = pi->conf_len;
2327 int type, hint, olen;
2328 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002329 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Marcel Holtmann861d6882007-10-20 13:37:06 +02002330 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002331 u16 result = L2CAP_CONF_SUCCESS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002332
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002333 BT_DBG("sk %p", sk);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01002334
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002335 while (len >= L2CAP_CONF_OPT_SIZE) {
2336 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002337
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03002338 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07002339 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002340
2341 switch (type) {
2342 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002343 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002344 break;
2345
2346 case L2CAP_CONF_FLUSH_TO:
2347 pi->flush_to = val;
2348 break;
2349
2350 case L2CAP_CONF_QOS:
2351 break;
2352
Marcel Holtmann6464f352007-10-20 13:39:51 +02002353 case L2CAP_CONF_RFC:
2354 if (olen == sizeof(rfc))
2355 memcpy(&rfc, (void *) val, olen);
2356 break;
2357
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002358 case L2CAP_CONF_FCS:
2359 if (val == L2CAP_FCS_NONE)
2360 pi->conf_state |= L2CAP_CONF_NO_FCS_RECV;
2361
2362 break;
2363
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002364 default:
2365 if (hint)
2366 break;
2367
2368 result = L2CAP_CONF_UNKNOWN;
2369 *((u8 *) ptr++) = type;
2370 break;
2371 }
2372 }
2373
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002374 if (pi->num_conf_rsp || pi->num_conf_req)
2375 goto done;
2376
2377 switch (pi->mode) {
2378 case L2CAP_MODE_STREAMING:
2379 case L2CAP_MODE_ERTM:
2380 pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
2381 if (!l2cap_mode_supported(pi->mode, pi->conn->feat_mask))
2382 return -ECONNREFUSED;
2383 break;
2384 default:
2385 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
2386 break;
2387 }
2388
2389done:
2390 if (pi->mode != rfc.mode) {
2391 result = L2CAP_CONF_UNACCEPT;
2392 rfc.mode = pi->mode;
2393
2394 if (pi->num_conf_rsp == 1)
2395 return -ECONNREFUSED;
2396
2397 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2398 sizeof(rfc), (unsigned long) &rfc);
2399 }
2400
2401
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002402 if (result == L2CAP_CONF_SUCCESS) {
2403 /* Configure output options and let the other side know
2404 * which ones we don't like. */
2405
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002406 if (mtu < L2CAP_DEFAULT_MIN_MTU)
2407 result = L2CAP_CONF_UNACCEPT;
2408 else {
2409 pi->omtu = mtu;
2410 pi->conf_state |= L2CAP_CONF_MTU_DONE;
2411 }
2412 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002413
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002414 switch (rfc.mode) {
2415 case L2CAP_MODE_BASIC:
2416 pi->fcs = L2CAP_FCS_NONE;
2417 pi->conf_state |= L2CAP_CONF_MODE_DONE;
2418 break;
2419
2420 case L2CAP_MODE_ERTM:
2421 pi->remote_tx_win = rfc.txwin_size;
2422 pi->remote_max_tx = rfc.max_transmit;
2423 pi->max_pdu_size = rfc.max_pdu_size;
2424
2425 rfc.retrans_timeout = L2CAP_DEFAULT_RETRANS_TO;
2426 rfc.monitor_timeout = L2CAP_DEFAULT_MONITOR_TO;
2427
2428 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03002429
2430 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2431 sizeof(rfc), (unsigned long) &rfc);
2432
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002433 break;
2434
2435 case L2CAP_MODE_STREAMING:
2436 pi->remote_tx_win = rfc.txwin_size;
2437 pi->max_pdu_size = rfc.max_pdu_size;
2438
2439 pi->conf_state |= L2CAP_CONF_MODE_DONE;
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03002440
2441 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2442 sizeof(rfc), (unsigned long) &rfc);
2443
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002444 break;
2445
2446 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02002447 result = L2CAP_CONF_UNACCEPT;
2448
2449 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002450 rfc.mode = pi->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002451 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002452
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002453 if (result == L2CAP_CONF_SUCCESS)
2454 pi->conf_state |= L2CAP_CONF_OUTPUT_DONE;
2455 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002456 rsp->scid = cpu_to_le16(pi->dcid);
2457 rsp->result = cpu_to_le16(result);
2458 rsp->flags = cpu_to_le16(0x0000);
2459
2460 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002461}
2462
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002463static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data, u16 *result)
2464{
2465 struct l2cap_pinfo *pi = l2cap_pi(sk);
2466 struct l2cap_conf_req *req = data;
2467 void *ptr = req->data;
2468 int type, olen;
2469 unsigned long val;
2470 struct l2cap_conf_rfc rfc;
2471
2472 BT_DBG("sk %p, rsp %p, len %d, req %p", sk, rsp, len, data);
2473
2474 while (len >= L2CAP_CONF_OPT_SIZE) {
2475 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
2476
2477 switch (type) {
2478 case L2CAP_CONF_MTU:
2479 if (val < L2CAP_DEFAULT_MIN_MTU) {
2480 *result = L2CAP_CONF_UNACCEPT;
2481 pi->omtu = L2CAP_DEFAULT_MIN_MTU;
2482 } else
2483 pi->omtu = val;
2484 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
2485 break;
2486
2487 case L2CAP_CONF_FLUSH_TO:
2488 pi->flush_to = val;
2489 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
2490 2, pi->flush_to);
2491 break;
2492
2493 case L2CAP_CONF_RFC:
2494 if (olen == sizeof(rfc))
2495 memcpy(&rfc, (void *)val, olen);
2496
2497 if ((pi->conf_state & L2CAP_CONF_STATE2_DEVICE) &&
2498 rfc.mode != pi->mode)
2499 return -ECONNREFUSED;
2500
2501 pi->mode = rfc.mode;
2502 pi->fcs = 0;
2503
2504 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2505 sizeof(rfc), (unsigned long) &rfc);
2506 break;
2507 }
2508 }
2509
2510 if (*result == L2CAP_CONF_SUCCESS) {
2511 switch (rfc.mode) {
2512 case L2CAP_MODE_ERTM:
2513 pi->remote_tx_win = rfc.txwin_size;
2514 pi->retrans_timeout = rfc.retrans_timeout;
2515 pi->monitor_timeout = rfc.monitor_timeout;
2516 pi->max_pdu_size = le16_to_cpu(rfc.max_pdu_size);
2517 break;
2518 case L2CAP_MODE_STREAMING:
2519 pi->max_pdu_size = le16_to_cpu(rfc.max_pdu_size);
2520 break;
2521 }
2522 }
2523
2524 req->dcid = cpu_to_le16(pi->dcid);
2525 req->flags = cpu_to_le16(0x0000);
2526
2527 return ptr - data;
2528}
2529
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002530static int l2cap_build_conf_rsp(struct sock *sk, void *data, u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002531{
2532 struct l2cap_conf_rsp *rsp = data;
2533 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002534
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002535 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002536
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002537 rsp->scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002538 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002539 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002540
2541 return ptr - data;
2542}
2543
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002544static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2545{
2546 struct l2cap_cmd_rej *rej = (struct l2cap_cmd_rej *) data;
2547
2548 if (rej->reason != 0x0000)
2549 return 0;
2550
2551 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
2552 cmd->ident == conn->info_ident) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002553 del_timer(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01002554
2555 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002556 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01002557
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002558 l2cap_conn_start(conn);
2559 }
2560
2561 return 0;
2562}
2563
Linus Torvalds1da177e2005-04-16 15:20:36 -07002564static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2565{
2566 struct l2cap_chan_list *list = &conn->chan_list;
2567 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
2568 struct l2cap_conn_rsp rsp;
2569 struct sock *sk, *parent;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002570 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002571
2572 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002573 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002574
2575 BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
2576
2577 /* Check if we have socket listening on psm */
2578 parent = l2cap_get_sock_by_psm(BT_LISTEN, psm, conn->src);
2579 if (!parent) {
2580 result = L2CAP_CR_BAD_PSM;
2581 goto sendresp;
2582 }
2583
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002584 /* Check if the ACL is secure enough (if not SDP) */
2585 if (psm != cpu_to_le16(0x0001) &&
2586 !hci_conn_check_link_mode(conn->hcon)) {
Marcel Holtmann2950f212009-02-12 14:02:50 +01002587 conn->disc_reason = 0x05;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002588 result = L2CAP_CR_SEC_BLOCK;
2589 goto response;
2590 }
2591
Linus Torvalds1da177e2005-04-16 15:20:36 -07002592 result = L2CAP_CR_NO_MEM;
2593
2594 /* Check for backlog size */
2595 if (sk_acceptq_is_full(parent)) {
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09002596 BT_DBG("backlog full %d", parent->sk_ack_backlog);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002597 goto response;
2598 }
2599
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09002600 sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002601 if (!sk)
2602 goto response;
2603
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002604 write_lock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002605
2606 /* Check if we already have channel with that dcid */
2607 if (__l2cap_get_chan_by_dcid(list, scid)) {
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002608 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002609 sock_set_flag(sk, SOCK_ZAPPED);
2610 l2cap_sock_kill(sk);
2611 goto response;
2612 }
2613
2614 hci_conn_hold(conn->hcon);
2615
2616 l2cap_sock_init(sk, parent);
2617 bacpy(&bt_sk(sk)->src, conn->src);
2618 bacpy(&bt_sk(sk)->dst, conn->dst);
2619 l2cap_pi(sk)->psm = psm;
2620 l2cap_pi(sk)->dcid = scid;
2621
2622 __l2cap_chan_add(conn, sk, parent);
2623 dcid = l2cap_pi(sk)->scid;
2624
2625 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
2626
Linus Torvalds1da177e2005-04-16 15:20:36 -07002627 l2cap_pi(sk)->ident = cmd->ident;
2628
Marcel Holtmann984947d2009-02-06 23:35:19 +01002629 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002630 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002631 if (bt_sk(sk)->defer_setup) {
2632 sk->sk_state = BT_CONNECT2;
2633 result = L2CAP_CR_PEND;
2634 status = L2CAP_CS_AUTHOR_PEND;
2635 parent->sk_data_ready(parent, 0);
2636 } else {
2637 sk->sk_state = BT_CONFIG;
2638 result = L2CAP_CR_SUCCESS;
2639 status = L2CAP_CS_NO_INFO;
2640 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002641 } else {
2642 sk->sk_state = BT_CONNECT2;
2643 result = L2CAP_CR_PEND;
2644 status = L2CAP_CS_AUTHEN_PEND;
2645 }
2646 } else {
2647 sk->sk_state = BT_CONNECT2;
2648 result = L2CAP_CR_PEND;
2649 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002650 }
2651
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002652 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002653
2654response:
2655 bh_unlock_sock(parent);
2656
2657sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002658 rsp.scid = cpu_to_le16(scid);
2659 rsp.dcid = cpu_to_le16(dcid);
2660 rsp.result = cpu_to_le16(result);
2661 rsp.status = cpu_to_le16(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002662 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002663
2664 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
2665 struct l2cap_info_req info;
2666 info.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
2667
2668 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
2669 conn->info_ident = l2cap_get_ident(conn);
2670
2671 mod_timer(&conn->info_timer, jiffies +
2672 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
2673
2674 l2cap_send_cmd(conn, conn->info_ident,
2675 L2CAP_INFO_REQ, sizeof(info), &info);
2676 }
2677
Linus Torvalds1da177e2005-04-16 15:20:36 -07002678 return 0;
2679}
2680
2681static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2682{
2683 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
2684 u16 scid, dcid, result, status;
2685 struct sock *sk;
2686 u8 req[128];
2687
2688 scid = __le16_to_cpu(rsp->scid);
2689 dcid = __le16_to_cpu(rsp->dcid);
2690 result = __le16_to_cpu(rsp->result);
2691 status = __le16_to_cpu(rsp->status);
2692
2693 BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
2694
2695 if (scid) {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002696 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2697 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002698 return 0;
2699 } else {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002700 sk = l2cap_get_chan_by_ident(&conn->chan_list, cmd->ident);
2701 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002702 return 0;
2703 }
2704
2705 switch (result) {
2706 case L2CAP_CR_SUCCESS:
2707 sk->sk_state = BT_CONFIG;
2708 l2cap_pi(sk)->ident = 0;
2709 l2cap_pi(sk)->dcid = dcid;
2710 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
2711
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002712 l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_CONNECT_PEND;
2713
Linus Torvalds1da177e2005-04-16 15:20:36 -07002714 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
2715 l2cap_build_conf_req(sk, req), req);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002716 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002717 break;
2718
2719 case L2CAP_CR_PEND:
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002720 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002721 break;
2722
2723 default:
2724 l2cap_chan_del(sk, ECONNREFUSED);
2725 break;
2726 }
2727
2728 bh_unlock_sock(sk);
2729 return 0;
2730}
2731
Al Viro88219a02007-07-29 00:17:25 -07002732static 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 -07002733{
2734 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
2735 u16 dcid, flags;
2736 u8 rsp[64];
2737 struct sock *sk;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002738 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002739
2740 dcid = __le16_to_cpu(req->dcid);
2741 flags = __le16_to_cpu(req->flags);
2742
2743 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
2744
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002745 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
2746 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002747 return -ENOENT;
2748
Marcel Holtmann354f60a2006-11-18 22:15:20 +01002749 if (sk->sk_state == BT_DISCONN)
2750 goto unlock;
2751
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002752 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07002753 len = cmd_len - sizeof(*req);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002754 if (l2cap_pi(sk)->conf_len + len > sizeof(l2cap_pi(sk)->conf_req)) {
2755 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
2756 l2cap_build_conf_rsp(sk, rsp,
2757 L2CAP_CONF_REJECT, flags), rsp);
2758 goto unlock;
2759 }
2760
2761 /* Store config. */
2762 memcpy(l2cap_pi(sk)->conf_req + l2cap_pi(sk)->conf_len, req->data, len);
2763 l2cap_pi(sk)->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002764
2765 if (flags & 0x0001) {
2766 /* Incomplete config. Send empty response. */
2767 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002768 l2cap_build_conf_rsp(sk, rsp,
2769 L2CAP_CONF_SUCCESS, 0x0001), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002770 goto unlock;
2771 }
2772
2773 /* Complete config. */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002774 len = l2cap_parse_conf_req(sk, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002775 if (len < 0) {
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002776 l2cap_send_disconn_req(conn, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002777 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002778 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002779
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002780 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002781 l2cap_pi(sk)->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002782
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002783 /* Reset config buffer. */
2784 l2cap_pi(sk)->conf_len = 0;
2785
Marcel Holtmann876d9482007-10-20 13:35:42 +02002786 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE))
2787 goto unlock;
2788
Linus Torvalds1da177e2005-04-16 15:20:36 -07002789 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) {
Joe Perchesf64f9e72009-11-29 16:55:45 -08002790 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) ||
2791 l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002792 l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
2793
Linus Torvalds1da177e2005-04-16 15:20:36 -07002794 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002795
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002796 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002797 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002798 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002799 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
2800 l2cap_ertm_init(sk);
2801
Linus Torvalds1da177e2005-04-16 15:20:36 -07002802 l2cap_chan_ready(sk);
Marcel Holtmann876d9482007-10-20 13:35:42 +02002803 goto unlock;
2804 }
2805
2806 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002807 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002808 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002809 l2cap_build_conf_req(sk, buf), buf);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002810 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002811 }
2812
2813unlock:
2814 bh_unlock_sock(sk);
2815 return 0;
2816}
2817
2818static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2819{
2820 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
2821 u16 scid, flags, result;
2822 struct sock *sk;
2823
2824 scid = __le16_to_cpu(rsp->scid);
2825 flags = __le16_to_cpu(rsp->flags);
2826 result = __le16_to_cpu(rsp->result);
2827
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002828 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x",
2829 scid, flags, result);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002830
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002831 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2832 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002833 return 0;
2834
2835 switch (result) {
2836 case L2CAP_CONF_SUCCESS:
2837 break;
2838
2839 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002840 if (l2cap_pi(sk)->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
2841 int len = cmd->len - sizeof(*rsp);
2842 char req[64];
2843
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02002844 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
2845 l2cap_send_disconn_req(conn, sk);
2846 goto done;
2847 }
2848
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002849 /* throw out any old stored conf requests */
2850 result = L2CAP_CONF_SUCCESS;
2851 len = l2cap_parse_conf_rsp(sk, rsp->data,
2852 len, req, &result);
2853 if (len < 0) {
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002854 l2cap_send_disconn_req(conn, sk);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002855 goto done;
2856 }
2857
2858 l2cap_send_cmd(conn, l2cap_get_ident(conn),
2859 L2CAP_CONF_REQ, len, req);
2860 l2cap_pi(sk)->num_conf_req++;
2861 if (result != L2CAP_CONF_SUCCESS)
2862 goto done;
2863 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002864 }
2865
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09002866 default:
Linus Torvalds1da177e2005-04-16 15:20:36 -07002867 sk->sk_state = BT_DISCONN;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02002868 sk->sk_err = ECONNRESET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002869 l2cap_sock_set_timer(sk, HZ * 5);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002870 l2cap_send_disconn_req(conn, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002871 goto done;
2872 }
2873
2874 if (flags & 0x01)
2875 goto done;
2876
Linus Torvalds1da177e2005-04-16 15:20:36 -07002877 l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE;
2878
2879 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) {
Joe Perchesf64f9e72009-11-29 16:55:45 -08002880 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) ||
2881 l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002882 l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
2883
Linus Torvalds1da177e2005-04-16 15:20:36 -07002884 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002885 l2cap_pi(sk)->next_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002886 l2cap_pi(sk)->expected_tx_seq = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002887 __skb_queue_head_init(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002888 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
2889 l2cap_ertm_init(sk);
2890
Linus Torvalds1da177e2005-04-16 15:20:36 -07002891 l2cap_chan_ready(sk);
2892 }
2893
2894done:
2895 bh_unlock_sock(sk);
2896 return 0;
2897}
2898
2899static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2900{
2901 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
2902 struct l2cap_disconn_rsp rsp;
2903 u16 dcid, scid;
2904 struct sock *sk;
2905
2906 scid = __le16_to_cpu(req->scid);
2907 dcid = __le16_to_cpu(req->dcid);
2908
2909 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
2910
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002911 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
2912 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002913 return 0;
2914
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002915 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
2916 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002917 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
2918
2919 sk->sk_shutdown = SHUTDOWN_MASK;
2920
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002921 skb_queue_purge(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002922
2923 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
2924 skb_queue_purge(SREJ_QUEUE(sk));
2925 del_timer(&l2cap_pi(sk)->retrans_timer);
2926 del_timer(&l2cap_pi(sk)->monitor_timer);
2927 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002928
Linus Torvalds1da177e2005-04-16 15:20:36 -07002929 l2cap_chan_del(sk, ECONNRESET);
2930 bh_unlock_sock(sk);
2931
2932 l2cap_sock_kill(sk);
2933 return 0;
2934}
2935
2936static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2937{
2938 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
2939 u16 dcid, scid;
2940 struct sock *sk;
2941
2942 scid = __le16_to_cpu(rsp->scid);
2943 dcid = __le16_to_cpu(rsp->dcid);
2944
2945 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
2946
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002947 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2948 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002949 return 0;
2950
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002951 skb_queue_purge(TX_QUEUE(sk));
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002952
2953 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
2954 skb_queue_purge(SREJ_QUEUE(sk));
2955 del_timer(&l2cap_pi(sk)->retrans_timer);
2956 del_timer(&l2cap_pi(sk)->monitor_timer);
2957 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002958
Linus Torvalds1da177e2005-04-16 15:20:36 -07002959 l2cap_chan_del(sk, 0);
2960 bh_unlock_sock(sk);
2961
2962 l2cap_sock_kill(sk);
2963 return 0;
2964}
2965
2966static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2967{
2968 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002969 u16 type;
2970
2971 type = __le16_to_cpu(req->type);
2972
2973 BT_DBG("type 0x%4.4x", type);
2974
Marcel Holtmannf0709e02007-10-20 13:38:51 +02002975 if (type == L2CAP_IT_FEAT_MASK) {
2976 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07002977 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02002978 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
2979 rsp->type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
2980 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07002981 if (enable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002982 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
2983 | L2CAP_FEAT_FCS;
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03002984 put_unaligned_le32(feat_mask, rsp->data);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02002985 l2cap_send_cmd(conn, cmd->ident,
2986 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002987 } else if (type == L2CAP_IT_FIXED_CHAN) {
2988 u8 buf[12];
2989 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
2990 rsp->type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
2991 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
2992 memcpy(buf + 4, l2cap_fixed_chan, 8);
2993 l2cap_send_cmd(conn, cmd->ident,
2994 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02002995 } else {
2996 struct l2cap_info_rsp rsp;
2997 rsp.type = cpu_to_le16(type);
2998 rsp.result = cpu_to_le16(L2CAP_IR_NOTSUPP);
2999 l2cap_send_cmd(conn, cmd->ident,
3000 L2CAP_INFO_RSP, sizeof(rsp), &rsp);
3001 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003002
3003 return 0;
3004}
3005
3006static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3007{
3008 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
3009 u16 type, result;
3010
3011 type = __le16_to_cpu(rsp->type);
3012 result = __le16_to_cpu(rsp->result);
3013
3014 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
3015
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003016 del_timer(&conn->info_timer);
3017
Marcel Holtmann984947d2009-02-06 23:35:19 +01003018 if (type == L2CAP_IT_FEAT_MASK) {
Harvey Harrison83985312008-05-02 16:25:46 -07003019 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003020
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003021 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003022 struct l2cap_info_req req;
3023 req.type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3024
3025 conn->info_ident = l2cap_get_ident(conn);
3026
3027 l2cap_send_cmd(conn, conn->info_ident,
3028 L2CAP_INFO_REQ, sizeof(req), &req);
3029 } else {
3030 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
3031 conn->info_ident = 0;
3032
3033 l2cap_conn_start(conn);
3034 }
3035 } else if (type == L2CAP_IT_FIXED_CHAN) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01003036 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003037 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003038
3039 l2cap_conn_start(conn);
3040 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003041
Linus Torvalds1da177e2005-04-16 15:20:36 -07003042 return 0;
3043}
3044
3045static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
3046{
3047 u8 *data = skb->data;
3048 int len = skb->len;
3049 struct l2cap_cmd_hdr cmd;
3050 int err = 0;
3051
3052 l2cap_raw_recv(conn, skb);
3053
3054 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07003055 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003056 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
3057 data += L2CAP_CMD_HDR_SIZE;
3058 len -= L2CAP_CMD_HDR_SIZE;
3059
Al Viro88219a02007-07-29 00:17:25 -07003060 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003061
Al Viro88219a02007-07-29 00:17:25 -07003062 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 -07003063
Al Viro88219a02007-07-29 00:17:25 -07003064 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003065 BT_DBG("corrupted command");
3066 break;
3067 }
3068
3069 switch (cmd.code) {
3070 case L2CAP_COMMAND_REJ:
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003071 l2cap_command_rej(conn, &cmd, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003072 break;
3073
3074 case L2CAP_CONN_REQ:
3075 err = l2cap_connect_req(conn, &cmd, data);
3076 break;
3077
3078 case L2CAP_CONN_RSP:
3079 err = l2cap_connect_rsp(conn, &cmd, data);
3080 break;
3081
3082 case L2CAP_CONF_REQ:
Al Viro88219a02007-07-29 00:17:25 -07003083 err = l2cap_config_req(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003084 break;
3085
3086 case L2CAP_CONF_RSP:
3087 err = l2cap_config_rsp(conn, &cmd, data);
3088 break;
3089
3090 case L2CAP_DISCONN_REQ:
3091 err = l2cap_disconnect_req(conn, &cmd, data);
3092 break;
3093
3094 case L2CAP_DISCONN_RSP:
3095 err = l2cap_disconnect_rsp(conn, &cmd, data);
3096 break;
3097
3098 case L2CAP_ECHO_REQ:
Al Viro88219a02007-07-29 00:17:25 -07003099 l2cap_send_cmd(conn, cmd.ident, L2CAP_ECHO_RSP, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003100 break;
3101
3102 case L2CAP_ECHO_RSP:
3103 break;
3104
3105 case L2CAP_INFO_REQ:
3106 err = l2cap_information_req(conn, &cmd, data);
3107 break;
3108
3109 case L2CAP_INFO_RSP:
3110 err = l2cap_information_rsp(conn, &cmd, data);
3111 break;
3112
3113 default:
3114 BT_ERR("Unknown signaling command 0x%2.2x", cmd.code);
3115 err = -EINVAL;
3116 break;
3117 }
3118
3119 if (err) {
3120 struct l2cap_cmd_rej rej;
3121 BT_DBG("error %d", err);
3122
3123 /* FIXME: Map err to a valid reason */
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003124 rej.reason = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003125 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
3126 }
3127
Al Viro88219a02007-07-29 00:17:25 -07003128 data += cmd_len;
3129 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003130 }
3131
3132 kfree_skb(skb);
3133}
3134
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003135static int l2cap_check_fcs(struct l2cap_pinfo *pi, struct sk_buff *skb)
3136{
3137 u16 our_fcs, rcv_fcs;
3138 int hdr_size = L2CAP_HDR_SIZE + 2;
3139
3140 if (pi->fcs == L2CAP_FCS_CRC16) {
3141 skb_trim(skb, skb->len - 2);
3142 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
3143 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
3144
3145 if (our_fcs != rcv_fcs)
3146 return -EINVAL;
3147 }
3148 return 0;
3149}
3150
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003151static void l2cap_add_to_srej_queue(struct sock *sk, struct sk_buff *skb, u8 tx_seq, u8 sar)
3152{
3153 struct sk_buff *next_skb;
3154
3155 bt_cb(skb)->tx_seq = tx_seq;
3156 bt_cb(skb)->sar = sar;
3157
3158 next_skb = skb_peek(SREJ_QUEUE(sk));
3159 if (!next_skb) {
3160 __skb_queue_tail(SREJ_QUEUE(sk), skb);
3161 return;
3162 }
3163
3164 do {
3165 if (bt_cb(next_skb)->tx_seq > tx_seq) {
3166 __skb_queue_before(SREJ_QUEUE(sk), next_skb, skb);
3167 return;
3168 }
3169
3170 if (skb_queue_is_last(SREJ_QUEUE(sk), next_skb))
3171 break;
3172
3173 } while((next_skb = skb_queue_next(SREJ_QUEUE(sk), next_skb)));
3174
3175 __skb_queue_tail(SREJ_QUEUE(sk), skb);
3176}
3177
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003178static int l2cap_sar_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
3179{
3180 struct l2cap_pinfo *pi = l2cap_pi(sk);
3181 struct sk_buff *_skb;
3182 int err = -EINVAL;
3183
3184 switch (control & L2CAP_CTRL_SAR) {
3185 case L2CAP_SDU_UNSEGMENTED:
3186 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3187 kfree_skb(pi->sdu);
3188 break;
3189 }
3190
3191 err = sock_queue_rcv_skb(sk, skb);
3192 if (!err)
3193 return 0;
3194
3195 break;
3196
3197 case L2CAP_SDU_START:
3198 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
3199 kfree_skb(pi->sdu);
3200 break;
3201 }
3202
3203 pi->sdu_len = get_unaligned_le16(skb->data);
3204 skb_pull(skb, 2);
3205
3206 pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
3207 if (!pi->sdu) {
3208 err = -ENOMEM;
3209 break;
3210 }
3211
3212 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3213
3214 pi->conn_state |= L2CAP_CONN_SAR_SDU;
3215 pi->partial_sdu_len = skb->len;
3216 err = 0;
3217 break;
3218
3219 case L2CAP_SDU_CONTINUE:
3220 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3221 break;
3222
3223 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3224
3225 pi->partial_sdu_len += skb->len;
3226 if (pi->partial_sdu_len > pi->sdu_len)
3227 kfree_skb(pi->sdu);
3228 else
3229 err = 0;
3230
3231 break;
3232
3233 case L2CAP_SDU_END:
3234 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
3235 break;
3236
3237 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
3238
3239 pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
3240 pi->partial_sdu_len += skb->len;
3241
3242 if (pi->partial_sdu_len == pi->sdu_len) {
3243 _skb = skb_clone(pi->sdu, GFP_ATOMIC);
3244 err = sock_queue_rcv_skb(sk, _skb);
3245 if (err < 0)
3246 kfree_skb(_skb);
3247 }
3248 kfree_skb(pi->sdu);
3249 err = 0;
3250
3251 break;
3252 }
3253
3254 kfree_skb(skb);
3255 return err;
3256}
3257
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003258static void l2cap_check_srej_gap(struct sock *sk, u8 tx_seq)
3259{
3260 struct sk_buff *skb;
3261 u16 control = 0;
3262
3263 while((skb = skb_peek(SREJ_QUEUE(sk)))) {
3264 if (bt_cb(skb)->tx_seq != tx_seq)
3265 break;
3266
3267 skb = skb_dequeue(SREJ_QUEUE(sk));
3268 control |= bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
3269 l2cap_sar_reassembly_sdu(sk, skb, control);
3270 l2cap_pi(sk)->buffer_seq_srej =
3271 (l2cap_pi(sk)->buffer_seq_srej + 1) % 64;
3272 tx_seq++;
3273 }
3274}
3275
3276static void l2cap_resend_srejframe(struct sock *sk, u8 tx_seq)
3277{
3278 struct l2cap_pinfo *pi = l2cap_pi(sk);
3279 struct srej_list *l, *tmp;
3280 u16 control;
3281
3282 list_for_each_entry_safe(l,tmp, SREJ_LIST(sk), list) {
3283 if (l->tx_seq == tx_seq) {
3284 list_del(&l->list);
3285 kfree(l);
3286 return;
3287 }
3288 control = L2CAP_SUPER_SELECT_REJECT;
3289 control |= l->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3290 l2cap_send_sframe(pi, control);
3291 list_del(&l->list);
3292 list_add_tail(&l->list, SREJ_LIST(sk));
3293 }
3294}
3295
3296static void l2cap_send_srejframe(struct sock *sk, u8 tx_seq)
3297{
3298 struct l2cap_pinfo *pi = l2cap_pi(sk);
3299 struct srej_list *new;
3300 u16 control;
3301
3302 while (tx_seq != pi->expected_tx_seq) {
3303 control = L2CAP_SUPER_SELECT_REJECT;
3304 control |= pi->expected_tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
Gustavo F. Padovanef54fd92009-08-20 22:26:04 -03003305 if (pi->conn_state & L2CAP_CONN_SEND_PBIT) {
3306 control |= L2CAP_CTRL_POLL;
3307 pi->conn_state &= ~L2CAP_CONN_SEND_PBIT;
3308 }
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003309 l2cap_send_sframe(pi, control);
3310
3311 new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC);
3312 new->tx_seq = pi->expected_tx_seq++;
3313 list_add_tail(&new->list, SREJ_LIST(sk));
3314 }
3315 pi->expected_tx_seq++;
3316}
3317
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003318static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
3319{
3320 struct l2cap_pinfo *pi = l2cap_pi(sk);
3321 u8 tx_seq = __get_txseq(rx_control);
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003322 u8 req_seq = __get_reqseq(rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003323 u16 tx_control = 0;
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003324 u8 sar = rx_control >> L2CAP_CTRL_SAR_SHIFT;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003325 int err = 0;
3326
3327 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
3328
Gustavo F. Padovan9f121a52009-10-03 02:34:38 -03003329 pi->expected_ack_seq = req_seq;
3330 l2cap_drop_acked_frames(sk);
3331
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003332 if (tx_seq == pi->expected_tx_seq)
3333 goto expected;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003334
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003335 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3336 struct srej_list *first;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003337
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003338 first = list_first_entry(SREJ_LIST(sk),
3339 struct srej_list, list);
3340 if (tx_seq == first->tx_seq) {
3341 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3342 l2cap_check_srej_gap(sk, tx_seq);
3343
3344 list_del(&first->list);
3345 kfree(first);
3346
3347 if (list_empty(SREJ_LIST(sk))) {
3348 pi->buffer_seq = pi->buffer_seq_srej;
3349 pi->conn_state &= ~L2CAP_CONN_SREJ_SENT;
3350 }
3351 } else {
3352 struct srej_list *l;
3353 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3354
3355 list_for_each_entry(l, SREJ_LIST(sk), list) {
3356 if (l->tx_seq == tx_seq) {
3357 l2cap_resend_srejframe(sk, tx_seq);
3358 return 0;
3359 }
3360 }
3361 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003362 }
3363 } else {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003364 pi->conn_state |= L2CAP_CONN_SREJ_SENT;
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003365
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003366 INIT_LIST_HEAD(SREJ_LIST(sk));
3367 pi->buffer_seq_srej = pi->buffer_seq;
3368
3369 __skb_queue_head_init(SREJ_QUEUE(sk));
3370 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3371
Gustavo F. Padovanef54fd92009-08-20 22:26:04 -03003372 pi->conn_state |= L2CAP_CONN_SEND_PBIT;
3373
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003374 l2cap_send_srejframe(sk, tx_seq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003375 }
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003376 return 0;
3377
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003378expected:
3379 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
3380
3381 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
3382 l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
3383 return 0;
3384 }
3385
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03003386 if (rx_control & L2CAP_CTRL_FINAL) {
3387 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3388 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
3389 else {
3390 sk->sk_send_head = TX_QUEUE(sk)->next;
3391 pi->next_tx_seq = pi->expected_ack_seq;
3392 l2cap_ertm_send(sk);
3393 }
3394 }
3395
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003396 pi->buffer_seq = (pi->buffer_seq + 1) % 64;
3397
3398 err = l2cap_sar_reassembly_sdu(sk, skb, rx_control);
3399 if (err < 0)
3400 return err;
3401
3402 pi->num_to_ack = (pi->num_to_ack + 1) % L2CAP_DEFAULT_NUM_TO_ACK;
3403 if (pi->num_to_ack == L2CAP_DEFAULT_NUM_TO_ACK - 1) {
3404 tx_control |= L2CAP_SUPER_RCV_READY;
3405 tx_control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3406 l2cap_send_sframe(pi, tx_control);
3407 }
3408 return 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003409}
3410
3411static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
3412{
3413 struct l2cap_pinfo *pi = l2cap_pi(sk);
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003414 u8 tx_seq = __get_reqseq(rx_control);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003415
3416 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
3417
3418 switch (rx_control & L2CAP_CTRL_SUPERVISE) {
3419 case L2CAP_SUPER_RCV_READY:
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03003420 if (rx_control & L2CAP_CTRL_POLL) {
3421 u16 control = L2CAP_CTRL_FINAL;
Gustavo F. Padovanca42a612009-08-26 04:04:01 -03003422 control |= L2CAP_SUPER_RCV_READY |
3423 (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03003424 l2cap_send_sframe(l2cap_pi(sk), control);
Gustavo F. Padovan2246b2f2009-08-26 04:04:02 -03003425 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3426
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03003427 } else if (rx_control & L2CAP_CTRL_FINAL) {
Gustavo F. Padovan2246b2f2009-08-26 04:04:02 -03003428 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
Gustavo F. Padovanca42a612009-08-26 04:04:01 -03003429 pi->expected_ack_seq = tx_seq;
3430 l2cap_drop_acked_frames(sk);
3431
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03003432 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3433 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
3434 else {
3435 sk->sk_send_head = TX_QUEUE(sk)->next;
3436 pi->next_tx_seq = pi->expected_ack_seq;
3437 l2cap_ertm_send(sk);
3438 }
3439
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03003440 if (!(pi->conn_state & L2CAP_CONN_WAIT_F))
3441 break;
3442
3443 pi->conn_state &= ~L2CAP_CONN_WAIT_F;
3444 del_timer(&pi->monitor_timer);
3445
3446 if (pi->unacked_frames > 0)
3447 __mod_retrans_timer();
3448 } else {
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003449 pi->expected_ack_seq = tx_seq;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03003450 l2cap_drop_acked_frames(sk);
Gustavo F. Padovan2246b2f2009-08-26 04:04:02 -03003451
Joe Perchesf64f9e72009-11-29 16:55:45 -08003452 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
3453 (pi->unacked_frames > 0))
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03003454 __mod_retrans_timer();
Gustavo F. Padovan2246b2f2009-08-26 04:04:02 -03003455
Gustavo F. Padovan2246b2f2009-08-26 04:04:02 -03003456 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
Gustavo F. Padovan186de9a2009-12-15 15:56:34 -02003457 l2cap_ertm_send(sk);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03003458 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003459 break;
3460
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003461 case L2CAP_SUPER_REJECT:
Gustavo F. Padovan2246b2f2009-08-26 04:04:02 -03003462 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3463
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003464 pi->expected_ack_seq = __get_reqseq(rx_control);
3465 l2cap_drop_acked_frames(sk);
3466
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03003467 if (rx_control & L2CAP_CTRL_FINAL) {
3468 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3469 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
3470 else {
3471 sk->sk_send_head = TX_QUEUE(sk)->next;
3472 pi->next_tx_seq = pi->expected_ack_seq;
3473 l2cap_ertm_send(sk);
3474 }
3475 } else {
3476 sk->sk_send_head = TX_QUEUE(sk)->next;
3477 pi->next_tx_seq = pi->expected_ack_seq;
3478 l2cap_ertm_send(sk);
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003479
Gustavo F. Padovan4ec10d92009-10-03 02:34:39 -03003480 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
3481 pi->srej_save_reqseq = tx_seq;
3482 pi->conn_state |= L2CAP_CONN_REJ_ACT;
3483 }
3484 }
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003485
3486 break;
3487
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003488 case L2CAP_SUPER_SELECT_REJECT:
Gustavo F. Padovan2246b2f2009-08-26 04:04:02 -03003489 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3490
Gustavo F. Padovanef54fd92009-08-20 22:26:04 -03003491 if (rx_control & L2CAP_CTRL_POLL) {
Gustavo F. Padovanef54fd92009-08-20 22:26:04 -03003492 pi->expected_ack_seq = tx_seq;
3493 l2cap_drop_acked_frames(sk);
Gustavo F. Padovan186ee8c2009-12-15 20:13:27 -02003494 l2cap_retransmit_frame(sk, tx_seq);
Gustavo F. Padovanef54fd92009-08-20 22:26:04 -03003495 l2cap_ertm_send(sk);
3496 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
3497 pi->srej_save_reqseq = tx_seq;
3498 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
3499 }
3500 } else if (rx_control & L2CAP_CTRL_FINAL) {
3501 if ((pi->conn_state & L2CAP_CONN_SREJ_ACT) &&
3502 pi->srej_save_reqseq == tx_seq)
Gustavo F. Padovan889a3ca2009-10-03 02:34:37 -03003503 pi->conn_state &= ~L2CAP_CONN_SREJ_ACT;
Gustavo F. Padovanef54fd92009-08-20 22:26:04 -03003504 else
3505 l2cap_retransmit_frame(sk, tx_seq);
3506 }
3507 else {
3508 l2cap_retransmit_frame(sk, tx_seq);
3509 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
3510 pi->srej_save_reqseq = tx_seq;
3511 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
3512 }
3513 }
Gustavo F. Padovan8f171542009-08-20 22:26:03 -03003514 break;
3515
3516 case L2CAP_SUPER_RCV_NOT_READY:
Gustavo F. Padovan2246b2f2009-08-26 04:04:02 -03003517 pi->conn_state |= L2CAP_CONN_REMOTE_BUSY;
3518 pi->expected_ack_seq = tx_seq;
3519 l2cap_drop_acked_frames(sk);
3520
3521 del_timer(&l2cap_pi(sk)->retrans_timer);
3522 if (rx_control & L2CAP_CTRL_POLL) {
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03003523 u16 control = L2CAP_CTRL_FINAL;
3524 l2cap_send_rr_or_rnr(l2cap_pi(sk), control);
Gustavo F. Padovan2246b2f2009-08-26 04:04:02 -03003525 }
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003526 break;
3527 }
3528
Gustavo F. Padovanfaaebd12010-05-01 16:15:35 -03003529 kfree_skb(skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003530 return 0;
3531}
3532
Linus Torvalds1da177e2005-04-16 15:20:36 -07003533static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk_buff *skb)
3534{
3535 struct sock *sk;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003536 struct l2cap_pinfo *pi;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003537 u16 control, len;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003538 u8 tx_seq;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003539
3540 sk = l2cap_get_chan_by_scid(&conn->chan_list, cid);
3541 if (!sk) {
3542 BT_DBG("unknown cid 0x%4.4x", cid);
3543 goto drop;
3544 }
3545
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003546 pi = l2cap_pi(sk);
3547
Linus Torvalds1da177e2005-04-16 15:20:36 -07003548 BT_DBG("sk %p, len %d", sk, skb->len);
3549
3550 if (sk->sk_state != BT_CONNECTED)
3551 goto drop;
3552
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003553 switch (pi->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003554 case L2CAP_MODE_BASIC:
3555 /* If socket recv buffers overflows we drop data here
3556 * which is *bad* because L2CAP has to be reliable.
3557 * But we don't have any other choice. L2CAP doesn't
3558 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003559
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003560 if (pi->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003561 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003562
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003563 if (!sock_queue_rcv_skb(sk, skb))
3564 goto done;
3565 break;
3566
3567 case L2CAP_MODE_ERTM:
3568 control = get_unaligned_le16(skb->data);
3569 skb_pull(skb, 2);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003570 len = skb->len;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003571
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003572 if (__is_sar_start(control))
3573 len -= 2;
3574
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003575 if (pi->fcs == L2CAP_FCS_CRC16)
3576 len -= 2;
3577
Gustavo F. Padovan30afb5b2009-08-20 22:25:59 -03003578 /*
3579 * We can just drop the corrupted I-frame here.
3580 * Receiver will miss it and start proper recovery
3581 * procedures and ask retransmission.
3582 */
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003583 if (len > L2CAP_DEFAULT_MAX_PDU_SIZE)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003584 goto drop;
3585
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003586 if (l2cap_check_fcs(pi, skb))
3587 goto drop;
3588
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003589 if (__is_iframe(control))
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02003590 l2cap_data_channel_iframe(sk, control, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003591 else
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02003592 l2cap_data_channel_sframe(sk, control, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003593
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02003594 goto done;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003595
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003596 case L2CAP_MODE_STREAMING:
3597 control = get_unaligned_le16(skb->data);
3598 skb_pull(skb, 2);
3599 len = skb->len;
3600
3601 if (__is_sar_start(control))
3602 len -= 2;
3603
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003604 if (pi->fcs == L2CAP_FCS_CRC16)
3605 len -= 2;
3606
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003607 if (len > L2CAP_DEFAULT_MAX_PDU_SIZE || __is_sframe(control))
3608 goto drop;
3609
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003610 if (l2cap_check_fcs(pi, skb))
3611 goto drop;
3612
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003613 tx_seq = __get_txseq(control);
3614
3615 if (pi->expected_tx_seq == tx_seq)
3616 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
3617 else
Gustavo F. Padovan7dffe422010-05-01 16:15:36 -03003618 pi->expected_tx_seq = (tx_seq + 1) % 64;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003619
Andrei Emeltchenkofcafde22009-12-22 15:58:08 +02003620 l2cap_sar_reassembly_sdu(sk, skb, control);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03003621
3622 goto done;
3623
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003624 default:
3625 BT_DBG("sk %p: bad mode 0x%2.2x", sk, l2cap_pi(sk)->mode);
3626 break;
3627 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003628
3629drop:
3630 kfree_skb(skb);
3631
3632done:
Marcel Holtmann01394182006-07-03 10:02:46 +02003633 if (sk)
3634 bh_unlock_sock(sk);
3635
Linus Torvalds1da177e2005-04-16 15:20:36 -07003636 return 0;
3637}
3638
Al Viro8e036fc2007-07-29 00:16:36 -07003639static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003640{
3641 struct sock *sk;
3642
3643 sk = l2cap_get_sock_by_psm(0, psm, conn->src);
3644 if (!sk)
3645 goto drop;
3646
3647 BT_DBG("sk %p, len %d", sk, skb->len);
3648
3649 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_CONNECTED)
3650 goto drop;
3651
3652 if (l2cap_pi(sk)->imtu < skb->len)
3653 goto drop;
3654
3655 if (!sock_queue_rcv_skb(sk, skb))
3656 goto done;
3657
3658drop:
3659 kfree_skb(skb);
3660
3661done:
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003662 if (sk)
3663 bh_unlock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003664 return 0;
3665}
3666
3667static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
3668{
3669 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07003670 u16 cid, len;
3671 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003672
3673 skb_pull(skb, L2CAP_HDR_SIZE);
3674 cid = __le16_to_cpu(lh->cid);
3675 len = __le16_to_cpu(lh->len);
3676
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03003677 if (len != skb->len) {
3678 kfree_skb(skb);
3679 return;
3680 }
3681
Linus Torvalds1da177e2005-04-16 15:20:36 -07003682 BT_DBG("len %d, cid 0x%4.4x", len, cid);
3683
3684 switch (cid) {
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03003685 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07003686 l2cap_sig_channel(conn, skb);
3687 break;
3688
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03003689 case L2CAP_CID_CONN_LESS:
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03003690 psm = get_unaligned_le16(skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003691 skb_pull(skb, 2);
3692 l2cap_conless_channel(conn, psm, skb);
3693 break;
3694
3695 default:
3696 l2cap_data_channel(conn, cid, skb);
3697 break;
3698 }
3699}
3700
3701/* ---- L2CAP interface with lower layer (HCI) ---- */
3702
3703static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
3704{
3705 int exact = 0, lm1 = 0, lm2 = 0;
3706 register struct sock *sk;
3707 struct hlist_node *node;
3708
3709 if (type != ACL_LINK)
3710 return 0;
3711
3712 BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
3713
3714 /* Find listening sockets and check their link_mode */
3715 read_lock(&l2cap_sk_list.lock);
3716 sk_for_each(sk, node, &l2cap_sk_list.head) {
3717 if (sk->sk_state != BT_LISTEN)
3718 continue;
3719
3720 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01003721 lm1 |= HCI_LM_ACCEPT;
3722 if (l2cap_pi(sk)->role_switch)
3723 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003724 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01003725 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
3726 lm2 |= HCI_LM_ACCEPT;
3727 if (l2cap_pi(sk)->role_switch)
3728 lm2 |= HCI_LM_MASTER;
3729 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003730 }
3731 read_unlock(&l2cap_sk_list.lock);
3732
3733 return exact ? lm1 : lm2;
3734}
3735
3736static int l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
3737{
Marcel Holtmann01394182006-07-03 10:02:46 +02003738 struct l2cap_conn *conn;
3739
Linus Torvalds1da177e2005-04-16 15:20:36 -07003740 BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
3741
3742 if (hcon->type != ACL_LINK)
3743 return 0;
3744
3745 if (!status) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003746 conn = l2cap_conn_add(hcon, status);
3747 if (conn)
3748 l2cap_conn_ready(conn);
Marcel Holtmann01394182006-07-03 10:02:46 +02003749 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -07003750 l2cap_conn_del(hcon, bt_err(status));
3751
3752 return 0;
3753}
3754
Marcel Holtmann2950f212009-02-12 14:02:50 +01003755static int l2cap_disconn_ind(struct hci_conn *hcon)
3756{
3757 struct l2cap_conn *conn = hcon->l2cap_data;
3758
3759 BT_DBG("hcon %p", hcon);
3760
3761 if (hcon->type != ACL_LINK || !conn)
3762 return 0x13;
3763
3764 return conn->disc_reason;
3765}
3766
3767static int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003768{
3769 BT_DBG("hcon %p reason %d", hcon, reason);
3770
3771 if (hcon->type != ACL_LINK)
3772 return 0;
3773
3774 l2cap_conn_del(hcon, bt_err(reason));
Marcel Holtmann01394182006-07-03 10:02:46 +02003775
Linus Torvalds1da177e2005-04-16 15:20:36 -07003776 return 0;
3777}
3778
Marcel Holtmannf62e4322009-01-15 21:58:44 +01003779static inline void l2cap_check_encryption(struct sock *sk, u8 encrypt)
3780{
Marcel Holtmann255c7602009-02-04 21:07:19 +01003781 if (sk->sk_type != SOCK_SEQPACKET)
3782 return;
3783
Marcel Holtmannf62e4322009-01-15 21:58:44 +01003784 if (encrypt == 0x00) {
3785 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM) {
3786 l2cap_sock_clear_timer(sk);
3787 l2cap_sock_set_timer(sk, HZ * 5);
3788 } else if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
3789 __l2cap_sock_close(sk, ECONNREFUSED);
3790 } else {
3791 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM)
3792 l2cap_sock_clear_timer(sk);
3793 }
3794}
3795
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01003796static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003797{
3798 struct l2cap_chan_list *l;
Marcel Holtmann40be4922008-07-14 20:13:50 +02003799 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003800 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003801
Marcel Holtmann01394182006-07-03 10:02:46 +02003802 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003803 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02003804
Linus Torvalds1da177e2005-04-16 15:20:36 -07003805 l = &conn->chan_list;
3806
3807 BT_DBG("conn %p", conn);
3808
3809 read_lock(&l->lock);
3810
3811 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
3812 bh_lock_sock(sk);
3813
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003814 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND) {
3815 bh_unlock_sock(sk);
3816 continue;
3817 }
3818
Marcel Holtmannf62e4322009-01-15 21:58:44 +01003819 if (!status && (sk->sk_state == BT_CONNECTED ||
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01003820 sk->sk_state == BT_CONFIG)) {
Marcel Holtmannf62e4322009-01-15 21:58:44 +01003821 l2cap_check_encryption(sk, encrypt);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02003822 bh_unlock_sock(sk);
3823 continue;
3824 }
3825
Marcel Holtmannb1235d72008-07-14 20:13:54 +02003826 if (sk->sk_state == BT_CONNECT) {
3827 if (!status) {
3828 struct l2cap_conn_req req;
3829 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
3830 req.psm = l2cap_pi(sk)->psm;
3831
3832 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
3833
3834 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
3835 L2CAP_CONN_REQ, sizeof(req), &req);
3836 } else {
3837 l2cap_sock_clear_timer(sk);
3838 l2cap_sock_set_timer(sk, HZ / 10);
3839 }
3840 } else if (sk->sk_state == BT_CONNECT2) {
3841 struct l2cap_conn_rsp rsp;
3842 __u16 result;
3843
3844 if (!status) {
3845 sk->sk_state = BT_CONFIG;
3846 result = L2CAP_CR_SUCCESS;
3847 } else {
3848 sk->sk_state = BT_DISCONN;
3849 l2cap_sock_set_timer(sk, HZ / 10);
3850 result = L2CAP_CR_SEC_BLOCK;
3851 }
3852
3853 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
3854 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
3855 rsp.result = cpu_to_le16(result);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003856 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02003857 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
3858 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003859 }
3860
Linus Torvalds1da177e2005-04-16 15:20:36 -07003861 bh_unlock_sock(sk);
3862 }
3863
3864 read_unlock(&l->lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02003865
Linus Torvalds1da177e2005-04-16 15:20:36 -07003866 return 0;
3867}
3868
3869static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
3870{
3871 struct l2cap_conn *conn = hcon->l2cap_data;
3872
3873 if (!conn && !(conn = l2cap_conn_add(hcon, 0)))
3874 goto drop;
3875
3876 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
3877
3878 if (flags & ACL_START) {
3879 struct l2cap_hdr *hdr;
3880 int len;
3881
3882 if (conn->rx_len) {
3883 BT_ERR("Unexpected start frame (len %d)", skb->len);
3884 kfree_skb(conn->rx_skb);
3885 conn->rx_skb = NULL;
3886 conn->rx_len = 0;
3887 l2cap_conn_unreliable(conn, ECOMM);
3888 }
3889
3890 if (skb->len < 2) {
3891 BT_ERR("Frame is too short (len %d)", skb->len);
3892 l2cap_conn_unreliable(conn, ECOMM);
3893 goto drop;
3894 }
3895
3896 hdr = (struct l2cap_hdr *) skb->data;
3897 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
3898
3899 if (len == skb->len) {
3900 /* Complete frame received */
3901 l2cap_recv_frame(conn, skb);
3902 return 0;
3903 }
3904
3905 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
3906
3907 if (skb->len > len) {
3908 BT_ERR("Frame is too long (len %d, expected len %d)",
3909 skb->len, len);
3910 l2cap_conn_unreliable(conn, ECOMM);
3911 goto drop;
3912 }
3913
3914 /* Allocate skb for the complete frame (with header) */
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003915 conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC);
3916 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003917 goto drop;
3918
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03003919 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003920 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003921 conn->rx_len = len - skb->len;
3922 } else {
3923 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
3924
3925 if (!conn->rx_len) {
3926 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
3927 l2cap_conn_unreliable(conn, ECOMM);
3928 goto drop;
3929 }
3930
3931 if (skb->len > conn->rx_len) {
3932 BT_ERR("Fragment is too long (len %d, expected %d)",
3933 skb->len, conn->rx_len);
3934 kfree_skb(conn->rx_skb);
3935 conn->rx_skb = NULL;
3936 conn->rx_len = 0;
3937 l2cap_conn_unreliable(conn, ECOMM);
3938 goto drop;
3939 }
3940
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03003941 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003942 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003943 conn->rx_len -= skb->len;
3944
3945 if (!conn->rx_len) {
3946 /* Complete frame received */
3947 l2cap_recv_frame(conn, conn->rx_skb);
3948 conn->rx_skb = NULL;
3949 }
3950 }
3951
3952drop:
3953 kfree_skb(skb);
3954 return 0;
3955}
3956
Marcel Holtmannaef7d972010-03-21 05:27:45 +01003957static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003958{
3959 struct sock *sk;
3960 struct hlist_node *node;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003961
3962 read_lock_bh(&l2cap_sk_list.lock);
3963
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08003964 sk_for_each(sk, node, &l2cap_sk_list.head) {
3965 struct l2cap_pinfo *pi = l2cap_pi(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003966
Marcel Holtmannaef7d972010-03-21 05:27:45 +01003967 seq_printf(f, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d\n",
3968 batostr(&bt_sk(sk)->src),
3969 batostr(&bt_sk(sk)->dst),
3970 sk->sk_state, __le16_to_cpu(pi->psm),
3971 pi->scid, pi->dcid,
3972 pi->imtu, pi->omtu, pi->sec_level);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08003973 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003974
Linus Torvalds1da177e2005-04-16 15:20:36 -07003975 read_unlock_bh(&l2cap_sk_list.lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08003976
Marcel Holtmannaef7d972010-03-21 05:27:45 +01003977 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003978}
3979
Marcel Holtmannaef7d972010-03-21 05:27:45 +01003980static int l2cap_debugfs_open(struct inode *inode, struct file *file)
3981{
3982 return single_open(file, l2cap_debugfs_show, inode->i_private);
3983}
3984
3985static const struct file_operations l2cap_debugfs_fops = {
3986 .open = l2cap_debugfs_open,
3987 .read = seq_read,
3988 .llseek = seq_lseek,
3989 .release = single_release,
3990};
3991
3992static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003993
Eric Dumazet90ddc4f2005-12-22 12:49:22 -08003994static const struct proto_ops l2cap_sock_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003995 .family = PF_BLUETOOTH,
3996 .owner = THIS_MODULE,
3997 .release = l2cap_sock_release,
3998 .bind = l2cap_sock_bind,
3999 .connect = l2cap_sock_connect,
4000 .listen = l2cap_sock_listen,
4001 .accept = l2cap_sock_accept,
4002 .getname = l2cap_sock_getname,
4003 .sendmsg = l2cap_sock_sendmsg,
Marcel Holtmannf66dc812009-01-15 21:57:00 +01004004 .recvmsg = l2cap_sock_recvmsg,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004005 .poll = bt_sock_poll,
Marcel Holtmann3241ad82008-07-14 20:13:50 +02004006 .ioctl = bt_sock_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004007 .mmap = sock_no_mmap,
4008 .socketpair = sock_no_socketpair,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004009 .shutdown = l2cap_sock_shutdown,
4010 .setsockopt = l2cap_sock_setsockopt,
4011 .getsockopt = l2cap_sock_getsockopt
4012};
4013
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +00004014static const struct net_proto_family l2cap_sock_family_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004015 .family = PF_BLUETOOTH,
4016 .owner = THIS_MODULE,
4017 .create = l2cap_sock_create,
4018};
4019
4020static struct hci_proto l2cap_hci_proto = {
4021 .name = "L2CAP",
4022 .id = HCI_PROTO_L2CAP,
4023 .connect_ind = l2cap_connect_ind,
4024 .connect_cfm = l2cap_connect_cfm,
4025 .disconn_ind = l2cap_disconn_ind,
Marcel Holtmann2950f212009-02-12 14:02:50 +01004026 .disconn_cfm = l2cap_disconn_cfm,
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01004027 .security_cfm = l2cap_security_cfm,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004028 .recv_acldata = l2cap_recv_acldata
4029};
4030
4031static int __init l2cap_init(void)
4032{
4033 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08004034
Linus Torvalds1da177e2005-04-16 15:20:36 -07004035 err = proto_register(&l2cap_proto, 0);
4036 if (err < 0)
4037 return err;
4038
4039 err = bt_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops);
4040 if (err < 0) {
4041 BT_ERR("L2CAP socket registration failed");
4042 goto error;
4043 }
4044
4045 err = hci_register_proto(&l2cap_hci_proto);
4046 if (err < 0) {
4047 BT_ERR("L2CAP protocol registration failed");
4048 bt_sock_unregister(BTPROTO_L2CAP);
4049 goto error;
4050 }
4051
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004052 if (bt_debugfs) {
4053 l2cap_debugfs = debugfs_create_file("l2cap", 0444,
4054 bt_debugfs, NULL, &l2cap_debugfs_fops);
4055 if (!l2cap_debugfs)
4056 BT_ERR("Failed to create L2CAP debug file");
4057 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004058
4059 BT_INFO("L2CAP ver %s", VERSION);
4060 BT_INFO("L2CAP socket layer initialized");
4061
4062 return 0;
4063
4064error:
4065 proto_unregister(&l2cap_proto);
4066 return err;
4067}
4068
4069static void __exit l2cap_exit(void)
4070{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01004071 debugfs_remove(l2cap_debugfs);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004072
4073 if (bt_sock_unregister(BTPROTO_L2CAP) < 0)
4074 BT_ERR("L2CAP socket unregistration failed");
4075
4076 if (hci_unregister_proto(&l2cap_hci_proto) < 0)
4077 BT_ERR("L2CAP protocol unregistration failed");
4078
4079 proto_unregister(&l2cap_proto);
4080}
4081
4082void l2cap_load(void)
4083{
4084 /* Dummy function to trigger automatic L2CAP module loading by
4085 * other modules that use L2CAP sockets but don't use any other
4086 * symbols from it. */
4087 return;
4088}
4089EXPORT_SYMBOL(l2cap_load);
4090
4091module_init(l2cap_init);
4092module_exit(l2cap_exit);
4093
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07004094module_param(enable_ertm, bool, 0644);
4095MODULE_PARM_DESC(enable_ertm, "Enable enhanced retransmission mode");
4096
Marcel Holtmann5fbcd3d2009-10-05 11:35:43 +02004097module_param(max_transmit, uint, 0644);
4098MODULE_PARM_DESC(max_transmit, "Max transmit value (default = 3)");
4099
Marcel Holtmann63fbd242008-08-18 13:23:53 +02004100MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004101MODULE_DESCRIPTION("Bluetooth L2CAP ver " VERSION);
4102MODULE_VERSION(VERSION);
4103MODULE_LICENSE("GPL");
4104MODULE_ALIAS("bt-proto-0");