blob: 4b325250236fd87b3f647bfc40f2e5bc3cb0e3b4 [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 address family and sockets. */
26
Linus Torvalds1da177e2005-04-16 15:20:36 -070027#include <linux/module.h>
Marcel Holtmannffcecac2013-10-17 17:24:18 -070028#include <linux/debugfs.h>
Marcel Holtmann9e8305b2016-08-30 05:00:35 +020029#include <linux/stringify.h>
Marcel Holtmann3241ad82008-07-14 20:13:50 +020030#include <asm/ioctls.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070031
32#include <net/bluetooth/bluetooth.h>
Masatake YAMATO256a06c2012-07-26 01:26:32 +090033#include <linux/proc_fs.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070034
Marcel Holtmanne64c97b2016-07-21 14:12:41 +020035#include "leds.h"
Marcel Holtmannee485292014-12-29 20:48:35 -080036#include "selftest.h"
37
Linus Torvalds1da177e2005-04-16 15:20:36 -070038/* Bluetooth sockets */
39#define BT_MAX_PROTO 8
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +000040static const struct net_proto_family *bt_proto[BT_MAX_PROTO];
Marcel Holtmanndb7aa1c2008-11-30 12:17:19 +010041static DEFINE_RWLOCK(bt_proto_lock);
Dave Young68845cb2008-04-01 23:58:35 -070042
Dave Young68845cb2008-04-01 23:58:35 -070043static struct lock_class_key bt_lock_key[BT_MAX_PROTO];
Jan Engelhardt36cbd3d2009-08-05 10:42:58 -070044static const char *const bt_key_strings[BT_MAX_PROTO] = {
Dave Young68845cb2008-04-01 23:58:35 -070045 "sk_lock-AF_BLUETOOTH-BTPROTO_L2CAP",
46 "sk_lock-AF_BLUETOOTH-BTPROTO_HCI",
47 "sk_lock-AF_BLUETOOTH-BTPROTO_SCO",
48 "sk_lock-AF_BLUETOOTH-BTPROTO_RFCOMM",
49 "sk_lock-AF_BLUETOOTH-BTPROTO_BNEP",
50 "sk_lock-AF_BLUETOOTH-BTPROTO_CMTP",
51 "sk_lock-AF_BLUETOOTH-BTPROTO_HIDP",
52 "sk_lock-AF_BLUETOOTH-BTPROTO_AVDTP",
53};
54
Marcel Holtmanndb7aa1c2008-11-30 12:17:19 +010055static struct lock_class_key bt_slock_key[BT_MAX_PROTO];
Jan Engelhardt36cbd3d2009-08-05 10:42:58 -070056static const char *const bt_slock_key_strings[BT_MAX_PROTO] = {
Dave Young68845cb2008-04-01 23:58:35 -070057 "slock-AF_BLUETOOTH-BTPROTO_L2CAP",
58 "slock-AF_BLUETOOTH-BTPROTO_HCI",
59 "slock-AF_BLUETOOTH-BTPROTO_SCO",
60 "slock-AF_BLUETOOTH-BTPROTO_RFCOMM",
61 "slock-AF_BLUETOOTH-BTPROTO_BNEP",
62 "slock-AF_BLUETOOTH-BTPROTO_CMTP",
63 "slock-AF_BLUETOOTH-BTPROTO_HIDP",
64 "slock-AF_BLUETOOTH-BTPROTO_AVDTP",
65};
Marcel Holtmanndb7aa1c2008-11-30 12:17:19 +010066
Octavian Purdilab5a30dd2012-01-22 00:28:34 +020067void bt_sock_reclassify_lock(struct sock *sk, int proto)
Marcel Holtmanndb7aa1c2008-11-30 12:17:19 +010068{
Octavian Purdilab5a30dd2012-01-22 00:28:34 +020069 BUG_ON(!sk);
Hannes Frederic Sowafafc4e12016-04-08 15:11:27 +020070 BUG_ON(!sock_allow_reclassification(sk));
Marcel Holtmanndb7aa1c2008-11-30 12:17:19 +010071
72 sock_lock_init_class_and_name(sk,
73 bt_slock_key_strings[proto], &bt_slock_key[proto],
74 bt_key_strings[proto], &bt_lock_key[proto]);
75}
Octavian Purdilab5a30dd2012-01-22 00:28:34 +020076EXPORT_SYMBOL(bt_sock_reclassify_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -070077
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +000078int bt_sock_register(int proto, const struct net_proto_family *ops)
Linus Torvalds1da177e2005-04-16 15:20:36 -070079{
Marcel Holtmann74da6262006-10-15 17:31:14 +020080 int err = 0;
81
Linus Torvalds1da177e2005-04-16 15:20:36 -070082 if (proto < 0 || proto >= BT_MAX_PROTO)
83 return -EINVAL;
84
Marcel Holtmann74da6262006-10-15 17:31:14 +020085 write_lock(&bt_proto_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -070086
Marcel Holtmann74da6262006-10-15 17:31:14 +020087 if (bt_proto[proto])
88 err = -EEXIST;
89 else
90 bt_proto[proto] = ops;
91
92 write_unlock(&bt_proto_lock);
93
94 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -070095}
96EXPORT_SYMBOL(bt_sock_register);
97
David Herrmannbe9f97f2013-02-24 19:36:52 +010098void bt_sock_unregister(int proto)
Linus Torvalds1da177e2005-04-16 15:20:36 -070099{
100 if (proto < 0 || proto >= BT_MAX_PROTO)
David Herrmannbe9f97f2013-02-24 19:36:52 +0100101 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700102
Marcel Holtmann74da6262006-10-15 17:31:14 +0200103 write_lock(&bt_proto_lock);
David Herrmannbe9f97f2013-02-24 19:36:52 +0100104 bt_proto[proto] = NULL;
Marcel Holtmann74da6262006-10-15 17:31:14 +0200105 write_unlock(&bt_proto_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700106}
107EXPORT_SYMBOL(bt_sock_unregister);
108
Robert Love1b817cf2008-10-15 15:35:44 -0400109#ifdef CONFIG_PARANOID_NETWORK
110static inline int current_has_bt_admin(void)
111{
112 return !current_euid();
113}
114
115static inline int current_has_bt(void)
116{
117 return current_has_bt_admin();
118}
119# else
120static inline int current_has_bt_admin(void)
121{
122 return 1;
123}
124
125static inline int current_has_bt(void)
126{
127 return 1;
128}
129#endif
130
Eric Paris3f378b62009-11-05 22:18:14 -0800131static int bt_sock_create(struct net *net, struct socket *sock, int proto,
132 int kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700133{
Marcel Holtmann74da6262006-10-15 17:31:14 +0200134 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700135
Robert Love1b817cf2008-10-15 15:35:44 -0400136 if (proto == BTPROTO_RFCOMM || proto == BTPROTO_SCO ||
137 proto == BTPROTO_L2CAP) {
138 if (!current_has_bt())
139 return -EPERM;
140 } else if (!current_has_bt_admin())
141 return -EPERM;
142
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700143 if (net != &init_net)
144 return -EAFNOSUPPORT;
145
Linus Torvalds1da177e2005-04-16 15:20:36 -0700146 if (proto < 0 || proto >= BT_MAX_PROTO)
147 return -EINVAL;
148
Johannes Berg95a5afc2008-10-16 15:24:51 -0700149 if (!bt_proto[proto])
Linus Torvalds1da177e2005-04-16 15:20:36 -0700150 request_module("bt-proto-%d", proto);
Marcel Holtmann74da6262006-10-15 17:31:14 +0200151
Linus Torvalds1da177e2005-04-16 15:20:36 -0700152 err = -EPROTONOSUPPORT;
Marcel Holtmann74da6262006-10-15 17:31:14 +0200153
154 read_lock(&bt_proto_lock);
155
Linus Torvalds1da177e2005-04-16 15:20:36 -0700156 if (bt_proto[proto] && try_module_get(bt_proto[proto]->owner)) {
Eric Paris3f378b62009-11-05 22:18:14 -0800157 err = bt_proto[proto]->create(net, sock, proto, kern);
Octavian Purdilab5a30dd2012-01-22 00:28:34 +0200158 if (!err)
159 bt_sock_reclassify_lock(sock->sk, proto);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700160 module_put(bt_proto[proto]->owner);
161 }
Marcel Holtmann74da6262006-10-15 17:31:14 +0200162
163 read_unlock(&bt_proto_lock);
164
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900165 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700166}
167
168void bt_sock_link(struct bt_sock_list *l, struct sock *sk)
169{
Gustavo F. Padovan94f5bfb2011-12-27 15:28:48 -0200170 write_lock(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700171 sk_add_node(sk, &l->head);
Gustavo F. Padovan94f5bfb2011-12-27 15:28:48 -0200172 write_unlock(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700173}
174EXPORT_SYMBOL(bt_sock_link);
175
176void bt_sock_unlink(struct bt_sock_list *l, struct sock *sk)
177{
Gustavo F. Padovan94f5bfb2011-12-27 15:28:48 -0200178 write_lock(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700179 sk_del_node_init(sk);
Gustavo F. Padovan94f5bfb2011-12-27 15:28:48 -0200180 write_unlock(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700181}
182EXPORT_SYMBOL(bt_sock_unlink);
183
184void bt_accept_enqueue(struct sock *parent, struct sock *sk)
185{
186 BT_DBG("parent %p, sk %p", parent, sk);
187
188 sock_hold(sk);
189 list_add_tail(&bt_sk(sk)->accept_q, &bt_sk(parent)->accept_q);
190 bt_sk(sk)->parent = parent;
191 parent->sk_ack_backlog++;
192}
193EXPORT_SYMBOL(bt_accept_enqueue);
194
195void bt_accept_unlink(struct sock *sk)
196{
197 BT_DBG("sk %p state %d", sk, sk->sk_state);
198
199 list_del_init(&bt_sk(sk)->accept_q);
200 bt_sk(sk)->parent->sk_ack_backlog--;
201 bt_sk(sk)->parent = NULL;
202 sock_put(sk);
203}
204EXPORT_SYMBOL(bt_accept_unlink);
205
206struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock)
207{
Geliang Tang7eb74042015-12-18 23:33:25 +0800208 struct bt_sock *s, *n;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700209 struct sock *sk;
210
211 BT_DBG("parent %p", parent);
212
Geliang Tang7eb74042015-12-18 23:33:25 +0800213 list_for_each_entry_safe(s, n, &bt_sk(parent)->accept_q, accept_q) {
214 sk = (struct sock *)s;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700215
Gustavo F. Padovan8a154a82011-12-20 17:15:56 -0200216 lock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700217
218 /* FIXME: Is this check still needed */
219 if (sk->sk_state == BT_CLOSED) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700220 bt_accept_unlink(sk);
Yichen Zhao1a11ec82015-12-01 11:11:01 -0800221 release_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700222 continue;
223 }
224
Marcel Holtmannc4f912e2009-01-15 21:52:16 +0100225 if (sk->sk_state == BT_CONNECTED || !newsock ||
Vinicius Costa Gomesd0609912012-05-31 22:53:39 -0300226 test_bit(BT_SK_DEFER_SETUP, &bt_sk(parent)->flags)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700227 bt_accept_unlink(sk);
228 if (newsock)
229 sock_graft(sk, newsock);
Andrei Emeltchenkod37f50e2011-01-24 10:53:24 +0200230
Gustavo F. Padovan8a154a82011-12-20 17:15:56 -0200231 release_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700232 return sk;
233 }
234
Gustavo F. Padovan8a154a82011-12-20 17:15:56 -0200235 release_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700236 }
Andrei Emeltchenkod37f50e2011-01-24 10:53:24 +0200237
Linus Torvalds1da177e2005-04-16 15:20:36 -0700238 return NULL;
239}
240EXPORT_SYMBOL(bt_accept_dequeue);
241
Ying Xue1b784142015-03-02 15:37:48 +0800242int bt_sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
243 int flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700244{
245 int noblock = flags & MSG_DONTWAIT;
246 struct sock *sk = sock->sk;
247 struct sk_buff *skb;
248 size_t copied;
Denis Kenziorb5f34f92016-06-27 11:01:12 -0500249 size_t skblen;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700250 int err;
251
Marcel Holtmanna418b892008-11-30 12:17:28 +0100252 BT_DBG("sock %p sk %p len %zu", sock, sk, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700253
Marcel Holtmannd94a6102015-10-25 22:45:18 +0100254 if (flags & MSG_OOB)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700255 return -EOPNOTSUPP;
256
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +0200257 skb = skb_recv_datagram(sk, flags, noblock, &err);
258 if (!skb) {
Hannes Frederic Sowaf3d33422013-11-21 03:14:22 +0100259 if (sk->sk_shutdown & RCV_SHUTDOWN)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700260 return 0;
Hannes Frederic Sowaf3d33422013-11-21 03:14:22 +0100261
Linus Torvalds1da177e2005-04-16 15:20:36 -0700262 return err;
263 }
264
Denis Kenziorb5f34f92016-06-27 11:01:12 -0500265 skblen = skb->len;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700266 copied = skb->len;
267 if (len < copied) {
268 msg->msg_flags |= MSG_TRUNC;
269 copied = len;
270 }
271
Arnaldo Carvalho de Melobadff6d2007-03-13 13:06:52 -0300272 skb_reset_transport_header(skb);
David S. Miller51f3d022014-11-05 16:46:40 -0500273 err = skb_copy_datagram_msg(skb, 0, msg, copied);
Marcel Holtmannd9763692013-10-13 12:55:28 -0700274 if (err == 0) {
Neil Horman3b885782009-10-12 13:26:31 -0700275 sock_recv_ts_and_drops(msg, sk, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700276
Marcel Holtmannd9763692013-10-13 12:55:28 -0700277 if (bt_sk(sk)->skb_msg_name)
278 bt_sk(sk)->skb_msg_name(skb, msg->msg_name,
279 &msg->msg_namelen);
Marcel Holtmannd9763692013-10-13 12:55:28 -0700280 }
281
Linus Torvalds1da177e2005-04-16 15:20:36 -0700282 skb_free_datagram(sk, skb);
283
Luiz Augusto von Dentz90a56f72016-08-12 15:11:28 +0300284 if (flags & MSG_TRUNC)
Denis Kenziorb5f34f92016-06-27 11:01:12 -0500285 copied = skblen;
286
Linus Torvalds1da177e2005-04-16 15:20:36 -0700287 return err ? : copied;
288}
289EXPORT_SYMBOL(bt_sock_recvmsg);
290
Mat Martineau796c86e2010-09-08 10:05:27 -0700291static long bt_sock_data_wait(struct sock *sk, long timeo)
292{
293 DECLARE_WAITQUEUE(wait, current);
294
295 add_wait_queue(sk_sleep(sk), &wait);
296 for (;;) {
297 set_current_state(TASK_INTERRUPTIBLE);
298
299 if (!skb_queue_empty(&sk->sk_receive_queue))
300 break;
301
302 if (sk->sk_err || (sk->sk_shutdown & RCV_SHUTDOWN))
303 break;
304
305 if (signal_pending(current) || !timeo)
306 break;
307
Eric Dumazet9cd3e072015-11-29 20:03:10 -0800308 sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk);
Mat Martineau796c86e2010-09-08 10:05:27 -0700309 release_sock(sk);
310 timeo = schedule_timeout(timeo);
311 lock_sock(sk);
Eric Dumazet9cd3e072015-11-29 20:03:10 -0800312 sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk);
Mat Martineau796c86e2010-09-08 10:05:27 -0700313 }
314
315 __set_current_state(TASK_RUNNING);
316 remove_wait_queue(sk_sleep(sk), &wait);
317 return timeo;
318}
319
Ying Xue1b784142015-03-02 15:37:48 +0800320int bt_sock_stream_recvmsg(struct socket *sock, struct msghdr *msg,
321 size_t size, int flags)
Mat Martineau796c86e2010-09-08 10:05:27 -0700322{
323 struct sock *sk = sock->sk;
324 int err = 0;
325 size_t target, copied = 0;
326 long timeo;
327
328 if (flags & MSG_OOB)
329 return -EOPNOTSUPP;
330
Mat Martineau796c86e2010-09-08 10:05:27 -0700331 BT_DBG("sk %p size %zu", sk, size);
332
333 lock_sock(sk);
334
335 target = sock_rcvlowat(sk, flags & MSG_WAITALL, size);
336 timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
337
338 do {
339 struct sk_buff *skb;
340 int chunk;
341
342 skb = skb_dequeue(&sk->sk_receive_queue);
343 if (!skb) {
344 if (copied >= target)
345 break;
346
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +0200347 err = sock_error(sk);
348 if (err)
Mat Martineau796c86e2010-09-08 10:05:27 -0700349 break;
350 if (sk->sk_shutdown & RCV_SHUTDOWN)
351 break;
352
353 err = -EAGAIN;
354 if (!timeo)
355 break;
356
357 timeo = bt_sock_data_wait(sk, timeo);
358
359 if (signal_pending(current)) {
360 err = sock_intr_errno(timeo);
361 goto out;
362 }
363 continue;
364 }
365
366 chunk = min_t(unsigned int, skb->len, size);
David S. Miller51f3d022014-11-05 16:46:40 -0500367 if (skb_copy_datagram_msg(skb, 0, msg, chunk)) {
Mat Martineau796c86e2010-09-08 10:05:27 -0700368 skb_queue_head(&sk->sk_receive_queue, skb);
369 if (!copied)
370 copied = -EFAULT;
371 break;
372 }
373 copied += chunk;
374 size -= chunk;
375
376 sock_recv_ts_and_drops(msg, sk, skb);
377
378 if (!(flags & MSG_PEEK)) {
Mat Martineau5b668eb2011-07-22 14:53:59 -0700379 int skb_len = skb_headlen(skb);
380
381 if (chunk <= skb_len) {
382 __skb_pull(skb, chunk);
383 } else {
384 struct sk_buff *frag;
385
386 __skb_pull(skb, skb_len);
387 chunk -= skb_len;
388
389 skb_walk_frags(skb, frag) {
390 if (chunk <= frag->len) {
391 /* Pulling partial data */
392 skb->len -= chunk;
393 skb->data_len -= chunk;
394 __skb_pull(frag, chunk);
395 break;
396 } else if (frag->len) {
397 /* Pulling all frag data */
398 chunk -= frag->len;
399 skb->len -= frag->len;
400 skb->data_len -= frag->len;
401 __skb_pull(frag, frag->len);
402 }
403 }
404 }
405
Mat Martineau796c86e2010-09-08 10:05:27 -0700406 if (skb->len) {
407 skb_queue_head(&sk->sk_receive_queue, skb);
408 break;
409 }
410 kfree_skb(skb);
411
412 } else {
413 /* put message back and return */
414 skb_queue_head(&sk->sk_receive_queue, skb);
415 break;
416 }
417 } while (size);
418
419out:
420 release_sock(sk);
421 return copied ? : err;
422}
423EXPORT_SYMBOL(bt_sock_stream_recvmsg);
424
Linus Torvalds1da177e2005-04-16 15:20:36 -0700425static inline unsigned int bt_accept_poll(struct sock *parent)
426{
Geliang Tang7eb74042015-12-18 23:33:25 +0800427 struct bt_sock *s, *n;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700428 struct sock *sk;
429
Geliang Tang7eb74042015-12-18 23:33:25 +0800430 list_for_each_entry_safe(s, n, &bt_sk(parent)->accept_q, accept_q) {
431 sk = (struct sock *)s;
Marcel Holtmannd5f2d2b2009-02-16 02:57:30 +0100432 if (sk->sk_state == BT_CONNECTED ||
Gustavo Padovanc5daa682012-05-16 12:17:10 -0300433 (test_bit(BT_SK_DEFER_SETUP, &bt_sk(parent)->flags) &&
434 sk->sk_state == BT_CONNECT2))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700435 return POLLIN | POLLRDNORM;
436 }
437
438 return 0;
439}
440
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300441unsigned int bt_sock_poll(struct file *file, struct socket *sock,
442 poll_table *wait)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700443{
444 struct sock *sk = sock->sk;
445 unsigned int mask = 0;
446
447 BT_DBG("sock %p, sk %p", sock, sk);
448
Eric Dumazetaa395142010-04-20 13:03:51 +0000449 poll_wait(file, sk_sleep(sk), wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700450
451 if (sk->sk_state == BT_LISTEN)
452 return bt_accept_poll(sk);
453
454 if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue))
Keller, Jacob E7d4c04f2013-03-28 11:19:25 +0000455 mask |= POLLERR |
Jacob Keller8facd5f2013-04-02 13:55:40 -0700456 (sock_flag(sk, SOCK_SELECT_ERR_QUEUE) ? POLLPRI : 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700457
Davide Libenzif348d702006-03-25 03:07:39 -0800458 if (sk->sk_shutdown & RCV_SHUTDOWN)
Eric Dumazetdb409802010-09-06 11:13:50 +0000459 mask |= POLLRDHUP | POLLIN | POLLRDNORM;
Davide Libenzif348d702006-03-25 03:07:39 -0800460
Linus Torvalds1da177e2005-04-16 15:20:36 -0700461 if (sk->sk_shutdown == SHUTDOWN_MASK)
462 mask |= POLLHUP;
463
Eric Dumazetdb409802010-09-06 11:13:50 +0000464 if (!skb_queue_empty(&sk->sk_receive_queue))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700465 mask |= POLLIN | POLLRDNORM;
466
467 if (sk->sk_state == BT_CLOSED)
468 mask |= POLLHUP;
469
470 if (sk->sk_state == BT_CONNECT ||
471 sk->sk_state == BT_CONNECT2 ||
472 sk->sk_state == BT_CONFIG)
473 return mask;
474
Gustavo Padovanc5daa682012-05-16 12:17:10 -0300475 if (!test_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags) && sock_writeable(sk))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700476 mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
477 else
Eric Dumazet9cd3e072015-11-29 20:03:10 -0800478 sk_set_bit(SOCKWQ_ASYNC_NOSPACE, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700479
480 return mask;
481}
482EXPORT_SYMBOL(bt_sock_poll);
483
Marcel Holtmann3241ad82008-07-14 20:13:50 +0200484int bt_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
485{
486 struct sock *sk = sock->sk;
Marcel Holtmann43cbeee2008-07-14 20:13:51 +0200487 struct sk_buff *skb;
488 long amount;
Marcel Holtmann3241ad82008-07-14 20:13:50 +0200489 int err;
490
491 BT_DBG("sk %p cmd %x arg %lx", sk, cmd, arg);
492
493 switch (cmd) {
Marcel Holtmann43cbeee2008-07-14 20:13:51 +0200494 case TIOCOUTQ:
495 if (sk->sk_state == BT_LISTEN)
496 return -EINVAL;
497
Eric Dumazet31e6d362009-06-17 19:05:41 -0700498 amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk);
Marcel Holtmann43cbeee2008-07-14 20:13:51 +0200499 if (amount < 0)
500 amount = 0;
501 err = put_user(amount, (int __user *) arg);
502 break;
503
504 case TIOCINQ:
505 if (sk->sk_state == BT_LISTEN)
506 return -EINVAL;
507
508 lock_sock(sk);
509 skb = skb_peek(&sk->sk_receive_queue);
510 amount = skb ? skb->len : 0;
511 release_sock(sk);
512 err = put_user(amount, (int __user *) arg);
513 break;
514
Marcel Holtmann3241ad82008-07-14 20:13:50 +0200515 case SIOCGSTAMP:
516 err = sock_get_timestamp(sk, (struct timeval __user *) arg);
517 break;
518
519 case SIOCGSTAMPNS:
520 err = sock_get_timestampns(sk, (struct timespec __user *) arg);
521 break;
522
523 default:
524 err = -ENOIOCTLCMD;
525 break;
526 }
527
528 return err;
529}
530EXPORT_SYMBOL(bt_sock_ioctl);
531
Johan Hedberg0fba96f2013-09-25 13:26:04 +0300532/* This function expects the sk lock to be held when called */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700533int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo)
534{
535 DECLARE_WAITQUEUE(wait, current);
536 int err = 0;
537
538 BT_DBG("sk %p", sk);
539
Eric Dumazetaa395142010-04-20 13:03:51 +0000540 add_wait_queue(sk_sleep(sk), &wait);
Peter Hurley9be4e3f2011-07-24 00:10:46 -0400541 set_current_state(TASK_INTERRUPTIBLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700542 while (sk->sk_state != state) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700543 if (!timeo) {
Marcel Holtmannb4c612a2006-09-23 09:54:38 +0200544 err = -EINPROGRESS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700545 break;
546 }
547
548 if (signal_pending(current)) {
549 err = sock_intr_errno(timeo);
550 break;
551 }
552
553 release_sock(sk);
554 timeo = schedule_timeout(timeo);
555 lock_sock(sk);
Peter Hurley9be4e3f2011-07-24 00:10:46 -0400556 set_current_state(TASK_INTERRUPTIBLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700557
Benjamin LaHaisec1cbe4b2005-12-13 23:22:19 -0800558 err = sock_error(sk);
559 if (err)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700560 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700561 }
Peter Hurley9be4e3f2011-07-24 00:10:46 -0400562 __set_current_state(TASK_RUNNING);
Eric Dumazetaa395142010-04-20 13:03:51 +0000563 remove_wait_queue(sk_sleep(sk), &wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700564 return err;
565}
566EXPORT_SYMBOL(bt_sock_wait_state);
567
Johan Hedberge793dcf2013-09-16 13:05:19 +0300568/* This function expects the sk lock to be held when called */
569int bt_sock_wait_ready(struct sock *sk, unsigned long flags)
570{
571 DECLARE_WAITQUEUE(wait, current);
572 unsigned long timeo;
573 int err = 0;
574
575 BT_DBG("sk %p", sk);
576
577 timeo = sock_sndtimeo(sk, flags & O_NONBLOCK);
578
579 add_wait_queue(sk_sleep(sk), &wait);
580 set_current_state(TASK_INTERRUPTIBLE);
581 while (test_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags)) {
582 if (!timeo) {
583 err = -EAGAIN;
584 break;
585 }
586
587 if (signal_pending(current)) {
588 err = sock_intr_errno(timeo);
589 break;
590 }
591
592 release_sock(sk);
593 timeo = schedule_timeout(timeo);
594 lock_sock(sk);
595 set_current_state(TASK_INTERRUPTIBLE);
596
597 err = sock_error(sk);
598 if (err)
599 break;
600 }
601 __set_current_state(TASK_RUNNING);
602 remove_wait_queue(sk_sleep(sk), &wait);
603
604 return err;
605}
606EXPORT_SYMBOL(bt_sock_wait_ready);
607
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900608#ifdef CONFIG_PROC_FS
609struct bt_seq_state {
610 struct bt_sock_list *l;
611};
612
613static void *bt_seq_start(struct seq_file *seq, loff_t *pos)
614 __acquires(seq->private->l->lock)
615{
616 struct bt_seq_state *s = seq->private;
617 struct bt_sock_list *l = s->l;
618
619 read_lock(&l->lock);
620 return seq_hlist_start_head(&l->head, *pos);
621}
622
623static void *bt_seq_next(struct seq_file *seq, void *v, loff_t *pos)
624{
625 struct bt_seq_state *s = seq->private;
626 struct bt_sock_list *l = s->l;
627
628 return seq_hlist_next(v, &l->head, pos);
629}
630
631static void bt_seq_stop(struct seq_file *seq, void *v)
632 __releases(seq->private->l->lock)
633{
634 struct bt_seq_state *s = seq->private;
635 struct bt_sock_list *l = s->l;
636
637 read_unlock(&l->lock);
638}
639
640static int bt_seq_show(struct seq_file *seq, void *v)
641{
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900642 struct bt_seq_state *s = seq->private;
643 struct bt_sock_list *l = s->l;
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900644
645 if (v == SEQ_START_TOKEN) {
Marcel Holtmannc5605752013-10-14 02:05:25 -0700646 seq_puts(seq ,"sk RefCnt Rmem Wmem User Inode Parent");
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900647
648 if (l->custom_seq_show) {
649 seq_putc(seq, ' ');
650 l->custom_seq_show(seq, v);
651 }
652
653 seq_putc(seq, '\n');
654 } else {
Andrei Emeltchenko09d5d4a2012-08-07 18:05:04 +0300655 struct sock *sk = sk_entry(v);
656 struct bt_sock *bt = bt_sk(sk);
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900657
Andrei Emeltchenko7028a882012-09-25 12:49:45 +0300658 seq_printf(seq,
Marcel Holtmann5f6cd792013-10-13 10:34:03 -0700659 "%pK %-6d %-6u %-6u %-6u %-6lu %-6lu",
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900660 sk,
661 atomic_read(&sk->sk_refcnt),
662 sk_rmem_alloc_get(sk),
663 sk_wmem_alloc_get(sk),
Eric W. Biederman1bbb3092012-10-03 20:32:17 -0700664 from_kuid(seq_user_ns(seq), sock_i_uid(sk)),
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900665 sock_i_ino(sk),
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900666 bt->parent? sock_i_ino(bt->parent): 0LU);
667
668 if (l->custom_seq_show) {
669 seq_putc(seq, ' ');
670 l->custom_seq_show(seq, v);
671 }
672
673 seq_putc(seq, '\n');
674 }
675 return 0;
676}
677
Fabian Frederick26b0f4e2014-06-30 19:26:23 +0200678static const struct seq_operations bt_seq_ops = {
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900679 .start = bt_seq_start,
680 .next = bt_seq_next,
681 .stop = bt_seq_stop,
682 .show = bt_seq_show,
683};
684
685static int bt_seq_open(struct inode *inode, struct file *file)
686{
687 struct bt_sock_list *sk_list;
688 struct bt_seq_state *s;
689
Al Virod9dda782013-03-31 18:16:14 -0400690 sk_list = PDE_DATA(inode);
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900691 s = __seq_open_private(file, &bt_seq_ops,
692 sizeof(struct bt_seq_state));
Andrei Emeltchenko31f47072012-08-07 18:05:06 +0300693 if (!s)
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900694 return -ENOMEM;
695
696 s->l = sk_list;
697 return 0;
698}
699
Al Viro14805352013-04-04 19:12:06 -0400700static const struct file_operations bt_fops = {
701 .open = bt_seq_open,
702 .read = seq_read,
703 .llseek = seq_lseek,
704 .release = seq_release_private
705};
706
Al Virob0316612013-04-04 19:14:33 -0400707int bt_procfs_init(struct net *net, const char *name,
Prasanna Karthikf37590b2015-11-17 11:06:53 +0000708 struct bt_sock_list *sk_list,
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900709 int (* seq_show)(struct seq_file *, void *))
710{
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900711 sk_list->custom_seq_show = seq_show;
712
Al Viro4d006262013-04-04 19:16:06 -0400713 if (!proc_create_data(name, 0, net->proc_net, &bt_fops, sk_list))
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900714 return -ENOMEM;
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900715 return 0;
716}
717
718void bt_procfs_cleanup(struct net *net, const char *name)
719{
Gao fengece31ff2013-02-18 01:34:56 +0000720 remove_proc_entry(name, net->proc_net);
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900721}
722#else
Al Virob0316612013-04-04 19:14:33 -0400723int bt_procfs_init(struct net *net, const char *name,
Prasanna Karthikf37590b2015-11-17 11:06:53 +0000724 struct bt_sock_list *sk_list,
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900725 int (* seq_show)(struct seq_file *, void *))
726{
727 return 0;
728}
729
730void bt_procfs_cleanup(struct net *net, const char *name)
731{
732}
733#endif
734EXPORT_SYMBOL(bt_procfs_init);
735EXPORT_SYMBOL(bt_procfs_cleanup);
736
Linus Torvalds1da177e2005-04-16 15:20:36 -0700737static struct net_proto_family bt_sock_family_ops = {
738 .owner = THIS_MODULE,
739 .family = PF_BLUETOOTH,
740 .create = bt_sock_create,
741};
742
Marcel Holtmannffcecac2013-10-17 17:24:18 -0700743struct dentry *bt_debugfs;
744EXPORT_SYMBOL_GPL(bt_debugfs);
745
Marcel Holtmann9e8305b2016-08-30 05:00:35 +0200746#define VERSION __stringify(BT_SUBSYS_VERSION) "." \
747 __stringify(BT_SUBSYS_REVISION)
748
Linus Torvalds1da177e2005-04-16 15:20:36 -0700749static int __init bt_init(void)
750{
Marcel Holtmann27d35282006-07-03 10:02:37 +0200751 int err;
752
Eyal Birgerb4772ef2015-03-01 14:58:29 +0200753 sock_skb_cb_check_size(sizeof(struct bt_skb_cb));
Marcel Holtmann7cb9d202014-09-14 22:50:46 +0200754
Marcel Holtmann9e8305b2016-08-30 05:00:35 +0200755 BT_INFO("Core ver %s", VERSION);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700756
Marcel Holtmannee485292014-12-29 20:48:35 -0800757 err = bt_selftest();
758 if (err < 0)
759 return err;
760
Marcel Holtmannffcecac2013-10-17 17:24:18 -0700761 bt_debugfs = debugfs_create_dir("bluetooth", NULL);
762
Marcel Holtmanne64c97b2016-07-21 14:12:41 +0200763 bt_leds_init();
764
Marcel Holtmann27d35282006-07-03 10:02:37 +0200765 err = bt_sysfs_init();
766 if (err < 0)
767 return err;
768
769 err = sock_register(&bt_sock_family_ops);
770 if (err < 0) {
771 bt_sysfs_cleanup();
772 return err;
773 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700774
775 BT_INFO("HCI device and connection manager initialized");
776
Gustavo F. Padovan64274512011-02-07 20:08:52 -0200777 err = hci_sock_init();
778 if (err < 0)
779 goto error;
780
781 err = l2cap_init();
Anand Gadiyar0ed54da2011-02-22 12:43:26 +0530782 if (err < 0)
Gustavo F. Padovan64274512011-02-07 20:08:52 -0200783 goto sock_err;
Gustavo F. Padovan64274512011-02-07 20:08:52 -0200784
785 err = sco_init();
786 if (err < 0) {
787 l2cap_exit();
788 goto sock_err;
789 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700790
Johan Hedberg6d785aa32015-03-06 21:08:51 +0200791 err = mgmt_init();
792 if (err < 0) {
793 sco_exit();
794 l2cap_exit();
795 goto sock_err;
796 }
797
Linus Torvalds1da177e2005-04-16 15:20:36 -0700798 return 0;
Gustavo F. Padovan64274512011-02-07 20:08:52 -0200799
800sock_err:
801 hci_sock_cleanup();
802
803error:
804 sock_unregister(PF_BLUETOOTH);
805 bt_sysfs_cleanup();
806
807 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700808}
809
810static void __exit bt_exit(void)
811{
Johan Hedberg6d785aa32015-03-06 21:08:51 +0200812 mgmt_exit();
813
Gustavo F. Padovan64274512011-02-07 20:08:52 -0200814 sco_exit();
815
816 l2cap_exit();
817
Linus Torvalds1da177e2005-04-16 15:20:36 -0700818 hci_sock_cleanup();
819
Linus Torvalds1da177e2005-04-16 15:20:36 -0700820 sock_unregister(PF_BLUETOOTH);
Marcel Holtmann27d35282006-07-03 10:02:37 +0200821
822 bt_sysfs_cleanup();
Marcel Holtmannffcecac2013-10-17 17:24:18 -0700823
Marcel Holtmanne64c97b2016-07-21 14:12:41 +0200824 bt_leds_cleanup();
825
Marcel Holtmannffcecac2013-10-17 17:24:18 -0700826 debugfs_remove_recursive(bt_debugfs);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700827}
828
829subsys_initcall(bt_init);
830module_exit(bt_exit);
831
Marcel Holtmann63fbd242008-08-18 13:23:53 +0200832MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
Marcel Holtmann9e8305b2016-08-30 05:00:35 +0200833MODULE_DESCRIPTION("Bluetooth Core ver " VERSION);
834MODULE_VERSION(VERSION);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700835MODULE_LICENSE("GPL");
836MODULE_ALIAS_NETPROTO(PF_BLUETOOTH);