blob: ffa78d3cd8ac4a096666f5a0d43ff71aa2f0dacf [file] [log] [blame]
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02001/*
2 BlueZ - Bluetooth protocol stack for Linux
3 Copyright (C) 2000-2001 Qualcomm Incorporated
4 Copyright (C) 2009-2010 Gustavo F. Padovan <gustavo@padovan.org>
5 Copyright (C) 2010 Google Inc.
Gustavo F. Padovan590051d2011-12-18 13:39:33 -02006 Copyright (C) 2011 ProFUSION Embedded Systems
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02007
8 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License version 2 as
12 published by the Free Software Foundation;
13
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
17 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
18 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
19 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
21 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
23 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
24 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
25 SOFTWARE IS DISCLAIMED.
26*/
27
28/* Bluetooth L2CAP sockets. */
29
Paul Gortmakerbc3b2d72011-07-15 11:47:34 -040030#include <linux/export.h>
Paul Moore6230c9b2011-10-07 09:40:59 +000031
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -020032#include <net/bluetooth/bluetooth.h>
Gustavo F. Padovan33575df2011-02-04 02:48:48 -020033#include <net/bluetooth/hci_core.h>
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -020034#include <net/bluetooth/l2cap.h>
Marcel Holtmannac4b7232013-10-10 14:54:16 -070035
36#include "smp.h"
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -020037
Masatake YAMATO5b28d952012-07-26 01:29:25 +090038static struct bt_sock_list l2cap_sk_list = {
39 .lock = __RW_LOCK_UNLOCKED(l2cap_sk_list.lock)
40};
41
Gustavo F. Padovancf2f90f2011-04-27 18:40:39 -030042static const struct proto_ops l2cap_sock_ops;
Gustavo F. Padovan80808e42011-05-16 17:24:37 -030043static void l2cap_sock_init(struct sock *sk, struct sock *parent);
Gustavo Padovan2d792812012-10-06 10:07:01 +010044static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock,
45 int proto, gfp_t prio);
Gustavo F. Padovancf2f90f2011-04-27 18:40:39 -030046
David Herrmannb3916db2013-04-05 14:57:34 +020047bool l2cap_is_socket(struct socket *sock)
48{
49 return sock && sock->ops == &l2cap_sock_ops;
50}
51EXPORT_SYMBOL(l2cap_is_socket);
52
Gustavo F. Padovanaf6bcd82011-02-04 02:40:28 -020053static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
54{
55 struct sock *sk = sock->sk;
Gustavo F. Padovan43434782011-04-12 18:31:57 -030056 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Gustavo F. Padovanaf6bcd82011-02-04 02:40:28 -020057 struct sockaddr_l2 la;
58 int len, err = 0;
59
60 BT_DBG("sk %p", sk);
61
62 if (!addr || addr->sa_family != AF_BLUETOOTH)
63 return -EINVAL;
64
65 memset(&la, 0, sizeof(la));
66 len = min_t(unsigned int, sizeof(la), alen);
67 memcpy(&la, addr, len);
68
Ville Tervob62f3282011-02-10 22:38:50 -030069 if (la.l2_cid && la.l2_psm)
Gustavo F. Padovanaf6bcd82011-02-04 02:40:28 -020070 return -EINVAL;
71
Johan Hedberg80c1a2e2013-10-14 21:17:52 +030072 if (!bdaddr_type_is_valid(la.l2_bdaddr_type))
73 return -EINVAL;
74
Gustavo F. Padovanaf6bcd82011-02-04 02:40:28 -020075 lock_sock(sk);
76
77 if (sk->sk_state != BT_OPEN) {
78 err = -EBADFD;
79 goto done;
80 }
81
82 if (la.l2_psm) {
83 __u16 psm = __le16_to_cpu(la.l2_psm);
84
85 /* PSM must be odd and lsb of upper byte must be 0 */
86 if ((psm & 0x0101) != 0x0001) {
87 err = -EINVAL;
88 goto done;
89 }
90
91 /* Restrict usage of well-known PSMs */
92 if (psm < 0x1001 && !capable(CAP_NET_BIND_SERVICE)) {
93 err = -EACCES;
94 goto done;
95 }
96 }
97
Ville Tervob62f3282011-02-10 22:38:50 -030098 if (la.l2_cid)
Santosh Nayak6e4aff12012-03-01 22:46:36 +053099 err = l2cap_add_scid(chan, __le16_to_cpu(la.l2_cid));
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300100 else
101 err = l2cap_add_psm(chan, &la.l2_bdaddr, la.l2_psm);
Ville Tervob62f3282011-02-10 22:38:50 -0300102
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300103 if (err < 0)
104 goto done;
105
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700106 switch (chan->chan_type) {
Marcel Holtmann3124b842013-10-12 07:19:32 -0700107 case L2CAP_CHAN_CONN_LESS:
108 if (__le16_to_cpu(la.l2_psm) == L2CAP_PSM_3DSP)
109 chan->sec_level = BT_SECURITY_SDP;
110 break;
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700111 case L2CAP_CHAN_CONN_ORIENTED:
112 if (__le16_to_cpu(la.l2_psm) == L2CAP_PSM_SDP ||
113 __le16_to_cpu(la.l2_psm) == L2CAP_PSM_RFCOMM)
114 chan->sec_level = BT_SECURITY_SDP;
115 break;
116 }
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300117
Marcel Holtmann7eafc592013-10-13 08:12:47 -0700118 bacpy(&chan->src, &la.l2_bdaddr);
Marcel Holtmann4f1654e2013-10-13 08:50:41 -0700119 chan->src_type = la.l2_bdaddr_type;
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300120
121 chan->state = BT_BOUND;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300122 sk->sk_state = BT_BOUND;
Gustavo F. Padovanaf6bcd82011-02-04 02:40:28 -0200123
124done:
125 release_sock(sk);
126 return err;
127}
128
Gustavo Padovan2d792812012-10-06 10:07:01 +0100129static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr,
130 int alen, int flags)
Gustavo F. Padovan4e34c502011-02-04 02:56:13 -0200131{
132 struct sock *sk = sock->sk;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300133 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Gustavo F. Padovan4e34c502011-02-04 02:56:13 -0200134 struct sockaddr_l2 la;
135 int len, err = 0;
136
137 BT_DBG("sk %p", sk);
138
139 if (!addr || alen < sizeof(addr->sa_family) ||
140 addr->sa_family != AF_BLUETOOTH)
141 return -EINVAL;
142
143 memset(&la, 0, sizeof(la));
144 len = min_t(unsigned int, sizeof(la), alen);
145 memcpy(&la, addr, len);
146
Ville Tervoacd7d372011-02-10 22:38:49 -0300147 if (la.l2_cid && la.l2_psm)
Gustavo F. Padovan4e34c502011-02-04 02:56:13 -0200148 return -EINVAL;
149
Johan Hedberg80c1a2e2013-10-14 21:17:52 +0300150 if (!bdaddr_type_is_valid(la.l2_bdaddr_type))
151 return -EINVAL;
152
Johan Hedberg1f209382013-10-14 21:17:53 +0300153 if (chan->src_type == BDADDR_BREDR && la.l2_bdaddr_type != BDADDR_BREDR)
154 return -EINVAL;
155
156 if (chan->src_type != BDADDR_BREDR && la.l2_bdaddr_type == BDADDR_BREDR)
157 return -EINVAL;
158
Santosh Nayak6e4aff12012-03-01 22:46:36 +0530159 err = l2cap_chan_connect(chan, la.l2_psm, __le16_to_cpu(la.l2_cid),
Andre Guedes8e9f9892012-04-24 21:02:55 -0300160 &la.l2_bdaddr, la.l2_bdaddr_type);
Gustavo F. Padovan4e34c502011-02-04 02:56:13 -0200161 if (err)
Andrei Emeltchenkob3fb6112012-02-22 17:11:57 +0200162 return err;
Gustavo F. Padovan4e34c502011-02-04 02:56:13 -0200163
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200164 lock_sock(sk);
165
Gustavo F. Padovan4e34c502011-02-04 02:56:13 -0200166 err = bt_sock_wait_state(sk, BT_CONNECTED,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100167 sock_sndtimeo(sk, flags & O_NONBLOCK));
Andrei Emeltchenkob3fb6112012-02-22 17:11:57 +0200168
169 release_sock(sk);
170
Gustavo F. Padovan4e34c502011-02-04 02:56:13 -0200171 return err;
172}
173
Gustavo F. Padovanaf6bcd82011-02-04 02:40:28 -0200174static int l2cap_sock_listen(struct socket *sock, int backlog)
175{
176 struct sock *sk = sock->sk;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300177 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Gustavo F. Padovanaf6bcd82011-02-04 02:40:28 -0200178 int err = 0;
179
180 BT_DBG("sk %p backlog %d", sk, backlog);
181
182 lock_sock(sk);
183
Marcel Holtmann6b3af732012-04-19 13:43:51 +0200184 if (sk->sk_state != BT_BOUND) {
Gustavo F. Padovanaf6bcd82011-02-04 02:40:28 -0200185 err = -EBADFD;
186 goto done;
187 }
188
Marcel Holtmann6b3af732012-04-19 13:43:51 +0200189 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM) {
190 err = -EINVAL;
191 goto done;
192 }
193
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300194 switch (chan->mode) {
Gustavo F. Padovanaf6bcd82011-02-04 02:40:28 -0200195 case L2CAP_MODE_BASIC:
196 break;
197 case L2CAP_MODE_ERTM:
198 case L2CAP_MODE_STREAMING:
199 if (!disable_ertm)
200 break;
201 /* fall through */
202 default:
203 err = -ENOTSUPP;
204 goto done;
205 }
206
Gustavo F. Padovanaf6bcd82011-02-04 02:40:28 -0200207 sk->sk_max_ack_backlog = backlog;
208 sk->sk_ack_backlog = 0;
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300209
210 chan->state = BT_LISTEN;
Gustavo F. Padovanaf6bcd82011-02-04 02:40:28 -0200211 sk->sk_state = BT_LISTEN;
212
213done:
214 release_sock(sk);
215 return err;
216}
217
Gustavo Padovan2d792812012-10-06 10:07:01 +0100218static int l2cap_sock_accept(struct socket *sock, struct socket *newsock,
219 int flags)
Gustavo F. Padovanc47b7c72011-02-04 02:42:23 -0200220{
221 DECLARE_WAITQUEUE(wait, current);
222 struct sock *sk = sock->sk, *nsk;
223 long timeo;
224 int err = 0;
225
226 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
227
Gustavo F. Padovanc47b7c72011-02-04 02:42:23 -0200228 timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
229
230 BT_DBG("sk %p timeo %ld", sk, timeo);
231
232 /* Wait for an incoming connection. (wake-one). */
233 add_wait_queue_exclusive(sk_sleep(sk), &wait);
Peter Hurleyf9a3c202011-07-24 00:10:52 -0400234 while (1) {
Gustavo F. Padovanc47b7c72011-02-04 02:42:23 -0200235 set_current_state(TASK_INTERRUPTIBLE);
Gustavo F. Padovanc47b7c72011-02-04 02:42:23 -0200236
237 if (sk->sk_state != BT_LISTEN) {
238 err = -EBADFD;
239 break;
240 }
241
Peter Hurleyf9a3c202011-07-24 00:10:52 -0400242 nsk = bt_accept_dequeue(sk, newsock);
243 if (nsk)
244 break;
245
246 if (!timeo) {
247 err = -EAGAIN;
248 break;
249 }
250
Gustavo F. Padovanc47b7c72011-02-04 02:42:23 -0200251 if (signal_pending(current)) {
252 err = sock_intr_errno(timeo);
253 break;
254 }
Peter Hurleyf9a3c202011-07-24 00:10:52 -0400255
256 release_sock(sk);
257 timeo = schedule_timeout(timeo);
258 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
Gustavo F. Padovanc47b7c72011-02-04 02:42:23 -0200259 }
Peter Hurleyf9a3c202011-07-24 00:10:52 -0400260 __set_current_state(TASK_RUNNING);
Gustavo F. Padovanc47b7c72011-02-04 02:42:23 -0200261 remove_wait_queue(sk_sleep(sk), &wait);
262
263 if (err)
264 goto done;
265
266 newsock->state = SS_CONNECTED;
267
268 BT_DBG("new socket %p", nsk);
269
270done:
271 release_sock(sk);
272 return err;
273}
274
Gustavo Padovan2d792812012-10-06 10:07:01 +0100275static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr,
276 int *len, int peer)
Gustavo F. Padovand7175d52011-02-04 02:43:46 -0200277{
278 struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
279 struct sock *sk = sock->sk;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300280 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Gustavo F. Padovand7175d52011-02-04 02:43:46 -0200281
282 BT_DBG("sock %p, sk %p", sock, sk);
283
Mathias Krause792039c2012-08-15 11:31:51 +0000284 memset(la, 0, sizeof(struct sockaddr_l2));
Gustavo F. Padovand7175d52011-02-04 02:43:46 -0200285 addr->sa_family = AF_BLUETOOTH;
286 *len = sizeof(struct sockaddr_l2);
287
288 if (peer) {
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300289 la->l2_psm = chan->psm;
Marcel Holtmann7eafc592013-10-13 08:12:47 -0700290 bacpy(&la->l2_bdaddr, &chan->dst);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300291 la->l2_cid = cpu_to_le16(chan->dcid);
Marcel Holtmann4f1654e2013-10-13 08:50:41 -0700292 la->l2_bdaddr_type = chan->dst_type;
Gustavo F. Padovand7175d52011-02-04 02:43:46 -0200293 } else {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300294 la->l2_psm = chan->sport;
Marcel Holtmann7eafc592013-10-13 08:12:47 -0700295 bacpy(&la->l2_bdaddr, &chan->src);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300296 la->l2_cid = cpu_to_le16(chan->scid);
Marcel Holtmann4f1654e2013-10-13 08:50:41 -0700297 la->l2_bdaddr_type = chan->src_type;
Gustavo F. Padovand7175d52011-02-04 02:43:46 -0200298 }
299
300 return 0;
301}
302
Gustavo Padovan2d792812012-10-06 10:07:01 +0100303static int l2cap_sock_getsockopt_old(struct socket *sock, int optname,
304 char __user *optval, int __user *optlen)
Gustavo F. Padovan99f48082011-02-04 02:52:55 -0200305{
306 struct sock *sk = sock->sk;
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300307 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Gustavo F. Padovan99f48082011-02-04 02:52:55 -0200308 struct l2cap_options opts;
309 struct l2cap_conninfo cinfo;
310 int len, err = 0;
311 u32 opt;
312
313 BT_DBG("sk %p", sk);
314
315 if (get_user(len, optlen))
316 return -EFAULT;
317
318 lock_sock(sk);
319
320 switch (optname) {
321 case L2CAP_OPTIONS:
Vasiliy Kulikove3fb5922011-02-10 20:59:42 +0300322 memset(&opts, 0, sizeof(opts));
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300323 opts.imtu = chan->imtu;
324 opts.omtu = chan->omtu;
325 opts.flush_to = chan->flush_to;
326 opts.mode = chan->mode;
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -0300327 opts.fcs = chan->fcs;
328 opts.max_tx = chan->max_tx;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +0300329 opts.txwin_size = chan->tx_win;
Gustavo F. Padovan99f48082011-02-04 02:52:55 -0200330
331 len = min_t(unsigned int, len, sizeof(opts));
332 if (copy_to_user(optval, (char *) &opts, len))
333 err = -EFAULT;
334
335 break;
336
337 case L2CAP_LM:
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300338 switch (chan->sec_level) {
Gustavo F. Padovan99f48082011-02-04 02:52:55 -0200339 case BT_SECURITY_LOW:
340 opt = L2CAP_LM_AUTH;
341 break;
342 case BT_SECURITY_MEDIUM:
343 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT;
344 break;
345 case BT_SECURITY_HIGH:
346 opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT |
Gustavo Padovan2d792812012-10-06 10:07:01 +0100347 L2CAP_LM_SECURE;
Gustavo F. Padovan99f48082011-02-04 02:52:55 -0200348 break;
349 default:
350 opt = 0;
351 break;
352 }
353
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +0300354 if (test_bit(FLAG_ROLE_SWITCH, &chan->flags))
Gustavo F. Padovan99f48082011-02-04 02:52:55 -0200355 opt |= L2CAP_LM_MASTER;
356
Andrei Emeltchenkoecf61bd2011-10-11 14:04:32 +0300357 if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags))
Gustavo F. Padovan99f48082011-02-04 02:52:55 -0200358 opt |= L2CAP_LM_RELIABLE;
359
360 if (put_user(opt, (u32 __user *) optval))
361 err = -EFAULT;
362 break;
363
364 case L2CAP_CONNINFO:
365 if (sk->sk_state != BT_CONNECTED &&
Gustavo Padovanc5daa682012-05-16 12:17:10 -0300366 !(sk->sk_state == BT_CONNECT2 &&
367 test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags))) {
Gustavo F. Padovan99f48082011-02-04 02:52:55 -0200368 err = -ENOTCONN;
369 break;
370 }
371
Filip Palian8d03e972011-05-12 19:32:46 +0200372 memset(&cinfo, 0, sizeof(cinfo));
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300373 cinfo.hci_handle = chan->conn->hcon->handle;
374 memcpy(cinfo.dev_class, chan->conn->hcon->dev_class, 3);
Gustavo F. Padovan99f48082011-02-04 02:52:55 -0200375
376 len = min_t(unsigned int, len, sizeof(cinfo));
377 if (copy_to_user(optval, (char *) &cinfo, len))
378 err = -EFAULT;
379
380 break;
381
382 default:
383 err = -ENOPROTOOPT;
384 break;
385 }
386
387 release_sock(sk);
388 return err;
389}
390
Gustavo Padovan2d792812012-10-06 10:07:01 +0100391static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname,
392 char __user *optval, int __user *optlen)
Gustavo F. Padovan99f48082011-02-04 02:52:55 -0200393{
394 struct sock *sk = sock->sk;
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300395 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Gustavo F. Padovan99f48082011-02-04 02:52:55 -0200396 struct bt_security sec;
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700397 struct bt_power pwr;
Gustavo F. Padovan99f48082011-02-04 02:52:55 -0200398 int len, err = 0;
399
400 BT_DBG("sk %p", sk);
401
402 if (level == SOL_L2CAP)
403 return l2cap_sock_getsockopt_old(sock, optname, optval, optlen);
404
405 if (level != SOL_BLUETOOTH)
406 return -ENOPROTOOPT;
407
408 if (get_user(len, optlen))
409 return -EFAULT;
410
411 lock_sock(sk);
412
413 switch (optname) {
414 case BT_SECURITY:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300415 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100416 chan->chan_type != L2CAP_CHAN_RAW) {
Gustavo F. Padovan99f48082011-02-04 02:52:55 -0200417 err = -EINVAL;
418 break;
419 }
420
Vinicius Costa Gomes8f360112011-07-08 18:31:46 -0300421 memset(&sec, 0, sizeof(sec));
Andrei Emeltchenko85e34362012-10-05 16:56:54 +0300422 if (chan->conn) {
Gustavo Padovanc6585a42012-05-07 03:07:26 -0300423 sec.level = chan->conn->hcon->sec_level;
Gustavo F. Padovan99f48082011-02-04 02:52:55 -0200424
Andrei Emeltchenko85e34362012-10-05 16:56:54 +0300425 if (sk->sk_state == BT_CONNECTED)
426 sec.key_size = chan->conn->hcon->enc_key_size;
427 } else {
428 sec.level = chan->sec_level;
429 }
Vinicius Costa Gomes8f360112011-07-08 18:31:46 -0300430
Gustavo F. Padovan99f48082011-02-04 02:52:55 -0200431 len = min_t(unsigned int, len, sizeof(sec));
432 if (copy_to_user(optval, (char *) &sec, len))
433 err = -EFAULT;
434
435 break;
436
437 case BT_DEFER_SETUP:
438 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
439 err = -EINVAL;
440 break;
441 }
442
Gustavo Padovanc5daa682012-05-16 12:17:10 -0300443 if (put_user(test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags),
444 (u32 __user *) optval))
Gustavo F. Padovan99f48082011-02-04 02:52:55 -0200445 err = -EFAULT;
446
447 break;
448
449 case BT_FLUSHABLE:
Andrei Emeltchenkod57b0e82011-10-11 14:04:31 +0300450 if (put_user(test_bit(FLAG_FLUSHABLE, &chan->flags),
Gustavo Padovan2d792812012-10-06 10:07:01 +0100451 (u32 __user *) optval))
Gustavo F. Padovan99f48082011-02-04 02:52:55 -0200452 err = -EFAULT;
453
454 break;
455
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700456 case BT_POWER:
457 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
Gustavo Padovan2d792812012-10-06 10:07:01 +0100458 && sk->sk_type != SOCK_RAW) {
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700459 err = -EINVAL;
460 break;
461 }
462
Andrei Emeltchenko15770b12011-10-11 14:04:33 +0300463 pwr.force_active = test_bit(FLAG_FORCE_ACTIVE, &chan->flags);
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700464
465 len = min_t(unsigned int, len, sizeof(pwr));
466 if (copy_to_user(optval, (char *) &pwr, len))
467 err = -EFAULT;
468
469 break;
470
Mat Martineau2ea66482011-11-02 16:18:30 -0700471 case BT_CHANNEL_POLICY:
Mat Martineau2ea66482011-11-02 16:18:30 -0700472 if (put_user(chan->chan_policy, (u32 __user *) optval))
473 err = -EFAULT;
474 break;
475
Gustavo F. Padovan99f48082011-02-04 02:52:55 -0200476 default:
477 err = -ENOPROTOOPT;
478 break;
479 }
480
481 release_sock(sk);
482 return err;
483}
484
Andre Guedes682877c2012-05-31 17:01:34 -0300485static bool l2cap_valid_mtu(struct l2cap_chan *chan, u16 mtu)
486{
487 switch (chan->scid) {
Johan Hedberg073d1cf2013-04-29 19:35:35 +0300488 case L2CAP_CID_ATT:
Andre Guedes8c3a4f02012-05-31 17:01:35 -0300489 if (mtu < L2CAP_LE_MIN_MTU)
Andre Guedes682877c2012-05-31 17:01:34 -0300490 return false;
491 break;
492
493 default:
494 if (mtu < L2CAP_DEFAULT_MIN_MTU)
495 return false;
496 }
497
498 return true;
499}
500
Gustavo Padovan2d792812012-10-06 10:07:01 +0100501static int l2cap_sock_setsockopt_old(struct socket *sock, int optname,
502 char __user *optval, unsigned int optlen)
Gustavo F. Padovan33575df2011-02-04 02:48:48 -0200503{
504 struct sock *sk = sock->sk;
Gustavo F. Padovanb4450032011-04-12 18:15:09 -0300505 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Gustavo F. Padovan33575df2011-02-04 02:48:48 -0200506 struct l2cap_options opts;
507 int len, err = 0;
508 u32 opt;
509
510 BT_DBG("sk %p", sk);
511
512 lock_sock(sk);
513
514 switch (optname) {
515 case L2CAP_OPTIONS:
516 if (sk->sk_state == BT_CONNECTED) {
517 err = -EINVAL;
518 break;
519 }
520
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300521 opts.imtu = chan->imtu;
522 opts.omtu = chan->omtu;
523 opts.flush_to = chan->flush_to;
524 opts.mode = chan->mode;
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -0300525 opts.fcs = chan->fcs;
526 opts.max_tx = chan->max_tx;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +0300527 opts.txwin_size = chan->tx_win;
Gustavo F. Padovan33575df2011-02-04 02:48:48 -0200528
529 len = min_t(unsigned int, sizeof(opts), optlen);
530 if (copy_from_user((char *) &opts, optval, len)) {
531 err = -EFAULT;
532 break;
533 }
534
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +0300535 if (opts.txwin_size > L2CAP_DEFAULT_EXT_WINDOW) {
Gustavo F. Padovan33575df2011-02-04 02:48:48 -0200536 err = -EINVAL;
537 break;
538 }
539
Andre Guedes682877c2012-05-31 17:01:34 -0300540 if (!l2cap_valid_mtu(chan, opts.imtu)) {
541 err = -EINVAL;
542 break;
543 }
544
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300545 chan->mode = opts.mode;
546 switch (chan->mode) {
Gustavo F. Padovan33575df2011-02-04 02:48:48 -0200547 case L2CAP_MODE_BASIC:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -0300548 clear_bit(CONF_STATE2_DEVICE, &chan->conf_state);
Gustavo F. Padovan33575df2011-02-04 02:48:48 -0200549 break;
550 case L2CAP_MODE_ERTM:
551 case L2CAP_MODE_STREAMING:
552 if (!disable_ertm)
553 break;
554 /* fall through */
555 default:
556 err = -EINVAL;
557 break;
558 }
559
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300560 chan->imtu = opts.imtu;
561 chan->omtu = opts.omtu;
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -0300562 chan->fcs = opts.fcs;
563 chan->max_tx = opts.max_tx;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +0300564 chan->tx_win = opts.txwin_size;
Andrei Emeltchenko12d59782012-10-10 17:38:26 +0300565 chan->flush_to = opts.flush_to;
Gustavo F. Padovan33575df2011-02-04 02:48:48 -0200566 break;
567
568 case L2CAP_LM:
569 if (get_user(opt, (u32 __user *) optval)) {
570 err = -EFAULT;
571 break;
572 }
573
574 if (opt & L2CAP_LM_AUTH)
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300575 chan->sec_level = BT_SECURITY_LOW;
Gustavo F. Padovan33575df2011-02-04 02:48:48 -0200576 if (opt & L2CAP_LM_ENCRYPT)
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300577 chan->sec_level = BT_SECURITY_MEDIUM;
Gustavo F. Padovan33575df2011-02-04 02:48:48 -0200578 if (opt & L2CAP_LM_SECURE)
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300579 chan->sec_level = BT_SECURITY_HIGH;
Gustavo F. Padovan33575df2011-02-04 02:48:48 -0200580
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +0300581 if (opt & L2CAP_LM_MASTER)
582 set_bit(FLAG_ROLE_SWITCH, &chan->flags);
583 else
584 clear_bit(FLAG_ROLE_SWITCH, &chan->flags);
Andrei Emeltchenkoecf61bd2011-10-11 14:04:32 +0300585
586 if (opt & L2CAP_LM_RELIABLE)
587 set_bit(FLAG_FORCE_RELIABLE, &chan->flags);
588 else
589 clear_bit(FLAG_FORCE_RELIABLE, &chan->flags);
Gustavo F. Padovan33575df2011-02-04 02:48:48 -0200590 break;
591
592 default:
593 err = -ENOPROTOOPT;
594 break;
595 }
596
597 release_sock(sk);
598 return err;
599}
600
Gustavo Padovan2d792812012-10-06 10:07:01 +0100601static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
602 char __user *optval, unsigned int optlen)
Gustavo F. Padovan33575df2011-02-04 02:48:48 -0200603{
604 struct sock *sk = sock->sk;
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300605 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Gustavo F. Padovan33575df2011-02-04 02:48:48 -0200606 struct bt_security sec;
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700607 struct bt_power pwr;
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300608 struct l2cap_conn *conn;
Gustavo F. Padovan33575df2011-02-04 02:48:48 -0200609 int len, err = 0;
610 u32 opt;
611
612 BT_DBG("sk %p", sk);
613
614 if (level == SOL_L2CAP)
615 return l2cap_sock_setsockopt_old(sock, optname, optval, optlen);
616
617 if (level != SOL_BLUETOOTH)
618 return -ENOPROTOOPT;
619
620 lock_sock(sk);
621
622 switch (optname) {
623 case BT_SECURITY:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300624 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100625 chan->chan_type != L2CAP_CHAN_RAW) {
Gustavo F. Padovan33575df2011-02-04 02:48:48 -0200626 err = -EINVAL;
627 break;
628 }
629
630 sec.level = BT_SECURITY_LOW;
631
632 len = min_t(unsigned int, sizeof(sec), optlen);
633 if (copy_from_user((char *) &sec, optval, len)) {
634 err = -EFAULT;
635 break;
636 }
637
638 if (sec.level < BT_SECURITY_LOW ||
Gustavo Padovan2d792812012-10-06 10:07:01 +0100639 sec.level > BT_SECURITY_HIGH) {
Gustavo F. Padovan33575df2011-02-04 02:48:48 -0200640 err = -EINVAL;
641 break;
642 }
643
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300644 chan->sec_level = sec.level;
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300645
Gustavo F. Padovan0bee1d62011-11-05 19:58:31 -0200646 if (!chan->conn)
647 break;
648
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300649 conn = chan->conn;
Gustavo F. Padovan0bee1d62011-11-05 19:58:31 -0200650
651 /*change security for LE channels */
Johan Hedberg073d1cf2013-04-29 19:35:35 +0300652 if (chan->scid == L2CAP_CID_ATT) {
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300653 if (!conn->hcon->out) {
654 err = -EINVAL;
655 break;
656 }
657
Vinicius Costa Gomescc110922012-08-23 21:32:43 -0300658 if (smp_conn_security(conn->hcon, sec.level))
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300659 break;
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300660 sk->sk_state = BT_CONFIG;
Gustavo F. Padovan3542b8542011-12-28 13:54:17 -0200661 chan->state = BT_CONFIG;
Gustavo F. Padovan0bee1d62011-11-05 19:58:31 -0200662
Gustavo Padovana7d77232012-05-13 03:20:07 -0300663 /* or for ACL link */
664 } else if ((sk->sk_state == BT_CONNECT2 &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100665 test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) ||
Gustavo Padovana7d77232012-05-13 03:20:07 -0300666 sk->sk_state == BT_CONNECTED) {
667 if (!l2cap_chan_check_security(chan))
Gustavo Padovanc5daa682012-05-16 12:17:10 -0300668 set_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags);
Gustavo Padovana7d77232012-05-13 03:20:07 -0300669 else
670 sk->sk_state_change(sk);
Gustavo F. Padovan0bee1d62011-11-05 19:58:31 -0200671 } else {
672 err = -EINVAL;
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300673 }
Gustavo F. Padovan33575df2011-02-04 02:48:48 -0200674 break;
675
676 case BT_DEFER_SETUP:
677 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
678 err = -EINVAL;
679 break;
680 }
681
682 if (get_user(opt, (u32 __user *) optval)) {
683 err = -EFAULT;
684 break;
685 }
686
Marcel Holtmannbdc25782013-10-14 02:45:34 -0700687 if (opt) {
Gustavo Padovanc5daa682012-05-16 12:17:10 -0300688 set_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags);
Marcel Holtmannbdc25782013-10-14 02:45:34 -0700689 set_bit(FLAG_DEFER_SETUP, &chan->flags);
690 } else {
Gustavo Padovanc5daa682012-05-16 12:17:10 -0300691 clear_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags);
Marcel Holtmannbdc25782013-10-14 02:45:34 -0700692 clear_bit(FLAG_DEFER_SETUP, &chan->flags);
693 }
Gustavo F. Padovan33575df2011-02-04 02:48:48 -0200694 break;
695
696 case BT_FLUSHABLE:
697 if (get_user(opt, (u32 __user *) optval)) {
698 err = -EFAULT;
699 break;
700 }
701
702 if (opt > BT_FLUSHABLE_ON) {
703 err = -EINVAL;
704 break;
705 }
706
707 if (opt == BT_FLUSHABLE_OFF) {
Johannes Bergc1f23a22013-10-07 18:19:16 +0200708 conn = chan->conn;
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300709 /* proceed further only when we have l2cap_conn and
Gustavo F. Padovan33575df2011-02-04 02:48:48 -0200710 No Flush support in the LM */
711 if (!conn || !lmp_no_flush_capable(conn->hcon->hdev)) {
712 err = -EINVAL;
713 break;
714 }
715 }
716
Andrei Emeltchenkod57b0e82011-10-11 14:04:31 +0300717 if (opt)
718 set_bit(FLAG_FLUSHABLE, &chan->flags);
719 else
720 clear_bit(FLAG_FLUSHABLE, &chan->flags);
Gustavo F. Padovan33575df2011-02-04 02:48:48 -0200721 break;
722
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700723 case BT_POWER:
724 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100725 chan->chan_type != L2CAP_CHAN_RAW) {
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700726 err = -EINVAL;
727 break;
728 }
729
730 pwr.force_active = BT_POWER_FORCE_ACTIVE_ON;
731
732 len = min_t(unsigned int, sizeof(pwr), optlen);
733 if (copy_from_user((char *) &pwr, optval, len)) {
734 err = -EFAULT;
735 break;
736 }
Andrei Emeltchenko15770b12011-10-11 14:04:33 +0300737
738 if (pwr.force_active)
739 set_bit(FLAG_FORCE_ACTIVE, &chan->flags);
740 else
741 clear_bit(FLAG_FORCE_ACTIVE, &chan->flags);
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700742 break;
743
Mat Martineau2ea66482011-11-02 16:18:30 -0700744 case BT_CHANNEL_POLICY:
Mat Martineau2ea66482011-11-02 16:18:30 -0700745 if (get_user(opt, (u32 __user *) optval)) {
746 err = -EFAULT;
747 break;
748 }
749
750 if (opt > BT_CHANNEL_POLICY_AMP_PREFERRED) {
751 err = -EINVAL;
752 break;
753 }
754
755 if (chan->mode != L2CAP_MODE_ERTM &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100756 chan->mode != L2CAP_MODE_STREAMING) {
Mat Martineau2ea66482011-11-02 16:18:30 -0700757 err = -EOPNOTSUPP;
758 break;
759 }
760
761 chan->chan_policy = (u8) opt;
Mat Martineau3f7a56c2012-10-23 15:24:23 -0700762
763 if (sk->sk_state == BT_CONNECTED &&
764 chan->move_role == L2CAP_MOVE_ROLE_NONE)
765 l2cap_move_start(chan);
766
Gustavo F. Padovan33575df2011-02-04 02:48:48 -0200767 break;
768
769 default:
770 err = -ENOPROTOOPT;
771 break;
772 }
773
774 release_sock(sk);
775 return err;
776}
777
Gustavo Padovan2d792812012-10-06 10:07:01 +0100778static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
779 struct msghdr *msg, size_t len)
Gustavo F. Padovanfd83ccd2011-02-04 03:20:52 -0200780{
781 struct sock *sk = sock->sk;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300782 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Gustavo F. Padovanfd83ccd2011-02-04 03:20:52 -0200783 int err;
784
785 BT_DBG("sock %p, sk %p", sock, sk);
786
787 err = sock_error(sk);
788 if (err)
789 return err;
790
791 if (msg->msg_flags & MSG_OOB)
792 return -EOPNOTSUPP;
793
Mat Martineaua6a55682012-05-04 14:20:31 -0700794 if (sk->sk_state != BT_CONNECTED)
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -0300795 return -ENOTCONN;
Gustavo F. Padovanfd83ccd2011-02-04 03:20:52 -0200796
Johan Hedberge793dcf2013-09-16 13:05:19 +0300797 lock_sock(sk);
798 err = bt_sock_wait_ready(sk, msg->msg_flags);
799 release_sock(sk);
800 if (err)
801 return err;
802
Mat Martineaua6a55682012-05-04 14:20:31 -0700803 l2cap_chan_lock(chan);
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +0200804 err = l2cap_chan_send(chan, msg, len, sk->sk_priority);
Mat Martineaua6a55682012-05-04 14:20:31 -0700805 l2cap_chan_unlock(chan);
Gustavo F. Padovanfd83ccd2011-02-04 03:20:52 -0200806
Gustavo F. Padovanfd83ccd2011-02-04 03:20:52 -0200807 return err;
808}
809
Gustavo Padovan2d792812012-10-06 10:07:01 +0100810static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
811 struct msghdr *msg, size_t len, int flags)
Gustavo F. Padovan68983252011-02-04 03:02:31 -0200812{
813 struct sock *sk = sock->sk;
Mat Martineaue3281402011-07-07 09:39:02 -0700814 struct l2cap_pinfo *pi = l2cap_pi(sk);
815 int err;
Gustavo F. Padovan68983252011-02-04 03:02:31 -0200816
817 lock_sock(sk);
818
Gustavo Padovanc5daa682012-05-16 12:17:10 -0300819 if (sk->sk_state == BT_CONNECT2 && test_bit(BT_SK_DEFER_SETUP,
820 &bt_sk(sk)->flags)) {
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300821 sk->sk_state = BT_CONFIG;
Gustavo F. Padovan3542b8542011-12-28 13:54:17 -0200822 pi->chan->state = BT_CONFIG;
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300823
Mat Martineaue3281402011-07-07 09:39:02 -0700824 __l2cap_connect_rsp_defer(pi->chan);
Johan Hedberg970871b2013-09-25 13:26:05 +0300825 err = 0;
826 goto done;
Gustavo F. Padovan68983252011-02-04 03:02:31 -0200827 }
828
829 release_sock(sk);
830
831 if (sock->type == SOCK_STREAM)
Mat Martineaue3281402011-07-07 09:39:02 -0700832 err = bt_sock_stream_recvmsg(iocb, sock, msg, len, flags);
833 else
834 err = bt_sock_recvmsg(iocb, sock, msg, len, flags);
Gustavo F. Padovan68983252011-02-04 03:02:31 -0200835
Mat Martineaue3281402011-07-07 09:39:02 -0700836 if (pi->chan->mode != L2CAP_MODE_ERTM)
837 return err;
838
839 /* Attempt to put pending rx data in the socket buffer */
840
841 lock_sock(sk);
842
843 if (!test_bit(CONN_LOCAL_BUSY, &pi->chan->conn_state))
844 goto done;
845
846 if (pi->rx_busy_skb) {
847 if (!sock_queue_rcv_skb(sk, pi->rx_busy_skb))
848 pi->rx_busy_skb = NULL;
849 else
850 goto done;
851 }
852
853 /* Restore data flow when half of the receive buffer is
854 * available. This avoids resending large numbers of
855 * frames.
856 */
857 if (atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf >> 1)
858 l2cap_chan_busy(pi->chan, 0);
859
860done:
861 release_sock(sk);
862 return err;
Gustavo F. Padovan68983252011-02-04 03:02:31 -0200863}
864
Gustavo F. Padovan05fc1572011-02-04 03:26:01 -0200865/* Kill socket (only if zapped and orphan)
866 * Must be called on unlocked socket.
867 */
Gustavo F. Padovanba3bd0e2011-05-16 18:23:24 -0300868static void l2cap_sock_kill(struct sock *sk)
Gustavo F. Padovan05fc1572011-02-04 03:26:01 -0200869{
870 if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket)
871 return;
872
Andrei Emeltchenkoe05dcc32012-02-17 11:40:56 +0200873 BT_DBG("sk %p state %s", sk, state_to_string(sk->sk_state));
Gustavo F. Padovan05fc1572011-02-04 03:26:01 -0200874
875 /* Kill poor orphan */
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300876
Jaganath Kanakkassery4af66c62012-07-13 18:17:55 +0530877 l2cap_chan_put(l2cap_pi(sk)->chan);
Gustavo F. Padovan05fc1572011-02-04 03:26:01 -0200878 sock_set_flag(sk, SOCK_DEAD);
879 sock_put(sk);
880}
881
Gustavo F. Padovandcba0db2011-02-04 03:08:36 -0200882static int l2cap_sock_shutdown(struct socket *sock, int how)
883{
884 struct sock *sk = sock->sk;
Andrei Emeltchenko7ddb6e02012-02-14 15:12:57 +0200885 struct l2cap_chan *chan;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200886 struct l2cap_conn *conn;
Gustavo F. Padovandcba0db2011-02-04 03:08:36 -0200887 int err = 0;
888
889 BT_DBG("sock %p, sk %p", sock, sk);
890
891 if (!sk)
892 return 0;
893
Andrei Emeltchenko7ddb6e02012-02-14 15:12:57 +0200894 chan = l2cap_pi(sk)->chan;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200895 conn = chan->conn;
896
897 if (conn)
898 mutex_lock(&conn->chan_lock);
Andrei Emeltchenko7ddb6e02012-02-14 15:12:57 +0200899
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200900 l2cap_chan_lock(chan);
Gustavo F. Padovandcba0db2011-02-04 03:08:36 -0200901 lock_sock(sk);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200902
Gustavo F. Padovandcba0db2011-02-04 03:08:36 -0200903 if (!sk->sk_shutdown) {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300904 if (chan->mode == L2CAP_MODE_ERTM)
Gustavo F. Padovandcba0db2011-02-04 03:08:36 -0200905 err = __l2cap_wait_ack(sk);
906
907 sk->sk_shutdown = SHUTDOWN_MASK;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200908
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200909 release_sock(sk);
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300910 l2cap_chan_close(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200911 lock_sock(sk);
Gustavo F. Padovandcba0db2011-02-04 03:08:36 -0200912
913 if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
914 err = bt_sock_wait_state(sk, BT_CLOSED,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100915 sk->sk_lingertime);
Gustavo F. Padovandcba0db2011-02-04 03:08:36 -0200916 }
917
918 if (!err && sk->sk_err)
919 err = -sk->sk_err;
920
921 release_sock(sk);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200922 l2cap_chan_unlock(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200923
924 if (conn)
925 mutex_unlock(&conn->chan_lock);
926
Gustavo F. Padovandcba0db2011-02-04 03:08:36 -0200927 return err;
928}
929
Gustavo F. Padovan554f05b2011-02-04 02:36:42 -0200930static int l2cap_sock_release(struct socket *sock)
931{
932 struct sock *sk = sock->sk;
933 int err;
934
935 BT_DBG("sock %p, sk %p", sock, sk);
936
937 if (!sk)
938 return 0;
939
Masatake YAMATO5b28d952012-07-26 01:29:25 +0900940 bt_sock_unlink(&l2cap_sk_list, sk);
941
Gustavo F. Padovan554f05b2011-02-04 02:36:42 -0200942 err = l2cap_sock_shutdown(sock, 2);
943
944 sock_orphan(sk);
945 l2cap_sock_kill(sk);
946 return err;
947}
948
Andrei Emeltchenkoc0df7f62012-05-27 22:27:52 -0300949static void l2cap_sock_cleanup_listen(struct sock *parent)
950{
951 struct sock *sk;
952
953 BT_DBG("parent %p", parent);
954
955 /* Close not yet accepted channels */
956 while ((sk = bt_accept_dequeue(parent, NULL))) {
957 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
958
959 l2cap_chan_lock(chan);
960 __clear_chan_timer(chan);
961 l2cap_chan_close(chan, ECONNRESET);
962 l2cap_chan_unlock(chan);
963
964 l2cap_sock_kill(sk);
965 }
966}
967
Gustavo Padovan80b98022012-05-27 22:27:51 -0300968static struct l2cap_chan *l2cap_sock_new_connection_cb(struct l2cap_chan *chan)
Gustavo F. Padovan80808e42011-05-16 17:24:37 -0300969{
Gustavo Padovan80b98022012-05-27 22:27:51 -0300970 struct sock *sk, *parent = chan->data;
Gustavo F. Padovan80808e42011-05-16 17:24:37 -0300971
Gustavo Padovan53826692012-05-27 22:27:55 -0300972 /* Check for backlog size */
973 if (sk_acceptq_is_full(parent)) {
974 BT_DBG("backlog full %d", parent->sk_ack_backlog);
975 return NULL;
976 }
977
Gustavo F. Padovan80808e42011-05-16 17:24:37 -0300978 sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100979 GFP_ATOMIC);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -0300980 if (!sk)
981 return NULL;
982
Octavian Purdilad22015a2012-01-22 00:28:34 +0200983 bt_sock_reclassify_lock(sk, BTPROTO_L2CAP);
984
Gustavo F. Padovan80808e42011-05-16 17:24:37 -0300985 l2cap_sock_init(sk, parent);
986
Gustavo Padovan644912e2012-10-12 19:35:23 +0800987 bt_accept_enqueue(parent, sk);
988
Gustavo F. Padovan80808e42011-05-16 17:24:37 -0300989 return l2cap_pi(sk)->chan;
990}
991
Gustavo Padovan80b98022012-05-27 22:27:51 -0300992static int l2cap_sock_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb)
Gustavo F. Padovan23070492011-05-16 17:57:22 -0300993{
Gustavo Padovan80b98022012-05-27 22:27:51 -0300994 struct sock *sk = chan->data;
Marcel Holtmann84b34d92013-10-13 11:36:07 -0700995 int err;
Gustavo F. Padovan23070492011-05-16 17:57:22 -0300996
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200997 lock_sock(sk);
998
Marcel Holtmann84b34d92013-10-13 11:36:07 -0700999 if (l2cap_pi(sk)->rx_busy_skb) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001000 err = -ENOMEM;
1001 goto done;
1002 }
Mat Martineaue3281402011-07-07 09:39:02 -07001003
1004 err = sock_queue_rcv_skb(sk, skb);
1005
1006 /* For ERTM, handle one skb that doesn't fit into the recv
1007 * buffer. This is important to do because the data frames
1008 * have already been acked, so the skb cannot be discarded.
1009 *
1010 * Notify the l2cap core that the buffer is full, so the
1011 * LOCAL_BUSY state is entered and no more frames are
1012 * acked and reassembled until there is buffer space
1013 * available.
1014 */
Marcel Holtmann84b34d92013-10-13 11:36:07 -07001015 if (err < 0 && chan->mode == L2CAP_MODE_ERTM) {
1016 l2cap_pi(sk)->rx_busy_skb = skb;
1017 l2cap_chan_busy(chan, 1);
Mat Martineaue3281402011-07-07 09:39:02 -07001018 err = 0;
1019 }
1020
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001021done:
1022 release_sock(sk);
1023
Mat Martineaue3281402011-07-07 09:39:02 -07001024 return err;
Gustavo F. Padovan23070492011-05-16 17:57:22 -03001025}
1026
Gustavo Padovan80b98022012-05-27 22:27:51 -03001027static void l2cap_sock_close_cb(struct l2cap_chan *chan)
Gustavo F. Padovanba3bd0e2011-05-16 18:23:24 -03001028{
Gustavo Padovan80b98022012-05-27 22:27:51 -03001029 struct sock *sk = chan->data;
Gustavo F. Padovanba3bd0e2011-05-16 18:23:24 -03001030
1031 l2cap_sock_kill(sk);
1032}
1033
Andrei Emeltchenkoc0df7f62012-05-27 22:27:52 -03001034static void l2cap_sock_teardown_cb(struct l2cap_chan *chan, int err)
1035{
1036 struct sock *sk = chan->data;
1037 struct sock *parent;
1038
1039 lock_sock(sk);
1040
1041 parent = bt_sk(sk)->parent;
1042
1043 sock_set_flag(sk, SOCK_ZAPPED);
1044
1045 switch (chan->state) {
1046 case BT_OPEN:
1047 case BT_BOUND:
1048 case BT_CLOSED:
1049 break;
1050 case BT_LISTEN:
1051 l2cap_sock_cleanup_listen(sk);
1052 sk->sk_state = BT_CLOSED;
1053 chan->state = BT_CLOSED;
1054
1055 break;
1056 default:
1057 sk->sk_state = BT_CLOSED;
1058 chan->state = BT_CLOSED;
1059
1060 sk->sk_err = err;
1061
1062 if (parent) {
1063 bt_accept_unlink(sk);
1064 parent->sk_data_ready(parent, 0);
1065 } else {
1066 sk->sk_state_change(sk);
1067 }
1068
1069 break;
1070 }
1071
1072 release_sock(sk);
1073}
1074
Gustavo Padovan53f52122013-10-15 19:24:45 -03001075static void l2cap_sock_state_change_cb(struct l2cap_chan *chan, int state,
1076 int err)
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001077{
Gustavo Padovan80b98022012-05-27 22:27:51 -03001078 struct sock *sk = chan->data;
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001079
1080 sk->sk_state = state;
Gustavo Padovan53f52122013-10-15 19:24:45 -03001081
1082 if (err)
1083 sk->sk_err = err;
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001084}
1085
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02001086static struct sk_buff *l2cap_sock_alloc_skb_cb(struct l2cap_chan *chan,
Gustavo Padovan90338942012-04-06 20:15:47 -03001087 unsigned long len, int nb)
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02001088{
Gustavo Padovan90338942012-04-06 20:15:47 -03001089 struct sk_buff *skb;
1090 int err;
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02001091
Mat Martineaua6a55682012-05-04 14:20:31 -07001092 l2cap_chan_unlock(chan);
Gustavo Padovan90338942012-04-06 20:15:47 -03001093 skb = bt_skb_send_alloc(chan->sk, len, nb, &err);
Mat Martineaua6a55682012-05-04 14:20:31 -07001094 l2cap_chan_lock(chan);
1095
Gustavo Padovan90338942012-04-06 20:15:47 -03001096 if (!skb)
1097 return ERR_PTR(err);
1098
1099 return skb;
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02001100}
1101
Andrei Emeltchenko54a59aa2012-05-27 22:27:53 -03001102static void l2cap_sock_ready_cb(struct l2cap_chan *chan)
1103{
1104 struct sock *sk = chan->data;
1105 struct sock *parent;
1106
1107 lock_sock(sk);
1108
1109 parent = bt_sk(sk)->parent;
1110
1111 BT_DBG("sk %p, parent %p", sk, parent);
1112
1113 sk->sk_state = BT_CONNECTED;
1114 sk->sk_state_change(sk);
1115
1116 if (parent)
1117 parent->sk_data_ready(parent, 0);
1118
1119 release_sock(sk);
1120}
1121
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08001122static void l2cap_sock_defer_cb(struct l2cap_chan *chan)
1123{
1124 struct sock *sk = chan->data;
1125 struct sock *parent = bt_sk(sk)->parent;
1126
1127 if (parent)
1128 parent->sk_data_ready(parent, 0);
1129}
1130
Marcel Holtmannd97c8992013-10-14 02:53:54 -07001131static void l2cap_sock_resume_cb(struct l2cap_chan *chan)
1132{
1133 struct sock *sk = chan->data;
1134
1135 clear_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags);
1136 sk->sk_state_change(sk);
1137}
1138
Gustavo Padovan8d836d72013-10-15 19:24:47 -03001139static long l2cap_sock_get_sndtimeo_cb(struct l2cap_chan *chan)
1140{
1141 struct sock *sk = chan->data;
1142
1143 return sk->sk_sndtimeo;
1144}
1145
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001146static struct l2cap_ops l2cap_chan_ops = {
1147 .name = "L2CAP Socket Interface",
1148 .new_connection = l2cap_sock_new_connection_cb,
Gustavo F. Padovan23070492011-05-16 17:57:22 -03001149 .recv = l2cap_sock_recv_cb,
Gustavo F. Padovanba3bd0e2011-05-16 18:23:24 -03001150 .close = l2cap_sock_close_cb,
Andrei Emeltchenkoc0df7f62012-05-27 22:27:52 -03001151 .teardown = l2cap_sock_teardown_cb,
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001152 .state_change = l2cap_sock_state_change_cb,
Andrei Emeltchenko54a59aa2012-05-27 22:27:53 -03001153 .ready = l2cap_sock_ready_cb,
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08001154 .defer = l2cap_sock_defer_cb,
Marcel Holtmannd97c8992013-10-14 02:53:54 -07001155 .resume = l2cap_sock_resume_cb,
Gustavo Padovan8d836d72013-10-15 19:24:47 -03001156 .get_sndtimeo = l2cap_sock_get_sndtimeo_cb,
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02001157 .alloc_skb = l2cap_sock_alloc_skb_cb,
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001158};
1159
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02001160static void l2cap_sock_destruct(struct sock *sk)
1161{
1162 BT_DBG("sk %p", sk);
1163
Sasha Levin23d3a862012-10-08 16:48:32 -04001164 if (l2cap_pi(sk)->chan)
1165 l2cap_chan_put(l2cap_pi(sk)->chan);
Marcel Holtmann84b34d92013-10-13 11:36:07 -07001166
Mat Martineaue3281402011-07-07 09:39:02 -07001167 if (l2cap_pi(sk)->rx_busy_skb) {
1168 kfree_skb(l2cap_pi(sk)->rx_busy_skb);
1169 l2cap_pi(sk)->rx_busy_skb = NULL;
1170 }
1171
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02001172 skb_queue_purge(&sk->sk_receive_queue);
1173 skb_queue_purge(&sk->sk_write_queue);
1174}
1175
Marcel Holtmann2edf8702013-10-13 12:55:29 -07001176static void l2cap_skb_msg_name(struct sk_buff *skb, void *msg_name,
1177 int *msg_namelen)
1178{
1179 struct sockaddr_l2 *la = (struct sockaddr_l2 *) msg_name;
1180
1181 memset(la, 0, sizeof(struct sockaddr_l2));
1182 la->l2_family = AF_BLUETOOTH;
1183 la->l2_psm = bt_cb(skb)->psm;
1184 bacpy(&la->l2_bdaddr, &bt_cb(skb)->bdaddr);
1185
1186 *msg_namelen = sizeof(struct sockaddr_l2);
1187}
1188
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001189static void l2cap_sock_init(struct sock *sk, struct sock *parent)
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02001190{
Marcel Holtmann84b34d92013-10-13 11:36:07 -07001191 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02001192
1193 BT_DBG("sk %p", sk);
1194
1195 if (parent) {
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03001196 struct l2cap_chan *pchan = l2cap_pi(parent)->chan;
1197
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02001198 sk->sk_type = parent->sk_type;
Gustavo Padovanc5daa682012-05-16 12:17:10 -03001199 bt_sk(sk)->flags = bt_sk(parent)->flags;
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02001200
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001201 chan->chan_type = pchan->chan_type;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03001202 chan->imtu = pchan->imtu;
1203 chan->omtu = pchan->omtu;
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03001204 chan->conf_state = pchan->conf_state;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03001205 chan->mode = pchan->mode;
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001206 chan->fcs = pchan->fcs;
1207 chan->max_tx = pchan->max_tx;
1208 chan->tx_win = pchan->tx_win;
Andrei Emeltchenko6b3c7102011-11-02 09:57:10 +02001209 chan->tx_win_max = pchan->tx_win_max;
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001210 chan->sec_level = pchan->sec_level;
Andrei Emeltchenkod57b0e82011-10-11 14:04:31 +03001211 chan->flags = pchan->flags;
Paul Moore6230c9b2011-10-07 09:40:59 +00001212
1213 security_sk_clone(parent, sk);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02001214 } else {
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001215 switch (sk->sk_type) {
1216 case SOCK_RAW:
1217 chan->chan_type = L2CAP_CHAN_RAW;
1218 break;
1219 case SOCK_DGRAM:
1220 chan->chan_type = L2CAP_CHAN_CONN_LESS;
Marcel Holtmann2edf8702013-10-13 12:55:29 -07001221 bt_sk(sk)->skb_msg_name = l2cap_skb_msg_name;
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001222 break;
1223 case SOCK_SEQPACKET:
1224 case SOCK_STREAM:
1225 chan->chan_type = L2CAP_CHAN_CONN_ORIENTED;
1226 break;
1227 }
1228
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03001229 chan->imtu = L2CAP_DEFAULT_MTU;
1230 chan->omtu = 0;
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02001231 if (!disable_ertm && sk->sk_type == SOCK_STREAM) {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03001232 chan->mode = L2CAP_MODE_ERTM;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001233 set_bit(CONF_STATE2_DEVICE, &chan->conf_state);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02001234 } else {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03001235 chan->mode = L2CAP_MODE_BASIC;
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02001236 }
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +03001237
1238 l2cap_chan_set_defaults(chan);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02001239 }
1240
1241 /* Default config options */
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03001242 chan->flush_to = L2CAP_DEFAULT_FLUSH_TO;
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001243
1244 chan->data = sk;
1245 chan->ops = &l2cap_chan_ops;
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02001246}
1247
1248static struct proto l2cap_proto = {
1249 .name = "L2CAP",
1250 .owner = THIS_MODULE,
1251 .obj_size = sizeof(struct l2cap_pinfo)
1252};
1253
Gustavo Padovan2d792812012-10-06 10:07:01 +01001254static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock,
1255 int proto, gfp_t prio)
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02001256{
1257 struct sock *sk;
Gustavo F. Padovandc50a062011-05-16 16:42:01 -03001258 struct l2cap_chan *chan;
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02001259
1260 sk = sk_alloc(net, PF_BLUETOOTH, prio, &l2cap_proto);
1261 if (!sk)
1262 return NULL;
1263
1264 sock_init_data(sock, sk);
1265 INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
1266
1267 sk->sk_destruct = l2cap_sock_destruct;
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08001268 sk->sk_sndtimeo = L2CAP_CONN_TIMEOUT;
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02001269
1270 sock_reset_flag(sk, SOCK_ZAPPED);
1271
1272 sk->sk_protocol = proto;
1273 sk->sk_state = BT_OPEN;
1274
Gustavo Padovaneef1d9b2012-03-25 13:59:16 -03001275 chan = l2cap_chan_create();
Gustavo F. Padovandc50a062011-05-16 16:42:01 -03001276 if (!chan) {
Jaganath Kanakkassery49dfbb92012-07-19 12:54:04 +05301277 sk_free(sk);
Gustavo F. Padovandc50a062011-05-16 16:42:01 -03001278 return NULL;
1279 }
1280
Mat Martineau61d6ef32012-04-27 16:50:50 -07001281 l2cap_chan_hold(chan);
1282
Gustavo Padovaneef1d9b2012-03-25 13:59:16 -03001283 chan->sk = sk;
1284
Gustavo F. Padovandc50a062011-05-16 16:42:01 -03001285 l2cap_pi(sk)->chan = chan;
1286
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02001287 return sk;
1288}
1289
1290static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol,
1291 int kern)
1292{
1293 struct sock *sk;
1294
1295 BT_DBG("sock %p", sock);
1296
1297 sock->state = SS_UNCONNECTED;
1298
1299 if (sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01001300 sock->type != SOCK_DGRAM && sock->type != SOCK_RAW)
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02001301 return -ESOCKTNOSUPPORT;
1302
1303 if (sock->type == SOCK_RAW && !kern && !capable(CAP_NET_RAW))
1304 return -EPERM;
1305
1306 sock->ops = &l2cap_sock_ops;
1307
1308 sk = l2cap_sock_alloc(net, sock, protocol, GFP_ATOMIC);
1309 if (!sk)
1310 return -ENOMEM;
1311
1312 l2cap_sock_init(sk, NULL);
Masatake YAMATO5b28d952012-07-26 01:29:25 +09001313 bt_sock_link(&l2cap_sk_list, sk);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02001314 return 0;
1315}
1316
Gustavo F. Padovancf2f90f2011-04-27 18:40:39 -03001317static const struct proto_ops l2cap_sock_ops = {
Gustavo F. Padovan65390582011-02-04 02:33:56 -02001318 .family = PF_BLUETOOTH,
1319 .owner = THIS_MODULE,
1320 .release = l2cap_sock_release,
1321 .bind = l2cap_sock_bind,
1322 .connect = l2cap_sock_connect,
1323 .listen = l2cap_sock_listen,
1324 .accept = l2cap_sock_accept,
1325 .getname = l2cap_sock_getname,
1326 .sendmsg = l2cap_sock_sendmsg,
1327 .recvmsg = l2cap_sock_recvmsg,
1328 .poll = bt_sock_poll,
1329 .ioctl = bt_sock_ioctl,
1330 .mmap = sock_no_mmap,
1331 .socketpair = sock_no_socketpair,
1332 .shutdown = l2cap_sock_shutdown,
1333 .setsockopt = l2cap_sock_setsockopt,
1334 .getsockopt = l2cap_sock_getsockopt
1335};
1336
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02001337static const struct net_proto_family l2cap_sock_family_ops = {
1338 .family = PF_BLUETOOTH,
1339 .owner = THIS_MODULE,
1340 .create = l2cap_sock_create,
1341};
1342
1343int __init l2cap_init_sockets(void)
1344{
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03001345 int err;
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02001346
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03001347 err = proto_register(&l2cap_proto, 0);
1348 if (err < 0)
1349 return err;
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02001350
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03001351 err = bt_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops);
Masatake YAMATO5b28d952012-07-26 01:29:25 +09001352 if (err < 0) {
1353 BT_ERR("L2CAP socket registration failed");
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03001354 goto error;
Masatake YAMATO5b28d952012-07-26 01:29:25 +09001355 }
1356
Al Virob0316612013-04-04 19:14:33 -04001357 err = bt_procfs_init(&init_net, "l2cap", &l2cap_sk_list,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001358 NULL);
Masatake YAMATO5b28d952012-07-26 01:29:25 +09001359 if (err < 0) {
1360 BT_ERR("Failed to create L2CAP proc file");
1361 bt_sock_unregister(BTPROTO_L2CAP);
1362 goto error;
1363 }
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02001364
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03001365 BT_INFO("L2CAP socket layer initialized");
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02001366
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03001367 return 0;
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02001368
1369error:
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03001370 proto_unregister(&l2cap_proto);
1371 return err;
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02001372}
1373
1374void l2cap_cleanup_sockets(void)
1375{
Masatake YAMATO5b28d952012-07-26 01:29:25 +09001376 bt_procfs_cleanup(&init_net, "l2cap");
David Herrmann5e9d7f82013-02-24 19:36:51 +01001377 bt_sock_unregister(BTPROTO_L2CAP);
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03001378 proto_unregister(&l2cap_proto);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02001379}