blob: a374fd27b5e1da88c7beec355339924c16d96faf [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>
Ingo Molnar174cd4b2017-02-02 19:15:33 +010030#include <linux/sched/signal.h>
31
Marcel Holtmann3241ad82008-07-14 20:13:50 +020032#include <asm/ioctls.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070033
34#include <net/bluetooth/bluetooth.h>
Masatake YAMATO256a06c2012-07-26 01:26:32 +090035#include <linux/proc_fs.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070036
Marcel Holtmanne64c97b2016-07-21 14:12:41 +020037#include "leds.h"
Marcel Holtmannee485292014-12-29 20:48:35 -080038#include "selftest.h"
39
Linus Torvalds1da177e2005-04-16 15:20:36 -070040/* Bluetooth sockets */
41#define BT_MAX_PROTO 8
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +000042static const struct net_proto_family *bt_proto[BT_MAX_PROTO];
Marcel Holtmanndb7aa1c2008-11-30 12:17:19 +010043static DEFINE_RWLOCK(bt_proto_lock);
Dave Young68845cb2008-04-01 23:58:35 -070044
Dave Young68845cb2008-04-01 23:58:35 -070045static struct lock_class_key bt_lock_key[BT_MAX_PROTO];
Jan Engelhardt36cbd3d2009-08-05 10:42:58 -070046static const char *const bt_key_strings[BT_MAX_PROTO] = {
Dave Young68845cb2008-04-01 23:58:35 -070047 "sk_lock-AF_BLUETOOTH-BTPROTO_L2CAP",
48 "sk_lock-AF_BLUETOOTH-BTPROTO_HCI",
49 "sk_lock-AF_BLUETOOTH-BTPROTO_SCO",
50 "sk_lock-AF_BLUETOOTH-BTPROTO_RFCOMM",
51 "sk_lock-AF_BLUETOOTH-BTPROTO_BNEP",
52 "sk_lock-AF_BLUETOOTH-BTPROTO_CMTP",
53 "sk_lock-AF_BLUETOOTH-BTPROTO_HIDP",
54 "sk_lock-AF_BLUETOOTH-BTPROTO_AVDTP",
55};
56
Marcel Holtmanndb7aa1c2008-11-30 12:17:19 +010057static struct lock_class_key bt_slock_key[BT_MAX_PROTO];
Jan Engelhardt36cbd3d2009-08-05 10:42:58 -070058static const char *const bt_slock_key_strings[BT_MAX_PROTO] = {
Dave Young68845cb2008-04-01 23:58:35 -070059 "slock-AF_BLUETOOTH-BTPROTO_L2CAP",
60 "slock-AF_BLUETOOTH-BTPROTO_HCI",
61 "slock-AF_BLUETOOTH-BTPROTO_SCO",
62 "slock-AF_BLUETOOTH-BTPROTO_RFCOMM",
63 "slock-AF_BLUETOOTH-BTPROTO_BNEP",
64 "slock-AF_BLUETOOTH-BTPROTO_CMTP",
65 "slock-AF_BLUETOOTH-BTPROTO_HIDP",
66 "slock-AF_BLUETOOTH-BTPROTO_AVDTP",
67};
Marcel Holtmanndb7aa1c2008-11-30 12:17:19 +010068
Octavian Purdilab5a30dd2012-01-22 00:28:34 +020069void bt_sock_reclassify_lock(struct sock *sk, int proto)
Marcel Holtmanndb7aa1c2008-11-30 12:17:19 +010070{
Octavian Purdilab5a30dd2012-01-22 00:28:34 +020071 BUG_ON(!sk);
Hannes Frederic Sowafafc4e12016-04-08 15:11:27 +020072 BUG_ON(!sock_allow_reclassification(sk));
Marcel Holtmanndb7aa1c2008-11-30 12:17:19 +010073
74 sock_lock_init_class_and_name(sk,
75 bt_slock_key_strings[proto], &bt_slock_key[proto],
76 bt_key_strings[proto], &bt_lock_key[proto]);
77}
Octavian Purdilab5a30dd2012-01-22 00:28:34 +020078EXPORT_SYMBOL(bt_sock_reclassify_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -070079
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +000080int bt_sock_register(int proto, const struct net_proto_family *ops)
Linus Torvalds1da177e2005-04-16 15:20:36 -070081{
Marcel Holtmann74da6262006-10-15 17:31:14 +020082 int err = 0;
83
Linus Torvalds1da177e2005-04-16 15:20:36 -070084 if (proto < 0 || proto >= BT_MAX_PROTO)
85 return -EINVAL;
86
Marcel Holtmann74da6262006-10-15 17:31:14 +020087 write_lock(&bt_proto_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -070088
Marcel Holtmann74da6262006-10-15 17:31:14 +020089 if (bt_proto[proto])
90 err = -EEXIST;
91 else
92 bt_proto[proto] = ops;
93
94 write_unlock(&bt_proto_lock);
95
96 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -070097}
98EXPORT_SYMBOL(bt_sock_register);
99
David Herrmannbe9f97f2013-02-24 19:36:52 +0100100void bt_sock_unregister(int proto)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700101{
102 if (proto < 0 || proto >= BT_MAX_PROTO)
David Herrmannbe9f97f2013-02-24 19:36:52 +0100103 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700104
Marcel Holtmann74da6262006-10-15 17:31:14 +0200105 write_lock(&bt_proto_lock);
David Herrmannbe9f97f2013-02-24 19:36:52 +0100106 bt_proto[proto] = NULL;
Marcel Holtmann74da6262006-10-15 17:31:14 +0200107 write_unlock(&bt_proto_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700108}
109EXPORT_SYMBOL(bt_sock_unregister);
110
Eric Paris3f378b62009-11-05 22:18:14 -0800111static int bt_sock_create(struct net *net, struct socket *sock, int proto,
112 int kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700113{
Marcel Holtmann74da6262006-10-15 17:31:14 +0200114 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700115
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700116 if (net != &init_net)
117 return -EAFNOSUPPORT;
118
Linus Torvalds1da177e2005-04-16 15:20:36 -0700119 if (proto < 0 || proto >= BT_MAX_PROTO)
120 return -EINVAL;
121
Johannes Berg95a5afc2008-10-16 15:24:51 -0700122 if (!bt_proto[proto])
Linus Torvalds1da177e2005-04-16 15:20:36 -0700123 request_module("bt-proto-%d", proto);
Marcel Holtmann74da6262006-10-15 17:31:14 +0200124
Linus Torvalds1da177e2005-04-16 15:20:36 -0700125 err = -EPROTONOSUPPORT;
Marcel Holtmann74da6262006-10-15 17:31:14 +0200126
127 read_lock(&bt_proto_lock);
128
Linus Torvalds1da177e2005-04-16 15:20:36 -0700129 if (bt_proto[proto] && try_module_get(bt_proto[proto]->owner)) {
Eric Paris3f378b62009-11-05 22:18:14 -0800130 err = bt_proto[proto]->create(net, sock, proto, kern);
Octavian Purdilab5a30dd2012-01-22 00:28:34 +0200131 if (!err)
132 bt_sock_reclassify_lock(sock->sk, proto);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700133 module_put(bt_proto[proto]->owner);
134 }
Marcel Holtmann74da6262006-10-15 17:31:14 +0200135
136 read_unlock(&bt_proto_lock);
137
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900138 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700139}
140
141void bt_sock_link(struct bt_sock_list *l, struct sock *sk)
142{
Gustavo F. Padovan94f5bfb2011-12-27 15:28:48 -0200143 write_lock(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700144 sk_add_node(sk, &l->head);
Gustavo F. Padovan94f5bfb2011-12-27 15:28:48 -0200145 write_unlock(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700146}
147EXPORT_SYMBOL(bt_sock_link);
148
149void bt_sock_unlink(struct bt_sock_list *l, struct sock *sk)
150{
Gustavo F. Padovan94f5bfb2011-12-27 15:28:48 -0200151 write_lock(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700152 sk_del_node_init(sk);
Gustavo F. Padovan94f5bfb2011-12-27 15:28:48 -0200153 write_unlock(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700154}
155EXPORT_SYMBOL(bt_sock_unlink);
156
157void bt_accept_enqueue(struct sock *parent, struct sock *sk)
158{
159 BT_DBG("parent %p, sk %p", parent, sk);
160
161 sock_hold(sk);
Dean Jenkinse1633762017-03-10 11:34:45 +0000162 lock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700163 list_add_tail(&bt_sk(sk)->accept_q, &bt_sk(parent)->accept_q);
164 bt_sk(sk)->parent = parent;
Dean Jenkinse1633762017-03-10 11:34:45 +0000165 release_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700166 parent->sk_ack_backlog++;
167}
168EXPORT_SYMBOL(bt_accept_enqueue);
169
170void bt_accept_unlink(struct sock *sk)
171{
172 BT_DBG("sk %p state %d", sk, sk->sk_state);
173
174 list_del_init(&bt_sk(sk)->accept_q);
175 bt_sk(sk)->parent->sk_ack_backlog--;
176 bt_sk(sk)->parent = NULL;
177 sock_put(sk);
178}
179EXPORT_SYMBOL(bt_accept_unlink);
180
181struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock)
182{
Geliang Tang7eb74042015-12-18 23:33:25 +0800183 struct bt_sock *s, *n;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700184 struct sock *sk;
185
186 BT_DBG("parent %p", parent);
187
Geliang Tang7eb74042015-12-18 23:33:25 +0800188 list_for_each_entry_safe(s, n, &bt_sk(parent)->accept_q, accept_q) {
189 sk = (struct sock *)s;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700190
Gustavo F. Padovan8a154a82011-12-20 17:15:56 -0200191 lock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700192
193 /* FIXME: Is this check still needed */
194 if (sk->sk_state == BT_CLOSED) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700195 bt_accept_unlink(sk);
Yichen Zhao1a11ec892015-12-01 11:11:01 -0800196 release_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700197 continue;
198 }
199
Marcel Holtmannc4f912e2009-01-15 21:52:16 +0100200 if (sk->sk_state == BT_CONNECTED || !newsock ||
Vinicius Costa Gomesd0609912012-05-31 22:53:39 -0300201 test_bit(BT_SK_DEFER_SETUP, &bt_sk(parent)->flags)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700202 bt_accept_unlink(sk);
203 if (newsock)
204 sock_graft(sk, newsock);
Andrei Emeltchenkod37f50e2011-01-24 10:53:24 +0200205
Gustavo F. Padovan8a154a82011-12-20 17:15:56 -0200206 release_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700207 return sk;
208 }
209
Gustavo F. Padovan8a154a82011-12-20 17:15:56 -0200210 release_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700211 }
Andrei Emeltchenkod37f50e2011-01-24 10:53:24 +0200212
Linus Torvalds1da177e2005-04-16 15:20:36 -0700213 return NULL;
214}
215EXPORT_SYMBOL(bt_accept_dequeue);
216
Ying Xue1b784142015-03-02 15:37:48 +0800217int bt_sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
218 int flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700219{
220 int noblock = flags & MSG_DONTWAIT;
221 struct sock *sk = sock->sk;
222 struct sk_buff *skb;
223 size_t copied;
Denis Kenziorb5f34f92016-06-27 11:01:12 -0500224 size_t skblen;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700225 int err;
226
Marcel Holtmanna418b892008-11-30 12:17:28 +0100227 BT_DBG("sock %p sk %p len %zu", sock, sk, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700228
Marcel Holtmannd94a6102015-10-25 22:45:18 +0100229 if (flags & MSG_OOB)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700230 return -EOPNOTSUPP;
231
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +0200232 skb = skb_recv_datagram(sk, flags, noblock, &err);
233 if (!skb) {
Hannes Frederic Sowaf3d33422013-11-21 03:14:22 +0100234 if (sk->sk_shutdown & RCV_SHUTDOWN)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700235 return 0;
Hannes Frederic Sowaf3d33422013-11-21 03:14:22 +0100236
Linus Torvalds1da177e2005-04-16 15:20:36 -0700237 return err;
238 }
239
Denis Kenziorb5f34f92016-06-27 11:01:12 -0500240 skblen = skb->len;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700241 copied = skb->len;
242 if (len < copied) {
243 msg->msg_flags |= MSG_TRUNC;
244 copied = len;
245 }
246
Arnaldo Carvalho de Melobadff6d2007-03-13 13:06:52 -0300247 skb_reset_transport_header(skb);
David S. Miller51f3d022014-11-05 16:46:40 -0500248 err = skb_copy_datagram_msg(skb, 0, msg, copied);
Marcel Holtmannd9763692013-10-13 12:55:28 -0700249 if (err == 0) {
Neil Horman3b885782009-10-12 13:26:31 -0700250 sock_recv_ts_and_drops(msg, sk, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700251
Ezequiel Garcia9dcbc312016-12-29 09:51:19 -0300252 if (msg->msg_name && bt_sk(sk)->skb_msg_name)
Marcel Holtmannd9763692013-10-13 12:55:28 -0700253 bt_sk(sk)->skb_msg_name(skb, msg->msg_name,
254 &msg->msg_namelen);
Marcel Holtmannd9763692013-10-13 12:55:28 -0700255 }
256
Linus Torvalds1da177e2005-04-16 15:20:36 -0700257 skb_free_datagram(sk, skb);
258
Luiz Augusto von Dentz90a56f72016-08-12 15:11:28 +0300259 if (flags & MSG_TRUNC)
Denis Kenziorb5f34f92016-06-27 11:01:12 -0500260 copied = skblen;
261
Linus Torvalds1da177e2005-04-16 15:20:36 -0700262 return err ? : copied;
263}
264EXPORT_SYMBOL(bt_sock_recvmsg);
265
Mat Martineau796c86e2010-09-08 10:05:27 -0700266static long bt_sock_data_wait(struct sock *sk, long timeo)
267{
268 DECLARE_WAITQUEUE(wait, current);
269
270 add_wait_queue(sk_sleep(sk), &wait);
271 for (;;) {
272 set_current_state(TASK_INTERRUPTIBLE);
273
274 if (!skb_queue_empty(&sk->sk_receive_queue))
275 break;
276
277 if (sk->sk_err || (sk->sk_shutdown & RCV_SHUTDOWN))
278 break;
279
280 if (signal_pending(current) || !timeo)
281 break;
282
Eric Dumazet9cd3e072015-11-29 20:03:10 -0800283 sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk);
Mat Martineau796c86e2010-09-08 10:05:27 -0700284 release_sock(sk);
285 timeo = schedule_timeout(timeo);
286 lock_sock(sk);
Eric Dumazet9cd3e072015-11-29 20:03:10 -0800287 sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk);
Mat Martineau796c86e2010-09-08 10:05:27 -0700288 }
289
290 __set_current_state(TASK_RUNNING);
291 remove_wait_queue(sk_sleep(sk), &wait);
292 return timeo;
293}
294
Ying Xue1b784142015-03-02 15:37:48 +0800295int bt_sock_stream_recvmsg(struct socket *sock, struct msghdr *msg,
296 size_t size, int flags)
Mat Martineau796c86e2010-09-08 10:05:27 -0700297{
298 struct sock *sk = sock->sk;
299 int err = 0;
300 size_t target, copied = 0;
301 long timeo;
302
303 if (flags & MSG_OOB)
304 return -EOPNOTSUPP;
305
Mat Martineau796c86e2010-09-08 10:05:27 -0700306 BT_DBG("sk %p size %zu", sk, size);
307
308 lock_sock(sk);
309
310 target = sock_rcvlowat(sk, flags & MSG_WAITALL, size);
311 timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
312
313 do {
314 struct sk_buff *skb;
315 int chunk;
316
317 skb = skb_dequeue(&sk->sk_receive_queue);
318 if (!skb) {
319 if (copied >= target)
320 break;
321
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +0200322 err = sock_error(sk);
323 if (err)
Mat Martineau796c86e2010-09-08 10:05:27 -0700324 break;
325 if (sk->sk_shutdown & RCV_SHUTDOWN)
326 break;
327
328 err = -EAGAIN;
329 if (!timeo)
330 break;
331
332 timeo = bt_sock_data_wait(sk, timeo);
333
334 if (signal_pending(current)) {
335 err = sock_intr_errno(timeo);
336 goto out;
337 }
338 continue;
339 }
340
341 chunk = min_t(unsigned int, skb->len, size);
David S. Miller51f3d022014-11-05 16:46:40 -0500342 if (skb_copy_datagram_msg(skb, 0, msg, chunk)) {
Mat Martineau796c86e2010-09-08 10:05:27 -0700343 skb_queue_head(&sk->sk_receive_queue, skb);
344 if (!copied)
345 copied = -EFAULT;
346 break;
347 }
348 copied += chunk;
349 size -= chunk;
350
351 sock_recv_ts_and_drops(msg, sk, skb);
352
353 if (!(flags & MSG_PEEK)) {
Mat Martineau5b668eb2011-07-22 14:53:59 -0700354 int skb_len = skb_headlen(skb);
355
356 if (chunk <= skb_len) {
357 __skb_pull(skb, chunk);
358 } else {
359 struct sk_buff *frag;
360
361 __skb_pull(skb, skb_len);
362 chunk -= skb_len;
363
364 skb_walk_frags(skb, frag) {
365 if (chunk <= frag->len) {
366 /* Pulling partial data */
367 skb->len -= chunk;
368 skb->data_len -= chunk;
369 __skb_pull(frag, chunk);
370 break;
371 } else if (frag->len) {
372 /* Pulling all frag data */
373 chunk -= frag->len;
374 skb->len -= frag->len;
375 skb->data_len -= frag->len;
376 __skb_pull(frag, frag->len);
377 }
378 }
379 }
380
Mat Martineau796c86e2010-09-08 10:05:27 -0700381 if (skb->len) {
382 skb_queue_head(&sk->sk_receive_queue, skb);
383 break;
384 }
385 kfree_skb(skb);
386
387 } else {
388 /* put message back and return */
389 skb_queue_head(&sk->sk_receive_queue, skb);
390 break;
391 }
392 } while (size);
393
394out:
395 release_sock(sk);
396 return copied ? : err;
397}
398EXPORT_SYMBOL(bt_sock_stream_recvmsg);
399
Linus Torvalds1da177e2005-04-16 15:20:36 -0700400static inline unsigned int bt_accept_poll(struct sock *parent)
401{
Geliang Tang7eb74042015-12-18 23:33:25 +0800402 struct bt_sock *s, *n;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700403 struct sock *sk;
404
Geliang Tang7eb74042015-12-18 23:33:25 +0800405 list_for_each_entry_safe(s, n, &bt_sk(parent)->accept_q, accept_q) {
406 sk = (struct sock *)s;
Marcel Holtmannd5f2d2b2009-02-16 02:57:30 +0100407 if (sk->sk_state == BT_CONNECTED ||
Gustavo Padovanc5daa682012-05-16 12:17:10 -0300408 (test_bit(BT_SK_DEFER_SETUP, &bt_sk(parent)->flags) &&
409 sk->sk_state == BT_CONNECT2))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700410 return POLLIN | POLLRDNORM;
411 }
412
413 return 0;
414}
415
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300416unsigned int bt_sock_poll(struct file *file, struct socket *sock,
417 poll_table *wait)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700418{
419 struct sock *sk = sock->sk;
420 unsigned int mask = 0;
421
422 BT_DBG("sock %p, sk %p", sock, sk);
423
Eric Dumazetaa395142010-04-20 13:03:51 +0000424 poll_wait(file, sk_sleep(sk), wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700425
426 if (sk->sk_state == BT_LISTEN)
427 return bt_accept_poll(sk);
428
429 if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue))
Keller, Jacob E7d4c04f2013-03-28 11:19:25 +0000430 mask |= POLLERR |
Jacob Keller8facd5f2013-04-02 13:55:40 -0700431 (sock_flag(sk, SOCK_SELECT_ERR_QUEUE) ? POLLPRI : 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700432
Davide Libenzif348d702006-03-25 03:07:39 -0800433 if (sk->sk_shutdown & RCV_SHUTDOWN)
Eric Dumazetdb409802010-09-06 11:13:50 +0000434 mask |= POLLRDHUP | POLLIN | POLLRDNORM;
Davide Libenzif348d702006-03-25 03:07:39 -0800435
Linus Torvalds1da177e2005-04-16 15:20:36 -0700436 if (sk->sk_shutdown == SHUTDOWN_MASK)
437 mask |= POLLHUP;
438
Eric Dumazetdb409802010-09-06 11:13:50 +0000439 if (!skb_queue_empty(&sk->sk_receive_queue))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700440 mask |= POLLIN | POLLRDNORM;
441
442 if (sk->sk_state == BT_CLOSED)
443 mask |= POLLHUP;
444
445 if (sk->sk_state == BT_CONNECT ||
446 sk->sk_state == BT_CONNECT2 ||
447 sk->sk_state == BT_CONFIG)
448 return mask;
449
Gustavo Padovanc5daa682012-05-16 12:17:10 -0300450 if (!test_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags) && sock_writeable(sk))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700451 mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
452 else
Eric Dumazet9cd3e072015-11-29 20:03:10 -0800453 sk_set_bit(SOCKWQ_ASYNC_NOSPACE, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700454
455 return mask;
456}
457EXPORT_SYMBOL(bt_sock_poll);
458
Marcel Holtmann3241ad82008-07-14 20:13:50 +0200459int bt_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
460{
461 struct sock *sk = sock->sk;
Marcel Holtmann43cbeee2008-07-14 20:13:51 +0200462 struct sk_buff *skb;
463 long amount;
Marcel Holtmann3241ad82008-07-14 20:13:50 +0200464 int err;
465
466 BT_DBG("sk %p cmd %x arg %lx", sk, cmd, arg);
467
468 switch (cmd) {
Marcel Holtmann43cbeee2008-07-14 20:13:51 +0200469 case TIOCOUTQ:
470 if (sk->sk_state == BT_LISTEN)
471 return -EINVAL;
472
Eric Dumazet31e6d362009-06-17 19:05:41 -0700473 amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk);
Marcel Holtmann43cbeee2008-07-14 20:13:51 +0200474 if (amount < 0)
475 amount = 0;
476 err = put_user(amount, (int __user *) arg);
477 break;
478
479 case TIOCINQ:
480 if (sk->sk_state == BT_LISTEN)
481 return -EINVAL;
482
483 lock_sock(sk);
484 skb = skb_peek(&sk->sk_receive_queue);
485 amount = skb ? skb->len : 0;
486 release_sock(sk);
487 err = put_user(amount, (int __user *) arg);
488 break;
489
Marcel Holtmann3241ad82008-07-14 20:13:50 +0200490 case SIOCGSTAMP:
491 err = sock_get_timestamp(sk, (struct timeval __user *) arg);
492 break;
493
494 case SIOCGSTAMPNS:
495 err = sock_get_timestampns(sk, (struct timespec __user *) arg);
496 break;
497
498 default:
499 err = -ENOIOCTLCMD;
500 break;
501 }
502
503 return err;
504}
505EXPORT_SYMBOL(bt_sock_ioctl);
506
Johan Hedberg0fba96f92013-09-25 13:26:04 +0300507/* This function expects the sk lock to be held when called */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700508int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo)
509{
510 DECLARE_WAITQUEUE(wait, current);
511 int err = 0;
512
513 BT_DBG("sk %p", sk);
514
Eric Dumazetaa395142010-04-20 13:03:51 +0000515 add_wait_queue(sk_sleep(sk), &wait);
Peter Hurley9be4e3f2011-07-24 00:10:46 -0400516 set_current_state(TASK_INTERRUPTIBLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700517 while (sk->sk_state != state) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700518 if (!timeo) {
Marcel Holtmannb4c612a2006-09-23 09:54:38 +0200519 err = -EINPROGRESS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700520 break;
521 }
522
523 if (signal_pending(current)) {
524 err = sock_intr_errno(timeo);
525 break;
526 }
527
528 release_sock(sk);
529 timeo = schedule_timeout(timeo);
530 lock_sock(sk);
Peter Hurley9be4e3f2011-07-24 00:10:46 -0400531 set_current_state(TASK_INTERRUPTIBLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700532
Benjamin LaHaisec1cbe4b2005-12-13 23:22:19 -0800533 err = sock_error(sk);
534 if (err)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700535 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700536 }
Peter Hurley9be4e3f2011-07-24 00:10:46 -0400537 __set_current_state(TASK_RUNNING);
Eric Dumazetaa395142010-04-20 13:03:51 +0000538 remove_wait_queue(sk_sleep(sk), &wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700539 return err;
540}
541EXPORT_SYMBOL(bt_sock_wait_state);
542
Johan Hedberge793dcf2013-09-16 13:05:19 +0300543/* This function expects the sk lock to be held when called */
544int bt_sock_wait_ready(struct sock *sk, unsigned long flags)
545{
546 DECLARE_WAITQUEUE(wait, current);
547 unsigned long timeo;
548 int err = 0;
549
550 BT_DBG("sk %p", sk);
551
552 timeo = sock_sndtimeo(sk, flags & O_NONBLOCK);
553
554 add_wait_queue(sk_sleep(sk), &wait);
555 set_current_state(TASK_INTERRUPTIBLE);
556 while (test_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags)) {
557 if (!timeo) {
558 err = -EAGAIN;
559 break;
560 }
561
562 if (signal_pending(current)) {
563 err = sock_intr_errno(timeo);
564 break;
565 }
566
567 release_sock(sk);
568 timeo = schedule_timeout(timeo);
569 lock_sock(sk);
570 set_current_state(TASK_INTERRUPTIBLE);
571
572 err = sock_error(sk);
573 if (err)
574 break;
575 }
576 __set_current_state(TASK_RUNNING);
577 remove_wait_queue(sk_sleep(sk), &wait);
578
579 return err;
580}
581EXPORT_SYMBOL(bt_sock_wait_ready);
582
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900583#ifdef CONFIG_PROC_FS
584struct bt_seq_state {
585 struct bt_sock_list *l;
586};
587
588static void *bt_seq_start(struct seq_file *seq, loff_t *pos)
589 __acquires(seq->private->l->lock)
590{
591 struct bt_seq_state *s = seq->private;
592 struct bt_sock_list *l = s->l;
593
594 read_lock(&l->lock);
595 return seq_hlist_start_head(&l->head, *pos);
596}
597
598static void *bt_seq_next(struct seq_file *seq, void *v, loff_t *pos)
599{
600 struct bt_seq_state *s = seq->private;
601 struct bt_sock_list *l = s->l;
602
603 return seq_hlist_next(v, &l->head, pos);
604}
605
606static void bt_seq_stop(struct seq_file *seq, void *v)
607 __releases(seq->private->l->lock)
608{
609 struct bt_seq_state *s = seq->private;
610 struct bt_sock_list *l = s->l;
611
612 read_unlock(&l->lock);
613}
614
615static int bt_seq_show(struct seq_file *seq, void *v)
616{
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900617 struct bt_seq_state *s = seq->private;
618 struct bt_sock_list *l = s->l;
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900619
620 if (v == SEQ_START_TOKEN) {
Marcel Holtmannc5605752013-10-14 02:05:25 -0700621 seq_puts(seq ,"sk RefCnt Rmem Wmem User Inode Parent");
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900622
623 if (l->custom_seq_show) {
624 seq_putc(seq, ' ');
625 l->custom_seq_show(seq, v);
626 }
627
628 seq_putc(seq, '\n');
629 } else {
Andrei Emeltchenko09d5d4a2012-08-07 18:05:04 +0300630 struct sock *sk = sk_entry(v);
631 struct bt_sock *bt = bt_sk(sk);
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900632
Andrei Emeltchenko7028a882012-09-25 12:49:45 +0300633 seq_printf(seq,
Marcel Holtmann5f6cd792013-10-13 10:34:03 -0700634 "%pK %-6d %-6u %-6u %-6u %-6lu %-6lu",
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900635 sk,
636 atomic_read(&sk->sk_refcnt),
637 sk_rmem_alloc_get(sk),
638 sk_wmem_alloc_get(sk),
Eric W. Biederman1bbb3092012-10-03 20:32:17 -0700639 from_kuid(seq_user_ns(seq), sock_i_uid(sk)),
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900640 sock_i_ino(sk),
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900641 bt->parent? sock_i_ino(bt->parent): 0LU);
642
643 if (l->custom_seq_show) {
644 seq_putc(seq, ' ');
645 l->custom_seq_show(seq, v);
646 }
647
648 seq_putc(seq, '\n');
649 }
650 return 0;
651}
652
Fabian Frederick26b0f4e2014-06-30 19:26:23 +0200653static const struct seq_operations bt_seq_ops = {
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900654 .start = bt_seq_start,
655 .next = bt_seq_next,
656 .stop = bt_seq_stop,
657 .show = bt_seq_show,
658};
659
660static int bt_seq_open(struct inode *inode, struct file *file)
661{
662 struct bt_sock_list *sk_list;
663 struct bt_seq_state *s;
664
Al Virod9dda782013-03-31 18:16:14 -0400665 sk_list = PDE_DATA(inode);
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900666 s = __seq_open_private(file, &bt_seq_ops,
667 sizeof(struct bt_seq_state));
Andrei Emeltchenko31f47072012-08-07 18:05:06 +0300668 if (!s)
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900669 return -ENOMEM;
670
671 s->l = sk_list;
672 return 0;
673}
674
Al Viro14805352013-04-04 19:12:06 -0400675static const struct file_operations bt_fops = {
676 .open = bt_seq_open,
677 .read = seq_read,
678 .llseek = seq_lseek,
679 .release = seq_release_private
680};
681
Al Virob0316612013-04-04 19:14:33 -0400682int bt_procfs_init(struct net *net, const char *name,
Prasanna Karthikf37590b2015-11-17 11:06:53 +0000683 struct bt_sock_list *sk_list,
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900684 int (* seq_show)(struct seq_file *, void *))
685{
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900686 sk_list->custom_seq_show = seq_show;
687
Al Viro4d006262013-04-04 19:16:06 -0400688 if (!proc_create_data(name, 0, net->proc_net, &bt_fops, sk_list))
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900689 return -ENOMEM;
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900690 return 0;
691}
692
693void bt_procfs_cleanup(struct net *net, const char *name)
694{
Gao fengece31ff2013-02-18 01:34:56 +0000695 remove_proc_entry(name, net->proc_net);
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900696}
697#else
Al Virob0316612013-04-04 19:14:33 -0400698int bt_procfs_init(struct net *net, const char *name,
Prasanna Karthikf37590b2015-11-17 11:06:53 +0000699 struct bt_sock_list *sk_list,
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900700 int (* seq_show)(struct seq_file *, void *))
701{
702 return 0;
703}
704
705void bt_procfs_cleanup(struct net *net, const char *name)
706{
707}
708#endif
709EXPORT_SYMBOL(bt_procfs_init);
710EXPORT_SYMBOL(bt_procfs_cleanup);
711
Linus Torvalds1da177e2005-04-16 15:20:36 -0700712static struct net_proto_family bt_sock_family_ops = {
713 .owner = THIS_MODULE,
714 .family = PF_BLUETOOTH,
715 .create = bt_sock_create,
716};
717
Marcel Holtmannffcecac2013-10-17 17:24:18 -0700718struct dentry *bt_debugfs;
719EXPORT_SYMBOL_GPL(bt_debugfs);
720
Marcel Holtmann9e8305b2016-08-30 05:00:35 +0200721#define VERSION __stringify(BT_SUBSYS_VERSION) "." \
722 __stringify(BT_SUBSYS_REVISION)
723
Linus Torvalds1da177e2005-04-16 15:20:36 -0700724static int __init bt_init(void)
725{
Marcel Holtmann27d35282006-07-03 10:02:37 +0200726 int err;
727
Eyal Birgerb4772ef2015-03-01 14:58:29 +0200728 sock_skb_cb_check_size(sizeof(struct bt_skb_cb));
Marcel Holtmann7cb9d202014-09-14 22:50:46 +0200729
Marcel Holtmann9e8305b2016-08-30 05:00:35 +0200730 BT_INFO("Core ver %s", VERSION);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700731
Marcel Holtmannee485292014-12-29 20:48:35 -0800732 err = bt_selftest();
733 if (err < 0)
734 return err;
735
Marcel Holtmannffcecac2013-10-17 17:24:18 -0700736 bt_debugfs = debugfs_create_dir("bluetooth", NULL);
737
Marcel Holtmanne64c97b2016-07-21 14:12:41 +0200738 bt_leds_init();
739
Marcel Holtmann27d35282006-07-03 10:02:37 +0200740 err = bt_sysfs_init();
741 if (err < 0)
742 return err;
743
744 err = sock_register(&bt_sock_family_ops);
745 if (err < 0) {
746 bt_sysfs_cleanup();
747 return err;
748 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700749
750 BT_INFO("HCI device and connection manager initialized");
751
Gustavo F. Padovan64274512011-02-07 20:08:52 -0200752 err = hci_sock_init();
753 if (err < 0)
754 goto error;
755
756 err = l2cap_init();
Anand Gadiyar0ed54da2011-02-22 12:43:26 +0530757 if (err < 0)
Gustavo F. Padovan64274512011-02-07 20:08:52 -0200758 goto sock_err;
Gustavo F. Padovan64274512011-02-07 20:08:52 -0200759
760 err = sco_init();
761 if (err < 0) {
762 l2cap_exit();
763 goto sock_err;
764 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700765
Johan Hedberg6d785aa32015-03-06 21:08:51 +0200766 err = mgmt_init();
767 if (err < 0) {
768 sco_exit();
769 l2cap_exit();
770 goto sock_err;
771 }
772
Linus Torvalds1da177e2005-04-16 15:20:36 -0700773 return 0;
Gustavo F. Padovan64274512011-02-07 20:08:52 -0200774
775sock_err:
776 hci_sock_cleanup();
777
778error:
779 sock_unregister(PF_BLUETOOTH);
780 bt_sysfs_cleanup();
781
782 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700783}
784
785static void __exit bt_exit(void)
786{
Johan Hedberg6d785aa32015-03-06 21:08:51 +0200787 mgmt_exit();
788
Gustavo F. Padovan64274512011-02-07 20:08:52 -0200789 sco_exit();
790
791 l2cap_exit();
792
Linus Torvalds1da177e2005-04-16 15:20:36 -0700793 hci_sock_cleanup();
794
Linus Torvalds1da177e2005-04-16 15:20:36 -0700795 sock_unregister(PF_BLUETOOTH);
Marcel Holtmann27d35282006-07-03 10:02:37 +0200796
797 bt_sysfs_cleanup();
Marcel Holtmannffcecac2013-10-17 17:24:18 -0700798
Marcel Holtmanne64c97b2016-07-21 14:12:41 +0200799 bt_leds_cleanup();
800
Marcel Holtmannffcecac2013-10-17 17:24:18 -0700801 debugfs_remove_recursive(bt_debugfs);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700802}
803
804subsys_initcall(bt_init);
805module_exit(bt_exit);
806
Marcel Holtmann63fbd242008-08-18 13:23:53 +0200807MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
Marcel Holtmann9e8305b2016-08-30 05:00:35 +0200808MODULE_DESCRIPTION("Bluetooth Core ver " VERSION);
809MODULE_VERSION(VERSION);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700810MODULE_LICENSE("GPL");
811MODULE_ALIAS_NETPROTO(PF_BLUETOOTH);