blob: 167e025326974cd20f8c2b5f8b1111efff8a7b9b [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. Padovanaf05b30b2009-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 Holtmannb1235d7962008-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 Holtmannb1235d7962008-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 Holtmannb1235d7962008-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. Padovanaf05b30b2009-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. Padovanaf05b30b2009-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. Padovanaf05b30b2009-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. Padovanaf05b30b2009-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 Holtmannb1235d7962008-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. Padovanaf05b30b2009-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
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -0300336static inline int l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control)
337{
338 struct sk_buff *skb;
339 struct l2cap_hdr *lh;
340 struct l2cap_conn *conn = pi->conn;
341 int count;
342
343 BT_DBG("pi %p, control 0x%2.2x", pi, control);
344
345 count = min_t(unsigned int, conn->mtu, L2CAP_HDR_SIZE + 2);
346 control |= L2CAP_CTRL_FRAME_TYPE;
347
348 skb = bt_skb_alloc(count, GFP_ATOMIC);
349 if (!skb)
350 return -ENOMEM;
351
352 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
353 lh->len = cpu_to_le16(2);
354 lh->cid = cpu_to_le16(pi->dcid);
355 put_unaligned_le16(control, skb_put(skb, 2));
356
357 return hci_send_acl(pi->conn->hcon, skb, 0);
358}
359
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200360static void l2cap_do_start(struct sock *sk)
361{
362 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
363
364 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +0100365 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
366 return;
367
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100368 if (l2cap_check_security(sk)) {
Marcel Holtmannb1235d7962008-07-14 20:13:54 +0200369 struct l2cap_conn_req req;
370 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
371 req.psm = l2cap_pi(sk)->psm;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200372
Marcel Holtmannb1235d7962008-07-14 20:13:54 +0200373 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200374
Marcel Holtmannb1235d7962008-07-14 20:13:54 +0200375 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200376 L2CAP_CONN_REQ, sizeof(req), &req);
Marcel Holtmannb1235d7962008-07-14 20:13:54 +0200377 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200378 } else {
379 struct l2cap_info_req req;
380 req.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
381
382 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
383 conn->info_ident = l2cap_get_ident(conn);
384
385 mod_timer(&conn->info_timer, jiffies +
386 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
387
388 l2cap_send_cmd(conn, conn->info_ident,
389 L2CAP_INFO_REQ, sizeof(req), &req);
390 }
391}
392
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300393static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct sock *sk)
394{
395 struct l2cap_disconn_req req;
396
397 req.dcid = cpu_to_le16(l2cap_pi(sk)->dcid);
398 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
399 l2cap_send_cmd(conn, l2cap_get_ident(conn),
400 L2CAP_DISCONN_REQ, sizeof(req), &req);
401}
402
Linus Torvalds1da177e2005-04-16 15:20:36 -0700403/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200404static void l2cap_conn_start(struct l2cap_conn *conn)
405{
406 struct l2cap_chan_list *l = &conn->chan_list;
407 struct sock *sk;
408
409 BT_DBG("conn %p", conn);
410
411 read_lock(&l->lock);
412
413 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
414 bh_lock_sock(sk);
415
416 if (sk->sk_type != SOCK_SEQPACKET) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200417 bh_unlock_sock(sk);
418 continue;
419 }
420
421 if (sk->sk_state == BT_CONNECT) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100422 if (l2cap_check_security(sk)) {
Marcel Holtmannb1235d7962008-07-14 20:13:54 +0200423 struct l2cap_conn_req req;
424 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
425 req.psm = l2cap_pi(sk)->psm;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200426
Marcel Holtmannb1235d7962008-07-14 20:13:54 +0200427 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200428
Marcel Holtmannb1235d7962008-07-14 20:13:54 +0200429 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200430 L2CAP_CONN_REQ, sizeof(req), &req);
Marcel Holtmannb1235d7962008-07-14 20:13:54 +0200431 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200432 } else if (sk->sk_state == BT_CONNECT2) {
433 struct l2cap_conn_rsp rsp;
434 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
435 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
436
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100437 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100438 if (bt_sk(sk)->defer_setup) {
439 struct sock *parent = bt_sk(sk)->parent;
440 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
441 rsp.status = cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
442 parent->sk_data_ready(parent, 0);
443
444 } else {
445 sk->sk_state = BT_CONFIG;
446 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
447 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
448 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200449 } else {
450 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
451 rsp.status = cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
452 }
453
454 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
455 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
456 }
457
458 bh_unlock_sock(sk);
459 }
460
461 read_unlock(&l->lock);
462}
463
464static void l2cap_conn_ready(struct l2cap_conn *conn)
465{
466 struct l2cap_chan_list *l = &conn->chan_list;
467 struct sock *sk;
468
469 BT_DBG("conn %p", conn);
470
471 read_lock(&l->lock);
472
473 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
474 bh_lock_sock(sk);
475
476 if (sk->sk_type != SOCK_SEQPACKET) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200477 l2cap_sock_clear_timer(sk);
478 sk->sk_state = BT_CONNECTED;
479 sk->sk_state_change(sk);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200480 } else if (sk->sk_state == BT_CONNECT)
481 l2cap_do_start(sk);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200482
483 bh_unlock_sock(sk);
484 }
485
486 read_unlock(&l->lock);
487}
488
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200489/* Notify sockets that we cannot guaranty reliability anymore */
490static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
491{
492 struct l2cap_chan_list *l = &conn->chan_list;
493 struct sock *sk;
494
495 BT_DBG("conn %p", conn);
496
497 read_lock(&l->lock);
498
499 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100500 if (l2cap_pi(sk)->force_reliable)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200501 sk->sk_err = err;
502 }
503
504 read_unlock(&l->lock);
505}
506
507static void l2cap_info_timeout(unsigned long arg)
508{
509 struct l2cap_conn *conn = (void *) arg;
510
Marcel Holtmann984947d2009-02-06 23:35:19 +0100511 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +0100512 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +0100513
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200514 l2cap_conn_start(conn);
515}
516
Linus Torvalds1da177e2005-04-16 15:20:36 -0700517static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
518{
Marcel Holtmann01394182006-07-03 10:02:46 +0200519 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700520
Marcel Holtmann01394182006-07-03 10:02:46 +0200521 if (conn || status)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700522 return conn;
523
Marcel Holtmann01394182006-07-03 10:02:46 +0200524 conn = kzalloc(sizeof(struct l2cap_conn), GFP_ATOMIC);
525 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700526 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700527
528 hcon->l2cap_data = conn;
529 conn->hcon = hcon;
530
Marcel Holtmann01394182006-07-03 10:02:46 +0200531 BT_DBG("hcon %p conn %p", hcon, conn);
532
Linus Torvalds1da177e2005-04-16 15:20:36 -0700533 conn->mtu = hcon->hdev->acl_mtu;
534 conn->src = &hcon->hdev->bdaddr;
535 conn->dst = &hcon->dst;
536
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200537 conn->feat_mask = 0;
538
Marcel Holtmannb1235d7962008-07-14 20:13:54 +0200539 setup_timer(&conn->info_timer, l2cap_info_timeout,
540 (unsigned long) conn);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200541
Linus Torvalds1da177e2005-04-16 15:20:36 -0700542 spin_lock_init(&conn->lock);
543 rwlock_init(&conn->chan_list.lock);
544
Marcel Holtmann2950f212009-02-12 14:02:50 +0100545 conn->disc_reason = 0x13;
546
Linus Torvalds1da177e2005-04-16 15:20:36 -0700547 return conn;
548}
549
Marcel Holtmann01394182006-07-03 10:02:46 +0200550static void l2cap_conn_del(struct hci_conn *hcon, int err)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700551{
Marcel Holtmann01394182006-07-03 10:02:46 +0200552 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700553 struct sock *sk;
554
Marcel Holtmann01394182006-07-03 10:02:46 +0200555 if (!conn)
556 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700557
558 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
559
Wei Yongjun7585b972009-02-25 18:29:52 +0800560 kfree_skb(conn->rx_skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700561
562 /* Kill channels */
563 while ((sk = conn->chan_list.head)) {
564 bh_lock_sock(sk);
565 l2cap_chan_del(sk, err);
566 bh_unlock_sock(sk);
567 l2cap_sock_kill(sk);
568 }
569
Dave Young8e8440f2008-03-03 12:18:55 -0800570 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
571 del_timer_sync(&conn->info_timer);
Thomas Gleixner3ab22732008-02-26 17:42:56 -0800572
Linus Torvalds1da177e2005-04-16 15:20:36 -0700573 hcon->l2cap_data = NULL;
574 kfree(conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700575}
576
577static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
578{
579 struct l2cap_chan_list *l = &conn->chan_list;
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200580 write_lock_bh(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700581 __l2cap_chan_add(conn, sk, parent);
Marcel Holtmannfd1278d2006-07-12 23:00:07 +0200582 write_unlock_bh(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700583}
584
Linus Torvalds1da177e2005-04-16 15:20:36 -0700585/* ---- Socket interface ---- */
Al Viro8e036fc2007-07-29 00:16:36 -0700586static struct sock *__l2cap_get_sock_by_addr(__le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700587{
588 struct sock *sk;
589 struct hlist_node *node;
590 sk_for_each(sk, node, &l2cap_sk_list.head)
591 if (l2cap_pi(sk)->sport == psm && !bacmp(&bt_sk(sk)->src, src))
592 goto found;
593 sk = NULL;
594found:
595 return sk;
596}
597
598/* Find socket with psm and source bdaddr.
599 * Returns closest match.
600 */
Al Viro8e036fc2007-07-29 00:16:36 -0700601static struct sock *__l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700602{
603 struct sock *sk = NULL, *sk1 = NULL;
604 struct hlist_node *node;
605
606 sk_for_each(sk, node, &l2cap_sk_list.head) {
607 if (state && sk->sk_state != state)
608 continue;
609
610 if (l2cap_pi(sk)->psm == psm) {
611 /* Exact match. */
612 if (!bacmp(&bt_sk(sk)->src, src))
613 break;
614
615 /* Closest match */
616 if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY))
617 sk1 = sk;
618 }
619 }
620 return node ? sk : sk1;
621}
622
623/* Find socket with given address (psm, src).
624 * Returns locked socket */
Al Viro8e036fc2007-07-29 00:16:36 -0700625static inline struct sock *l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700626{
627 struct sock *s;
628 read_lock(&l2cap_sk_list.lock);
629 s = __l2cap_get_sock_by_psm(state, psm, src);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300630 if (s)
631 bh_lock_sock(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700632 read_unlock(&l2cap_sk_list.lock);
633 return s;
634}
635
636static void l2cap_sock_destruct(struct sock *sk)
637{
638 BT_DBG("sk %p", sk);
639
640 skb_queue_purge(&sk->sk_receive_queue);
641 skb_queue_purge(&sk->sk_write_queue);
642}
643
644static void l2cap_sock_cleanup_listen(struct sock *parent)
645{
646 struct sock *sk;
647
648 BT_DBG("parent %p", parent);
649
650 /* Close not yet accepted channels */
651 while ((sk = bt_accept_dequeue(parent, NULL)))
652 l2cap_sock_close(sk);
653
Marcel Holtmannb1235d7962008-07-14 20:13:54 +0200654 parent->sk_state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700655 sock_set_flag(parent, SOCK_ZAPPED);
656}
657
658/* Kill socket (only if zapped and orphan)
659 * Must be called on unlocked socket.
660 */
661static void l2cap_sock_kill(struct sock *sk)
662{
663 if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket)
664 return;
665
666 BT_DBG("sk %p state %d", sk, sk->sk_state);
667
668 /* Kill poor orphan */
669 bt_sock_unlink(&l2cap_sk_list, sk);
670 sock_set_flag(sk, SOCK_DEAD);
671 sock_put(sk);
672}
673
674static void __l2cap_sock_close(struct sock *sk, int reason)
675{
676 BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket);
677
678 switch (sk->sk_state) {
679 case BT_LISTEN:
680 l2cap_sock_cleanup_listen(sk);
681 break;
682
683 case BT_CONNECTED:
684 case BT_CONFIG:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700685 if (sk->sk_type == SOCK_SEQPACKET) {
686 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700687
688 sk->sk_state = BT_DISCONN;
689 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -0300690 l2cap_send_disconn_req(conn, sk);
Marcel Holtmannb1235d7962008-07-14 20:13:54 +0200691 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -0700692 l2cap_chan_del(sk, reason);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700693 break;
694
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100695 case BT_CONNECT2:
696 if (sk->sk_type == SOCK_SEQPACKET) {
697 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
698 struct l2cap_conn_rsp rsp;
699 __u16 result;
700
701 if (bt_sk(sk)->defer_setup)
702 result = L2CAP_CR_SEC_BLOCK;
703 else
704 result = L2CAP_CR_BAD_PSM;
705
706 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
707 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
708 rsp.result = cpu_to_le16(result);
709 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
710 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
711 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
712 } else
713 l2cap_chan_del(sk, reason);
714 break;
715
Linus Torvalds1da177e2005-04-16 15:20:36 -0700716 case BT_CONNECT:
717 case BT_DISCONN:
718 l2cap_chan_del(sk, reason);
719 break;
720
721 default:
722 sock_set_flag(sk, SOCK_ZAPPED);
723 break;
724 }
725}
726
727/* Must be called on unlocked socket. */
728static void l2cap_sock_close(struct sock *sk)
729{
730 l2cap_sock_clear_timer(sk);
731 lock_sock(sk);
732 __l2cap_sock_close(sk, ECONNRESET);
733 release_sock(sk);
734 l2cap_sock_kill(sk);
735}
736
737static void l2cap_sock_init(struct sock *sk, struct sock *parent)
738{
739 struct l2cap_pinfo *pi = l2cap_pi(sk);
740
741 BT_DBG("sk %p", sk);
742
743 if (parent) {
744 sk->sk_type = parent->sk_type;
Marcel Holtmannf66dc812009-01-15 21:57:00 +0100745 bt_sk(sk)->defer_setup = bt_sk(parent)->defer_setup;
746
Linus Torvalds1da177e2005-04-16 15:20:36 -0700747 pi->imtu = l2cap_pi(parent)->imtu;
748 pi->omtu = l2cap_pi(parent)->omtu;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -0700749 pi->mode = l2cap_pi(parent)->mode;
750 pi->fcs = l2cap_pi(parent)->fcs;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100751 pi->sec_level = l2cap_pi(parent)->sec_level;
752 pi->role_switch = l2cap_pi(parent)->role_switch;
753 pi->force_reliable = l2cap_pi(parent)->force_reliable;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700754 } else {
755 pi->imtu = L2CAP_DEFAULT_MTU;
756 pi->omtu = 0;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -0700757 pi->mode = L2CAP_MODE_BASIC;
758 pi->fcs = L2CAP_FCS_CRC16;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100759 pi->sec_level = BT_SECURITY_LOW;
760 pi->role_switch = 0;
761 pi->force_reliable = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700762 }
763
764 /* Default config options */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +0200765 pi->conf_len = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700766 pi->flush_to = L2CAP_DEFAULT_FLUSH_TO;
767}
768
769static struct proto l2cap_proto = {
770 .name = "L2CAP",
771 .owner = THIS_MODULE,
772 .obj_size = sizeof(struct l2cap_pinfo)
773};
774
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700775static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700776{
777 struct sock *sk;
778
Pavel Emelyanov6257ff22007-11-01 00:39:31 -0700779 sk = sk_alloc(net, PF_BLUETOOTH, prio, &l2cap_proto);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700780 if (!sk)
781 return NULL;
782
783 sock_init_data(sock, sk);
784 INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
785
786 sk->sk_destruct = l2cap_sock_destruct;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200787 sk->sk_sndtimeo = msecs_to_jiffies(L2CAP_CONN_TIMEOUT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700788
789 sock_reset_flag(sk, SOCK_ZAPPED);
790
791 sk->sk_protocol = proto;
Marcel Holtmannb1235d7962008-07-14 20:13:54 +0200792 sk->sk_state = BT_OPEN;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700793
Marcel Holtmannb1235d7962008-07-14 20:13:54 +0200794 setup_timer(&sk->sk_timer, l2cap_sock_timeout, (unsigned long) sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700795
796 bt_sock_link(&l2cap_sk_list, sk);
797 return sk;
798}
799
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700800static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700801{
802 struct sock *sk;
803
804 BT_DBG("sock %p", sock);
805
806 sock->state = SS_UNCONNECTED;
807
808 if (sock->type != SOCK_SEQPACKET &&
809 sock->type != SOCK_DGRAM && sock->type != SOCK_RAW)
810 return -ESOCKTNOSUPPORT;
811
812 if (sock->type == SOCK_RAW && !capable(CAP_NET_RAW))
813 return -EPERM;
814
815 sock->ops = &l2cap_sock_ops;
816
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700817 sk = l2cap_sock_alloc(net, sock, protocol, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700818 if (!sk)
819 return -ENOMEM;
820
821 l2cap_sock_init(sk, NULL);
822 return 0;
823}
824
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100825static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700826{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700827 struct sock *sk = sock->sk;
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100828 struct sockaddr_l2 la;
829 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700830
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100831 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700832
833 if (!addr || addr->sa_family != AF_BLUETOOTH)
834 return -EINVAL;
835
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100836 memset(&la, 0, sizeof(la));
837 len = min_t(unsigned int, sizeof(la), alen);
838 memcpy(&la, addr, len);
839
Marcel Holtmann2a517ca2009-02-16 03:20:31 +0100840 if (la.l2_cid)
841 return -EINVAL;
842
Linus Torvalds1da177e2005-04-16 15:20:36 -0700843 lock_sock(sk);
844
845 if (sk->sk_state != BT_OPEN) {
846 err = -EBADFD;
847 goto done;
848 }
849
Marcel Holtmannb4324b52009-06-07 18:06:51 +0200850 if (la.l2_psm && __le16_to_cpu(la.l2_psm) < 0x1001 &&
Marcel Holtmann847641d2007-01-22 22:00:45 +0100851 !capable(CAP_NET_BIND_SERVICE)) {
852 err = -EACCES;
853 goto done;
854 }
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900855
Linus Torvalds1da177e2005-04-16 15:20:36 -0700856 write_lock_bh(&l2cap_sk_list.lock);
857
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100858 if (la.l2_psm && __l2cap_get_sock_by_addr(la.l2_psm, &la.l2_bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700859 err = -EADDRINUSE;
860 } else {
861 /* Save source address */
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100862 bacpy(&bt_sk(sk)->src, &la.l2_bdaddr);
863 l2cap_pi(sk)->psm = la.l2_psm;
864 l2cap_pi(sk)->sport = la.l2_psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700865 sk->sk_state = BT_BOUND;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100866
Marcel Holtmannb4324b52009-06-07 18:06:51 +0200867 if (__le16_to_cpu(la.l2_psm) == 0x0001 ||
868 __le16_to_cpu(la.l2_psm) == 0x0003)
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100869 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700870 }
871
872 write_unlock_bh(&l2cap_sk_list.lock);
873
874done:
875 release_sock(sk);
876 return err;
877}
878
879static int l2cap_do_connect(struct sock *sk)
880{
881 bdaddr_t *src = &bt_sk(sk)->src;
882 bdaddr_t *dst = &bt_sk(sk)->dst;
883 struct l2cap_conn *conn;
884 struct hci_conn *hcon;
885 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200886 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +0200887 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700888
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100889 BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst),
890 l2cap_pi(sk)->psm);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700891
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300892 hdev = hci_get_route(dst, src);
893 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700894 return -EHOSTUNREACH;
895
896 hci_dev_lock_bh(hdev);
897
898 err = -ENOMEM;
899
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100900 if (sk->sk_type == SOCK_RAW) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100901 switch (l2cap_pi(sk)->sec_level) {
902 case BT_SECURITY_HIGH:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100903 auth_type = HCI_AT_DEDICATED_BONDING_MITM;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100904 break;
905 case BT_SECURITY_MEDIUM:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100906 auth_type = HCI_AT_DEDICATED_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100907 break;
908 default:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100909 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100910 break;
911 }
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100912 } else if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100913 if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200914 auth_type = HCI_AT_NO_BONDING_MITM;
915 else
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200916 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann435fef22009-02-09 03:55:28 +0100917
918 if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW)
919 l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100920 } else {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100921 switch (l2cap_pi(sk)->sec_level) {
922 case BT_SECURITY_HIGH:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100923 auth_type = HCI_AT_GENERAL_BONDING_MITM;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100924 break;
925 case BT_SECURITY_MEDIUM:
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200926 auth_type = HCI_AT_GENERAL_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100927 break;
928 default:
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100929 auth_type = HCI_AT_NO_BONDING;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100930 break;
931 }
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200932 }
933
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +0100934 hcon = hci_connect(hdev, ACL_LINK, dst,
935 l2cap_pi(sk)->sec_level, auth_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700936 if (!hcon)
937 goto done;
938
939 conn = l2cap_conn_add(hcon, 0);
940 if (!conn) {
941 hci_conn_put(hcon);
942 goto done;
943 }
944
945 err = 0;
946
947 /* Update source addr of the socket */
948 bacpy(src, conn->src);
949
950 l2cap_chan_add(conn, sk, NULL);
951
952 sk->sk_state = BT_CONNECT;
953 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
954
955 if (hcon->state == BT_CONNECTED) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200956 if (sk->sk_type != SOCK_SEQPACKET) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700957 l2cap_sock_clear_timer(sk);
958 sk->sk_state = BT_CONNECTED;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200959 } else
960 l2cap_do_start(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700961 }
962
963done:
964 hci_dev_unlock_bh(hdev);
965 hci_dev_put(hdev);
966 return err;
967}
968
969static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
970{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700971 struct sock *sk = sock->sk;
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100972 struct sockaddr_l2 la;
973 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700974
Linus Torvalds1da177e2005-04-16 15:20:36 -0700975 BT_DBG("sk %p", sk);
976
Marcel Holtmann2a517ca2009-02-16 03:20:31 +0100977 if (!addr || addr->sa_family != AF_BLUETOOTH)
978 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700979
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100980 memset(&la, 0, sizeof(la));
981 len = min_t(unsigned int, sizeof(la), alen);
982 memcpy(&la, addr, len);
983
Marcel Holtmann2a517ca2009-02-16 03:20:31 +0100984 if (la.l2_cid)
985 return -EINVAL;
986
987 lock_sock(sk);
988
Marcel Holtmannf29972d2009-02-12 05:07:45 +0100989 if (sk->sk_type == SOCK_SEQPACKET && !la.l2_psm) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700990 err = -EINVAL;
991 goto done;
992 }
993
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -0700994 switch (l2cap_pi(sk)->mode) {
995 case L2CAP_MODE_BASIC:
996 break;
997 case L2CAP_MODE_ERTM:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -0300998 case L2CAP_MODE_STREAMING:
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -0700999 if (enable_ertm)
1000 break;
1001 /* fall through */
1002 default:
1003 err = -ENOTSUPP;
1004 goto done;
1005 }
1006
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001007 switch (sk->sk_state) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001008 case BT_CONNECT:
1009 case BT_CONNECT2:
1010 case BT_CONFIG:
1011 /* Already connecting */
1012 goto wait;
1013
1014 case BT_CONNECTED:
1015 /* Already connected */
1016 goto done;
1017
1018 case BT_OPEN:
1019 case BT_BOUND:
1020 /* Can connect */
1021 break;
1022
1023 default:
1024 err = -EBADFD;
1025 goto done;
1026 }
1027
1028 /* Set destination address and psm */
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001029 bacpy(&bt_sk(sk)->dst, &la.l2_bdaddr);
1030 l2cap_pi(sk)->psm = la.l2_psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001031
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001032 err = l2cap_do_connect(sk);
1033 if (err)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001034 goto done;
1035
1036wait:
1037 err = bt_sock_wait_state(sk, BT_CONNECTED,
1038 sock_sndtimeo(sk, flags & O_NONBLOCK));
1039done:
1040 release_sock(sk);
1041 return err;
1042}
1043
1044static int l2cap_sock_listen(struct socket *sock, int backlog)
1045{
1046 struct sock *sk = sock->sk;
1047 int err = 0;
1048
1049 BT_DBG("sk %p backlog %d", sk, backlog);
1050
1051 lock_sock(sk);
1052
1053 if (sk->sk_state != BT_BOUND || sock->type != SOCK_SEQPACKET) {
1054 err = -EBADFD;
1055 goto done;
1056 }
1057
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001058 switch (l2cap_pi(sk)->mode) {
1059 case L2CAP_MODE_BASIC:
1060 break;
1061 case L2CAP_MODE_ERTM:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001062 case L2CAP_MODE_STREAMING:
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001063 if (enable_ertm)
1064 break;
1065 /* fall through */
1066 default:
1067 err = -ENOTSUPP;
1068 goto done;
1069 }
1070
Linus Torvalds1da177e2005-04-16 15:20:36 -07001071 if (!l2cap_pi(sk)->psm) {
1072 bdaddr_t *src = &bt_sk(sk)->src;
1073 u16 psm;
1074
1075 err = -EINVAL;
1076
1077 write_lock_bh(&l2cap_sk_list.lock);
1078
1079 for (psm = 0x1001; psm < 0x1100; psm += 2)
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001080 if (!__l2cap_get_sock_by_addr(cpu_to_le16(psm), src)) {
1081 l2cap_pi(sk)->psm = cpu_to_le16(psm);
1082 l2cap_pi(sk)->sport = cpu_to_le16(psm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001083 err = 0;
1084 break;
1085 }
1086
1087 write_unlock_bh(&l2cap_sk_list.lock);
1088
1089 if (err < 0)
1090 goto done;
1091 }
1092
1093 sk->sk_max_ack_backlog = backlog;
1094 sk->sk_ack_backlog = 0;
1095 sk->sk_state = BT_LISTEN;
1096
1097done:
1098 release_sock(sk);
1099 return err;
1100}
1101
1102static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int flags)
1103{
1104 DECLARE_WAITQUEUE(wait, current);
1105 struct sock *sk = sock->sk, *nsk;
1106 long timeo;
1107 int err = 0;
1108
Peter Zijlstrafcc70d52006-11-08 22:44:35 -08001109 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001110
1111 if (sk->sk_state != BT_LISTEN) {
1112 err = -EBADFD;
1113 goto done;
1114 }
1115
1116 timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
1117
1118 BT_DBG("sk %p timeo %ld", sk, timeo);
1119
1120 /* Wait for an incoming connection. (wake-one). */
1121 add_wait_queue_exclusive(sk->sk_sleep, &wait);
1122 while (!(nsk = bt_accept_dequeue(sk, newsock))) {
1123 set_current_state(TASK_INTERRUPTIBLE);
1124 if (!timeo) {
1125 err = -EAGAIN;
1126 break;
1127 }
1128
1129 release_sock(sk);
1130 timeo = schedule_timeout(timeo);
Peter Zijlstrafcc70d52006-11-08 22:44:35 -08001131 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001132
1133 if (sk->sk_state != BT_LISTEN) {
1134 err = -EBADFD;
1135 break;
1136 }
1137
1138 if (signal_pending(current)) {
1139 err = sock_intr_errno(timeo);
1140 break;
1141 }
1142 }
1143 set_current_state(TASK_RUNNING);
1144 remove_wait_queue(sk->sk_sleep, &wait);
1145
1146 if (err)
1147 goto done;
1148
1149 newsock->state = SS_CONNECTED;
1150
1151 BT_DBG("new socket %p", nsk);
1152
1153done:
1154 release_sock(sk);
1155 return err;
1156}
1157
1158static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
1159{
1160 struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
1161 struct sock *sk = sock->sk;
1162
1163 BT_DBG("sock %p, sk %p", sock, sk);
1164
1165 addr->sa_family = AF_BLUETOOTH;
1166 *len = sizeof(struct sockaddr_l2);
1167
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001168 if (peer) {
1169 la->l2_psm = l2cap_pi(sk)->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001170 bacpy(&la->l2_bdaddr, &bt_sk(sk)->dst);
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001171 la->l2_cid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001172 } else {
1173 la->l2_psm = l2cap_pi(sk)->sport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001174 bacpy(&la->l2_bdaddr, &bt_sk(sk)->src);
Marcel Holtmannb4324b52009-06-07 18:06:51 +02001175 la->l2_cid = cpu_to_le16(l2cap_pi(sk)->scid);
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001176 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001177
Linus Torvalds1da177e2005-04-16 15:20:36 -07001178 return 0;
1179}
1180
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001181static void l2cap_drop_acked_frames(struct sock *sk)
1182{
1183 struct sk_buff *skb;
1184
1185 while ((skb = skb_peek(TX_QUEUE(sk)))) {
1186 if (bt_cb(skb)->tx_seq == l2cap_pi(sk)->expected_ack_seq)
1187 break;
1188
1189 skb = skb_dequeue(TX_QUEUE(sk));
1190 kfree_skb(skb);
1191
1192 l2cap_pi(sk)->unacked_frames--;
1193 }
1194
1195 return;
1196}
1197
1198static inline int l2cap_do_send(struct sock *sk, struct sk_buff *skb)
1199{
1200 struct l2cap_pinfo *pi = l2cap_pi(sk);
1201 int err;
1202
1203 BT_DBG("sk %p, skb %p len %d", sk, skb, skb->len);
1204
1205 err = hci_send_acl(pi->conn->hcon, skb, 0);
1206 if (err < 0)
1207 kfree_skb(skb);
1208
1209 return err;
1210}
1211
1212static int l2cap_ertm_send(struct sock *sk)
1213{
1214 struct sk_buff *skb, *tx_skb;
1215 struct l2cap_pinfo *pi = l2cap_pi(sk);
1216 u16 control;
1217 int err;
1218
1219 while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(sk))) {
1220 tx_skb = skb_clone(skb, GFP_ATOMIC);
1221
1222 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
1223 control |= (pi->req_seq << L2CAP_CTRL_REQSEQ_SHIFT)
1224 | (pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
1225 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1226
1227 err = l2cap_do_send(sk, tx_skb);
1228 if (err < 0) {
1229 l2cap_send_disconn_req(pi->conn, sk);
1230 return err;
1231 }
1232
1233 bt_cb(skb)->tx_seq = pi->next_tx_seq;
1234 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
1235
1236 pi->unacked_frames++;
1237
1238 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1239 sk->sk_send_head = NULL;
1240 else
1241 sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
1242 }
1243
1244 return 0;
1245}
1246
1247static inline int l2cap_skbuff_fromiovec(struct sock *sk, struct msghdr *msg, int len, int count, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001248{
1249 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001250 struct sk_buff **frag;
1251 int err, sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001252
1253 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count)) {
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001254 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001255 }
1256
1257 sent += count;
1258 len -= count;
1259
1260 /* Continuation fragments (no L2CAP header) */
1261 frag = &skb_shinfo(skb)->frag_list;
1262 while (len) {
1263 count = min_t(unsigned int, conn->mtu, len);
1264
1265 *frag = bt_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err);
1266 if (!*frag)
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001267 return -EFAULT;
1268 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
1269 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001270
1271 sent += count;
1272 len -= count;
1273
1274 frag = &(*frag)->next;
1275 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001276
1277 return sent;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001278}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001279
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001280static struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, size_t len)
1281{
1282 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1283 struct sk_buff *skb;
1284 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1285 struct l2cap_hdr *lh;
1286
1287 BT_DBG("sk %p len %d", sk, (int)len);
1288
1289 count = min_t(unsigned int, (conn->mtu - hlen), len);
1290 skb = bt_skb_send_alloc(sk, count + hlen,
1291 msg->msg_flags & MSG_DONTWAIT, &err);
1292 if (!skb)
1293 return ERR_PTR(-ENOMEM);
1294
1295 /* Create L2CAP header */
1296 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1297 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1298 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1299 put_unaligned_le16(l2cap_pi(sk)->psm, skb_put(skb, 2));
1300
1301 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1302 if (unlikely(err < 0)) {
1303 kfree_skb(skb);
1304 return ERR_PTR(err);
1305 }
1306 return skb;
1307}
1308
1309static struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *msg, size_t len)
1310{
1311 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1312 struct sk_buff *skb;
1313 int err, count, hlen = L2CAP_HDR_SIZE;
1314 struct l2cap_hdr *lh;
1315
1316 BT_DBG("sk %p len %d", sk, (int)len);
1317
1318 count = min_t(unsigned int, (conn->mtu - hlen), len);
1319 skb = bt_skb_send_alloc(sk, count + hlen,
1320 msg->msg_flags & MSG_DONTWAIT, &err);
1321 if (!skb)
1322 return ERR_PTR(-ENOMEM);
1323
1324 /* Create L2CAP header */
1325 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1326 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1327 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1328
1329 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1330 if (unlikely(err < 0)) {
1331 kfree_skb(skb);
1332 return ERR_PTR(err);
1333 }
1334 return skb;
1335}
1336
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001337static struct sk_buff *l2cap_create_ertm_pdu(struct sock *sk, struct msghdr *msg, size_t len, u16 control, u16 sdulen)
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001338{
1339 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1340 struct sk_buff *skb;
1341 int err, count, hlen = L2CAP_HDR_SIZE + 2;
1342 struct l2cap_hdr *lh;
1343
1344 BT_DBG("sk %p len %d", sk, (int)len);
1345
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001346 if (sdulen)
1347 hlen += 2;
1348
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001349 count = min_t(unsigned int, (conn->mtu - hlen), len);
1350 skb = bt_skb_send_alloc(sk, count + hlen,
1351 msg->msg_flags & MSG_DONTWAIT, &err);
1352 if (!skb)
1353 return ERR_PTR(-ENOMEM);
1354
1355 /* Create L2CAP header */
1356 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
1357 lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
1358 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
1359 put_unaligned_le16(control, skb_put(skb, 2));
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001360 if (sdulen)
1361 put_unaligned_le16(sdulen, skb_put(skb, 2));
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001362
1363 err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
1364 if (unlikely(err < 0)) {
1365 kfree_skb(skb);
1366 return ERR_PTR(err);
1367 }
1368 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001369}
1370
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001371static inline int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len)
1372{
1373 struct l2cap_pinfo *pi = l2cap_pi(sk);
1374 struct sk_buff *skb;
1375 struct sk_buff_head sar_queue;
1376 u16 control;
1377 size_t size = 0;
1378
1379 __skb_queue_head_init(&sar_queue);
1380 control = L2CAP_SDU_START;
1381 skb = l2cap_create_ertm_pdu(sk, msg, pi->max_pdu_size, control, len);
1382 if (IS_ERR(skb))
1383 return PTR_ERR(skb);
1384
1385 __skb_queue_tail(&sar_queue, skb);
1386 len -= pi->max_pdu_size;
1387 size +=pi->max_pdu_size;
1388 control = 0;
1389
1390 while (len > 0) {
1391 size_t buflen;
1392
1393 if (len > pi->max_pdu_size) {
1394 control |= L2CAP_SDU_CONTINUE;
1395 buflen = pi->max_pdu_size;
1396 } else {
1397 control |= L2CAP_SDU_END;
1398 buflen = len;
1399 }
1400
1401 skb = l2cap_create_ertm_pdu(sk, msg, buflen, control, 0);
1402 if (IS_ERR(skb)) {
1403 skb_queue_purge(&sar_queue);
1404 return PTR_ERR(skb);
1405 }
1406
1407 __skb_queue_tail(&sar_queue, skb);
1408 len -= buflen;
1409 size += buflen;
1410 control = 0;
1411 }
1412 skb_queue_splice_tail(&sar_queue, TX_QUEUE(sk));
1413 if (sk->sk_send_head == NULL)
1414 sk->sk_send_head = sar_queue.next;
1415
1416 return size;
1417}
1418
Linus Torvalds1da177e2005-04-16 15:20:36 -07001419static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len)
1420{
1421 struct sock *sk = sock->sk;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001422 struct l2cap_pinfo *pi = l2cap_pi(sk);
1423 struct sk_buff *skb;
1424 u16 control;
1425 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001426
1427 BT_DBG("sock %p, sk %p", sock, sk);
1428
Benjamin LaHaisec1cbe4b2005-12-13 23:22:19 -08001429 err = sock_error(sk);
1430 if (err)
1431 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001432
1433 if (msg->msg_flags & MSG_OOB)
1434 return -EOPNOTSUPP;
1435
1436 /* Check outgoing MTU */
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001437 if (sk->sk_type == SOCK_SEQPACKET && pi->mode == L2CAP_MODE_BASIC
1438 && len > pi->omtu)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001439 return -EINVAL;
1440
1441 lock_sock(sk);
1442
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001443 if (sk->sk_state != BT_CONNECTED) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001444 err = -ENOTCONN;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001445 goto done;
1446 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001447
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001448 /* Connectionless channel */
1449 if (sk->sk_type == SOCK_DGRAM) {
1450 skb = l2cap_create_connless_pdu(sk, msg, len);
1451 err = l2cap_do_send(sk, skb);
1452 goto done;
1453 }
1454
1455 switch (pi->mode) {
1456 case L2CAP_MODE_BASIC:
1457 /* Create a basic PDU */
1458 skb = l2cap_create_basic_pdu(sk, msg, len);
1459 if (IS_ERR(skb)) {
1460 err = PTR_ERR(skb);
1461 goto done;
1462 }
1463
1464 err = l2cap_do_send(sk, skb);
1465 if (!err)
1466 err = len;
1467 break;
1468
1469 case L2CAP_MODE_ERTM:
1470 /* Entire SDU fits into one PDU */
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001471 if (len <= pi->max_pdu_size) {
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001472 control = L2CAP_SDU_UNSEGMENTED;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001473 skb = l2cap_create_ertm_pdu(sk, msg, len, control, 0);
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001474 if (IS_ERR(skb)) {
1475 err = PTR_ERR(skb);
1476 goto done;
1477 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001478 __skb_queue_tail(TX_QUEUE(sk), skb);
1479 if (sk->sk_send_head == NULL)
1480 sk->sk_send_head = skb;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001481 } else {
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03001482 /* Segment SDU into multiples PDUs */
1483 err = l2cap_sar_segment_sdu(sk, msg, len);
1484 if (err < 0)
1485 goto done;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001486 }
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001487
1488 err = l2cap_ertm_send(sk);
1489 if (!err)
1490 err = len;
1491 break;
1492
1493 default:
1494 BT_DBG("bad state %1.1x", pi->mode);
1495 err = -EINVAL;
1496 }
1497
1498done:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001499 release_sock(sk);
1500 return err;
1501}
1502
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001503static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags)
1504{
1505 struct sock *sk = sock->sk;
1506
1507 lock_sock(sk);
1508
1509 if (sk->sk_state == BT_CONNECT2 && bt_sk(sk)->defer_setup) {
1510 struct l2cap_conn_rsp rsp;
1511
1512 sk->sk_state = BT_CONFIG;
1513
1514 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
1515 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
1516 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
1517 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
1518 l2cap_send_cmd(l2cap_pi(sk)->conn, l2cap_pi(sk)->ident,
1519 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
1520
1521 release_sock(sk);
1522 return 0;
1523 }
1524
1525 release_sock(sk);
1526
1527 return bt_sock_recvmsg(iocb, sock, msg, len, flags);
1528}
1529
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001530static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, int optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001531{
1532 struct sock *sk = sock->sk;
1533 struct l2cap_options opts;
Marcel Holtmannf29972d2009-02-12 05:07:45 +01001534 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001535 u32 opt;
1536
1537 BT_DBG("sk %p", sk);
1538
1539 lock_sock(sk);
1540
1541 switch (optname) {
1542 case L2CAP_OPTIONS:
Marcel Holtmann0878b662007-05-05 00:35:59 +02001543 opts.imtu = l2cap_pi(sk)->imtu;
1544 opts.omtu = l2cap_pi(sk)->omtu;
1545 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001546 opts.mode = l2cap_pi(sk)->mode;
Marcel Holtmann0878b662007-05-05 00:35:59 +02001547
Linus Torvalds1da177e2005-04-16 15:20:36 -07001548 len = min_t(unsigned int, sizeof(opts), optlen);
1549 if (copy_from_user((char *) &opts, optval, len)) {
1550 err = -EFAULT;
1551 break;
1552 }
Marcel Holtmann0878b662007-05-05 00:35:59 +02001553
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001554 l2cap_pi(sk)->imtu = opts.imtu;
1555 l2cap_pi(sk)->omtu = opts.omtu;
1556 l2cap_pi(sk)->mode = opts.mode;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001557 break;
1558
1559 case L2CAP_LM:
1560 if (get_user(opt, (u32 __user *) optval)) {
1561 err = -EFAULT;
1562 break;
1563 }
1564
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001565 if (opt & L2CAP_LM_AUTH)
1566 l2cap_pi(sk)->sec_level = BT_SECURITY_LOW;
1567 if (opt & L2CAP_LM_ENCRYPT)
1568 l2cap_pi(sk)->sec_level = BT_SECURITY_MEDIUM;
1569 if (opt & L2CAP_LM_SECURE)
1570 l2cap_pi(sk)->sec_level = BT_SECURITY_HIGH;
1571
1572 l2cap_pi(sk)->role_switch = (opt & L2CAP_LM_MASTER);
1573 l2cap_pi(sk)->force_reliable = (opt & L2CAP_LM_RELIABLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001574 break;
1575
1576 default:
1577 err = -ENOPROTOOPT;
1578 break;
1579 }
1580
1581 release_sock(sk);
1582 return err;
1583}
1584
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001585static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen)
1586{
1587 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001588 struct bt_security sec;
1589 int len, err = 0;
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001590 u32 opt;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001591
1592 BT_DBG("sk %p", sk);
1593
1594 if (level == SOL_L2CAP)
1595 return l2cap_sock_setsockopt_old(sock, optname, optval, optlen);
1596
Marcel Holtmann0588d942009-01-16 10:06:13 +01001597 if (level != SOL_BLUETOOTH)
1598 return -ENOPROTOOPT;
1599
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001600 lock_sock(sk);
1601
1602 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001603 case BT_SECURITY:
Marcel Holtmann2526d3d2009-02-20 20:54:06 +01001604 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01001605 err = -EINVAL;
1606 break;
1607 }
1608
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001609 sec.level = BT_SECURITY_LOW;
1610
1611 len = min_t(unsigned int, sizeof(sec), optlen);
1612 if (copy_from_user((char *) &sec, optval, len)) {
1613 err = -EFAULT;
1614 break;
1615 }
1616
1617 if (sec.level < BT_SECURITY_LOW ||
1618 sec.level > BT_SECURITY_HIGH) {
1619 err = -EINVAL;
1620 break;
1621 }
1622
1623 l2cap_pi(sk)->sec_level = sec.level;
1624 break;
1625
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001626 case BT_DEFER_SETUP:
1627 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
1628 err = -EINVAL;
1629 break;
1630 }
1631
1632 if (get_user(opt, (u32 __user *) optval)) {
1633 err = -EFAULT;
1634 break;
1635 }
1636
1637 bt_sk(sk)->defer_setup = opt;
1638 break;
1639
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001640 default:
1641 err = -ENOPROTOOPT;
1642 break;
1643 }
1644
1645 release_sock(sk);
1646 return err;
1647}
1648
1649static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001650{
1651 struct sock *sk = sock->sk;
1652 struct l2cap_options opts;
1653 struct l2cap_conninfo cinfo;
1654 int len, err = 0;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001655 u32 opt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001656
1657 BT_DBG("sk %p", sk);
1658
1659 if (get_user(len, optlen))
1660 return -EFAULT;
1661
1662 lock_sock(sk);
1663
1664 switch (optname) {
1665 case L2CAP_OPTIONS:
1666 opts.imtu = l2cap_pi(sk)->imtu;
1667 opts.omtu = l2cap_pi(sk)->omtu;
1668 opts.flush_to = l2cap_pi(sk)->flush_to;
Marcel Holtmannc6b03cf2009-05-02 22:31:10 -07001669 opts.mode = l2cap_pi(sk)->mode;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001670
1671 len = min_t(unsigned int, len, sizeof(opts));
1672 if (copy_to_user(optval, (char *) &opts, len))
1673 err = -EFAULT;
1674
1675 break;
1676
1677 case L2CAP_LM:
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001678 switch (l2cap_pi(sk)->sec_level) {
1679 case BT_SECURITY_LOW:
1680 opt = L2CAP_LM_AUTH;
1681 break;
1682 case BT_SECURITY_MEDIUM:
1683 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT;
1684 break;
1685 case BT_SECURITY_HIGH:
1686 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT |
1687 L2CAP_LM_SECURE;
1688 break;
1689 default:
1690 opt = 0;
1691 break;
1692 }
1693
1694 if (l2cap_pi(sk)->role_switch)
1695 opt |= L2CAP_LM_MASTER;
1696
1697 if (l2cap_pi(sk)->force_reliable)
1698 opt |= L2CAP_LM_RELIABLE;
1699
1700 if (put_user(opt, (u32 __user *) optval))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001701 err = -EFAULT;
1702 break;
1703
1704 case L2CAP_CONNINFO:
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001705 if (sk->sk_state != BT_CONNECTED &&
1706 !(sk->sk_state == BT_CONNECT2 &&
1707 bt_sk(sk)->defer_setup)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001708 err = -ENOTCONN;
1709 break;
1710 }
1711
1712 cinfo.hci_handle = l2cap_pi(sk)->conn->hcon->handle;
1713 memcpy(cinfo.dev_class, l2cap_pi(sk)->conn->hcon->dev_class, 3);
1714
1715 len = min_t(unsigned int, len, sizeof(cinfo));
1716 if (copy_to_user(optval, (char *) &cinfo, len))
1717 err = -EFAULT;
1718
1719 break;
1720
1721 default:
1722 err = -ENOPROTOOPT;
1723 break;
1724 }
1725
1726 release_sock(sk);
1727 return err;
1728}
1729
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001730static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
1731{
1732 struct sock *sk = sock->sk;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001733 struct bt_security sec;
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001734 int len, err = 0;
1735
1736 BT_DBG("sk %p", sk);
1737
1738 if (level == SOL_L2CAP)
1739 return l2cap_sock_getsockopt_old(sock, optname, optval, optlen);
1740
Marcel Holtmann0588d942009-01-16 10:06:13 +01001741 if (level != SOL_BLUETOOTH)
1742 return -ENOPROTOOPT;
1743
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001744 if (get_user(len, optlen))
1745 return -EFAULT;
1746
1747 lock_sock(sk);
1748
1749 switch (optname) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001750 case BT_SECURITY:
Marcel Holtmann2526d3d2009-02-20 20:54:06 +01001751 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_RAW) {
Marcel Holtmann0588d942009-01-16 10:06:13 +01001752 err = -EINVAL;
1753 break;
1754 }
1755
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01001756 sec.level = l2cap_pi(sk)->sec_level;
1757
1758 len = min_t(unsigned int, len, sizeof(sec));
1759 if (copy_to_user(optval, (char *) &sec, len))
1760 err = -EFAULT;
1761
1762 break;
1763
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001764 case BT_DEFER_SETUP:
1765 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
1766 err = -EINVAL;
1767 break;
1768 }
1769
1770 if (put_user(bt_sk(sk)->defer_setup, (u32 __user *) optval))
1771 err = -EFAULT;
1772
1773 break;
1774
Marcel Holtmannd58daf42009-01-15 21:52:14 +01001775 default:
1776 err = -ENOPROTOOPT;
1777 break;
1778 }
1779
1780 release_sock(sk);
1781 return err;
1782}
1783
Linus Torvalds1da177e2005-04-16 15:20:36 -07001784static int l2cap_sock_shutdown(struct socket *sock, int how)
1785{
1786 struct sock *sk = sock->sk;
1787 int err = 0;
1788
1789 BT_DBG("sock %p, sk %p", sock, sk);
1790
1791 if (!sk)
1792 return 0;
1793
1794 lock_sock(sk);
1795 if (!sk->sk_shutdown) {
1796 sk->sk_shutdown = SHUTDOWN_MASK;
1797 l2cap_sock_clear_timer(sk);
1798 __l2cap_sock_close(sk, 0);
1799
1800 if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
Marcel Holtmannb1235d7962008-07-14 20:13:54 +02001801 err = bt_sock_wait_state(sk, BT_CLOSED,
1802 sk->sk_lingertime);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001803 }
1804 release_sock(sk);
1805 return err;
1806}
1807
1808static int l2cap_sock_release(struct socket *sock)
1809{
1810 struct sock *sk = sock->sk;
1811 int err;
1812
1813 BT_DBG("sock %p, sk %p", sock, sk);
1814
1815 if (!sk)
1816 return 0;
1817
1818 err = l2cap_sock_shutdown(sock, 2);
1819
1820 sock_orphan(sk);
1821 l2cap_sock_kill(sk);
1822 return err;
1823}
1824
Linus Torvalds1da177e2005-04-16 15:20:36 -07001825static void l2cap_chan_ready(struct sock *sk)
1826{
1827 struct sock *parent = bt_sk(sk)->parent;
1828
1829 BT_DBG("sk %p, parent %p", sk, parent);
1830
1831 l2cap_pi(sk)->conf_state = 0;
1832 l2cap_sock_clear_timer(sk);
1833
1834 if (!parent) {
1835 /* Outgoing channel.
1836 * Wake up socket sleeping on connect.
1837 */
1838 sk->sk_state = BT_CONNECTED;
1839 sk->sk_state_change(sk);
1840 } else {
1841 /* Incoming channel.
1842 * Wake up socket sleeping on accept.
1843 */
1844 parent->sk_data_ready(parent, 0);
1845 }
1846}
1847
1848/* Copy frame to all raw sockets on that connection */
1849static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
1850{
1851 struct l2cap_chan_list *l = &conn->chan_list;
1852 struct sk_buff *nskb;
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001853 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001854
1855 BT_DBG("conn %p", conn);
1856
1857 read_lock(&l->lock);
1858 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
1859 if (sk->sk_type != SOCK_RAW)
1860 continue;
1861
1862 /* Don't send frame to the socket it came from */
1863 if (skb->sk == sk)
1864 continue;
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001865 nskb = skb_clone(skb, GFP_ATOMIC);
1866 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001867 continue;
1868
1869 if (sock_queue_rcv_skb(sk, nskb))
1870 kfree_skb(nskb);
1871 }
1872 read_unlock(&l->lock);
1873}
1874
1875/* ---- L2CAP signalling commands ---- */
1876static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
1877 u8 code, u8 ident, u16 dlen, void *data)
1878{
1879 struct sk_buff *skb, **frag;
1880 struct l2cap_cmd_hdr *cmd;
1881 struct l2cap_hdr *lh;
1882 int len, count;
1883
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001884 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d",
1885 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001886
1887 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
1888 count = min_t(unsigned int, conn->mtu, len);
1889
1890 skb = bt_skb_alloc(count, GFP_ATOMIC);
1891 if (!skb)
1892 return NULL;
1893
1894 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07001895 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03001896 lh->cid = cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001897
1898 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
1899 cmd->code = code;
1900 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07001901 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001902
1903 if (dlen) {
1904 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
1905 memcpy(skb_put(skb, count), data, count);
1906 data += count;
1907 }
1908
1909 len -= skb->len;
1910
1911 /* Continuation fragments (no L2CAP header) */
1912 frag = &skb_shinfo(skb)->frag_list;
1913 while (len) {
1914 count = min_t(unsigned int, conn->mtu, len);
1915
1916 *frag = bt_skb_alloc(count, GFP_ATOMIC);
1917 if (!*frag)
1918 goto fail;
1919
1920 memcpy(skb_put(*frag, count), data, count);
1921
1922 len -= count;
1923 data += count;
1924
1925 frag = &(*frag)->next;
1926 }
1927
1928 return skb;
1929
1930fail:
1931 kfree_skb(skb);
1932 return NULL;
1933}
1934
1935static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned long *val)
1936{
1937 struct l2cap_conf_opt *opt = *ptr;
1938 int len;
1939
1940 len = L2CAP_CONF_OPT_SIZE + opt->len;
1941 *ptr += len;
1942
1943 *type = opt->type;
1944 *olen = opt->len;
1945
1946 switch (opt->len) {
1947 case 1:
1948 *val = *((u8 *) opt->val);
1949 break;
1950
1951 case 2:
Marcel Holtmann861d6882007-10-20 13:37:06 +02001952 *val = __le16_to_cpu(*((__le16 *) opt->val));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001953 break;
1954
1955 case 4:
Marcel Holtmann861d6882007-10-20 13:37:06 +02001956 *val = __le32_to_cpu(*((__le32 *) opt->val));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001957 break;
1958
1959 default:
1960 *val = (unsigned long) opt->val;
1961 break;
1962 }
1963
1964 BT_DBG("type 0x%2.2x len %d val 0x%lx", *type, opt->len, *val);
1965 return len;
1966}
1967
Linus Torvalds1da177e2005-04-16 15:20:36 -07001968static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
1969{
1970 struct l2cap_conf_opt *opt = *ptr;
1971
1972 BT_DBG("type 0x%2.2x len %d val 0x%lx", type, len, val);
1973
1974 opt->type = type;
1975 opt->len = len;
1976
1977 switch (len) {
1978 case 1:
1979 *((u8 *) opt->val) = val;
1980 break;
1981
1982 case 2:
Al Viro8e036fc2007-07-29 00:16:36 -07001983 *((__le16 *) opt->val) = cpu_to_le16(val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001984 break;
1985
1986 case 4:
Al Viro8e036fc2007-07-29 00:16:36 -07001987 *((__le32 *) opt->val) = cpu_to_le32(val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001988 break;
1989
1990 default:
1991 memcpy(opt->val, (void *) val, len);
1992 break;
1993 }
1994
1995 *ptr += L2CAP_CONF_OPT_SIZE + len;
1996}
1997
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03001998static int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
1999{
2000 u32 local_feat_mask = l2cap_feat_mask;
2001 if (enable_ertm)
2002 local_feat_mask |= L2CAP_FEAT_ERTM;
2003
2004 switch (mode) {
2005 case L2CAP_MODE_ERTM:
2006 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
2007 case L2CAP_MODE_STREAMING:
2008 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
2009 default:
2010 return 0x00;
2011 }
2012}
2013
2014static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
2015{
2016 switch (mode) {
2017 case L2CAP_MODE_STREAMING:
2018 case L2CAP_MODE_ERTM:
2019 if (l2cap_mode_supported(mode, remote_feat_mask))
2020 return mode;
2021 /* fall through */
2022 default:
2023 return L2CAP_MODE_BASIC;
2024 }
2025}
2026
Linus Torvalds1da177e2005-04-16 15:20:36 -07002027static int l2cap_build_conf_req(struct sock *sk, void *data)
2028{
2029 struct l2cap_pinfo *pi = l2cap_pi(sk);
2030 struct l2cap_conf_req *req = data;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002031 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_ERTM };
Linus Torvalds1da177e2005-04-16 15:20:36 -07002032 void *ptr = req->data;
2033
2034 BT_DBG("sk %p", sk);
2035
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002036 if (pi->num_conf_req || pi->num_conf_rsp)
2037 goto done;
2038
2039 switch (pi->mode) {
2040 case L2CAP_MODE_STREAMING:
2041 case L2CAP_MODE_ERTM:
2042 pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002043 if (!l2cap_mode_supported(pi->mode, pi->conn->feat_mask))
2044 l2cap_send_disconn_req(pi->conn, sk);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002045 break;
2046 default:
2047 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
2048 break;
2049 }
2050
2051done:
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002052 switch (pi->mode) {
2053 case L2CAP_MODE_BASIC:
2054 if (pi->imtu != L2CAP_DEFAULT_MTU)
2055 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
2056 break;
2057
2058 case L2CAP_MODE_ERTM:
2059 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002060 rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW;
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002061 rfc.max_transmit = L2CAP_DEFAULT_MAX_RECEIVE;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002062 rfc.retrans_timeout = 0;
2063 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002064 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002065
2066 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2067 sizeof(rfc), (unsigned long) &rfc);
2068 break;
2069
2070 case L2CAP_MODE_STREAMING:
2071 rfc.mode = L2CAP_MODE_STREAMING;
2072 rfc.txwin_size = 0;
2073 rfc.max_transmit = 0;
2074 rfc.retrans_timeout = 0;
2075 rfc.monitor_timeout = 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002076 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002077
2078 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2079 sizeof(rfc), (unsigned long) &rfc);
2080 break;
2081 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002082
2083 /* FIXME: Need actual value of the flush timeout */
2084 //if (flush_to != L2CAP_DEFAULT_FLUSH_TO)
2085 // l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2, pi->flush_to);
2086
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002087 req->dcid = cpu_to_le16(pi->dcid);
2088 req->flags = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002089
2090 return ptr - data;
2091}
2092
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002093static int l2cap_parse_conf_req(struct sock *sk, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002094{
2095 struct l2cap_pinfo *pi = l2cap_pi(sk);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002096 struct l2cap_conf_rsp *rsp = data;
2097 void *ptr = rsp->data;
2098 void *req = pi->conf_req;
2099 int len = pi->conf_len;
2100 int type, hint, olen;
2101 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002102 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Marcel Holtmann861d6882007-10-20 13:37:06 +02002103 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002104 u16 result = L2CAP_CONF_SUCCESS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002105
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002106 BT_DBG("sk %p", sk);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01002107
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002108 while (len >= L2CAP_CONF_OPT_SIZE) {
2109 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002110
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03002111 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07002112 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002113
2114 switch (type) {
2115 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002116 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002117 break;
2118
2119 case L2CAP_CONF_FLUSH_TO:
2120 pi->flush_to = val;
2121 break;
2122
2123 case L2CAP_CONF_QOS:
2124 break;
2125
Marcel Holtmann6464f352007-10-20 13:39:51 +02002126 case L2CAP_CONF_RFC:
2127 if (olen == sizeof(rfc))
2128 memcpy(&rfc, (void *) val, olen);
2129 break;
2130
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002131 default:
2132 if (hint)
2133 break;
2134
2135 result = L2CAP_CONF_UNKNOWN;
2136 *((u8 *) ptr++) = type;
2137 break;
2138 }
2139 }
2140
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002141 if (pi->num_conf_rsp || pi->num_conf_req)
2142 goto done;
2143
2144 switch (pi->mode) {
2145 case L2CAP_MODE_STREAMING:
2146 case L2CAP_MODE_ERTM:
2147 pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
2148 if (!l2cap_mode_supported(pi->mode, pi->conn->feat_mask))
2149 return -ECONNREFUSED;
2150 break;
2151 default:
2152 pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
2153 break;
2154 }
2155
2156done:
2157 if (pi->mode != rfc.mode) {
2158 result = L2CAP_CONF_UNACCEPT;
2159 rfc.mode = pi->mode;
2160
2161 if (pi->num_conf_rsp == 1)
2162 return -ECONNREFUSED;
2163
2164 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2165 sizeof(rfc), (unsigned long) &rfc);
2166 }
2167
2168
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002169 if (result == L2CAP_CONF_SUCCESS) {
2170 /* Configure output options and let the other side know
2171 * which ones we don't like. */
2172
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002173 if (mtu < L2CAP_DEFAULT_MIN_MTU)
2174 result = L2CAP_CONF_UNACCEPT;
2175 else {
2176 pi->omtu = mtu;
2177 pi->conf_state |= L2CAP_CONF_MTU_DONE;
2178 }
2179 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002180
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002181 switch (rfc.mode) {
2182 case L2CAP_MODE_BASIC:
2183 pi->fcs = L2CAP_FCS_NONE;
2184 pi->conf_state |= L2CAP_CONF_MODE_DONE;
2185 break;
2186
2187 case L2CAP_MODE_ERTM:
2188 pi->remote_tx_win = rfc.txwin_size;
2189 pi->remote_max_tx = rfc.max_transmit;
2190 pi->max_pdu_size = rfc.max_pdu_size;
2191
2192 rfc.retrans_timeout = L2CAP_DEFAULT_RETRANS_TO;
2193 rfc.monitor_timeout = L2CAP_DEFAULT_MONITOR_TO;
2194
2195 pi->conf_state |= L2CAP_CONF_MODE_DONE;
2196 break;
2197
2198 case L2CAP_MODE_STREAMING:
2199 pi->remote_tx_win = rfc.txwin_size;
2200 pi->max_pdu_size = rfc.max_pdu_size;
2201
2202 pi->conf_state |= L2CAP_CONF_MODE_DONE;
2203 break;
2204
2205 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02002206 result = L2CAP_CONF_UNACCEPT;
2207
2208 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002209 rfc.mode = pi->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002210 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002211
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002212 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2213 sizeof(rfc), (unsigned long) &rfc);
2214
2215 if (result == L2CAP_CONF_SUCCESS)
2216 pi->conf_state |= L2CAP_CONF_OUTPUT_DONE;
2217 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002218 rsp->scid = cpu_to_le16(pi->dcid);
2219 rsp->result = cpu_to_le16(result);
2220 rsp->flags = cpu_to_le16(0x0000);
2221
2222 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002223}
2224
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002225static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data, u16 *result)
2226{
2227 struct l2cap_pinfo *pi = l2cap_pi(sk);
2228 struct l2cap_conf_req *req = data;
2229 void *ptr = req->data;
2230 int type, olen;
2231 unsigned long val;
2232 struct l2cap_conf_rfc rfc;
2233
2234 BT_DBG("sk %p, rsp %p, len %d, req %p", sk, rsp, len, data);
2235
2236 while (len >= L2CAP_CONF_OPT_SIZE) {
2237 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
2238
2239 switch (type) {
2240 case L2CAP_CONF_MTU:
2241 if (val < L2CAP_DEFAULT_MIN_MTU) {
2242 *result = L2CAP_CONF_UNACCEPT;
2243 pi->omtu = L2CAP_DEFAULT_MIN_MTU;
2244 } else
2245 pi->omtu = val;
2246 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
2247 break;
2248
2249 case L2CAP_CONF_FLUSH_TO:
2250 pi->flush_to = val;
2251 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
2252 2, pi->flush_to);
2253 break;
2254
2255 case L2CAP_CONF_RFC:
2256 if (olen == sizeof(rfc))
2257 memcpy(&rfc, (void *)val, olen);
2258
2259 if ((pi->conf_state & L2CAP_CONF_STATE2_DEVICE) &&
2260 rfc.mode != pi->mode)
2261 return -ECONNREFUSED;
2262
2263 pi->mode = rfc.mode;
2264 pi->fcs = 0;
2265
2266 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2267 sizeof(rfc), (unsigned long) &rfc);
2268 break;
2269 }
2270 }
2271
2272 if (*result == L2CAP_CONF_SUCCESS) {
2273 switch (rfc.mode) {
2274 case L2CAP_MODE_ERTM:
2275 pi->remote_tx_win = rfc.txwin_size;
2276 pi->retrans_timeout = rfc.retrans_timeout;
2277 pi->monitor_timeout = rfc.monitor_timeout;
2278 pi->max_pdu_size = le16_to_cpu(rfc.max_pdu_size);
2279 break;
2280 case L2CAP_MODE_STREAMING:
2281 pi->max_pdu_size = le16_to_cpu(rfc.max_pdu_size);
2282 break;
2283 }
2284 }
2285
2286 req->dcid = cpu_to_le16(pi->dcid);
2287 req->flags = cpu_to_le16(0x0000);
2288
2289 return ptr - data;
2290}
2291
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002292static int l2cap_build_conf_rsp(struct sock *sk, void *data, u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002293{
2294 struct l2cap_conf_rsp *rsp = data;
2295 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002296
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002297 BT_DBG("sk %p", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002298
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002299 rsp->scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002300 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002301 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002302
2303 return ptr - data;
2304}
2305
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002306static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2307{
2308 struct l2cap_cmd_rej *rej = (struct l2cap_cmd_rej *) data;
2309
2310 if (rej->reason != 0x0000)
2311 return 0;
2312
2313 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
2314 cmd->ident == conn->info_ident) {
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002315 del_timer(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01002316
2317 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002318 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01002319
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002320 l2cap_conn_start(conn);
2321 }
2322
2323 return 0;
2324}
2325
Linus Torvalds1da177e2005-04-16 15:20:36 -07002326static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2327{
2328 struct l2cap_chan_list *list = &conn->chan_list;
2329 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
2330 struct l2cap_conn_rsp rsp;
2331 struct sock *sk, *parent;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002332 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002333
2334 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002335 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002336
2337 BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
2338
2339 /* Check if we have socket listening on psm */
2340 parent = l2cap_get_sock_by_psm(BT_LISTEN, psm, conn->src);
2341 if (!parent) {
2342 result = L2CAP_CR_BAD_PSM;
2343 goto sendresp;
2344 }
2345
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002346 /* Check if the ACL is secure enough (if not SDP) */
2347 if (psm != cpu_to_le16(0x0001) &&
2348 !hci_conn_check_link_mode(conn->hcon)) {
Marcel Holtmann2950f212009-02-12 14:02:50 +01002349 conn->disc_reason = 0x05;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02002350 result = L2CAP_CR_SEC_BLOCK;
2351 goto response;
2352 }
2353
Linus Torvalds1da177e2005-04-16 15:20:36 -07002354 result = L2CAP_CR_NO_MEM;
2355
2356 /* Check for backlog size */
2357 if (sk_acceptq_is_full(parent)) {
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09002358 BT_DBG("backlog full %d", parent->sk_ack_backlog);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002359 goto response;
2360 }
2361
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09002362 sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002363 if (!sk)
2364 goto response;
2365
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002366 write_lock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002367
2368 /* Check if we already have channel with that dcid */
2369 if (__l2cap_get_chan_by_dcid(list, scid)) {
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002370 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002371 sock_set_flag(sk, SOCK_ZAPPED);
2372 l2cap_sock_kill(sk);
2373 goto response;
2374 }
2375
2376 hci_conn_hold(conn->hcon);
2377
2378 l2cap_sock_init(sk, parent);
2379 bacpy(&bt_sk(sk)->src, conn->src);
2380 bacpy(&bt_sk(sk)->dst, conn->dst);
2381 l2cap_pi(sk)->psm = psm;
2382 l2cap_pi(sk)->dcid = scid;
2383
2384 __l2cap_chan_add(conn, sk, parent);
2385 dcid = l2cap_pi(sk)->scid;
2386
2387 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
2388
Linus Torvalds1da177e2005-04-16 15:20:36 -07002389 l2cap_pi(sk)->ident = cmd->ident;
2390
Marcel Holtmann984947d2009-02-06 23:35:19 +01002391 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01002392 if (l2cap_check_security(sk)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +01002393 if (bt_sk(sk)->defer_setup) {
2394 sk->sk_state = BT_CONNECT2;
2395 result = L2CAP_CR_PEND;
2396 status = L2CAP_CS_AUTHOR_PEND;
2397 parent->sk_data_ready(parent, 0);
2398 } else {
2399 sk->sk_state = BT_CONFIG;
2400 result = L2CAP_CR_SUCCESS;
2401 status = L2CAP_CS_NO_INFO;
2402 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002403 } else {
2404 sk->sk_state = BT_CONNECT2;
2405 result = L2CAP_CR_PEND;
2406 status = L2CAP_CS_AUTHEN_PEND;
2407 }
2408 } else {
2409 sk->sk_state = BT_CONNECT2;
2410 result = L2CAP_CR_PEND;
2411 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002412 }
2413
Marcel Holtmannfd1278d2006-07-12 23:00:07 +02002414 write_unlock_bh(&list->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002415
2416response:
2417 bh_unlock_sock(parent);
2418
2419sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002420 rsp.scid = cpu_to_le16(scid);
2421 rsp.dcid = cpu_to_le16(dcid);
2422 rsp.result = cpu_to_le16(result);
2423 rsp.status = cpu_to_le16(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002424 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002425
2426 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
2427 struct l2cap_info_req info;
2428 info.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
2429
2430 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
2431 conn->info_ident = l2cap_get_ident(conn);
2432
2433 mod_timer(&conn->info_timer, jiffies +
2434 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
2435
2436 l2cap_send_cmd(conn, conn->info_ident,
2437 L2CAP_INFO_REQ, sizeof(info), &info);
2438 }
2439
Linus Torvalds1da177e2005-04-16 15:20:36 -07002440 return 0;
2441}
2442
2443static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2444{
2445 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
2446 u16 scid, dcid, result, status;
2447 struct sock *sk;
2448 u8 req[128];
2449
2450 scid = __le16_to_cpu(rsp->scid);
2451 dcid = __le16_to_cpu(rsp->dcid);
2452 result = __le16_to_cpu(rsp->result);
2453 status = __le16_to_cpu(rsp->status);
2454
2455 BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
2456
2457 if (scid) {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002458 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2459 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002460 return 0;
2461 } else {
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002462 sk = l2cap_get_chan_by_ident(&conn->chan_list, cmd->ident);
2463 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002464 return 0;
2465 }
2466
2467 switch (result) {
2468 case L2CAP_CR_SUCCESS:
2469 sk->sk_state = BT_CONFIG;
2470 l2cap_pi(sk)->ident = 0;
2471 l2cap_pi(sk)->dcid = dcid;
2472 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
2473
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002474 l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_CONNECT_PEND;
2475
Linus Torvalds1da177e2005-04-16 15:20:36 -07002476 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
2477 l2cap_build_conf_req(sk, req), req);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002478 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002479 break;
2480
2481 case L2CAP_CR_PEND:
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01002482 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002483 break;
2484
2485 default:
2486 l2cap_chan_del(sk, ECONNREFUSED);
2487 break;
2488 }
2489
2490 bh_unlock_sock(sk);
2491 return 0;
2492}
2493
Al Viro88219a02007-07-29 00:17:25 -07002494static 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 -07002495{
2496 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
2497 u16 dcid, flags;
2498 u8 rsp[64];
2499 struct sock *sk;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002500 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002501
2502 dcid = __le16_to_cpu(req->dcid);
2503 flags = __le16_to_cpu(req->flags);
2504
2505 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
2506
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002507 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
2508 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002509 return -ENOENT;
2510
Marcel Holtmann354f60a2006-11-18 22:15:20 +01002511 if (sk->sk_state == BT_DISCONN)
2512 goto unlock;
2513
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002514 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07002515 len = cmd_len - sizeof(*req);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002516 if (l2cap_pi(sk)->conf_len + len > sizeof(l2cap_pi(sk)->conf_req)) {
2517 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
2518 l2cap_build_conf_rsp(sk, rsp,
2519 L2CAP_CONF_REJECT, flags), rsp);
2520 goto unlock;
2521 }
2522
2523 /* Store config. */
2524 memcpy(l2cap_pi(sk)->conf_req + l2cap_pi(sk)->conf_len, req->data, len);
2525 l2cap_pi(sk)->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002526
2527 if (flags & 0x0001) {
2528 /* Incomplete config. Send empty response. */
2529 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002530 l2cap_build_conf_rsp(sk, rsp,
2531 L2CAP_CONF_SUCCESS, 0x0001), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002532 goto unlock;
2533 }
2534
2535 /* Complete config. */
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002536 len = l2cap_parse_conf_req(sk, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002537 if (len < 0) {
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002538 l2cap_send_disconn_req(conn, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002539 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002540 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002541
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002542 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002543 l2cap_pi(sk)->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002544
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002545 /* Reset config buffer. */
2546 l2cap_pi(sk)->conf_len = 0;
2547
Marcel Holtmann876d9482007-10-20 13:35:42 +02002548 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE))
2549 goto unlock;
2550
Linus Torvalds1da177e2005-04-16 15:20:36 -07002551 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) {
2552 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03002553 l2cap_pi(sk)->next_tx_seq = 0;
2554 l2cap_pi(sk)->expected_ack_seq = 0;
2555 l2cap_pi(sk)->unacked_frames = 0;
2556 __skb_queue_head_init(TX_QUEUE(sk));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002557 l2cap_chan_ready(sk);
Marcel Holtmann876d9482007-10-20 13:35:42 +02002558 goto unlock;
2559 }
2560
2561 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002562 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002563 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Marcel Holtmann79d554a2008-07-14 20:13:44 +02002564 l2cap_build_conf_req(sk, buf), buf);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002565 l2cap_pi(sk)->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002566 }
2567
2568unlock:
2569 bh_unlock_sock(sk);
2570 return 0;
2571}
2572
2573static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2574{
2575 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
2576 u16 scid, flags, result;
2577 struct sock *sk;
2578
2579 scid = __le16_to_cpu(rsp->scid);
2580 flags = __le16_to_cpu(rsp->flags);
2581 result = __le16_to_cpu(rsp->result);
2582
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002583 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x",
2584 scid, flags, result);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002585
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002586 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2587 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002588 return 0;
2589
2590 switch (result) {
2591 case L2CAP_CONF_SUCCESS:
2592 break;
2593
2594 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002595 if (l2cap_pi(sk)->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
2596 int len = cmd->len - sizeof(*rsp);
2597 char req[64];
2598
2599 /* throw out any old stored conf requests */
2600 result = L2CAP_CONF_SUCCESS;
2601 len = l2cap_parse_conf_rsp(sk, rsp->data,
2602 len, req, &result);
2603 if (len < 0) {
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002604 l2cap_send_disconn_req(conn, sk);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002605 goto done;
2606 }
2607
2608 l2cap_send_cmd(conn, l2cap_get_ident(conn),
2609 L2CAP_CONF_REQ, len, req);
2610 l2cap_pi(sk)->num_conf_req++;
2611 if (result != L2CAP_CONF_SUCCESS)
2612 goto done;
2613 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002614 }
2615
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09002616 default:
Linus Torvalds1da177e2005-04-16 15:20:36 -07002617 sk->sk_state = BT_DISCONN;
Marcel Holtmannb1235d7962008-07-14 20:13:54 +02002618 sk->sk_err = ECONNRESET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002619 l2cap_sock_set_timer(sk, HZ * 5);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03002620 l2cap_send_disconn_req(conn, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002621 goto done;
2622 }
2623
2624 if (flags & 0x01)
2625 goto done;
2626
Linus Torvalds1da177e2005-04-16 15:20:36 -07002627 l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE;
2628
2629 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) {
2630 sk->sk_state = BT_CONNECTED;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03002631 l2cap_pi(sk)->expected_tx_seq = 0;
2632 l2cap_pi(sk)->num_to_ack = 0;
2633 __skb_queue_head_init(TX_QUEUE(sk));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002634 l2cap_chan_ready(sk);
2635 }
2636
2637done:
2638 bh_unlock_sock(sk);
2639 return 0;
2640}
2641
2642static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2643{
2644 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
2645 struct l2cap_disconn_rsp rsp;
2646 u16 dcid, scid;
2647 struct sock *sk;
2648
2649 scid = __le16_to_cpu(req->scid);
2650 dcid = __le16_to_cpu(req->dcid);
2651
2652 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
2653
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002654 sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
2655 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002656 return 0;
2657
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002658 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
2659 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002660 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
2661
2662 sk->sk_shutdown = SHUTDOWN_MASK;
2663
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03002664 skb_queue_purge(TX_QUEUE(sk));
2665
Linus Torvalds1da177e2005-04-16 15:20:36 -07002666 l2cap_chan_del(sk, ECONNRESET);
2667 bh_unlock_sock(sk);
2668
2669 l2cap_sock_kill(sk);
2670 return 0;
2671}
2672
2673static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2674{
2675 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
2676 u16 dcid, scid;
2677 struct sock *sk;
2678
2679 scid = __le16_to_cpu(rsp->scid);
2680 dcid = __le16_to_cpu(rsp->dcid);
2681
2682 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
2683
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002684 sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
2685 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002686 return 0;
2687
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03002688 skb_queue_purge(TX_QUEUE(sk));
2689
Linus Torvalds1da177e2005-04-16 15:20:36 -07002690 l2cap_chan_del(sk, 0);
2691 bh_unlock_sock(sk);
2692
2693 l2cap_sock_kill(sk);
2694 return 0;
2695}
2696
2697static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2698{
2699 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002700 u16 type;
2701
2702 type = __le16_to_cpu(req->type);
2703
2704 BT_DBG("type 0x%4.4x", type);
2705
Marcel Holtmannf0709e02007-10-20 13:38:51 +02002706 if (type == L2CAP_IT_FEAT_MASK) {
2707 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07002708 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02002709 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
2710 rsp->type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
2711 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07002712 if (enable_ertm)
2713 feat_mask |= L2CAP_FEAT_ERTM;
2714 put_unaligned(cpu_to_le32(feat_mask), (__le32 *) rsp->data);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02002715 l2cap_send_cmd(conn, cmd->ident,
2716 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002717 } else if (type == L2CAP_IT_FIXED_CHAN) {
2718 u8 buf[12];
2719 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
2720 rsp->type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
2721 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
2722 memcpy(buf + 4, l2cap_fixed_chan, 8);
2723 l2cap_send_cmd(conn, cmd->ident,
2724 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02002725 } else {
2726 struct l2cap_info_rsp rsp;
2727 rsp.type = cpu_to_le16(type);
2728 rsp.result = cpu_to_le16(L2CAP_IR_NOTSUPP);
2729 l2cap_send_cmd(conn, cmd->ident,
2730 L2CAP_INFO_RSP, sizeof(rsp), &rsp);
2731 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002732
2733 return 0;
2734}
2735
2736static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
2737{
2738 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
2739 u16 type, result;
2740
2741 type = __le16_to_cpu(rsp->type);
2742 result = __le16_to_cpu(rsp->result);
2743
2744 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
2745
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002746 del_timer(&conn->info_timer);
2747
Marcel Holtmann984947d2009-02-06 23:35:19 +01002748 if (type == L2CAP_IT_FEAT_MASK) {
Harvey Harrison83985312008-05-02 16:25:46 -07002749 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002750
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07002751 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002752 struct l2cap_info_req req;
2753 req.type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
2754
2755 conn->info_ident = l2cap_get_ident(conn);
2756
2757 l2cap_send_cmd(conn, conn->info_ident,
2758 L2CAP_INFO_REQ, sizeof(req), &req);
2759 } else {
2760 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
2761 conn->info_ident = 0;
2762
2763 l2cap_conn_start(conn);
2764 }
2765 } else if (type == L2CAP_IT_FIXED_CHAN) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01002766 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01002767 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01002768
2769 l2cap_conn_start(conn);
2770 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002771
Linus Torvalds1da177e2005-04-16 15:20:36 -07002772 return 0;
2773}
2774
2775static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
2776{
2777 u8 *data = skb->data;
2778 int len = skb->len;
2779 struct l2cap_cmd_hdr cmd;
2780 int err = 0;
2781
2782 l2cap_raw_recv(conn, skb);
2783
2784 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07002785 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002786 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
2787 data += L2CAP_CMD_HDR_SIZE;
2788 len -= L2CAP_CMD_HDR_SIZE;
2789
Al Viro88219a02007-07-29 00:17:25 -07002790 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002791
Al Viro88219a02007-07-29 00:17:25 -07002792 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 -07002793
Al Viro88219a02007-07-29 00:17:25 -07002794 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002795 BT_DBG("corrupted command");
2796 break;
2797 }
2798
2799 switch (cmd.code) {
2800 case L2CAP_COMMAND_REJ:
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02002801 l2cap_command_rej(conn, &cmd, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002802 break;
2803
2804 case L2CAP_CONN_REQ:
2805 err = l2cap_connect_req(conn, &cmd, data);
2806 break;
2807
2808 case L2CAP_CONN_RSP:
2809 err = l2cap_connect_rsp(conn, &cmd, data);
2810 break;
2811
2812 case L2CAP_CONF_REQ:
Al Viro88219a02007-07-29 00:17:25 -07002813 err = l2cap_config_req(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002814 break;
2815
2816 case L2CAP_CONF_RSP:
2817 err = l2cap_config_rsp(conn, &cmd, data);
2818 break;
2819
2820 case L2CAP_DISCONN_REQ:
2821 err = l2cap_disconnect_req(conn, &cmd, data);
2822 break;
2823
2824 case L2CAP_DISCONN_RSP:
2825 err = l2cap_disconnect_rsp(conn, &cmd, data);
2826 break;
2827
2828 case L2CAP_ECHO_REQ:
Al Viro88219a02007-07-29 00:17:25 -07002829 l2cap_send_cmd(conn, cmd.ident, L2CAP_ECHO_RSP, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002830 break;
2831
2832 case L2CAP_ECHO_RSP:
2833 break;
2834
2835 case L2CAP_INFO_REQ:
2836 err = l2cap_information_req(conn, &cmd, data);
2837 break;
2838
2839 case L2CAP_INFO_RSP:
2840 err = l2cap_information_rsp(conn, &cmd, data);
2841 break;
2842
2843 default:
2844 BT_ERR("Unknown signaling command 0x%2.2x", cmd.code);
2845 err = -EINVAL;
2846 break;
2847 }
2848
2849 if (err) {
2850 struct l2cap_cmd_rej rej;
2851 BT_DBG("error %d", err);
2852
2853 /* FIXME: Map err to a valid reason */
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002854 rej.reason = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002855 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
2856 }
2857
Al Viro88219a02007-07-29 00:17:25 -07002858 data += cmd_len;
2859 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002860 }
2861
2862 kfree_skb(skb);
2863}
2864
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002865static int l2cap_sar_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
2866{
2867 struct l2cap_pinfo *pi = l2cap_pi(sk);
2868 struct sk_buff *_skb;
2869 int err = -EINVAL;
2870
2871 switch (control & L2CAP_CTRL_SAR) {
2872 case L2CAP_SDU_UNSEGMENTED:
2873 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
2874 kfree_skb(pi->sdu);
2875 break;
2876 }
2877
2878 err = sock_queue_rcv_skb(sk, skb);
2879 if (!err)
2880 return 0;
2881
2882 break;
2883
2884 case L2CAP_SDU_START:
2885 if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
2886 kfree_skb(pi->sdu);
2887 break;
2888 }
2889
2890 pi->sdu_len = get_unaligned_le16(skb->data);
2891 skb_pull(skb, 2);
2892
2893 pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
2894 if (!pi->sdu) {
2895 err = -ENOMEM;
2896 break;
2897 }
2898
2899 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
2900
2901 pi->conn_state |= L2CAP_CONN_SAR_SDU;
2902 pi->partial_sdu_len = skb->len;
2903 err = 0;
2904 break;
2905
2906 case L2CAP_SDU_CONTINUE:
2907 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
2908 break;
2909
2910 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
2911
2912 pi->partial_sdu_len += skb->len;
2913 if (pi->partial_sdu_len > pi->sdu_len)
2914 kfree_skb(pi->sdu);
2915 else
2916 err = 0;
2917
2918 break;
2919
2920 case L2CAP_SDU_END:
2921 if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
2922 break;
2923
2924 memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
2925
2926 pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
2927 pi->partial_sdu_len += skb->len;
2928
2929 if (pi->partial_sdu_len == pi->sdu_len) {
2930 _skb = skb_clone(pi->sdu, GFP_ATOMIC);
2931 err = sock_queue_rcv_skb(sk, _skb);
2932 if (err < 0)
2933 kfree_skb(_skb);
2934 }
2935 kfree_skb(pi->sdu);
2936 err = 0;
2937
2938 break;
2939 }
2940
2941 kfree_skb(skb);
2942 return err;
2943}
2944
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03002945static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
2946{
2947 struct l2cap_pinfo *pi = l2cap_pi(sk);
2948 u8 tx_seq = __get_txseq(rx_control);
2949 u16 tx_control = 0;
2950 int err = 0;
2951
2952 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
2953
2954 if (tx_seq != pi->expected_tx_seq)
2955 return -EINVAL;
2956
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002957 err = l2cap_sar_reassembly_sdu(sk, skb, rx_control);
2958 if (err < 0)
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03002959 return err;
2960
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002961 pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03002962 pi->num_to_ack = (pi->num_to_ack + 1) % L2CAP_DEFAULT_NUM_TO_ACK;
2963 if (pi->num_to_ack == L2CAP_DEFAULT_NUM_TO_ACK - 1) {
2964 tx_control |= L2CAP_CTRL_FRAME_TYPE;
2965 tx_control |= L2CAP_SUPER_RCV_READY;
2966 tx_control |= pi->expected_tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
2967 err = l2cap_send_sframe(pi, tx_control);
2968 }
2969 return err;
2970}
2971
2972static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
2973{
2974 struct l2cap_pinfo *pi = l2cap_pi(sk);
2975
2976 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
2977
2978 switch (rx_control & L2CAP_CTRL_SUPERVISE) {
2979 case L2CAP_SUPER_RCV_READY:
2980 pi->expected_ack_seq = __get_reqseq(rx_control);
2981 l2cap_drop_acked_frames(sk);
2982 l2cap_ertm_send(sk);
2983 break;
2984
2985 case L2CAP_SUPER_RCV_NOT_READY:
2986 case L2CAP_SUPER_REJECT:
2987 case L2CAP_SUPER_SELECT_REJECT:
2988 break;
2989 }
2990
2991 return 0;
2992}
2993
Linus Torvalds1da177e2005-04-16 15:20:36 -07002994static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk_buff *skb)
2995{
2996 struct sock *sk;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002997 u16 control, len;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03002998 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002999
3000 sk = l2cap_get_chan_by_scid(&conn->chan_list, cid);
3001 if (!sk) {
3002 BT_DBG("unknown cid 0x%4.4x", cid);
3003 goto drop;
3004 }
3005
3006 BT_DBG("sk %p, len %d", sk, skb->len);
3007
3008 if (sk->sk_state != BT_CONNECTED)
3009 goto drop;
3010
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03003011 switch (l2cap_pi(sk)->mode) {
3012 case L2CAP_MODE_BASIC:
3013 /* If socket recv buffers overflows we drop data here
3014 * which is *bad* because L2CAP has to be reliable.
3015 * But we don't have any other choice. L2CAP doesn't
3016 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003017
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03003018 if (l2cap_pi(sk)->imtu < skb->len)
3019 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003020
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03003021 if (!sock_queue_rcv_skb(sk, skb))
3022 goto done;
3023 break;
3024
3025 case L2CAP_MODE_ERTM:
3026 control = get_unaligned_le16(skb->data);
3027 skb_pull(skb, 2);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003028 len = skb->len;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03003029
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03003030 if (__is_sar_start(control))
3031 len -= 2;
3032
3033 if (len > L2CAP_DEFAULT_MAX_PDU_SIZE)
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03003034 goto drop;
3035
3036 if (__is_iframe(control))
3037 err = l2cap_data_channel_iframe(sk, control, skb);
3038 else
3039 err = l2cap_data_channel_sframe(sk, control, skb);
3040
3041 if (!err)
3042 goto done;
3043 break;
3044
3045 default:
3046 BT_DBG("sk %p: bad mode 0x%2.2x", sk, l2cap_pi(sk)->mode);
3047 break;
3048 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003049
3050drop:
3051 kfree_skb(skb);
3052
3053done:
Marcel Holtmann01394182006-07-03 10:02:46 +02003054 if (sk)
3055 bh_unlock_sock(sk);
3056
Linus Torvalds1da177e2005-04-16 15:20:36 -07003057 return 0;
3058}
3059
Al Viro8e036fc2007-07-29 00:16:36 -07003060static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003061{
3062 struct sock *sk;
3063
3064 sk = l2cap_get_sock_by_psm(0, psm, conn->src);
3065 if (!sk)
3066 goto drop;
3067
3068 BT_DBG("sk %p, len %d", sk, skb->len);
3069
3070 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_CONNECTED)
3071 goto drop;
3072
3073 if (l2cap_pi(sk)->imtu < skb->len)
3074 goto drop;
3075
3076 if (!sock_queue_rcv_skb(sk, skb))
3077 goto done;
3078
3079drop:
3080 kfree_skb(skb);
3081
3082done:
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003083 if (sk)
3084 bh_unlock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003085 return 0;
3086}
3087
3088static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
3089{
3090 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07003091 u16 cid, len;
3092 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003093
3094 skb_pull(skb, L2CAP_HDR_SIZE);
3095 cid = __le16_to_cpu(lh->cid);
3096 len = __le16_to_cpu(lh->len);
3097
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03003098 if (len != skb->len) {
3099 kfree_skb(skb);
3100 return;
3101 }
3102
Linus Torvalds1da177e2005-04-16 15:20:36 -07003103 BT_DBG("len %d, cid 0x%4.4x", len, cid);
3104
3105 switch (cid) {
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03003106 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07003107 l2cap_sig_channel(conn, skb);
3108 break;
3109
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03003110 case L2CAP_CID_CONN_LESS:
Al Viro8e036fc2007-07-29 00:16:36 -07003111 psm = get_unaligned((__le16 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003112 skb_pull(skb, 2);
3113 l2cap_conless_channel(conn, psm, skb);
3114 break;
3115
3116 default:
3117 l2cap_data_channel(conn, cid, skb);
3118 break;
3119 }
3120}
3121
3122/* ---- L2CAP interface with lower layer (HCI) ---- */
3123
3124static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
3125{
3126 int exact = 0, lm1 = 0, lm2 = 0;
3127 register struct sock *sk;
3128 struct hlist_node *node;
3129
3130 if (type != ACL_LINK)
3131 return 0;
3132
3133 BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
3134
3135 /* Find listening sockets and check their link_mode */
3136 read_lock(&l2cap_sk_list.lock);
3137 sk_for_each(sk, node, &l2cap_sk_list.head) {
3138 if (sk->sk_state != BT_LISTEN)
3139 continue;
3140
3141 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01003142 lm1 |= HCI_LM_ACCEPT;
3143 if (l2cap_pi(sk)->role_switch)
3144 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003145 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01003146 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
3147 lm2 |= HCI_LM_ACCEPT;
3148 if (l2cap_pi(sk)->role_switch)
3149 lm2 |= HCI_LM_MASTER;
3150 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003151 }
3152 read_unlock(&l2cap_sk_list.lock);
3153
3154 return exact ? lm1 : lm2;
3155}
3156
3157static int l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
3158{
Marcel Holtmann01394182006-07-03 10:02:46 +02003159 struct l2cap_conn *conn;
3160
Linus Torvalds1da177e2005-04-16 15:20:36 -07003161 BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
3162
3163 if (hcon->type != ACL_LINK)
3164 return 0;
3165
3166 if (!status) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003167 conn = l2cap_conn_add(hcon, status);
3168 if (conn)
3169 l2cap_conn_ready(conn);
Marcel Holtmann01394182006-07-03 10:02:46 +02003170 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -07003171 l2cap_conn_del(hcon, bt_err(status));
3172
3173 return 0;
3174}
3175
Marcel Holtmann2950f212009-02-12 14:02:50 +01003176static int l2cap_disconn_ind(struct hci_conn *hcon)
3177{
3178 struct l2cap_conn *conn = hcon->l2cap_data;
3179
3180 BT_DBG("hcon %p", hcon);
3181
3182 if (hcon->type != ACL_LINK || !conn)
3183 return 0x13;
3184
3185 return conn->disc_reason;
3186}
3187
3188static int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003189{
3190 BT_DBG("hcon %p reason %d", hcon, reason);
3191
3192 if (hcon->type != ACL_LINK)
3193 return 0;
3194
3195 l2cap_conn_del(hcon, bt_err(reason));
Marcel Holtmann01394182006-07-03 10:02:46 +02003196
Linus Torvalds1da177e2005-04-16 15:20:36 -07003197 return 0;
3198}
3199
Marcel Holtmannf62e4322009-01-15 21:58:44 +01003200static inline void l2cap_check_encryption(struct sock *sk, u8 encrypt)
3201{
Marcel Holtmann255c7602009-02-04 21:07:19 +01003202 if (sk->sk_type != SOCK_SEQPACKET)
3203 return;
3204
Marcel Holtmannf62e4322009-01-15 21:58:44 +01003205 if (encrypt == 0x00) {
3206 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM) {
3207 l2cap_sock_clear_timer(sk);
3208 l2cap_sock_set_timer(sk, HZ * 5);
3209 } else if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
3210 __l2cap_sock_close(sk, ECONNREFUSED);
3211 } else {
3212 if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM)
3213 l2cap_sock_clear_timer(sk);
3214 }
3215}
3216
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01003217static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003218{
3219 struct l2cap_chan_list *l;
Marcel Holtmann40be4922008-07-14 20:13:50 +02003220 struct l2cap_conn *conn = hcon->l2cap_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003221 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003222
Marcel Holtmann01394182006-07-03 10:02:46 +02003223 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003224 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02003225
Linus Torvalds1da177e2005-04-16 15:20:36 -07003226 l = &conn->chan_list;
3227
3228 BT_DBG("conn %p", conn);
3229
3230 read_lock(&l->lock);
3231
3232 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
3233 bh_lock_sock(sk);
3234
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003235 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND) {
3236 bh_unlock_sock(sk);
3237 continue;
3238 }
3239
Marcel Holtmannf62e4322009-01-15 21:58:44 +01003240 if (!status && (sk->sk_state == BT_CONNECTED ||
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01003241 sk->sk_state == BT_CONFIG)) {
Marcel Holtmannf62e4322009-01-15 21:58:44 +01003242 l2cap_check_encryption(sk, encrypt);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02003243 bh_unlock_sock(sk);
3244 continue;
3245 }
3246
Marcel Holtmannb1235d7962008-07-14 20:13:54 +02003247 if (sk->sk_state == BT_CONNECT) {
3248 if (!status) {
3249 struct l2cap_conn_req req;
3250 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
3251 req.psm = l2cap_pi(sk)->psm;
3252
3253 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
3254
3255 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
3256 L2CAP_CONN_REQ, sizeof(req), &req);
3257 } else {
3258 l2cap_sock_clear_timer(sk);
3259 l2cap_sock_set_timer(sk, HZ / 10);
3260 }
3261 } else if (sk->sk_state == BT_CONNECT2) {
3262 struct l2cap_conn_rsp rsp;
3263 __u16 result;
3264
3265 if (!status) {
3266 sk->sk_state = BT_CONFIG;
3267 result = L2CAP_CR_SUCCESS;
3268 } else {
3269 sk->sk_state = BT_DISCONN;
3270 l2cap_sock_set_timer(sk, HZ / 10);
3271 result = L2CAP_CR_SEC_BLOCK;
3272 }
3273
3274 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
3275 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
3276 rsp.result = cpu_to_le16(result);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003277 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannb1235d7962008-07-14 20:13:54 +02003278 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
3279 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003280 }
3281
Linus Torvalds1da177e2005-04-16 15:20:36 -07003282 bh_unlock_sock(sk);
3283 }
3284
3285 read_unlock(&l->lock);
Marcel Holtmannb1235d7962008-07-14 20:13:54 +02003286
Linus Torvalds1da177e2005-04-16 15:20:36 -07003287 return 0;
3288}
3289
3290static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
3291{
3292 struct l2cap_conn *conn = hcon->l2cap_data;
3293
3294 if (!conn && !(conn = l2cap_conn_add(hcon, 0)))
3295 goto drop;
3296
3297 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
3298
3299 if (flags & ACL_START) {
3300 struct l2cap_hdr *hdr;
3301 int len;
3302
3303 if (conn->rx_len) {
3304 BT_ERR("Unexpected start frame (len %d)", skb->len);
3305 kfree_skb(conn->rx_skb);
3306 conn->rx_skb = NULL;
3307 conn->rx_len = 0;
3308 l2cap_conn_unreliable(conn, ECOMM);
3309 }
3310
3311 if (skb->len < 2) {
3312 BT_ERR("Frame is too short (len %d)", skb->len);
3313 l2cap_conn_unreliable(conn, ECOMM);
3314 goto drop;
3315 }
3316
3317 hdr = (struct l2cap_hdr *) skb->data;
3318 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
3319
3320 if (len == skb->len) {
3321 /* Complete frame received */
3322 l2cap_recv_frame(conn, skb);
3323 return 0;
3324 }
3325
3326 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
3327
3328 if (skb->len > len) {
3329 BT_ERR("Frame is too long (len %d, expected len %d)",
3330 skb->len, len);
3331 l2cap_conn_unreliable(conn, ECOMM);
3332 goto drop;
3333 }
3334
3335 /* Allocate skb for the complete frame (with header) */
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003336 conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC);
3337 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003338 goto drop;
3339
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03003340 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003341 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003342 conn->rx_len = len - skb->len;
3343 } else {
3344 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
3345
3346 if (!conn->rx_len) {
3347 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
3348 l2cap_conn_unreliable(conn, ECOMM);
3349 goto drop;
3350 }
3351
3352 if (skb->len > conn->rx_len) {
3353 BT_ERR("Fragment is too long (len %d, expected %d)",
3354 skb->len, conn->rx_len);
3355 kfree_skb(conn->rx_skb);
3356 conn->rx_skb = NULL;
3357 conn->rx_len = 0;
3358 l2cap_conn_unreliable(conn, ECOMM);
3359 goto drop;
3360 }
3361
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03003362 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003363 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003364 conn->rx_len -= skb->len;
3365
3366 if (!conn->rx_len) {
3367 /* Complete frame received */
3368 l2cap_recv_frame(conn, conn->rx_skb);
3369 conn->rx_skb = NULL;
3370 }
3371 }
3372
3373drop:
3374 kfree_skb(skb);
3375 return 0;
3376}
3377
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08003378static ssize_t l2cap_sysfs_show(struct class *dev, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003379{
3380 struct sock *sk;
3381 struct hlist_node *node;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08003382 char *str = buf;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003383
3384 read_lock_bh(&l2cap_sk_list.lock);
3385
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08003386 sk_for_each(sk, node, &l2cap_sk_list.head) {
3387 struct l2cap_pinfo *pi = l2cap_pi(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003388
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01003389 str += sprintf(str, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d\n",
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08003390 batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
Marcel Holtmannb4324b52009-06-07 18:06:51 +02003391 sk->sk_state, __le16_to_cpu(pi->psm), pi->scid,
3392 pi->dcid, pi->imtu, pi->omtu, pi->sec_level);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08003393 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003394
Linus Torvalds1da177e2005-04-16 15:20:36 -07003395 read_unlock_bh(&l2cap_sk_list.lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08003396
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003397 return str - buf;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003398}
3399
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08003400static CLASS_ATTR(l2cap, S_IRUGO, l2cap_sysfs_show, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003401
Eric Dumazet90ddc4f2005-12-22 12:49:22 -08003402static const struct proto_ops l2cap_sock_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003403 .family = PF_BLUETOOTH,
3404 .owner = THIS_MODULE,
3405 .release = l2cap_sock_release,
3406 .bind = l2cap_sock_bind,
3407 .connect = l2cap_sock_connect,
3408 .listen = l2cap_sock_listen,
3409 .accept = l2cap_sock_accept,
3410 .getname = l2cap_sock_getname,
3411 .sendmsg = l2cap_sock_sendmsg,
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003412 .recvmsg = l2cap_sock_recvmsg,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003413 .poll = bt_sock_poll,
Marcel Holtmann3241ad82008-07-14 20:13:50 +02003414 .ioctl = bt_sock_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003415 .mmap = sock_no_mmap,
3416 .socketpair = sock_no_socketpair,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003417 .shutdown = l2cap_sock_shutdown,
3418 .setsockopt = l2cap_sock_setsockopt,
3419 .getsockopt = l2cap_sock_getsockopt
3420};
3421
3422static struct net_proto_family l2cap_sock_family_ops = {
3423 .family = PF_BLUETOOTH,
3424 .owner = THIS_MODULE,
3425 .create = l2cap_sock_create,
3426};
3427
3428static struct hci_proto l2cap_hci_proto = {
3429 .name = "L2CAP",
3430 .id = HCI_PROTO_L2CAP,
3431 .connect_ind = l2cap_connect_ind,
3432 .connect_cfm = l2cap_connect_cfm,
3433 .disconn_ind = l2cap_disconn_ind,
Marcel Holtmann2950f212009-02-12 14:02:50 +01003434 .disconn_cfm = l2cap_disconn_cfm,
Marcel Holtmann8c1b2352009-01-15 21:58:04 +01003435 .security_cfm = l2cap_security_cfm,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003436 .recv_acldata = l2cap_recv_acldata
3437};
3438
3439static int __init l2cap_init(void)
3440{
3441 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08003442
Linus Torvalds1da177e2005-04-16 15:20:36 -07003443 err = proto_register(&l2cap_proto, 0);
3444 if (err < 0)
3445 return err;
3446
3447 err = bt_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops);
3448 if (err < 0) {
3449 BT_ERR("L2CAP socket registration failed");
3450 goto error;
3451 }
3452
3453 err = hci_register_proto(&l2cap_hci_proto);
3454 if (err < 0) {
3455 BT_ERR("L2CAP protocol registration failed");
3456 bt_sock_unregister(BTPROTO_L2CAP);
3457 goto error;
3458 }
3459
Marcel Holtmanndf5c37e2006-10-15 17:30:45 +02003460 if (class_create_file(bt_class, &class_attr_l2cap) < 0)
3461 BT_ERR("Failed to create L2CAP info file");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003462
3463 BT_INFO("L2CAP ver %s", VERSION);
3464 BT_INFO("L2CAP socket layer initialized");
3465
3466 return 0;
3467
3468error:
3469 proto_unregister(&l2cap_proto);
3470 return err;
3471}
3472
3473static void __exit l2cap_exit(void)
3474{
Marcel Holtmanna91f2e32006-07-03 10:02:41 +02003475 class_remove_file(bt_class, &class_attr_l2cap);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003476
3477 if (bt_sock_unregister(BTPROTO_L2CAP) < 0)
3478 BT_ERR("L2CAP socket unregistration failed");
3479
3480 if (hci_unregister_proto(&l2cap_hci_proto) < 0)
3481 BT_ERR("L2CAP protocol unregistration failed");
3482
3483 proto_unregister(&l2cap_proto);
3484}
3485
3486void l2cap_load(void)
3487{
3488 /* Dummy function to trigger automatic L2CAP module loading by
3489 * other modules that use L2CAP sockets but don't use any other
3490 * symbols from it. */
3491 return;
3492}
3493EXPORT_SYMBOL(l2cap_load);
3494
3495module_init(l2cap_init);
3496module_exit(l2cap_exit);
3497
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003498module_param(enable_ertm, bool, 0644);
3499MODULE_PARM_DESC(enable_ertm, "Enable enhanced retransmission mode");
3500
Marcel Holtmann63fbd242008-08-18 13:23:53 +02003501MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003502MODULE_DESCRIPTION("Bluetooth L2CAP ver " VERSION);
3503MODULE_VERSION(VERSION);
3504MODULE_LICENSE("GPL");
3505MODULE_ALIAS("bt-proto-0");