blob: af0fbf9ebfeb2145f0192ff8475b5cfe7e505a64 [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>
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -030043#include <linux/uaccess.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070044#include <net/sock.h>
45
46#include <asm/system.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070047#include <asm/unaligned.h>
48
49#include <net/bluetooth/bluetooth.h>
50#include <net/bluetooth/hci_core.h>
51#include <net/bluetooth/l2cap.h>
52
Marcel Holtmann44dd46d2009-05-02 19:09:01 -070053#define VERSION "2.14"
54
55static int enable_ertm = 0;
Marcel Holtmannf0709e02007-10-20 13:38:51 +020056
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -070057static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN;
Marcel Holtmanne1027a72009-02-09 09:18:02 +010058static u8 l2cap_fixed_chan[8] = { 0x02, };
Linus Torvalds1da177e2005-04-16 15:20:36 -070059
Eric Dumazet90ddc4f2005-12-22 12:49:22 -080060static const struct proto_ops l2cap_sock_ops;
Linus Torvalds1da177e2005-04-16 15:20:36 -070061
62static struct bt_sock_list l2cap_sk_list = {
Robert P. J. Dayd5fb2962008-03-28 16:17:38 -070063 .lock = __RW_LOCK_UNLOCKED(l2cap_sk_list.lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -070064};
65
Linus Torvalds1da177e2005-04-16 15:20:36 -070066static void __l2cap_sock_close(struct sock *sk, int reason);
67static void l2cap_sock_close(struct sock *sk);
68static void l2cap_sock_kill(struct sock *sk);
69
70static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
71 u8 code, u8 ident, u16 dlen, void *data);
72
73/* ---- L2CAP timers ---- */
74static void l2cap_sock_timeout(unsigned long arg)
75{
76 struct sock *sk = (struct sock *) arg;
Marcel Holtmannb1235d72008-07-14 20:13:54 +020077 int reason;
Linus Torvalds1da177e2005-04-16 15:20:36 -070078
79 BT_DBG("sock %p state %d", sk, sk->sk_state);
80
81 bh_lock_sock(sk);
Marcel Holtmannb1235d72008-07-14 20:13:54 +020082
Marcel Holtmannf62e4322009-01-15 21:58:44 +010083 if (sk->sk_state == BT_CONNECTED || sk->sk_state == BT_CONFIG)
84 reason = ECONNREFUSED;
85 else if (sk->sk_state == BT_CONNECT &&
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +010086 l2cap_pi(sk)->sec_level != BT_SECURITY_SDP)
Marcel Holtmannb1235d72008-07-14 20:13:54 +020087 reason = ECONNREFUSED;
88 else
89 reason = ETIMEDOUT;
90
91 __l2cap_sock_close(sk, reason);
92
Linus Torvalds1da177e2005-04-16 15:20:36 -070093 bh_unlock_sock(sk);
94
95 l2cap_sock_kill(sk);
96 sock_put(sk);
97}
98
99static void l2cap_sock_set_timer(struct sock *sk, long timeout)
100{
101 BT_DBG("sk %p state %d timeout %ld", sk, sk->sk_state, timeout);
102 sk_reset_timer(sk, &sk->sk_timer, jiffies + timeout);
103}
104
105static void l2cap_sock_clear_timer(struct sock *sk)
106{
107 BT_DBG("sock %p state %d", sk, sk->sk_state);
108 sk_stop_timer(sk, &sk->sk_timer);
109}
110
Marcel Holtmann01394182006-07-03 10:02:46 +0200111/* ---- L2CAP channels ---- */
112static struct sock *__l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, u16 cid)
113{
114 struct sock *s;
115 for (s = l->head; s; s = l2cap_pi(s)->next_c) {
116 if (l2cap_pi(s)->dcid == cid)
117 break;
118 }
119 return s;
120}
121
122static struct sock *__l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid)
123{
124 struct sock *s;
125 for (s = l->head; s; s = l2cap_pi(s)->next_c) {
126 if (l2cap_pi(s)->scid == cid)
127 break;
128 }
129 return s;
130}
131
132/* Find channel with given SCID.
133 * Returns locked socket */
134static inline struct sock *l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid)
135{
136 struct sock *s;
137 read_lock(&l->lock);
138 s = __l2cap_get_chan_by_scid(l, cid);
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -0300139 if (s)
140 bh_lock_sock(s);
Marcel Holtmann01394182006-07-03 10:02:46 +0200141 read_unlock(&l->lock);
142 return s;
143}
144
145static struct sock *__l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 ident)
146{
147 struct sock *s;
148 for (s = l->head; s; s = l2cap_pi(s)->next_c) {
149 if (l2cap_pi(s)->ident == ident)
150 break;
151 }
152 return s;
153}
154
155static inline struct sock *l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 ident)
156{
157 struct sock *s;
158 read_lock(&l->lock);
159 s = __l2cap_get_chan_by_ident(l, ident);
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -0300160 if (s)
161 bh_lock_sock(s);
Marcel Holtmann01394182006-07-03 10:02:46 +0200162 read_unlock(&l->lock);
163 return s;
164}
165
166static u16 l2cap_alloc_cid(struct l2cap_chan_list *l)
167{
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300168 u16 cid = L2CAP_CID_DYN_START;
Marcel Holtmann01394182006-07-03 10:02:46 +0200169
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300170 for (; cid < L2CAP_CID_DYN_END; cid++) {
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -0300171 if (!__l2cap_get_chan_by_scid(l, cid))
Marcel Holtmann01394182006-07-03 10:02:46 +0200172 return cid;
173 }
174
175 return 0;
176}
177
178static inline void __l2cap_chan_link(struct l2cap_chan_list *l, struct sock *sk)
179{
180 sock_hold(sk);
181
182 if (l->head)
183 l2cap_pi(l->head)->prev_c = sk;
184
185 l2cap_pi(sk)->next_c = l->head;
186 l2cap_pi(sk)->prev_c = NULL;
187 l->head = sk;
188}
189
190static inline void l2cap_chan_unlink(struct l2cap_chan_list *l, struct sock *sk)
191{
192 struct sock *next = l2cap_pi(sk)->next_c, *prev = l2cap_pi(sk)->prev_c;
193
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200194 write_lock_bh(&l->lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200195 if (sk == l->head)
196 l->head = next;
197
198 if (next)
199 l2cap_pi(next)->prev_c = prev;
200 if (prev)
201 l2cap_pi(prev)->next_c = next;
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200202 write_unlock_bh(&l->lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200203
204 __sock_put(sk);
205}
206
207static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
208{
209 struct l2cap_chan_list *l = &conn->chan_list;
210
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -0300211 BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
212 l2cap_pi(sk)->psm, l2cap_pi(sk)->dcid);
Marcel Holtmann01394182006-07-03 10:02:46 +0200213
Marcel Holtmann2950f212009-02-12 14:02:50 +0100214 conn->disc_reason = 0x13;
215
Marcel Holtmann01394182006-07-03 10:02:46 +0200216 l2cap_pi(sk)->conn = conn;
217
218 if (sk->sk_type == SOCK_SEQPACKET) {
219 /* Alloc CID for connection-oriented socket */
220 l2cap_pi(sk)->scid = l2cap_alloc_cid(l);
221 } else if (sk->sk_type == SOCK_DGRAM) {
222 /* Connectionless socket */
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300223 l2cap_pi(sk)->scid = L2CAP_CID_CONN_LESS;
224 l2cap_pi(sk)->dcid = L2CAP_CID_CONN_LESS;
Marcel Holtmann01394182006-07-03 10:02:46 +0200225 l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
226 } else {
227 /* Raw socket can send/recv signalling messages only */
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300228 l2cap_pi(sk)->scid = L2CAP_CID_SIGNALING;
229 l2cap_pi(sk)->dcid = L2CAP_CID_SIGNALING;
Marcel Holtmann01394182006-07-03 10:02:46 +0200230 l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
231 }
232
233 __l2cap_chan_link(l, sk);
234
235 if (parent)
236 bt_accept_enqueue(parent, sk);
237}
238
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900239/* Delete channel.
Marcel Holtmann01394182006-07-03 10:02:46 +0200240 * Must be called on the locked socket. */
241static void l2cap_chan_del(struct sock *sk, int err)
242{
243 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
244 struct sock *parent = bt_sk(sk)->parent;
245
246 l2cap_sock_clear_timer(sk);
247
248 BT_DBG("sk %p, conn %p, err %d", sk, conn, err);
249
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900250 if (conn) {
Marcel Holtmann01394182006-07-03 10:02:46 +0200251 /* Unlink from channel list */
252 l2cap_chan_unlink(&conn->chan_list, sk);
253 l2cap_pi(sk)->conn = NULL;
254 hci_conn_put(conn->hcon);
255 }
256
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200257 sk->sk_state = BT_CLOSED;
Marcel Holtmann01394182006-07-03 10:02:46 +0200258 sock_set_flag(sk, SOCK_ZAPPED);
259
260 if (err)
261 sk->sk_err = err;
262
263 if (parent) {
264 bt_accept_unlink(sk);
265 parent->sk_data_ready(parent, 0);
266 } else
267 sk->sk_state_change(sk);
268}
269
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200270/* Service level security */
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100271static inline int l2cap_check_security(struct sock *sk)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200272{
273 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100274 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200275
Marcel Holtmann00ae4af2009-02-12 16:19:45 +0100276 if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) {
277 if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
278 auth_type = HCI_AT_NO_BONDING_MITM;
279 else
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -0300280 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann00ae4af2009-02-12 16:19:45 +0100281
282 if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW)
283 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
284 } else {
285 switch (l2cap_pi(sk)->sec_level) {
286 case BT_SECURITY_HIGH:
287 auth_type = HCI_AT_GENERAL_BONDING_MITM;
288 break;
289 case BT_SECURITY_MEDIUM:
290 auth_type = HCI_AT_GENERAL_BONDING;
291 break;
292 default:
293 auth_type = HCI_AT_NO_BONDING;
294 break;
295 }
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100296 }
297
298 return hci_conn_security(conn->hcon, l2cap_pi(sk)->sec_level,
299 auth_type);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200300}
301
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200302static inline u8 l2cap_get_ident(struct l2cap_conn *conn)
303{
304 u8 id;
305
306 /* Get next available identificator.
307 * 1 - 128 are used by kernel.
308 * 129 - 199 are reserved.
309 * 200 - 254 are used by utilities like l2ping, etc.
310 */
311
312 spin_lock_bh(&conn->lock);
313
314 if (++conn->tx_ident > 128)
315 conn->tx_ident = 1;
316
317 id = conn->tx_ident;
318
319 spin_unlock_bh(&conn->lock);
320
321 return id;
322}
323
324static inline int l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data)
325{
326 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
327
328 BT_DBG("code 0x%2.2x", code);
329
330 if (!skb)
331 return -ENOMEM;
332
333 return hci_send_acl(conn->hcon, skb, 0);
334}
335
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200336static void l2cap_do_start(struct sock *sk)
337{
338 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
339
340 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +0100341 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
342 return;
343
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100344 if (l2cap_check_security(sk)) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200345 struct l2cap_conn_req req;
346 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
347 req.psm = l2cap_pi(sk)->psm;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200348
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200349 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200350
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200351 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200352 L2CAP_CONN_REQ, sizeof(req), &req);
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200353 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200354 } else {
355 struct l2cap_info_req req;
356 req.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
357
358 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
359 conn->info_ident = l2cap_get_ident(conn);
360
361 mod_timer(&conn->info_timer, jiffies +
362 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
363
364 l2cap_send_cmd(conn, conn->info_ident,
365 L2CAP_INFO_REQ, sizeof(req), &req);
366 }
367}
368
Linus Torvalds1da177e2005-04-16 15:20:36 -0700369/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200370static void l2cap_conn_start(struct l2cap_conn *conn)
371{
372 struct l2cap_chan_list *l = &conn->chan_list;
373 struct sock *sk;
374
375 BT_DBG("conn %p", conn);
376
377 read_lock(&l->lock);
378
379 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
380 bh_lock_sock(sk);
381
382 if (sk->sk_type != SOCK_SEQPACKET) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200383 bh_unlock_sock(sk);
384 continue;
385 }
386
387 if (sk->sk_state == BT_CONNECT) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100388 if (l2cap_check_security(sk)) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200389 struct l2cap_conn_req req;
390 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
391 req.psm = l2cap_pi(sk)->psm;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200392
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200393 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200394
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200395 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200396 L2CAP_CONN_REQ, sizeof(req), &req);
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200397 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200398 } else if (sk->sk_state == BT_CONNECT2) {
399 struct l2cap_conn_rsp rsp;
400 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
401 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
402
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100403 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100404 if (bt_sk(sk)->defer_setup) {
405 struct sock *parent = bt_sk(sk)->parent;
406 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
407 rsp.status = cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
408 parent->sk_data_ready(parent, 0);
409
410 } else {
411 sk->sk_state = BT_CONFIG;
412 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
413 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
414 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200415 } else {
416 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
417 rsp.status = cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
418 }
419
420 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
421 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
422 }
423
424 bh_unlock_sock(sk);
425 }
426
427 read_unlock(&l->lock);
428}
429
430static void l2cap_conn_ready(struct l2cap_conn *conn)
431{
432 struct l2cap_chan_list *l = &conn->chan_list;
433 struct sock *sk;
434
435 BT_DBG("conn %p", conn);
436
437 read_lock(&l->lock);
438
439 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
440 bh_lock_sock(sk);
441
442 if (sk->sk_type != SOCK_SEQPACKET) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200443 l2cap_sock_clear_timer(sk);
444 sk->sk_state = BT_CONNECTED;
445 sk->sk_state_change(sk);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200446 } else if (sk->sk_state == BT_CONNECT)
447 l2cap_do_start(sk);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200448
449 bh_unlock_sock(sk);
450 }
451
452 read_unlock(&l->lock);
453}
454
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200455/* Notify sockets that we cannot guaranty reliability anymore */
456static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
457{
458 struct l2cap_chan_list *l = &conn->chan_list;
459 struct sock *sk;
460
461 BT_DBG("conn %p", conn);
462
463 read_lock(&l->lock);
464
465 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100466 if (l2cap_pi(sk)->force_reliable)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200467 sk->sk_err = err;
468 }
469
470 read_unlock(&l->lock);
471}
472
473static void l2cap_info_timeout(unsigned long arg)
474{
475 struct l2cap_conn *conn = (void *) arg;
476
Marcel Holtmann984947d2009-02-06 23:35:19 +0100477 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +0100478 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +0100479
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200480 l2cap_conn_start(conn);
481}
482
Linus Torvalds1da177e2005-04-16 15:20:36 -0700483static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
484{
Marcel Holtmann01394182006-07-03 10:02:46 +0200485 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700486
Marcel Holtmann01394182006-07-03 10:02:46 +0200487 if (conn || status)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700488 return conn;
489
Marcel Holtmann01394182006-07-03 10:02:46 +0200490 conn = kzalloc(sizeof(struct l2cap_conn), GFP_ATOMIC);
491 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700492 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700493
494 hcon->l2cap_data = conn;
495 conn->hcon = hcon;
496
Marcel Holtmann01394182006-07-03 10:02:46 +0200497 BT_DBG("hcon %p conn %p", hcon, conn);
498
Linus Torvalds1da177e2005-04-16 15:20:36 -0700499 conn->mtu = hcon->hdev->acl_mtu;
500 conn->src = &hcon->hdev->bdaddr;
501 conn->dst = &hcon->dst;
502
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200503 conn->feat_mask = 0;
504
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200505 setup_timer(&conn->info_timer, l2cap_info_timeout,
506 (unsigned long) conn);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200507
Linus Torvalds1da177e2005-04-16 15:20:36 -0700508 spin_lock_init(&conn->lock);
509 rwlock_init(&conn->chan_list.lock);
510
Marcel Holtmann2950f212009-02-12 14:02:50 +0100511 conn->disc_reason = 0x13;
512
Linus Torvalds1da177e2005-04-16 15:20:36 -0700513 return conn;
514}
515
Marcel Holtmann01394182006-07-03 10:02:46 +0200516static void l2cap_conn_del(struct hci_conn *hcon, int err)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700517{
Marcel Holtmann01394182006-07-03 10:02:46 +0200518 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700519 struct sock *sk;
520
Marcel Holtmann01394182006-07-03 10:02:46 +0200521 if (!conn)
522 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700523
524 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
525
Wei Yongjun7585b972009-02-25 18:29:52 +0800526 kfree_skb(conn->rx_skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700527
528 /* Kill channels */
529 while ((sk = conn->chan_list.head)) {
530 bh_lock_sock(sk);
531 l2cap_chan_del(sk, err);
532 bh_unlock_sock(sk);
533 l2cap_sock_kill(sk);
534 }
535
Dave Young8e8440f2008-03-03 12:18:55 -0800536 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
537 del_timer_sync(&conn->info_timer);
Thomas Gleixner3ab22732008-02-26 17:42:56 -0800538
Linus Torvalds1da177e2005-04-16 15:20:36 -0700539 hcon->l2cap_data = NULL;
540 kfree(conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700541}
542
543static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
544{
545 struct l2cap_chan_list *l = &conn->chan_list;
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200546 write_lock_bh(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700547 __l2cap_chan_add(conn, sk, parent);
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200548 write_unlock_bh(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700549}
550
Linus Torvalds1da177e2005-04-16 15:20:36 -0700551/* ---- Socket interface ---- */
Al Viro8e036fc2007-07-29 00:16:36 -0700552static struct sock *__l2cap_get_sock_by_addr(__le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700553{
554 struct sock *sk;
555 struct hlist_node *node;
556 sk_for_each(sk, node, &l2cap_sk_list.head)
557 if (l2cap_pi(sk)->sport == psm && !bacmp(&bt_sk(sk)->src, src))
558 goto found;
559 sk = NULL;
560found:
561 return sk;
562}
563
564/* Find socket with psm and source bdaddr.
565 * Returns closest match.
566 */
Al Viro8e036fc2007-07-29 00:16:36 -0700567static struct sock *__l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700568{
569 struct sock *sk = NULL, *sk1 = NULL;
570 struct hlist_node *node;
571
572 sk_for_each(sk, node, &l2cap_sk_list.head) {
573 if (state && sk->sk_state != state)
574 continue;
575
576 if (l2cap_pi(sk)->psm == psm) {
577 /* Exact match. */
578 if (!bacmp(&bt_sk(sk)->src, src))
579 break;
580
581 /* Closest match */
582 if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY))
583 sk1 = sk;
584 }
585 }
586 return node ? sk : sk1;
587}
588
589/* Find socket with given address (psm, src).
590 * Returns locked socket */
Al Viro8e036fc2007-07-29 00:16:36 -0700591static inline struct sock *l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700592{
593 struct sock *s;
594 read_lock(&l2cap_sk_list.lock);
595 s = __l2cap_get_sock_by_psm(state, psm, src);
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -0300596 if (s)
597 bh_lock_sock(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700598 read_unlock(&l2cap_sk_list.lock);
599 return s;
600}
601
602static void l2cap_sock_destruct(struct sock *sk)
603{
604 BT_DBG("sk %p", sk);
605
606 skb_queue_purge(&sk->sk_receive_queue);
607 skb_queue_purge(&sk->sk_write_queue);
608}
609
610static void l2cap_sock_cleanup_listen(struct sock *parent)
611{
612 struct sock *sk;
613
614 BT_DBG("parent %p", parent);
615
616 /* Close not yet accepted channels */
617 while ((sk = bt_accept_dequeue(parent, NULL)))
618 l2cap_sock_close(sk);
619
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200620 parent->sk_state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700621 sock_set_flag(parent, SOCK_ZAPPED);
622}
623
624/* Kill socket (only if zapped and orphan)
625 * Must be called on unlocked socket.
626 */
627static void l2cap_sock_kill(struct sock *sk)
628{
629 if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket)
630 return;
631
632 BT_DBG("sk %p state %d", sk, sk->sk_state);
633
634 /* Kill poor orphan */
635 bt_sock_unlink(&l2cap_sk_list, sk);
636 sock_set_flag(sk, SOCK_DEAD);
637 sock_put(sk);
638}
639
640static void __l2cap_sock_close(struct sock *sk, int reason)
641{
642 BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket);
643
644 switch (sk->sk_state) {
645 case BT_LISTEN:
646 l2cap_sock_cleanup_listen(sk);
647 break;
648
649 case BT_CONNECTED:
650 case BT_CONFIG:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700651 if (sk->sk_type == SOCK_SEQPACKET) {
652 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
653 struct l2cap_disconn_req req;
654
655 sk->sk_state = BT_DISCONN;
656 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
657
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -0700658 req.dcid = cpu_to_le16(l2cap_pi(sk)->dcid);
659 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700660 l2cap_send_cmd(conn, l2cap_get_ident(conn),
661 L2CAP_DISCONN_REQ, sizeof(req), &req);
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200662 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -0700663 l2cap_chan_del(sk, reason);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700664 break;
665
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100666 case BT_CONNECT2:
667 if (sk->sk_type == SOCK_SEQPACKET) {
668 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
669 struct l2cap_conn_rsp rsp;
670 __u16 result;
671
672 if (bt_sk(sk)->defer_setup)
673 result = L2CAP_CR_SEC_BLOCK;
674 else
675 result = L2CAP_CR_BAD_PSM;
676
677 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
678 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
679 rsp.result = cpu_to_le16(result);
680 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
681 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
682 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
683 } else
684 l2cap_chan_del(sk, reason);
685 break;
686
Linus Torvalds1da177e2005-04-16 15:20:36 -0700687 case BT_CONNECT:
688 case BT_DISCONN:
689 l2cap_chan_del(sk, reason);
690 break;
691
692 default:
693 sock_set_flag(sk, SOCK_ZAPPED);
694 break;
695 }
696}
697
698/* Must be called on unlocked socket. */
699static void l2cap_sock_close(struct sock *sk)
700{
701 l2cap_sock_clear_timer(sk);
702 lock_sock(sk);
703 __l2cap_sock_close(sk, ECONNRESET);
704 release_sock(sk);
705 l2cap_sock_kill(sk);
706}
707
708static void l2cap_sock_init(struct sock *sk, struct sock *parent)
709{
710 struct l2cap_pinfo *pi = l2cap_pi(sk);
711
712 BT_DBG("sk %p", sk);
713
714 if (parent) {
715 sk->sk_type = parent->sk_type;
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100716 bt_sk(sk)->defer_setup = bt_sk(parent)->defer_setup;
717
Linus Torvalds1da177e2005-04-16 15:20:36 -0700718 pi->imtu = l2cap_pi(parent)->imtu;
719 pi->omtu = l2cap_pi(parent)->omtu;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -0700720 pi->mode = l2cap_pi(parent)->mode;
721 pi->fcs = l2cap_pi(parent)->fcs;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100722 pi->sec_level = l2cap_pi(parent)->sec_level;
723 pi->role_switch = l2cap_pi(parent)->role_switch;
724 pi->force_reliable = l2cap_pi(parent)->force_reliable;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700725 } else {
726 pi->imtu = L2CAP_DEFAULT_MTU;
727 pi->omtu = 0;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -0700728 pi->mode = L2CAP_MODE_BASIC;
729 pi->fcs = L2CAP_FCS_CRC16;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100730 pi->sec_level = BT_SECURITY_LOW;
731 pi->role_switch = 0;
732 pi->force_reliable = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700733 }
734
735 /* Default config options */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +0200736 pi->conf_len = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700737 pi->flush_to = L2CAP_DEFAULT_FLUSH_TO;
738}
739
740static struct proto l2cap_proto = {
741 .name = "L2CAP",
742 .owner = THIS_MODULE,
743 .obj_size = sizeof(struct l2cap_pinfo)
744};
745
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700746static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700747{
748 struct sock *sk;
749
Pavel Emelyanov6257ff22007-11-01 00:39:31 -0700750 sk = sk_alloc(net, PF_BLUETOOTH, prio, &l2cap_proto);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700751 if (!sk)
752 return NULL;
753
754 sock_init_data(sock, sk);
755 INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
756
757 sk->sk_destruct = l2cap_sock_destruct;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200758 sk->sk_sndtimeo = msecs_to_jiffies(L2CAP_CONN_TIMEOUT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700759
760 sock_reset_flag(sk, SOCK_ZAPPED);
761
762 sk->sk_protocol = proto;
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200763 sk->sk_state = BT_OPEN;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700764
Marcel Holtmannb1235d72008-07-14 20:13:54 +0200765 setup_timer(&sk->sk_timer, l2cap_sock_timeout, (unsigned long) sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700766
767 bt_sock_link(&l2cap_sk_list, sk);
768 return sk;
769}
770
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700771static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700772{
773 struct sock *sk;
774
775 BT_DBG("sock %p", sock);
776
777 sock->state = SS_UNCONNECTED;
778
779 if (sock->type != SOCK_SEQPACKET &&
780 sock->type != SOCK_DGRAM && sock->type != SOCK_RAW)
781 return -ESOCKTNOSUPPORT;
782
783 if (sock->type == SOCK_RAW && !capable(CAP_NET_RAW))
784 return -EPERM;
785
786 sock->ops = &l2cap_sock_ops;
787
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700788 sk = l2cap_sock_alloc(net, sock, protocol, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700789 if (!sk)
790 return -ENOMEM;
791
792 l2cap_sock_init(sk, NULL);
793 return 0;
794}
795
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100796static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700797{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700798 struct sock *sk = sock->sk;
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100799 struct sockaddr_l2 la;
800 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700801
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100802 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700803
804 if (!addr || addr->sa_family != AF_BLUETOOTH)
805 return -EINVAL;
806
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100807 memset(&la, 0, sizeof(la));
808 len = min_t(unsigned int, sizeof(la), alen);
809 memcpy(&la, addr, len);
810
Marcel Holtmann2a517ca2009-02-16 03:20:31 +0100811 if (la.l2_cid)
812 return -EINVAL;
813
Linus Torvalds1da177e2005-04-16 15:20:36 -0700814 lock_sock(sk);
815
816 if (sk->sk_state != BT_OPEN) {
817 err = -EBADFD;
818 goto done;
819 }
820
Marcel Holtmannb4324b52009-06-07 18:06:51 +0200821 if (la.l2_psm && __le16_to_cpu(la.l2_psm) < 0x1001 &&
Marcel Holtmann847641d2007-01-22 22:00:45 +0100822 !capable(CAP_NET_BIND_SERVICE)) {
823 err = -EACCES;
824 goto done;
825 }
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900826
Linus Torvalds1da177e2005-04-16 15:20:36 -0700827 write_lock_bh(&l2cap_sk_list.lock);
828
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100829 if (la.l2_psm && __l2cap_get_sock_by_addr(la.l2_psm, &la.l2_bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700830 err = -EADDRINUSE;
831 } else {
832 /* Save source address */
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100833 bacpy(&bt_sk(sk)->src, &la.l2_bdaddr);
834 l2cap_pi(sk)->psm = la.l2_psm;
835 l2cap_pi(sk)->sport = la.l2_psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700836 sk->sk_state = BT_BOUND;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100837
Marcel Holtmannb4324b52009-06-07 18:06:51 +0200838 if (__le16_to_cpu(la.l2_psm) == 0x0001 ||
839 __le16_to_cpu(la.l2_psm) == 0x0003)
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100840 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700841 }
842
843 write_unlock_bh(&l2cap_sk_list.lock);
844
845done:
846 release_sock(sk);
847 return err;
848}
849
850static int l2cap_do_connect(struct sock *sk)
851{
852 bdaddr_t *src = &bt_sk(sk)->src;
853 bdaddr_t *dst = &bt_sk(sk)->dst;
854 struct l2cap_conn *conn;
855 struct hci_conn *hcon;
856 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200857 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +0200858 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700859
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100860 BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst),
861 l2cap_pi(sk)->psm);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700862
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -0300863 hdev = hci_get_route(dst, src);
864 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700865 return -EHOSTUNREACH;
866
867 hci_dev_lock_bh(hdev);
868
869 err = -ENOMEM;
870
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100871 if (sk->sk_type == SOCK_RAW) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100872 switch (l2cap_pi(sk)->sec_level) {
873 case BT_SECURITY_HIGH:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100874 auth_type = HCI_AT_DEDICATED_BONDING_MITM;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100875 break;
876 case BT_SECURITY_MEDIUM:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100877 auth_type = HCI_AT_DEDICATED_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100878 break;
879 default:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100880 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100881 break;
882 }
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100883 } else if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100884 if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200885 auth_type = HCI_AT_NO_BONDING_MITM;
886 else
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200887 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann435fef22009-02-09 03:55:28 +0100888
889 if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW)
890 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100891 } else {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100892 switch (l2cap_pi(sk)->sec_level) {
893 case BT_SECURITY_HIGH:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100894 auth_type = HCI_AT_GENERAL_BONDING_MITM;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100895 break;
896 case BT_SECURITY_MEDIUM:
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200897 auth_type = HCI_AT_GENERAL_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100898 break;
899 default:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100900 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100901 break;
902 }
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200903 }
904
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100905 hcon = hci_connect(hdev, ACL_LINK, dst,
906 l2cap_pi(sk)->sec_level, auth_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700907 if (!hcon)
908 goto done;
909
910 conn = l2cap_conn_add(hcon, 0);
911 if (!conn) {
912 hci_conn_put(hcon);
913 goto done;
914 }
915
916 err = 0;
917
918 /* Update source addr of the socket */
919 bacpy(src, conn->src);
920
921 l2cap_chan_add(conn, sk, NULL);
922
923 sk->sk_state = BT_CONNECT;
924 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
925
926 if (hcon->state == BT_CONNECTED) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200927 if (sk->sk_type != SOCK_SEQPACKET) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700928 l2cap_sock_clear_timer(sk);
929 sk->sk_state = BT_CONNECTED;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200930 } else
931 l2cap_do_start(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700932 }
933
934done:
935 hci_dev_unlock_bh(hdev);
936 hci_dev_put(hdev);
937 return err;
938}
939
940static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
941{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700942 struct sock *sk = sock->sk;
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100943 struct sockaddr_l2 la;
944 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700945
Linus Torvalds1da177e2005-04-16 15:20:36 -0700946 BT_DBG("sk %p", sk);
947
Marcel Holtmann2a517ca2009-02-16 03:20:31 +0100948 if (!addr || addr->sa_family != AF_BLUETOOTH)
949 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700950
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100951 memset(&la, 0, sizeof(la));
952 len = min_t(unsigned int, sizeof(la), alen);
953 memcpy(&la, addr, len);
954
Marcel Holtmann2a517ca2009-02-16 03:20:31 +0100955 if (la.l2_cid)
956 return -EINVAL;
957
958 lock_sock(sk);
959
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100960 if (sk->sk_type == SOCK_SEQPACKET && !la.l2_psm) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700961 err = -EINVAL;
962 goto done;
963 }
964
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -0700965 switch (l2cap_pi(sk)->mode) {
966 case L2CAP_MODE_BASIC:
967 break;
968 case L2CAP_MODE_ERTM:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -0300969 case L2CAP_MODE_STREAMING:
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -0700970 if (enable_ertm)
971 break;
972 /* fall through */
973 default:
974 err = -ENOTSUPP;
975 goto done;
976 }
977
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -0300978 switch (sk->sk_state) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700979 case BT_CONNECT:
980 case BT_CONNECT2:
981 case BT_CONFIG:
982 /* Already connecting */
983 goto wait;
984
985 case BT_CONNECTED:
986 /* Already connected */
987 goto done;
988
989 case BT_OPEN:
990 case BT_BOUND:
991 /* Can connect */
992 break;
993
994 default:
995 err = -EBADFD;
996 goto done;
997 }
998
999 /* Set destination address and psm */
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001000 bacpy(&bt_sk(sk)->dst, &la.l2_bdaddr);
1001 l2cap_pi(sk)->psm = la.l2_psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001002
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03001003 err = l2cap_do_connect(sk);
1004 if (err)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001005 goto done;
1006
1007wait:
1008 err = bt_sock_wait_state(sk, BT_CONNECTED,
1009 sock_sndtimeo(sk, flags & O_NONBLOCK));
1010done:
1011 release_sock(sk);
1012 return err;
1013}
1014
1015static int l2cap_sock_listen(struct socket *sock, int backlog)
1016{
1017 struct sock *sk = sock->sk;
1018 int err = 0;
1019
1020 BT_DBG("sk %p backlog %d", sk, backlog);
1021
1022 lock_sock(sk);
1023
1024 if (sk->sk_state != BT_BOUND || sock->type != SOCK_SEQPACKET) {
1025 err = -EBADFD;
1026 goto done;
1027 }
1028
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001029 switch (l2cap_pi(sk)->mode) {
1030 case L2CAP_MODE_BASIC:
1031 break;
1032 case L2CAP_MODE_ERTM:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001033 case L2CAP_MODE_STREAMING:
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001034 if (enable_ertm)
1035 break;
1036 /* fall through */
1037 default:
1038 err = -ENOTSUPP;
1039 goto done;
1040 }
1041
Linus Torvalds1da177e2005-04-16 15:20:36 -07001042 if (!l2cap_pi(sk)->psm) {
1043 bdaddr_t *src = &bt_sk(sk)->src;
1044 u16 psm;
1045
1046 err = -EINVAL;
1047
1048 write_lock_bh(&l2cap_sk_list.lock);
1049
1050 for (psm = 0x1001; psm < 0x1100; psm += 2)
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001051 if (!__l2cap_get_sock_by_addr(cpu_to_le16(psm), src)) {
1052 l2cap_pi(sk)->psm = cpu_to_le16(psm);
1053 l2cap_pi(sk)->sport = cpu_to_le16(psm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001054 err = 0;
1055 break;
1056 }
1057
1058 write_unlock_bh(&l2cap_sk_list.lock);
1059
1060 if (err < 0)
1061 goto done;
1062 }
1063
1064 sk->sk_max_ack_backlog = backlog;
1065 sk->sk_ack_backlog = 0;
1066 sk->sk_state = BT_LISTEN;
1067
1068done:
1069 release_sock(sk);
1070 return err;
1071}
1072
1073static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int flags)
1074{
1075 DECLARE_WAITQUEUE(wait, current);
1076 struct sock *sk = sock->sk, *nsk;
1077 long timeo;
1078 int err = 0;
1079
Peter Zijlstrafcc70d52006-11-08 22:44:35 -08001080 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001081
1082 if (sk->sk_state != BT_LISTEN) {
1083 err = -EBADFD;
1084 goto done;
1085 }
1086
1087 timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
1088
1089 BT_DBG("sk %p timeo %ld", sk, timeo);
1090
1091 /* Wait for an incoming connection. (wake-one). */
1092 add_wait_queue_exclusive(sk->sk_sleep, &wait);
1093 while (!(nsk = bt_accept_dequeue(sk, newsock))) {
1094 set_current_state(TASK_INTERRUPTIBLE);
1095 if (!timeo) {
1096 err = -EAGAIN;
1097 break;
1098 }
1099
1100 release_sock(sk);
1101 timeo = schedule_timeout(timeo);
Peter Zijlstrafcc70d52006-11-08 22:44:35 -08001102 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001103
1104 if (sk->sk_state != BT_LISTEN) {
1105 err = -EBADFD;
1106 break;
1107 }
1108
1109 if (signal_pending(current)) {
1110 err = sock_intr_errno(timeo);
1111 break;
1112 }
1113 }
1114 set_current_state(TASK_RUNNING);
1115 remove_wait_queue(sk->sk_sleep, &wait);
1116
1117 if (err)
1118 goto done;
1119
1120 newsock->state = SS_CONNECTED;
1121
1122 BT_DBG("new socket %p", nsk);
1123
1124done:
1125 release_sock(sk);
1126 return err;
1127}
1128
1129static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
1130{
1131 struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
1132 struct sock *sk = sock->sk;
1133
1134 BT_DBG("sock %p, sk %p", sock, sk);
1135
1136 addr->sa_family = AF_BLUETOOTH;
1137 *len = sizeof(struct sockaddr_l2);
1138
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001139 if (peer) {
1140 la->l2_psm = l2cap_pi(sk)->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001141 bacpy(&la->l2_bdaddr, &bt_sk(sk)->dst);
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001142 la->l2_cid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001143 } else {
1144 la->l2_psm = l2cap_pi(sk)->sport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001145 bacpy(&la->l2_bdaddr, &bt_sk(sk)->src);
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001146 la->l2_cid = cpu_to_le16(l2cap_pi(sk)->scid);
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001147 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001148
Linus Torvalds1da177e2005-04-16 15:20:36 -07001149 return 0;
1150}
1151
1152static inline int l2cap_do_send(struct sock *sk, struct msghdr *msg, int len)
1153{
1154 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1155 struct sk_buff *skb, **frag;
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03001156 int err, hlen, count, sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001157 struct l2cap_hdr *lh;
1158
1159 BT_DBG("sk %p len %d", sk, len);
1160
1161 /* First fragment (with L2CAP header) */
1162 if (sk->sk_type == SOCK_DGRAM)
1163 hlen = L2CAP_HDR_SIZE + 2;
1164 else
1165 hlen = L2CAP_HDR_SIZE;
1166
1167 count = min_t(unsigned int, (conn->mtu - hlen), len);
1168
1169 skb = bt_skb_send_alloc(sk, hlen + count,
1170 msg->msg_flags & MSG_DONTWAIT, &err);
1171 if (!skb)
1172 return err;
1173
1174 /* Create L2CAP header */
1175 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07001176 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1177 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001178
1179 if (sk->sk_type == SOCK_DGRAM)
Al Viro8e036fc2007-07-29 00:16:36 -07001180 put_unaligned(l2cap_pi(sk)->psm, (__le16 *) skb_put(skb, 2));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001181
1182 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count)) {
1183 err = -EFAULT;
1184 goto fail;
1185 }
1186
1187 sent += count;
1188 len -= count;
1189
1190 /* Continuation fragments (no L2CAP header) */
1191 frag = &skb_shinfo(skb)->frag_list;
1192 while (len) {
1193 count = min_t(unsigned int, conn->mtu, len);
1194
1195 *frag = bt_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err);
1196 if (!*frag)
1197 goto fail;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001198
Linus Torvalds1da177e2005-04-16 15:20:36 -07001199 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count)) {
1200 err = -EFAULT;
1201 goto fail;
1202 }
1203
1204 sent += count;
1205 len -= count;
1206
1207 frag = &(*frag)->next;
1208 }
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03001209 err = hci_send_acl(conn->hcon, skb, 0);
1210 if (err < 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001211 goto fail;
1212
1213 return sent;
1214
1215fail:
1216 kfree_skb(skb);
1217 return err;
1218}
1219
1220static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len)
1221{
1222 struct sock *sk = sock->sk;
1223 int err = 0;
1224
1225 BT_DBG("sock %p, sk %p", sock, sk);
1226
Benjamin LaHaisec1cbe4b2005-12-13 23:22:19 -08001227 err = sock_error(sk);
1228 if (err)
1229 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001230
1231 if (msg->msg_flags & MSG_OOB)
1232 return -EOPNOTSUPP;
1233
1234 /* Check outgoing MTU */
1235 if (sk->sk_type != SOCK_RAW && len > l2cap_pi(sk)->omtu)
1236 return -EINVAL;
1237
1238 lock_sock(sk);
1239
1240 if (sk->sk_state == BT_CONNECTED)
1241 err = l2cap_do_send(sk, msg, len);
1242 else
1243 err = -ENOTCONN;
1244
1245 release_sock(sk);
1246 return err;
1247}
1248
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001249static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags)
1250{
1251 struct sock *sk = sock->sk;
1252
1253 lock_sock(sk);
1254
1255 if (sk->sk_state == BT_CONNECT2 && bt_sk(sk)->defer_setup) {
1256 struct l2cap_conn_rsp rsp;
1257
1258 sk->sk_state = BT_CONFIG;
1259
1260 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
1261 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
1262 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
1263 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
1264 l2cap_send_cmd(l2cap_pi(sk)->conn, l2cap_pi(sk)->ident,
1265 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
1266
1267 release_sock(sk);
1268 return 0;
1269 }
1270
1271 release_sock(sk);
1272
1273 return bt_sock_recvmsg(iocb, sock, msg, len, flags);
1274}
1275
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001276static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, int optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001277{
1278 struct sock *sk = sock->sk;
1279 struct l2cap_options opts;
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001280 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001281 u32 opt;
1282
1283 BT_DBG("sk %p", sk);
1284
1285 lock_sock(sk);
1286
1287 switch (optname) {
1288 case L2CAP_OPTIONS:
Marcel Holtmann0878b662007-05-05 00:35:59 +02001289 opts.imtu = l2cap_pi(sk)->imtu;
1290 opts.omtu = l2cap_pi(sk)->omtu;
1291 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001292 opts.mode = l2cap_pi(sk)->mode;
Marcel Holtmann0878b662007-05-05 00:35:59 +02001293
Linus Torvalds1da177e2005-04-16 15:20:36 -07001294 len = min_t(unsigned int, sizeof(opts), optlen);
1295 if (copy_from_user((char *) &opts, optval, len)) {
1296 err = -EFAULT;
1297 break;
1298 }
Marcel Holtmann0878b662007-05-05 00:35:59 +02001299
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001300 l2cap_pi(sk)->imtu = opts.imtu;
1301 l2cap_pi(sk)->omtu = opts.omtu;
1302 l2cap_pi(sk)->mode = opts.mode;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001303 break;
1304
1305 case L2CAP_LM:
1306 if (get_user(opt, (u32 __user *) optval)) {
1307 err = -EFAULT;
1308 break;
1309 }
1310
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001311 if (opt & L2CAP_LM_AUTH)
1312 l2cap_pi(sk)->sec_level = BT_SECURITY_LOW;
1313 if (opt & L2CAP_LM_ENCRYPT)
1314 l2cap_pi(sk)->sec_level = BT_SECURITY_MEDIUM;
1315 if (opt & L2CAP_LM_SECURE)
1316 l2cap_pi(sk)->sec_level = BT_SECURITY_HIGH;
1317
1318 l2cap_pi(sk)->role_switch = (opt & L2CAP_LM_MASTER);
1319 l2cap_pi(sk)->force_reliable = (opt & L2CAP_LM_RELIABLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001320 break;
1321
1322 default:
1323 err = -ENOPROTOOPT;
1324 break;
1325 }
1326
1327 release_sock(sk);
1328 return err;
1329}
1330
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001331static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen)
1332{
1333 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001334 struct bt_security sec;
1335 int len, err = 0;
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001336 u32 opt;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001337
1338 BT_DBG("sk %p", sk);
1339
1340 if (level == SOL_L2CAP)
1341 return l2cap_sock_setsockopt_old(sock, optname, optval, optlen);
1342
Marcel Holtmann0588d942009-01-16 10:06:13 +01001343 if (level != SOL_BLUETOOTH)
1344 return -ENOPROTOOPT;
1345
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001346 lock_sock(sk);
1347
1348 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001349 case BT_SECURITY:
Marcel Holtmann2526d3d2009-02-20 20:54:06 +01001350 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01001351 err = -EINVAL;
1352 break;
1353 }
1354
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001355 sec.level = BT_SECURITY_LOW;
1356
1357 len = min_t(unsigned int, sizeof(sec), optlen);
1358 if (copy_from_user((char *) &sec, optval, len)) {
1359 err = -EFAULT;
1360 break;
1361 }
1362
1363 if (sec.level < BT_SECURITY_LOW ||
1364 sec.level > BT_SECURITY_HIGH) {
1365 err = -EINVAL;
1366 break;
1367 }
1368
1369 l2cap_pi(sk)->sec_level = sec.level;
1370 break;
1371
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001372 case BT_DEFER_SETUP:
1373 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
1374 err = -EINVAL;
1375 break;
1376 }
1377
1378 if (get_user(opt, (u32 __user *) optval)) {
1379 err = -EFAULT;
1380 break;
1381 }
1382
1383 bt_sk(sk)->defer_setup = opt;
1384 break;
1385
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001386 default:
1387 err = -ENOPROTOOPT;
1388 break;
1389 }
1390
1391 release_sock(sk);
1392 return err;
1393}
1394
1395static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001396{
1397 struct sock *sk = sock->sk;
1398 struct l2cap_options opts;
1399 struct l2cap_conninfo cinfo;
1400 int len, err = 0;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001401 u32 opt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001402
1403 BT_DBG("sk %p", sk);
1404
1405 if (get_user(len, optlen))
1406 return -EFAULT;
1407
1408 lock_sock(sk);
1409
1410 switch (optname) {
1411 case L2CAP_OPTIONS:
1412 opts.imtu = l2cap_pi(sk)->imtu;
1413 opts.omtu = l2cap_pi(sk)->omtu;
1414 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001415 opts.mode = l2cap_pi(sk)->mode;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001416
1417 len = min_t(unsigned int, len, sizeof(opts));
1418 if (copy_to_user(optval, (char *) &opts, len))
1419 err = -EFAULT;
1420
1421 break;
1422
1423 case L2CAP_LM:
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001424 switch (l2cap_pi(sk)->sec_level) {
1425 case BT_SECURITY_LOW:
1426 opt = L2CAP_LM_AUTH;
1427 break;
1428 case BT_SECURITY_MEDIUM:
1429 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT;
1430 break;
1431 case BT_SECURITY_HIGH:
1432 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT |
1433 L2CAP_LM_SECURE;
1434 break;
1435 default:
1436 opt = 0;
1437 break;
1438 }
1439
1440 if (l2cap_pi(sk)->role_switch)
1441 opt |= L2CAP_LM_MASTER;
1442
1443 if (l2cap_pi(sk)->force_reliable)
1444 opt |= L2CAP_LM_RELIABLE;
1445
1446 if (put_user(opt, (u32 __user *) optval))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001447 err = -EFAULT;
1448 break;
1449
1450 case L2CAP_CONNINFO:
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001451 if (sk->sk_state != BT_CONNECTED &&
1452 !(sk->sk_state == BT_CONNECT2 &&
1453 bt_sk(sk)->defer_setup)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001454 err = -ENOTCONN;
1455 break;
1456 }
1457
1458 cinfo.hci_handle = l2cap_pi(sk)->conn->hcon->handle;
1459 memcpy(cinfo.dev_class, l2cap_pi(sk)->conn->hcon->dev_class, 3);
1460
1461 len = min_t(unsigned int, len, sizeof(cinfo));
1462 if (copy_to_user(optval, (char *) &cinfo, len))
1463 err = -EFAULT;
1464
1465 break;
1466
1467 default:
1468 err = -ENOPROTOOPT;
1469 break;
1470 }
1471
1472 release_sock(sk);
1473 return err;
1474}
1475
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001476static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
1477{
1478 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001479 struct bt_security sec;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001480 int len, err = 0;
1481
1482 BT_DBG("sk %p", sk);
1483
1484 if (level == SOL_L2CAP)
1485 return l2cap_sock_getsockopt_old(sock, optname, optval, optlen);
1486
Marcel Holtmann0588d942009-01-16 10:06:13 +01001487 if (level != SOL_BLUETOOTH)
1488 return -ENOPROTOOPT;
1489
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001490 if (get_user(len, optlen))
1491 return -EFAULT;
1492
1493 lock_sock(sk);
1494
1495 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001496 case BT_SECURITY:
Marcel Holtmann2526d3d2009-02-20 20:54:06 +01001497 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01001498 err = -EINVAL;
1499 break;
1500 }
1501
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001502 sec.level = l2cap_pi(sk)->sec_level;
1503
1504 len = min_t(unsigned int, len, sizeof(sec));
1505 if (copy_to_user(optval, (char *) &sec, len))
1506 err = -EFAULT;
1507
1508 break;
1509
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001510 case BT_DEFER_SETUP:
1511 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
1512 err = -EINVAL;
1513 break;
1514 }
1515
1516 if (put_user(bt_sk(sk)->defer_setup, (u32 __user *) optval))
1517 err = -EFAULT;
1518
1519 break;
1520
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001521 default:
1522 err = -ENOPROTOOPT;
1523 break;
1524 }
1525
1526 release_sock(sk);
1527 return err;
1528}
1529
Linus Torvalds1da177e2005-04-16 15:20:36 -07001530static int l2cap_sock_shutdown(struct socket *sock, int how)
1531{
1532 struct sock *sk = sock->sk;
1533 int err = 0;
1534
1535 BT_DBG("sock %p, sk %p", sock, sk);
1536
1537 if (!sk)
1538 return 0;
1539
1540 lock_sock(sk);
1541 if (!sk->sk_shutdown) {
1542 sk->sk_shutdown = SHUTDOWN_MASK;
1543 l2cap_sock_clear_timer(sk);
1544 __l2cap_sock_close(sk, 0);
1545
1546 if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
Marcel Holtmannb1235d72008-07-14 20:13:54 +02001547 err = bt_sock_wait_state(sk, BT_CLOSED,
1548 sk->sk_lingertime);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001549 }
1550 release_sock(sk);
1551 return err;
1552}
1553
1554static int l2cap_sock_release(struct socket *sock)
1555{
1556 struct sock *sk = sock->sk;
1557 int err;
1558
1559 BT_DBG("sock %p, sk %p", sock, sk);
1560
1561 if (!sk)
1562 return 0;
1563
1564 err = l2cap_sock_shutdown(sock, 2);
1565
1566 sock_orphan(sk);
1567 l2cap_sock_kill(sk);
1568 return err;
1569}
1570
Linus Torvalds1da177e2005-04-16 15:20:36 -07001571static void l2cap_chan_ready(struct sock *sk)
1572{
1573 struct sock *parent = bt_sk(sk)->parent;
1574
1575 BT_DBG("sk %p, parent %p", sk, parent);
1576
1577 l2cap_pi(sk)->conf_state = 0;
1578 l2cap_sock_clear_timer(sk);
1579
1580 if (!parent) {
1581 /* Outgoing channel.
1582 * Wake up socket sleeping on connect.
1583 */
1584 sk->sk_state = BT_CONNECTED;
1585 sk->sk_state_change(sk);
1586 } else {
1587 /* Incoming channel.
1588 * Wake up socket sleeping on accept.
1589 */
1590 parent->sk_data_ready(parent, 0);
1591 }
1592}
1593
1594/* Copy frame to all raw sockets on that connection */
1595static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
1596{
1597 struct l2cap_chan_list *l = &conn->chan_list;
1598 struct sk_buff *nskb;
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03001599 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001600
1601 BT_DBG("conn %p", conn);
1602
1603 read_lock(&l->lock);
1604 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
1605 if (sk->sk_type != SOCK_RAW)
1606 continue;
1607
1608 /* Don't send frame to the socket it came from */
1609 if (skb->sk == sk)
1610 continue;
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03001611 nskb = skb_clone(skb, GFP_ATOMIC);
1612 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001613 continue;
1614
1615 if (sock_queue_rcv_skb(sk, nskb))
1616 kfree_skb(nskb);
1617 }
1618 read_unlock(&l->lock);
1619}
1620
1621/* ---- L2CAP signalling commands ---- */
1622static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
1623 u8 code, u8 ident, u16 dlen, void *data)
1624{
1625 struct sk_buff *skb, **frag;
1626 struct l2cap_cmd_hdr *cmd;
1627 struct l2cap_hdr *lh;
1628 int len, count;
1629
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03001630 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d",
1631 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001632
1633 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
1634 count = min_t(unsigned int, conn->mtu, len);
1635
1636 skb = bt_skb_alloc(count, GFP_ATOMIC);
1637 if (!skb)
1638 return NULL;
1639
1640 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07001641 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03001642 lh->cid = cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001643
1644 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
1645 cmd->code = code;
1646 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07001647 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001648
1649 if (dlen) {
1650 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
1651 memcpy(skb_put(skb, count), data, count);
1652 data += count;
1653 }
1654
1655 len -= skb->len;
1656
1657 /* Continuation fragments (no L2CAP header) */
1658 frag = &skb_shinfo(skb)->frag_list;
1659 while (len) {
1660 count = min_t(unsigned int, conn->mtu, len);
1661
1662 *frag = bt_skb_alloc(count, GFP_ATOMIC);
1663 if (!*frag)
1664 goto fail;
1665
1666 memcpy(skb_put(*frag, count), data, count);
1667
1668 len -= count;
1669 data += count;
1670
1671 frag = &(*frag)->next;
1672 }
1673
1674 return skb;
1675
1676fail:
1677 kfree_skb(skb);
1678 return NULL;
1679}
1680
1681static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned long *val)
1682{
1683 struct l2cap_conf_opt *opt = *ptr;
1684 int len;
1685
1686 len = L2CAP_CONF_OPT_SIZE + opt->len;
1687 *ptr += len;
1688
1689 *type = opt->type;
1690 *olen = opt->len;
1691
1692 switch (opt->len) {
1693 case 1:
1694 *val = *((u8 *) opt->val);
1695 break;
1696
1697 case 2:
Marcel Holtmann861d6882007-10-20 13:37:06 +02001698 *val = __le16_to_cpu(*((__le16 *) opt->val));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001699 break;
1700
1701 case 4:
Marcel Holtmann861d6882007-10-20 13:37:06 +02001702 *val = __le32_to_cpu(*((__le32 *) opt->val));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001703 break;
1704
1705 default:
1706 *val = (unsigned long) opt->val;
1707 break;
1708 }
1709
1710 BT_DBG("type 0x%2.2x len %d val 0x%lx", *type, opt->len, *val);
1711 return len;
1712}
1713
Linus Torvalds1da177e2005-04-16 15:20:36 -07001714static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
1715{
1716 struct l2cap_conf_opt *opt = *ptr;
1717
1718 BT_DBG("type 0x%2.2x len %d val 0x%lx", type, len, val);
1719
1720 opt->type = type;
1721 opt->len = len;
1722
1723 switch (len) {
1724 case 1:
1725 *((u8 *) opt->val) = val;
1726 break;
1727
1728 case 2:
Al Viro8e036fc2007-07-29 00:16:36 -07001729 *((__le16 *) opt->val) = cpu_to_le16(val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001730 break;
1731
1732 case 4:
Al Viro8e036fc2007-07-29 00:16:36 -07001733 *((__le32 *) opt->val) = cpu_to_le32(val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001734 break;
1735
1736 default:
1737 memcpy(opt->val, (void *) val, len);
1738 break;
1739 }
1740
1741 *ptr += L2CAP_CONF_OPT_SIZE + len;
1742}
1743
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001744static int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
1745{
1746 u32 local_feat_mask = l2cap_feat_mask;
1747 if (enable_ertm)
1748 local_feat_mask |= L2CAP_FEAT_ERTM;
1749
1750 switch (mode) {
1751 case L2CAP_MODE_ERTM:
1752 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
1753 case L2CAP_MODE_STREAMING:
1754 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
1755 default:
1756 return 0x00;
1757 }
1758}
1759
1760static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
1761{
1762 switch (mode) {
1763 case L2CAP_MODE_STREAMING:
1764 case L2CAP_MODE_ERTM:
1765 if (l2cap_mode_supported(mode, remote_feat_mask))
1766 return mode;
1767 /* fall through */
1768 default:
1769 return L2CAP_MODE_BASIC;
1770 }
1771}
1772
Linus Torvalds1da177e2005-04-16 15:20:36 -07001773static int l2cap_build_conf_req(struct sock *sk, void *data)
1774{
1775 struct l2cap_pinfo *pi = l2cap_pi(sk);
1776 struct l2cap_conf_req *req = data;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001777 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_ERTM };
Linus Torvalds1da177e2005-04-16 15:20:36 -07001778 void *ptr = req->data;
1779
1780 BT_DBG("sk %p", sk);
1781
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001782 if (pi->num_conf_req || pi->num_conf_rsp)
1783 goto done;
1784
1785 switch (pi->mode) {
1786 case L2CAP_MODE_STREAMING:
1787 case L2CAP_MODE_ERTM:
1788 pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
1789 if (!l2cap_mode_supported(pi->mode, pi->conn->feat_mask)) {
1790 struct l2cap_disconn_req req;
1791 req.dcid = cpu_to_le16(pi->dcid);
1792 req.scid = cpu_to_le16(pi->scid);
1793 l2cap_send_cmd(pi->conn, l2cap_get_ident(pi->conn),
1794 L2CAP_DISCONN_REQ, sizeof(req), &req);
1795 }
1796 break;
1797 default:
1798 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
1799 break;
1800 }
1801
1802done:
Marcel Holtmann65c7c492009-05-02 23:07:53 -07001803 switch (pi->mode) {
1804 case L2CAP_MODE_BASIC:
1805 if (pi->imtu != L2CAP_DEFAULT_MTU)
1806 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
1807 break;
1808
1809 case L2CAP_MODE_ERTM:
1810 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001811 rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW;
Marcel Holtmann65c7c492009-05-02 23:07:53 -07001812 rfc.max_transmit = L2CAP_DEFAULT_MAX_RECEIVE;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001813 rfc.retrans_timeout = 0;
1814 rfc.monitor_timeout = 0;
1815 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_RX_APDU);
1816
1817 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
1818 sizeof(rfc), (unsigned long) &rfc);
1819 break;
1820
1821 case L2CAP_MODE_STREAMING:
1822 rfc.mode = L2CAP_MODE_STREAMING;
1823 rfc.txwin_size = 0;
1824 rfc.max_transmit = 0;
1825 rfc.retrans_timeout = 0;
1826 rfc.monitor_timeout = 0;
Marcel Holtmann65c7c492009-05-02 23:07:53 -07001827 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_RX_APDU);
1828
1829 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
1830 sizeof(rfc), (unsigned long) &rfc);
1831 break;
1832 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001833
1834 /* FIXME: Need actual value of the flush timeout */
1835 //if (flush_to != L2CAP_DEFAULT_FLUSH_TO)
1836 // l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2, pi->flush_to);
1837
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07001838 req->dcid = cpu_to_le16(pi->dcid);
1839 req->flags = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001840
1841 return ptr - data;
1842}
1843
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001844static int l2cap_parse_conf_req(struct sock *sk, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001845{
1846 struct l2cap_pinfo *pi = l2cap_pi(sk);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001847 struct l2cap_conf_rsp *rsp = data;
1848 void *ptr = rsp->data;
1849 void *req = pi->conf_req;
1850 int len = pi->conf_len;
1851 int type, hint, olen;
1852 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02001853 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Marcel Holtmann861d6882007-10-20 13:37:06 +02001854 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001855 u16 result = L2CAP_CONF_SUCCESS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001856
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001857 BT_DBG("sk %p", sk);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01001858
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001859 while (len >= L2CAP_CONF_OPT_SIZE) {
1860 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001861
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03001862 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07001863 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001864
1865 switch (type) {
1866 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02001867 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001868 break;
1869
1870 case L2CAP_CONF_FLUSH_TO:
1871 pi->flush_to = val;
1872 break;
1873
1874 case L2CAP_CONF_QOS:
1875 break;
1876
Marcel Holtmann6464f352007-10-20 13:39:51 +02001877 case L2CAP_CONF_RFC:
1878 if (olen == sizeof(rfc))
1879 memcpy(&rfc, (void *) val, olen);
1880 break;
1881
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001882 default:
1883 if (hint)
1884 break;
1885
1886 result = L2CAP_CONF_UNKNOWN;
1887 *((u8 *) ptr++) = type;
1888 break;
1889 }
1890 }
1891
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001892 if (pi->num_conf_rsp || pi->num_conf_req)
1893 goto done;
1894
1895 switch (pi->mode) {
1896 case L2CAP_MODE_STREAMING:
1897 case L2CAP_MODE_ERTM:
1898 pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
1899 if (!l2cap_mode_supported(pi->mode, pi->conn->feat_mask))
1900 return -ECONNREFUSED;
1901 break;
1902 default:
1903 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
1904 break;
1905 }
1906
1907done:
1908 if (pi->mode != rfc.mode) {
1909 result = L2CAP_CONF_UNACCEPT;
1910 rfc.mode = pi->mode;
1911
1912 if (pi->num_conf_rsp == 1)
1913 return -ECONNREFUSED;
1914
1915 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
1916 sizeof(rfc), (unsigned long) &rfc);
1917 }
1918
1919
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001920 if (result == L2CAP_CONF_SUCCESS) {
1921 /* Configure output options and let the other side know
1922 * which ones we don't like. */
1923
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001924 if (mtu < L2CAP_DEFAULT_MIN_MTU)
1925 result = L2CAP_CONF_UNACCEPT;
1926 else {
1927 pi->omtu = mtu;
1928 pi->conf_state |= L2CAP_CONF_MTU_DONE;
1929 }
1930 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001931
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001932 switch (rfc.mode) {
1933 case L2CAP_MODE_BASIC:
1934 pi->fcs = L2CAP_FCS_NONE;
1935 pi->conf_state |= L2CAP_CONF_MODE_DONE;
1936 break;
1937
1938 case L2CAP_MODE_ERTM:
1939 pi->remote_tx_win = rfc.txwin_size;
1940 pi->remote_max_tx = rfc.max_transmit;
1941 pi->max_pdu_size = rfc.max_pdu_size;
1942
1943 rfc.retrans_timeout = L2CAP_DEFAULT_RETRANS_TO;
1944 rfc.monitor_timeout = L2CAP_DEFAULT_MONITOR_TO;
1945
1946 pi->conf_state |= L2CAP_CONF_MODE_DONE;
1947 break;
1948
1949 case L2CAP_MODE_STREAMING:
1950 pi->remote_tx_win = rfc.txwin_size;
1951 pi->max_pdu_size = rfc.max_pdu_size;
1952
1953 pi->conf_state |= L2CAP_CONF_MODE_DONE;
1954 break;
1955
1956 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02001957 result = L2CAP_CONF_UNACCEPT;
1958
1959 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001960 rfc.mode = pi->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02001961 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001962
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001963 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
1964 sizeof(rfc), (unsigned long) &rfc);
1965
1966 if (result == L2CAP_CONF_SUCCESS)
1967 pi->conf_state |= L2CAP_CONF_OUTPUT_DONE;
1968 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02001969 rsp->scid = cpu_to_le16(pi->dcid);
1970 rsp->result = cpu_to_le16(result);
1971 rsp->flags = cpu_to_le16(0x0000);
1972
1973 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001974}
1975
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001976static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data, u16 *result)
1977{
1978 struct l2cap_pinfo *pi = l2cap_pi(sk);
1979 struct l2cap_conf_req *req = data;
1980 void *ptr = req->data;
1981 int type, olen;
1982 unsigned long val;
1983 struct l2cap_conf_rfc rfc;
1984
1985 BT_DBG("sk %p, rsp %p, len %d, req %p", sk, rsp, len, data);
1986
1987 while (len >= L2CAP_CONF_OPT_SIZE) {
1988 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
1989
1990 switch (type) {
1991 case L2CAP_CONF_MTU:
1992 if (val < L2CAP_DEFAULT_MIN_MTU) {
1993 *result = L2CAP_CONF_UNACCEPT;
1994 pi->omtu = L2CAP_DEFAULT_MIN_MTU;
1995 } else
1996 pi->omtu = val;
1997 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
1998 break;
1999
2000 case L2CAP_CONF_FLUSH_TO:
2001 pi->flush_to = val;
2002 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
2003 2, pi->flush_to);
2004 break;
2005
2006 case L2CAP_CONF_RFC:
2007 if (olen == sizeof(rfc))
2008 memcpy(&rfc, (void *)val, olen);
2009
2010 if ((pi->conf_state & L2CAP_CONF_STATE2_DEVICE) &&
2011 rfc.mode != pi->mode)
2012 return -ECONNREFUSED;
2013
2014 pi->mode = rfc.mode;
2015 pi->fcs = 0;
2016
2017 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2018 sizeof(rfc), (unsigned long) &rfc);
2019 break;
2020 }
2021 }
2022
2023 if (*result == L2CAP_CONF_SUCCESS) {
2024 switch (rfc.mode) {
2025 case L2CAP_MODE_ERTM:
2026 pi->remote_tx_win = rfc.txwin_size;
2027 pi->retrans_timeout = rfc.retrans_timeout;
2028 pi->monitor_timeout = rfc.monitor_timeout;
2029 pi->max_pdu_size = le16_to_cpu(rfc.max_pdu_size);
2030 break;
2031 case L2CAP_MODE_STREAMING:
2032 pi->max_pdu_size = le16_to_cpu(rfc.max_pdu_size);
2033 break;
2034 }
2035 }
2036
2037 req->dcid = cpu_to_le16(pi->dcid);
2038 req->flags = cpu_to_le16(0x0000);
2039
2040 return ptr - data;
2041}
2042
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002043static int l2cap_build_conf_rsp(struct sock *sk, void *data, u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002044{
2045 struct l2cap_conf_rsp *rsp = data;
2046 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002047
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002048 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002049
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002050 rsp->scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002051 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002052 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002053
2054 return ptr - data;
2055}
2056
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002057static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2058{
2059 struct l2cap_cmd_rej *rej = (struct l2cap_cmd_rej *) data;
2060
2061 if (rej->reason != 0x0000)
2062 return 0;
2063
2064 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
2065 cmd->ident == conn->info_ident) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002066 del_timer(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01002067
2068 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002069 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01002070
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002071 l2cap_conn_start(conn);
2072 }
2073
2074 return 0;
2075}
2076
Linus Torvalds1da177e2005-04-16 15:20:36 -07002077static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2078{
2079 struct l2cap_chan_list *list = &conn->chan_list;
2080 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
2081 struct l2cap_conn_rsp rsp;
2082 struct sock *sk, *parent;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002083 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002084
2085 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002086 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002087
2088 BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
2089
2090 /* Check if we have socket listening on psm */
2091 parent = l2cap_get_sock_by_psm(BT_LISTEN, psm, conn->src);
2092 if (!parent) {
2093 result = L2CAP_CR_BAD_PSM;
2094 goto sendresp;
2095 }
2096
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002097 /* Check if the ACL is secure enough (if not SDP) */
2098 if (psm != cpu_to_le16(0x0001) &&
2099 !hci_conn_check_link_mode(conn->hcon)) {
Marcel Holtmann2950f212009-02-12 14:02:50 +01002100 conn->disc_reason = 0x05;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002101 result = L2CAP_CR_SEC_BLOCK;
2102 goto response;
2103 }
2104
Linus Torvalds1da177e2005-04-16 15:20:36 -07002105 result = L2CAP_CR_NO_MEM;
2106
2107 /* Check for backlog size */
2108 if (sk_acceptq_is_full(parent)) {
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09002109 BT_DBG("backlog full %d", parent->sk_ack_backlog);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002110 goto response;
2111 }
2112
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09002113 sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002114 if (!sk)
2115 goto response;
2116
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002117 write_lock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002118
2119 /* Check if we already have channel with that dcid */
2120 if (__l2cap_get_chan_by_dcid(list, scid)) {
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002121 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002122 sock_set_flag(sk, SOCK_ZAPPED);
2123 l2cap_sock_kill(sk);
2124 goto response;
2125 }
2126
2127 hci_conn_hold(conn->hcon);
2128
2129 l2cap_sock_init(sk, parent);
2130 bacpy(&bt_sk(sk)->src, conn->src);
2131 bacpy(&bt_sk(sk)->dst, conn->dst);
2132 l2cap_pi(sk)->psm = psm;
2133 l2cap_pi(sk)->dcid = scid;
2134
2135 __l2cap_chan_add(conn, sk, parent);
2136 dcid = l2cap_pi(sk)->scid;
2137
2138 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
2139
Linus Torvalds1da177e2005-04-16 15:20:36 -07002140 l2cap_pi(sk)->ident = cmd->ident;
2141
Marcel Holtmann984947d2009-02-06 23:35:19 +01002142 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002143 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002144 if (bt_sk(sk)->defer_setup) {
2145 sk->sk_state = BT_CONNECT2;
2146 result = L2CAP_CR_PEND;
2147 status = L2CAP_CS_AUTHOR_PEND;
2148 parent->sk_data_ready(parent, 0);
2149 } else {
2150 sk->sk_state = BT_CONFIG;
2151 result = L2CAP_CR_SUCCESS;
2152 status = L2CAP_CS_NO_INFO;
2153 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002154 } else {
2155 sk->sk_state = BT_CONNECT2;
2156 result = L2CAP_CR_PEND;
2157 status = L2CAP_CS_AUTHEN_PEND;
2158 }
2159 } else {
2160 sk->sk_state = BT_CONNECT2;
2161 result = L2CAP_CR_PEND;
2162 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002163 }
2164
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002165 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002166
2167response:
2168 bh_unlock_sock(parent);
2169
2170sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002171 rsp.scid = cpu_to_le16(scid);
2172 rsp.dcid = cpu_to_le16(dcid);
2173 rsp.result = cpu_to_le16(result);
2174 rsp.status = cpu_to_le16(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002175 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002176
2177 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
2178 struct l2cap_info_req info;
2179 info.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
2180
2181 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
2182 conn->info_ident = l2cap_get_ident(conn);
2183
2184 mod_timer(&conn->info_timer, jiffies +
2185 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
2186
2187 l2cap_send_cmd(conn, conn->info_ident,
2188 L2CAP_INFO_REQ, sizeof(info), &info);
2189 }
2190
Linus Torvalds1da177e2005-04-16 15:20:36 -07002191 return 0;
2192}
2193
2194static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2195{
2196 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
2197 u16 scid, dcid, result, status;
2198 struct sock *sk;
2199 u8 req[128];
2200
2201 scid = __le16_to_cpu(rsp->scid);
2202 dcid = __le16_to_cpu(rsp->dcid);
2203 result = __le16_to_cpu(rsp->result);
2204 status = __le16_to_cpu(rsp->status);
2205
2206 BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
2207
2208 if (scid) {
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002209 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2210 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002211 return 0;
2212 } else {
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002213 sk = l2cap_get_chan_by_ident(&conn->chan_list, cmd->ident);
2214 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002215 return 0;
2216 }
2217
2218 switch (result) {
2219 case L2CAP_CR_SUCCESS:
2220 sk->sk_state = BT_CONFIG;
2221 l2cap_pi(sk)->ident = 0;
2222 l2cap_pi(sk)->dcid = dcid;
2223 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
2224
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002225 l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_CONNECT_PEND;
2226
Linus Torvalds1da177e2005-04-16 15:20:36 -07002227 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
2228 l2cap_build_conf_req(sk, req), req);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002229 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002230 break;
2231
2232 case L2CAP_CR_PEND:
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002233 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002234 break;
2235
2236 default:
2237 l2cap_chan_del(sk, ECONNREFUSED);
2238 break;
2239 }
2240
2241 bh_unlock_sock(sk);
2242 return 0;
2243}
2244
Al Viro88219a02007-07-29 00:17:25 -07002245static 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 -07002246{
2247 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
2248 u16 dcid, flags;
2249 u8 rsp[64];
2250 struct sock *sk;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002251 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002252
2253 dcid = __le16_to_cpu(req->dcid);
2254 flags = __le16_to_cpu(req->flags);
2255
2256 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
2257
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002258 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
2259 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002260 return -ENOENT;
2261
Marcel Holtmann354f60a2006-11-18 22:15:20 +01002262 if (sk->sk_state == BT_DISCONN)
2263 goto unlock;
2264
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002265 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07002266 len = cmd_len - sizeof(*req);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002267 if (l2cap_pi(sk)->conf_len + len > sizeof(l2cap_pi(sk)->conf_req)) {
2268 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
2269 l2cap_build_conf_rsp(sk, rsp,
2270 L2CAP_CONF_REJECT, flags), rsp);
2271 goto unlock;
2272 }
2273
2274 /* Store config. */
2275 memcpy(l2cap_pi(sk)->conf_req + l2cap_pi(sk)->conf_len, req->data, len);
2276 l2cap_pi(sk)->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002277
2278 if (flags & 0x0001) {
2279 /* Incomplete config. Send empty response. */
2280 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002281 l2cap_build_conf_rsp(sk, rsp,
2282 L2CAP_CONF_SUCCESS, 0x0001), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002283 goto unlock;
2284 }
2285
2286 /* Complete config. */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002287 len = l2cap_parse_conf_req(sk, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002288 if (len < 0) {
2289 struct l2cap_disconn_req req;
2290 req.dcid = cpu_to_le16(l2cap_pi(sk)->dcid);
2291 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
2292 l2cap_send_cmd(conn, l2cap_get_ident(conn),
2293 L2CAP_DISCONN_REQ, sizeof(req), &req);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002294 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002295 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002296
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002297 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002298 l2cap_pi(sk)->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002299
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002300 /* Reset config buffer. */
2301 l2cap_pi(sk)->conf_len = 0;
2302
Marcel Holtmann876d9482007-10-20 13:35:42 +02002303 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE))
2304 goto unlock;
2305
Linus Torvalds1da177e2005-04-16 15:20:36 -07002306 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) {
2307 sk->sk_state = BT_CONNECTED;
2308 l2cap_chan_ready(sk);
Marcel Holtmann876d9482007-10-20 13:35:42 +02002309 goto unlock;
2310 }
2311
2312 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002313 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002314 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002315 l2cap_build_conf_req(sk, buf), buf);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002316 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002317 }
2318
2319unlock:
2320 bh_unlock_sock(sk);
2321 return 0;
2322}
2323
2324static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2325{
2326 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
2327 u16 scid, flags, result;
2328 struct sock *sk;
2329
2330 scid = __le16_to_cpu(rsp->scid);
2331 flags = __le16_to_cpu(rsp->flags);
2332 result = __le16_to_cpu(rsp->result);
2333
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002334 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x",
2335 scid, flags, result);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002336
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002337 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2338 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002339 return 0;
2340
2341 switch (result) {
2342 case L2CAP_CONF_SUCCESS:
2343 break;
2344
2345 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002346 if (l2cap_pi(sk)->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
2347 int len = cmd->len - sizeof(*rsp);
2348 char req[64];
2349
2350 /* throw out any old stored conf requests */
2351 result = L2CAP_CONF_SUCCESS;
2352 len = l2cap_parse_conf_rsp(sk, rsp->data,
2353 len, req, &result);
2354 if (len < 0) {
2355 struct l2cap_disconn_req req;
2356 req.dcid = cpu_to_le16(l2cap_pi(sk)->dcid);
2357 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
2358 l2cap_send_cmd(conn, l2cap_get_ident(conn),
2359 L2CAP_DISCONN_REQ, sizeof(req), &req);
2360 goto done;
2361 }
2362
2363 l2cap_send_cmd(conn, l2cap_get_ident(conn),
2364 L2CAP_CONF_REQ, len, req);
2365 l2cap_pi(sk)->num_conf_req++;
2366 if (result != L2CAP_CONF_SUCCESS)
2367 goto done;
2368 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002369 }
2370
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09002371 default:
Linus Torvalds1da177e2005-04-16 15:20:36 -07002372 sk->sk_state = BT_DISCONN;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02002373 sk->sk_err = ECONNRESET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002374 l2cap_sock_set_timer(sk, HZ * 5);
2375 {
2376 struct l2cap_disconn_req req;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002377 req.dcid = cpu_to_le16(l2cap_pi(sk)->dcid);
2378 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002379 l2cap_send_cmd(conn, l2cap_get_ident(conn),
2380 L2CAP_DISCONN_REQ, sizeof(req), &req);
2381 }
2382 goto done;
2383 }
2384
2385 if (flags & 0x01)
2386 goto done;
2387
Linus Torvalds1da177e2005-04-16 15:20:36 -07002388 l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE;
2389
2390 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) {
2391 sk->sk_state = BT_CONNECTED;
2392 l2cap_chan_ready(sk);
2393 }
2394
2395done:
2396 bh_unlock_sock(sk);
2397 return 0;
2398}
2399
2400static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2401{
2402 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
2403 struct l2cap_disconn_rsp rsp;
2404 u16 dcid, scid;
2405 struct sock *sk;
2406
2407 scid = __le16_to_cpu(req->scid);
2408 dcid = __le16_to_cpu(req->dcid);
2409
2410 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
2411
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002412 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
2413 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002414 return 0;
2415
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002416 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
2417 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002418 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
2419
2420 sk->sk_shutdown = SHUTDOWN_MASK;
2421
2422 l2cap_chan_del(sk, ECONNRESET);
2423 bh_unlock_sock(sk);
2424
2425 l2cap_sock_kill(sk);
2426 return 0;
2427}
2428
2429static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2430{
2431 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
2432 u16 dcid, scid;
2433 struct sock *sk;
2434
2435 scid = __le16_to_cpu(rsp->scid);
2436 dcid = __le16_to_cpu(rsp->dcid);
2437
2438 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
2439
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002440 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2441 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002442 return 0;
2443
2444 l2cap_chan_del(sk, 0);
2445 bh_unlock_sock(sk);
2446
2447 l2cap_sock_kill(sk);
2448 return 0;
2449}
2450
2451static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2452{
2453 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002454 u16 type;
2455
2456 type = __le16_to_cpu(req->type);
2457
2458 BT_DBG("type 0x%4.4x", type);
2459
Marcel Holtmannf0709e02007-10-20 13:38:51 +02002460 if (type == L2CAP_IT_FEAT_MASK) {
2461 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07002462 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02002463 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
2464 rsp->type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
2465 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07002466 if (enable_ertm)
2467 feat_mask |= L2CAP_FEAT_ERTM;
2468 put_unaligned(cpu_to_le32(feat_mask), (__le32 *) rsp->data);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02002469 l2cap_send_cmd(conn, cmd->ident,
2470 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002471 } else if (type == L2CAP_IT_FIXED_CHAN) {
2472 u8 buf[12];
2473 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
2474 rsp->type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
2475 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
2476 memcpy(buf + 4, l2cap_fixed_chan, 8);
2477 l2cap_send_cmd(conn, cmd->ident,
2478 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02002479 } else {
2480 struct l2cap_info_rsp rsp;
2481 rsp.type = cpu_to_le16(type);
2482 rsp.result = cpu_to_le16(L2CAP_IR_NOTSUPP);
2483 l2cap_send_cmd(conn, cmd->ident,
2484 L2CAP_INFO_RSP, sizeof(rsp), &rsp);
2485 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002486
2487 return 0;
2488}
2489
2490static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2491{
2492 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
2493 u16 type, result;
2494
2495 type = __le16_to_cpu(rsp->type);
2496 result = __le16_to_cpu(rsp->result);
2497
2498 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
2499
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002500 del_timer(&conn->info_timer);
2501
Marcel Holtmann984947d2009-02-06 23:35:19 +01002502 if (type == L2CAP_IT_FEAT_MASK) {
Harvey Harrison83985312008-05-02 16:25:46 -07002503 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002504
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07002505 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002506 struct l2cap_info_req req;
2507 req.type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
2508
2509 conn->info_ident = l2cap_get_ident(conn);
2510
2511 l2cap_send_cmd(conn, conn->info_ident,
2512 L2CAP_INFO_REQ, sizeof(req), &req);
2513 } else {
2514 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
2515 conn->info_ident = 0;
2516
2517 l2cap_conn_start(conn);
2518 }
2519 } else if (type == L2CAP_IT_FIXED_CHAN) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01002520 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002521 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01002522
2523 l2cap_conn_start(conn);
2524 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002525
Linus Torvalds1da177e2005-04-16 15:20:36 -07002526 return 0;
2527}
2528
2529static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
2530{
2531 u8 *data = skb->data;
2532 int len = skb->len;
2533 struct l2cap_cmd_hdr cmd;
2534 int err = 0;
2535
2536 l2cap_raw_recv(conn, skb);
2537
2538 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07002539 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002540 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
2541 data += L2CAP_CMD_HDR_SIZE;
2542 len -= L2CAP_CMD_HDR_SIZE;
2543
Al Viro88219a02007-07-29 00:17:25 -07002544 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002545
Al Viro88219a02007-07-29 00:17:25 -07002546 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 -07002547
Al Viro88219a02007-07-29 00:17:25 -07002548 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002549 BT_DBG("corrupted command");
2550 break;
2551 }
2552
2553 switch (cmd.code) {
2554 case L2CAP_COMMAND_REJ:
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002555 l2cap_command_rej(conn, &cmd, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002556 break;
2557
2558 case L2CAP_CONN_REQ:
2559 err = l2cap_connect_req(conn, &cmd, data);
2560 break;
2561
2562 case L2CAP_CONN_RSP:
2563 err = l2cap_connect_rsp(conn, &cmd, data);
2564 break;
2565
2566 case L2CAP_CONF_REQ:
Al Viro88219a02007-07-29 00:17:25 -07002567 err = l2cap_config_req(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002568 break;
2569
2570 case L2CAP_CONF_RSP:
2571 err = l2cap_config_rsp(conn, &cmd, data);
2572 break;
2573
2574 case L2CAP_DISCONN_REQ:
2575 err = l2cap_disconnect_req(conn, &cmd, data);
2576 break;
2577
2578 case L2CAP_DISCONN_RSP:
2579 err = l2cap_disconnect_rsp(conn, &cmd, data);
2580 break;
2581
2582 case L2CAP_ECHO_REQ:
Al Viro88219a02007-07-29 00:17:25 -07002583 l2cap_send_cmd(conn, cmd.ident, L2CAP_ECHO_RSP, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002584 break;
2585
2586 case L2CAP_ECHO_RSP:
2587 break;
2588
2589 case L2CAP_INFO_REQ:
2590 err = l2cap_information_req(conn, &cmd, data);
2591 break;
2592
2593 case L2CAP_INFO_RSP:
2594 err = l2cap_information_rsp(conn, &cmd, data);
2595 break;
2596
2597 default:
2598 BT_ERR("Unknown signaling command 0x%2.2x", cmd.code);
2599 err = -EINVAL;
2600 break;
2601 }
2602
2603 if (err) {
2604 struct l2cap_cmd_rej rej;
2605 BT_DBG("error %d", err);
2606
2607 /* FIXME: Map err to a valid reason */
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002608 rej.reason = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002609 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
2610 }
2611
Al Viro88219a02007-07-29 00:17:25 -07002612 data += cmd_len;
2613 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002614 }
2615
2616 kfree_skb(skb);
2617}
2618
2619static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk_buff *skb)
2620{
2621 struct sock *sk;
2622
2623 sk = l2cap_get_chan_by_scid(&conn->chan_list, cid);
2624 if (!sk) {
2625 BT_DBG("unknown cid 0x%4.4x", cid);
2626 goto drop;
2627 }
2628
2629 BT_DBG("sk %p, len %d", sk, skb->len);
2630
2631 if (sk->sk_state != BT_CONNECTED)
2632 goto drop;
2633
2634 if (l2cap_pi(sk)->imtu < skb->len)
2635 goto drop;
2636
2637 /* If socket recv buffers overflows we drop data here
2638 * which is *bad* because L2CAP has to be reliable.
2639 * But we don't have any other choice. L2CAP doesn't
2640 * provide flow control mechanism. */
2641
2642 if (!sock_queue_rcv_skb(sk, skb))
2643 goto done;
2644
2645drop:
2646 kfree_skb(skb);
2647
2648done:
Marcel Holtmann01394182006-07-03 10:02:46 +02002649 if (sk)
2650 bh_unlock_sock(sk);
2651
Linus Torvalds1da177e2005-04-16 15:20:36 -07002652 return 0;
2653}
2654
Al Viro8e036fc2007-07-29 00:16:36 -07002655static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002656{
2657 struct sock *sk;
2658
2659 sk = l2cap_get_sock_by_psm(0, psm, conn->src);
2660 if (!sk)
2661 goto drop;
2662
2663 BT_DBG("sk %p, len %d", sk, skb->len);
2664
2665 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_CONNECTED)
2666 goto drop;
2667
2668 if (l2cap_pi(sk)->imtu < skb->len)
2669 goto drop;
2670
2671 if (!sock_queue_rcv_skb(sk, skb))
2672 goto done;
2673
2674drop:
2675 kfree_skb(skb);
2676
2677done:
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002678 if (sk)
2679 bh_unlock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002680 return 0;
2681}
2682
2683static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
2684{
2685 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07002686 u16 cid, len;
2687 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002688
2689 skb_pull(skb, L2CAP_HDR_SIZE);
2690 cid = __le16_to_cpu(lh->cid);
2691 len = __le16_to_cpu(lh->len);
2692
2693 BT_DBG("len %d, cid 0x%4.4x", len, cid);
2694
2695 switch (cid) {
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03002696 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07002697 l2cap_sig_channel(conn, skb);
2698 break;
2699
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03002700 case L2CAP_CID_CONN_LESS:
Al Viro8e036fc2007-07-29 00:16:36 -07002701 psm = get_unaligned((__le16 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002702 skb_pull(skb, 2);
2703 l2cap_conless_channel(conn, psm, skb);
2704 break;
2705
2706 default:
2707 l2cap_data_channel(conn, cid, skb);
2708 break;
2709 }
2710}
2711
2712/* ---- L2CAP interface with lower layer (HCI) ---- */
2713
2714static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
2715{
2716 int exact = 0, lm1 = 0, lm2 = 0;
2717 register struct sock *sk;
2718 struct hlist_node *node;
2719
2720 if (type != ACL_LINK)
2721 return 0;
2722
2723 BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
2724
2725 /* Find listening sockets and check their link_mode */
2726 read_lock(&l2cap_sk_list.lock);
2727 sk_for_each(sk, node, &l2cap_sk_list.head) {
2728 if (sk->sk_state != BT_LISTEN)
2729 continue;
2730
2731 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002732 lm1 |= HCI_LM_ACCEPT;
2733 if (l2cap_pi(sk)->role_switch)
2734 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002735 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002736 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
2737 lm2 |= HCI_LM_ACCEPT;
2738 if (l2cap_pi(sk)->role_switch)
2739 lm2 |= HCI_LM_MASTER;
2740 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002741 }
2742 read_unlock(&l2cap_sk_list.lock);
2743
2744 return exact ? lm1 : lm2;
2745}
2746
2747static int l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
2748{
Marcel Holtmann01394182006-07-03 10:02:46 +02002749 struct l2cap_conn *conn;
2750
Linus Torvalds1da177e2005-04-16 15:20:36 -07002751 BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
2752
2753 if (hcon->type != ACL_LINK)
2754 return 0;
2755
2756 if (!status) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002757 conn = l2cap_conn_add(hcon, status);
2758 if (conn)
2759 l2cap_conn_ready(conn);
Marcel Holtmann01394182006-07-03 10:02:46 +02002760 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -07002761 l2cap_conn_del(hcon, bt_err(status));
2762
2763 return 0;
2764}
2765
Marcel Holtmann2950f212009-02-12 14:02:50 +01002766static int l2cap_disconn_ind(struct hci_conn *hcon)
2767{
2768 struct l2cap_conn *conn = hcon->l2cap_data;
2769
2770 BT_DBG("hcon %p", hcon);
2771
2772 if (hcon->type != ACL_LINK || !conn)
2773 return 0x13;
2774
2775 return conn->disc_reason;
2776}
2777
2778static int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002779{
2780 BT_DBG("hcon %p reason %d", hcon, reason);
2781
2782 if (hcon->type != ACL_LINK)
2783 return 0;
2784
2785 l2cap_conn_del(hcon, bt_err(reason));
Marcel Holtmann01394182006-07-03 10:02:46 +02002786
Linus Torvalds1da177e2005-04-16 15:20:36 -07002787 return 0;
2788}
2789
Marcel Holtmannf62e4322009-01-15 21:58:44 +01002790static inline void l2cap_check_encryption(struct sock *sk, u8 encrypt)
2791{
Marcel Holtmann255c7602009-02-04 21:07:19 +01002792 if (sk->sk_type != SOCK_SEQPACKET)
2793 return;
2794
Marcel Holtmannf62e4322009-01-15 21:58:44 +01002795 if (encrypt == 0x00) {
2796 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM) {
2797 l2cap_sock_clear_timer(sk);
2798 l2cap_sock_set_timer(sk, HZ * 5);
2799 } else if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
2800 __l2cap_sock_close(sk, ECONNREFUSED);
2801 } else {
2802 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM)
2803 l2cap_sock_clear_timer(sk);
2804 }
2805}
2806
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01002807static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002808{
2809 struct l2cap_chan_list *l;
Marcel Holtmann40be4922008-07-14 20:13:50 +02002810 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002811 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002812
Marcel Holtmann01394182006-07-03 10:02:46 +02002813 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002814 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02002815
Linus Torvalds1da177e2005-04-16 15:20:36 -07002816 l = &conn->chan_list;
2817
2818 BT_DBG("conn %p", conn);
2819
2820 read_lock(&l->lock);
2821
2822 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
2823 bh_lock_sock(sk);
2824
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002825 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND) {
2826 bh_unlock_sock(sk);
2827 continue;
2828 }
2829
Marcel Holtmannf62e4322009-01-15 21:58:44 +01002830 if (!status && (sk->sk_state == BT_CONNECTED ||
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01002831 sk->sk_state == BT_CONFIG)) {
Marcel Holtmannf62e4322009-01-15 21:58:44 +01002832 l2cap_check_encryption(sk, encrypt);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02002833 bh_unlock_sock(sk);
2834 continue;
2835 }
2836
Marcel Holtmannb1235d72008-07-14 20:13:54 +02002837 if (sk->sk_state == BT_CONNECT) {
2838 if (!status) {
2839 struct l2cap_conn_req req;
2840 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
2841 req.psm = l2cap_pi(sk)->psm;
2842
2843 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
2844
2845 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
2846 L2CAP_CONN_REQ, sizeof(req), &req);
2847 } else {
2848 l2cap_sock_clear_timer(sk);
2849 l2cap_sock_set_timer(sk, HZ / 10);
2850 }
2851 } else if (sk->sk_state == BT_CONNECT2) {
2852 struct l2cap_conn_rsp rsp;
2853 __u16 result;
2854
2855 if (!status) {
2856 sk->sk_state = BT_CONFIG;
2857 result = L2CAP_CR_SUCCESS;
2858 } else {
2859 sk->sk_state = BT_DISCONN;
2860 l2cap_sock_set_timer(sk, HZ / 10);
2861 result = L2CAP_CR_SEC_BLOCK;
2862 }
2863
2864 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
2865 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
2866 rsp.result = cpu_to_le16(result);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002867 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02002868 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
2869 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002870 }
2871
Linus Torvalds1da177e2005-04-16 15:20:36 -07002872 bh_unlock_sock(sk);
2873 }
2874
2875 read_unlock(&l->lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02002876
Linus Torvalds1da177e2005-04-16 15:20:36 -07002877 return 0;
2878}
2879
2880static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
2881{
2882 struct l2cap_conn *conn = hcon->l2cap_data;
2883
2884 if (!conn && !(conn = l2cap_conn_add(hcon, 0)))
2885 goto drop;
2886
2887 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
2888
2889 if (flags & ACL_START) {
2890 struct l2cap_hdr *hdr;
2891 int len;
2892
2893 if (conn->rx_len) {
2894 BT_ERR("Unexpected start frame (len %d)", skb->len);
2895 kfree_skb(conn->rx_skb);
2896 conn->rx_skb = NULL;
2897 conn->rx_len = 0;
2898 l2cap_conn_unreliable(conn, ECOMM);
2899 }
2900
2901 if (skb->len < 2) {
2902 BT_ERR("Frame is too short (len %d)", skb->len);
2903 l2cap_conn_unreliable(conn, ECOMM);
2904 goto drop;
2905 }
2906
2907 hdr = (struct l2cap_hdr *) skb->data;
2908 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
2909
2910 if (len == skb->len) {
2911 /* Complete frame received */
2912 l2cap_recv_frame(conn, skb);
2913 return 0;
2914 }
2915
2916 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
2917
2918 if (skb->len > len) {
2919 BT_ERR("Frame is too long (len %d, expected len %d)",
2920 skb->len, len);
2921 l2cap_conn_unreliable(conn, ECOMM);
2922 goto drop;
2923 }
2924
2925 /* Allocate skb for the complete frame (with header) */
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002926 conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC);
2927 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002928 goto drop;
2929
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03002930 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002931 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002932 conn->rx_len = len - skb->len;
2933 } else {
2934 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
2935
2936 if (!conn->rx_len) {
2937 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
2938 l2cap_conn_unreliable(conn, ECOMM);
2939 goto drop;
2940 }
2941
2942 if (skb->len > conn->rx_len) {
2943 BT_ERR("Fragment is too long (len %d, expected %d)",
2944 skb->len, conn->rx_len);
2945 kfree_skb(conn->rx_skb);
2946 conn->rx_skb = NULL;
2947 conn->rx_len = 0;
2948 l2cap_conn_unreliable(conn, ECOMM);
2949 goto drop;
2950 }
2951
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03002952 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002953 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002954 conn->rx_len -= skb->len;
2955
2956 if (!conn->rx_len) {
2957 /* Complete frame received */
2958 l2cap_recv_frame(conn, conn->rx_skb);
2959 conn->rx_skb = NULL;
2960 }
2961 }
2962
2963drop:
2964 kfree_skb(skb);
2965 return 0;
2966}
2967
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08002968static ssize_t l2cap_sysfs_show(struct class *dev, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002969{
2970 struct sock *sk;
2971 struct hlist_node *node;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08002972 char *str = buf;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002973
2974 read_lock_bh(&l2cap_sk_list.lock);
2975
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08002976 sk_for_each(sk, node, &l2cap_sk_list.head) {
2977 struct l2cap_pinfo *pi = l2cap_pi(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002978
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002979 str += sprintf(str, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d\n",
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08002980 batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
Marcel Holtmannb4324b52009-06-07 18:06:51 +02002981 sk->sk_state, __le16_to_cpu(pi->psm), pi->scid,
2982 pi->dcid, pi->imtu, pi->omtu, pi->sec_level);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08002983 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002984
Linus Torvalds1da177e2005-04-16 15:20:36 -07002985 read_unlock_bh(&l2cap_sk_list.lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08002986
Gustavo F. Padovanaf05b302009-04-20 01:31:08 -03002987 return str - buf;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002988}
2989
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08002990static CLASS_ATTR(l2cap, S_IRUGO, l2cap_sysfs_show, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002991
Eric Dumazet90ddc4f2005-12-22 12:49:22 -08002992static const struct proto_ops l2cap_sock_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002993 .family = PF_BLUETOOTH,
2994 .owner = THIS_MODULE,
2995 .release = l2cap_sock_release,
2996 .bind = l2cap_sock_bind,
2997 .connect = l2cap_sock_connect,
2998 .listen = l2cap_sock_listen,
2999 .accept = l2cap_sock_accept,
3000 .getname = l2cap_sock_getname,
3001 .sendmsg = l2cap_sock_sendmsg,
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003002 .recvmsg = l2cap_sock_recvmsg,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003003 .poll = bt_sock_poll,
Marcel Holtmann3241ad82008-07-14 20:13:50 +02003004 .ioctl = bt_sock_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003005 .mmap = sock_no_mmap,
3006 .socketpair = sock_no_socketpair,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003007 .shutdown = l2cap_sock_shutdown,
3008 .setsockopt = l2cap_sock_setsockopt,
3009 .getsockopt = l2cap_sock_getsockopt
3010};
3011
3012static struct net_proto_family l2cap_sock_family_ops = {
3013 .family = PF_BLUETOOTH,
3014 .owner = THIS_MODULE,
3015 .create = l2cap_sock_create,
3016};
3017
3018static struct hci_proto l2cap_hci_proto = {
3019 .name = "L2CAP",
3020 .id = HCI_PROTO_L2CAP,
3021 .connect_ind = l2cap_connect_ind,
3022 .connect_cfm = l2cap_connect_cfm,
3023 .disconn_ind = l2cap_disconn_ind,
Marcel Holtmann2950f212009-02-12 14:02:50 +01003024 .disconn_cfm = l2cap_disconn_cfm,
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01003025 .security_cfm = l2cap_security_cfm,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003026 .recv_acldata = l2cap_recv_acldata
3027};
3028
3029static int __init l2cap_init(void)
3030{
3031 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08003032
Linus Torvalds1da177e2005-04-16 15:20:36 -07003033 err = proto_register(&l2cap_proto, 0);
3034 if (err < 0)
3035 return err;
3036
3037 err = bt_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops);
3038 if (err < 0) {
3039 BT_ERR("L2CAP socket registration failed");
3040 goto error;
3041 }
3042
3043 err = hci_register_proto(&l2cap_hci_proto);
3044 if (err < 0) {
3045 BT_ERR("L2CAP protocol registration failed");
3046 bt_sock_unregister(BTPROTO_L2CAP);
3047 goto error;
3048 }
3049
Marcel Holtmanndf5c37e2006-10-15 17:30:45 +02003050 if (class_create_file(bt_class, &class_attr_l2cap) < 0)
3051 BT_ERR("Failed to create L2CAP info file");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003052
3053 BT_INFO("L2CAP ver %s", VERSION);
3054 BT_INFO("L2CAP socket layer initialized");
3055
3056 return 0;
3057
3058error:
3059 proto_unregister(&l2cap_proto);
3060 return err;
3061}
3062
3063static void __exit l2cap_exit(void)
3064{
Marcel Holtmanna91f2e32006-07-03 10:02:41 +02003065 class_remove_file(bt_class, &class_attr_l2cap);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003066
3067 if (bt_sock_unregister(BTPROTO_L2CAP) < 0)
3068 BT_ERR("L2CAP socket unregistration failed");
3069
3070 if (hci_unregister_proto(&l2cap_hci_proto) < 0)
3071 BT_ERR("L2CAP protocol unregistration failed");
3072
3073 proto_unregister(&l2cap_proto);
3074}
3075
3076void l2cap_load(void)
3077{
3078 /* Dummy function to trigger automatic L2CAP module loading by
3079 * other modules that use L2CAP sockets but don't use any other
3080 * symbols from it. */
3081 return;
3082}
3083EXPORT_SYMBOL(l2cap_load);
3084
3085module_init(l2cap_init);
3086module_exit(l2cap_exit);
3087
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003088module_param(enable_ertm, bool, 0644);
3089MODULE_PARM_DESC(enable_ertm, "Enable enhanced retransmission mode");
3090
Marcel Holtmann63fbd242008-08-18 13:23:53 +02003091MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003092MODULE_DESCRIPTION("Bluetooth L2CAP ver " VERSION);
3093MODULE_VERSION(VERSION);
3094MODULE_LICENSE("GPL");
3095MODULE_ALIAS("bt-proto-0");