blob: 0b5f729d08d2b41abcfcdb1d7322d3c1ce01fa89 [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 Holtmann3241ad82008-07-14 20:13:50 +020029#include <asm/ioctls.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070030
31#include <net/bluetooth/bluetooth.h>
Masatake YAMATO256a06c2012-07-26 01:26:32 +090032#include <linux/proc_fs.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070033
Marcel Holtmannee485292014-12-29 20:48:35 -080034#include "selftest.h"
35
Linus Torvalds1da177e2005-04-16 15:20:36 -070036/* Bluetooth sockets */
37#define BT_MAX_PROTO 8
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +000038static const struct net_proto_family *bt_proto[BT_MAX_PROTO];
Marcel Holtmanndb7aa1c2008-11-30 12:17:19 +010039static DEFINE_RWLOCK(bt_proto_lock);
Dave Young68845cb2008-04-01 23:58:35 -070040
Dave Young68845cb2008-04-01 23:58:35 -070041static struct lock_class_key bt_lock_key[BT_MAX_PROTO];
Jan Engelhardt36cbd3d2009-08-05 10:42:58 -070042static const char *const bt_key_strings[BT_MAX_PROTO] = {
Dave Young68845cb2008-04-01 23:58:35 -070043 "sk_lock-AF_BLUETOOTH-BTPROTO_L2CAP",
44 "sk_lock-AF_BLUETOOTH-BTPROTO_HCI",
45 "sk_lock-AF_BLUETOOTH-BTPROTO_SCO",
46 "sk_lock-AF_BLUETOOTH-BTPROTO_RFCOMM",
47 "sk_lock-AF_BLUETOOTH-BTPROTO_BNEP",
48 "sk_lock-AF_BLUETOOTH-BTPROTO_CMTP",
49 "sk_lock-AF_BLUETOOTH-BTPROTO_HIDP",
50 "sk_lock-AF_BLUETOOTH-BTPROTO_AVDTP",
51};
52
Marcel Holtmanndb7aa1c2008-11-30 12:17:19 +010053static struct lock_class_key bt_slock_key[BT_MAX_PROTO];
Jan Engelhardt36cbd3d2009-08-05 10:42:58 -070054static const char *const bt_slock_key_strings[BT_MAX_PROTO] = {
Dave Young68845cb2008-04-01 23:58:35 -070055 "slock-AF_BLUETOOTH-BTPROTO_L2CAP",
56 "slock-AF_BLUETOOTH-BTPROTO_HCI",
57 "slock-AF_BLUETOOTH-BTPROTO_SCO",
58 "slock-AF_BLUETOOTH-BTPROTO_RFCOMM",
59 "slock-AF_BLUETOOTH-BTPROTO_BNEP",
60 "slock-AF_BLUETOOTH-BTPROTO_CMTP",
61 "slock-AF_BLUETOOTH-BTPROTO_HIDP",
62 "slock-AF_BLUETOOTH-BTPROTO_AVDTP",
63};
Marcel Holtmanndb7aa1c2008-11-30 12:17:19 +010064
Octavian Purdilab5a30dd2012-01-22 00:28:34 +020065void bt_sock_reclassify_lock(struct sock *sk, int proto)
Marcel Holtmanndb7aa1c2008-11-30 12:17:19 +010066{
Octavian Purdilab5a30dd2012-01-22 00:28:34 +020067 BUG_ON(!sk);
Hannes Frederic Sowafafc4e12016-04-08 15:11:27 +020068 BUG_ON(!sock_allow_reclassification(sk));
Marcel Holtmanndb7aa1c2008-11-30 12:17:19 +010069
70 sock_lock_init_class_and_name(sk,
71 bt_slock_key_strings[proto], &bt_slock_key[proto],
72 bt_key_strings[proto], &bt_lock_key[proto]);
73}
Octavian Purdilab5a30dd2012-01-22 00:28:34 +020074EXPORT_SYMBOL(bt_sock_reclassify_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -070075
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +000076int bt_sock_register(int proto, const struct net_proto_family *ops)
Linus Torvalds1da177e2005-04-16 15:20:36 -070077{
Marcel Holtmann74da6262006-10-15 17:31:14 +020078 int err = 0;
79
Linus Torvalds1da177e2005-04-16 15:20:36 -070080 if (proto < 0 || proto >= BT_MAX_PROTO)
81 return -EINVAL;
82
Marcel Holtmann74da6262006-10-15 17:31:14 +020083 write_lock(&bt_proto_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -070084
Marcel Holtmann74da6262006-10-15 17:31:14 +020085 if (bt_proto[proto])
86 err = -EEXIST;
87 else
88 bt_proto[proto] = ops;
89
90 write_unlock(&bt_proto_lock);
91
92 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -070093}
94EXPORT_SYMBOL(bt_sock_register);
95
David Herrmannbe9f97f2013-02-24 19:36:52 +010096void bt_sock_unregister(int proto)
Linus Torvalds1da177e2005-04-16 15:20:36 -070097{
98 if (proto < 0 || proto >= BT_MAX_PROTO)
David Herrmannbe9f97f2013-02-24 19:36:52 +010099 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700100
Marcel Holtmann74da6262006-10-15 17:31:14 +0200101 write_lock(&bt_proto_lock);
David Herrmannbe9f97f2013-02-24 19:36:52 +0100102 bt_proto[proto] = NULL;
Marcel Holtmann74da6262006-10-15 17:31:14 +0200103 write_unlock(&bt_proto_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700104}
105EXPORT_SYMBOL(bt_sock_unregister);
106
Eric Paris3f378b62009-11-05 22:18:14 -0800107static int bt_sock_create(struct net *net, struct socket *sock, int proto,
108 int kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700109{
Marcel Holtmann74da6262006-10-15 17:31:14 +0200110 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700111
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700112 if (net != &init_net)
113 return -EAFNOSUPPORT;
114
Linus Torvalds1da177e2005-04-16 15:20:36 -0700115 if (proto < 0 || proto >= BT_MAX_PROTO)
116 return -EINVAL;
117
Johannes Berg95a5afc2008-10-16 15:24:51 -0700118 if (!bt_proto[proto])
Linus Torvalds1da177e2005-04-16 15:20:36 -0700119 request_module("bt-proto-%d", proto);
Marcel Holtmann74da6262006-10-15 17:31:14 +0200120
Linus Torvalds1da177e2005-04-16 15:20:36 -0700121 err = -EPROTONOSUPPORT;
Marcel Holtmann74da6262006-10-15 17:31:14 +0200122
123 read_lock(&bt_proto_lock);
124
Linus Torvalds1da177e2005-04-16 15:20:36 -0700125 if (bt_proto[proto] && try_module_get(bt_proto[proto]->owner)) {
Eric Paris3f378b62009-11-05 22:18:14 -0800126 err = bt_proto[proto]->create(net, sock, proto, kern);
Octavian Purdilab5a30dd2012-01-22 00:28:34 +0200127 if (!err)
128 bt_sock_reclassify_lock(sock->sk, proto);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700129 module_put(bt_proto[proto]->owner);
130 }
Marcel Holtmann74da6262006-10-15 17:31:14 +0200131
132 read_unlock(&bt_proto_lock);
133
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900134 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700135}
136
137void bt_sock_link(struct bt_sock_list *l, struct sock *sk)
138{
Gustavo F. Padovan94f5bfb2011-12-27 15:28:48 -0200139 write_lock(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700140 sk_add_node(sk, &l->head);
Gustavo F. Padovan94f5bfb2011-12-27 15:28:48 -0200141 write_unlock(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700142}
143EXPORT_SYMBOL(bt_sock_link);
144
145void bt_sock_unlink(struct bt_sock_list *l, struct sock *sk)
146{
Gustavo F. Padovan94f5bfb2011-12-27 15:28:48 -0200147 write_lock(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700148 sk_del_node_init(sk);
Gustavo F. Padovan94f5bfb2011-12-27 15:28:48 -0200149 write_unlock(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700150}
151EXPORT_SYMBOL(bt_sock_unlink);
152
153void bt_accept_enqueue(struct sock *parent, struct sock *sk)
154{
155 BT_DBG("parent %p, sk %p", parent, sk);
156
157 sock_hold(sk);
158 list_add_tail(&bt_sk(sk)->accept_q, &bt_sk(parent)->accept_q);
159 bt_sk(sk)->parent = parent;
160 parent->sk_ack_backlog++;
161}
162EXPORT_SYMBOL(bt_accept_enqueue);
163
164void bt_accept_unlink(struct sock *sk)
165{
166 BT_DBG("sk %p state %d", sk, sk->sk_state);
167
168 list_del_init(&bt_sk(sk)->accept_q);
169 bt_sk(sk)->parent->sk_ack_backlog--;
170 bt_sk(sk)->parent = NULL;
171 sock_put(sk);
172}
173EXPORT_SYMBOL(bt_accept_unlink);
174
175struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock)
176{
Geliang Tang7eb74042015-12-18 23:33:25 +0800177 struct bt_sock *s, *n;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700178 struct sock *sk;
179
180 BT_DBG("parent %p", parent);
181
Geliang Tang7eb74042015-12-18 23:33:25 +0800182 list_for_each_entry_safe(s, n, &bt_sk(parent)->accept_q, accept_q) {
183 sk = (struct sock *)s;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700184
Gustavo F. Padovan8a154a82011-12-20 17:15:56 -0200185 lock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700186
187 /* FIXME: Is this check still needed */
188 if (sk->sk_state == BT_CLOSED) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700189 bt_accept_unlink(sk);
Yichen Zhao1a11ec82015-12-01 11:11:01 -0800190 release_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700191 continue;
192 }
193
Marcel Holtmannc4f912e2009-01-15 21:52:16 +0100194 if (sk->sk_state == BT_CONNECTED || !newsock ||
Vinicius Costa Gomesd0609912012-05-31 22:53:39 -0300195 test_bit(BT_SK_DEFER_SETUP, &bt_sk(parent)->flags)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700196 bt_accept_unlink(sk);
197 if (newsock)
198 sock_graft(sk, newsock);
Andrei Emeltchenkod37f50e2011-01-24 10:53:24 +0200199
Gustavo F. Padovan8a154a82011-12-20 17:15:56 -0200200 release_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700201 return sk;
202 }
203
Gustavo F. Padovan8a154a82011-12-20 17:15:56 -0200204 release_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700205 }
Andrei Emeltchenkod37f50e2011-01-24 10:53:24 +0200206
Linus Torvalds1da177e2005-04-16 15:20:36 -0700207 return NULL;
208}
209EXPORT_SYMBOL(bt_accept_dequeue);
210
Ying Xue1b784142015-03-02 15:37:48 +0800211int bt_sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
212 int flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700213{
214 int noblock = flags & MSG_DONTWAIT;
215 struct sock *sk = sock->sk;
216 struct sk_buff *skb;
217 size_t copied;
Denis Kenziorb5f34f92016-06-27 11:01:12 -0500218 size_t skblen;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700219 int err;
220
Marcel Holtmanna418b892008-11-30 12:17:28 +0100221 BT_DBG("sock %p sk %p len %zu", sock, sk, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700222
Marcel Holtmannd94a6102015-10-25 22:45:18 +0100223 if (flags & MSG_OOB)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700224 return -EOPNOTSUPP;
225
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +0200226 skb = skb_recv_datagram(sk, flags, noblock, &err);
227 if (!skb) {
Hannes Frederic Sowaf3d33422013-11-21 03:14:22 +0100228 if (sk->sk_shutdown & RCV_SHUTDOWN)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700229 return 0;
Hannes Frederic Sowaf3d33422013-11-21 03:14:22 +0100230
Linus Torvalds1da177e2005-04-16 15:20:36 -0700231 return err;
232 }
233
Denis Kenziorb5f34f92016-06-27 11:01:12 -0500234 skblen = skb->len;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700235 copied = skb->len;
236 if (len < copied) {
237 msg->msg_flags |= MSG_TRUNC;
238 copied = len;
239 }
240
Arnaldo Carvalho de Melobadff6d2007-03-13 13:06:52 -0300241 skb_reset_transport_header(skb);
David S. Miller51f3d022014-11-05 16:46:40 -0500242 err = skb_copy_datagram_msg(skb, 0, msg, copied);
Marcel Holtmannd9763692013-10-13 12:55:28 -0700243 if (err == 0) {
Neil Horman3b885782009-10-12 13:26:31 -0700244 sock_recv_ts_and_drops(msg, sk, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700245
Marcel Holtmannd9763692013-10-13 12:55:28 -0700246 if (bt_sk(sk)->skb_msg_name)
247 bt_sk(sk)->skb_msg_name(skb, msg->msg_name,
248 &msg->msg_namelen);
Marcel Holtmannd9763692013-10-13 12:55:28 -0700249 }
250
Linus Torvalds1da177e2005-04-16 15:20:36 -0700251 skb_free_datagram(sk, skb);
252
Luiz Augusto von Dentz90a56f72016-08-12 15:11:28 +0300253 if (flags & MSG_TRUNC)
Denis Kenziorb5f34f92016-06-27 11:01:12 -0500254 copied = skblen;
255
Linus Torvalds1da177e2005-04-16 15:20:36 -0700256 return err ? : copied;
257}
258EXPORT_SYMBOL(bt_sock_recvmsg);
259
Mat Martineau796c86e2010-09-08 10:05:27 -0700260static long bt_sock_data_wait(struct sock *sk, long timeo)
261{
262 DECLARE_WAITQUEUE(wait, current);
263
264 add_wait_queue(sk_sleep(sk), &wait);
265 for (;;) {
266 set_current_state(TASK_INTERRUPTIBLE);
267
268 if (!skb_queue_empty(&sk->sk_receive_queue))
269 break;
270
271 if (sk->sk_err || (sk->sk_shutdown & RCV_SHUTDOWN))
272 break;
273
274 if (signal_pending(current) || !timeo)
275 break;
276
Eric Dumazet9cd3e072015-11-29 20:03:10 -0800277 sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk);
Mat Martineau796c86e2010-09-08 10:05:27 -0700278 release_sock(sk);
279 timeo = schedule_timeout(timeo);
280 lock_sock(sk);
Eric Dumazet9cd3e072015-11-29 20:03:10 -0800281 sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk);
Mat Martineau796c86e2010-09-08 10:05:27 -0700282 }
283
284 __set_current_state(TASK_RUNNING);
285 remove_wait_queue(sk_sleep(sk), &wait);
286 return timeo;
287}
288
Ying Xue1b784142015-03-02 15:37:48 +0800289int bt_sock_stream_recvmsg(struct socket *sock, struct msghdr *msg,
290 size_t size, int flags)
Mat Martineau796c86e2010-09-08 10:05:27 -0700291{
292 struct sock *sk = sock->sk;
293 int err = 0;
294 size_t target, copied = 0;
295 long timeo;
296
297 if (flags & MSG_OOB)
298 return -EOPNOTSUPP;
299
Mat Martineau796c86e2010-09-08 10:05:27 -0700300 BT_DBG("sk %p size %zu", sk, size);
301
302 lock_sock(sk);
303
304 target = sock_rcvlowat(sk, flags & MSG_WAITALL, size);
305 timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
306
307 do {
308 struct sk_buff *skb;
309 int chunk;
310
311 skb = skb_dequeue(&sk->sk_receive_queue);
312 if (!skb) {
313 if (copied >= target)
314 break;
315
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +0200316 err = sock_error(sk);
317 if (err)
Mat Martineau796c86e2010-09-08 10:05:27 -0700318 break;
319 if (sk->sk_shutdown & RCV_SHUTDOWN)
320 break;
321
322 err = -EAGAIN;
323 if (!timeo)
324 break;
325
326 timeo = bt_sock_data_wait(sk, timeo);
327
328 if (signal_pending(current)) {
329 err = sock_intr_errno(timeo);
330 goto out;
331 }
332 continue;
333 }
334
335 chunk = min_t(unsigned int, skb->len, size);
David S. Miller51f3d022014-11-05 16:46:40 -0500336 if (skb_copy_datagram_msg(skb, 0, msg, chunk)) {
Mat Martineau796c86e2010-09-08 10:05:27 -0700337 skb_queue_head(&sk->sk_receive_queue, skb);
338 if (!copied)
339 copied = -EFAULT;
340 break;
341 }
342 copied += chunk;
343 size -= chunk;
344
345 sock_recv_ts_and_drops(msg, sk, skb);
346
347 if (!(flags & MSG_PEEK)) {
Mat Martineau5b668eb2011-07-22 14:53:59 -0700348 int skb_len = skb_headlen(skb);
349
350 if (chunk <= skb_len) {
351 __skb_pull(skb, chunk);
352 } else {
353 struct sk_buff *frag;
354
355 __skb_pull(skb, skb_len);
356 chunk -= skb_len;
357
358 skb_walk_frags(skb, frag) {
359 if (chunk <= frag->len) {
360 /* Pulling partial data */
361 skb->len -= chunk;
362 skb->data_len -= chunk;
363 __skb_pull(frag, chunk);
364 break;
365 } else if (frag->len) {
366 /* Pulling all frag data */
367 chunk -= frag->len;
368 skb->len -= frag->len;
369 skb->data_len -= frag->len;
370 __skb_pull(frag, frag->len);
371 }
372 }
373 }
374
Mat Martineau796c86e2010-09-08 10:05:27 -0700375 if (skb->len) {
376 skb_queue_head(&sk->sk_receive_queue, skb);
377 break;
378 }
379 kfree_skb(skb);
380
381 } else {
382 /* put message back and return */
383 skb_queue_head(&sk->sk_receive_queue, skb);
384 break;
385 }
386 } while (size);
387
388out:
389 release_sock(sk);
390 return copied ? : err;
391}
392EXPORT_SYMBOL(bt_sock_stream_recvmsg);
393
Linus Torvalds1da177e2005-04-16 15:20:36 -0700394static inline unsigned int bt_accept_poll(struct sock *parent)
395{
Geliang Tang7eb74042015-12-18 23:33:25 +0800396 struct bt_sock *s, *n;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700397 struct sock *sk;
398
Geliang Tang7eb74042015-12-18 23:33:25 +0800399 list_for_each_entry_safe(s, n, &bt_sk(parent)->accept_q, accept_q) {
400 sk = (struct sock *)s;
Marcel Holtmannd5f2d2b2009-02-16 02:57:30 +0100401 if (sk->sk_state == BT_CONNECTED ||
Gustavo Padovanc5daa682012-05-16 12:17:10 -0300402 (test_bit(BT_SK_DEFER_SETUP, &bt_sk(parent)->flags) &&
403 sk->sk_state == BT_CONNECT2))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700404 return POLLIN | POLLRDNORM;
405 }
406
407 return 0;
408}
409
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300410unsigned int bt_sock_poll(struct file *file, struct socket *sock,
411 poll_table *wait)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700412{
413 struct sock *sk = sock->sk;
414 unsigned int mask = 0;
415
416 BT_DBG("sock %p, sk %p", sock, sk);
417
Eric Dumazetaa395142010-04-20 13:03:51 +0000418 poll_wait(file, sk_sleep(sk), wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700419
420 if (sk->sk_state == BT_LISTEN)
421 return bt_accept_poll(sk);
422
423 if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue))
Keller, Jacob E7d4c04f2013-03-28 11:19:25 +0000424 mask |= POLLERR |
Jacob Keller8facd5f2013-04-02 13:55:40 -0700425 (sock_flag(sk, SOCK_SELECT_ERR_QUEUE) ? POLLPRI : 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700426
Davide Libenzif348d702006-03-25 03:07:39 -0800427 if (sk->sk_shutdown & RCV_SHUTDOWN)
Eric Dumazetdb409802010-09-06 11:13:50 +0000428 mask |= POLLRDHUP | POLLIN | POLLRDNORM;
Davide Libenzif348d702006-03-25 03:07:39 -0800429
Linus Torvalds1da177e2005-04-16 15:20:36 -0700430 if (sk->sk_shutdown == SHUTDOWN_MASK)
431 mask |= POLLHUP;
432
Eric Dumazetdb409802010-09-06 11:13:50 +0000433 if (!skb_queue_empty(&sk->sk_receive_queue))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700434 mask |= POLLIN | POLLRDNORM;
435
436 if (sk->sk_state == BT_CLOSED)
437 mask |= POLLHUP;
438
439 if (sk->sk_state == BT_CONNECT ||
440 sk->sk_state == BT_CONNECT2 ||
441 sk->sk_state == BT_CONFIG)
442 return mask;
443
Gustavo Padovanc5daa682012-05-16 12:17:10 -0300444 if (!test_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags) && sock_writeable(sk))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700445 mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
446 else
Eric Dumazet9cd3e072015-11-29 20:03:10 -0800447 sk_set_bit(SOCKWQ_ASYNC_NOSPACE, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700448
449 return mask;
450}
451EXPORT_SYMBOL(bt_sock_poll);
452
Marcel Holtmann3241ad82008-07-14 20:13:50 +0200453int bt_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
454{
455 struct sock *sk = sock->sk;
Marcel Holtmann43cbeee2008-07-14 20:13:51 +0200456 struct sk_buff *skb;
457 long amount;
Marcel Holtmann3241ad82008-07-14 20:13:50 +0200458 int err;
459
460 BT_DBG("sk %p cmd %x arg %lx", sk, cmd, arg);
461
462 switch (cmd) {
Marcel Holtmann43cbeee2008-07-14 20:13:51 +0200463 case TIOCOUTQ:
464 if (sk->sk_state == BT_LISTEN)
465 return -EINVAL;
466
Eric Dumazet31e6d362009-06-17 19:05:41 -0700467 amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk);
Marcel Holtmann43cbeee2008-07-14 20:13:51 +0200468 if (amount < 0)
469 amount = 0;
470 err = put_user(amount, (int __user *) arg);
471 break;
472
473 case TIOCINQ:
474 if (sk->sk_state == BT_LISTEN)
475 return -EINVAL;
476
477 lock_sock(sk);
478 skb = skb_peek(&sk->sk_receive_queue);
479 amount = skb ? skb->len : 0;
480 release_sock(sk);
481 err = put_user(amount, (int __user *) arg);
482 break;
483
Marcel Holtmann3241ad82008-07-14 20:13:50 +0200484 case SIOCGSTAMP:
485 err = sock_get_timestamp(sk, (struct timeval __user *) arg);
486 break;
487
488 case SIOCGSTAMPNS:
489 err = sock_get_timestampns(sk, (struct timespec __user *) arg);
490 break;
491
492 default:
493 err = -ENOIOCTLCMD;
494 break;
495 }
496
497 return err;
498}
499EXPORT_SYMBOL(bt_sock_ioctl);
500
Johan Hedberg0fba96f2013-09-25 13:26:04 +0300501/* This function expects the sk lock to be held when called */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700502int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo)
503{
504 DECLARE_WAITQUEUE(wait, current);
505 int err = 0;
506
507 BT_DBG("sk %p", sk);
508
Eric Dumazetaa395142010-04-20 13:03:51 +0000509 add_wait_queue(sk_sleep(sk), &wait);
Peter Hurley9be4e3f2011-07-24 00:10:46 -0400510 set_current_state(TASK_INTERRUPTIBLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700511 while (sk->sk_state != state) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700512 if (!timeo) {
Marcel Holtmannb4c612a2006-09-23 09:54:38 +0200513 err = -EINPROGRESS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700514 break;
515 }
516
517 if (signal_pending(current)) {
518 err = sock_intr_errno(timeo);
519 break;
520 }
521
522 release_sock(sk);
523 timeo = schedule_timeout(timeo);
524 lock_sock(sk);
Peter Hurley9be4e3f2011-07-24 00:10:46 -0400525 set_current_state(TASK_INTERRUPTIBLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700526
Benjamin LaHaisec1cbe4b2005-12-13 23:22:19 -0800527 err = sock_error(sk);
528 if (err)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700529 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700530 }
Peter Hurley9be4e3f2011-07-24 00:10:46 -0400531 __set_current_state(TASK_RUNNING);
Eric Dumazetaa395142010-04-20 13:03:51 +0000532 remove_wait_queue(sk_sleep(sk), &wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700533 return err;
534}
535EXPORT_SYMBOL(bt_sock_wait_state);
536
Johan Hedberge793dcf2013-09-16 13:05:19 +0300537/* This function expects the sk lock to be held when called */
538int bt_sock_wait_ready(struct sock *sk, unsigned long flags)
539{
540 DECLARE_WAITQUEUE(wait, current);
541 unsigned long timeo;
542 int err = 0;
543
544 BT_DBG("sk %p", sk);
545
546 timeo = sock_sndtimeo(sk, flags & O_NONBLOCK);
547
548 add_wait_queue(sk_sleep(sk), &wait);
549 set_current_state(TASK_INTERRUPTIBLE);
550 while (test_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags)) {
551 if (!timeo) {
552 err = -EAGAIN;
553 break;
554 }
555
556 if (signal_pending(current)) {
557 err = sock_intr_errno(timeo);
558 break;
559 }
560
561 release_sock(sk);
562 timeo = schedule_timeout(timeo);
563 lock_sock(sk);
564 set_current_state(TASK_INTERRUPTIBLE);
565
566 err = sock_error(sk);
567 if (err)
568 break;
569 }
570 __set_current_state(TASK_RUNNING);
571 remove_wait_queue(sk_sleep(sk), &wait);
572
573 return err;
574}
575EXPORT_SYMBOL(bt_sock_wait_ready);
576
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900577#ifdef CONFIG_PROC_FS
578struct bt_seq_state {
579 struct bt_sock_list *l;
580};
581
582static void *bt_seq_start(struct seq_file *seq, loff_t *pos)
583 __acquires(seq->private->l->lock)
584{
585 struct bt_seq_state *s = seq->private;
586 struct bt_sock_list *l = s->l;
587
588 read_lock(&l->lock);
589 return seq_hlist_start_head(&l->head, *pos);
590}
591
592static void *bt_seq_next(struct seq_file *seq, void *v, loff_t *pos)
593{
594 struct bt_seq_state *s = seq->private;
595 struct bt_sock_list *l = s->l;
596
597 return seq_hlist_next(v, &l->head, pos);
598}
599
600static void bt_seq_stop(struct seq_file *seq, void *v)
601 __releases(seq->private->l->lock)
602{
603 struct bt_seq_state *s = seq->private;
604 struct bt_sock_list *l = s->l;
605
606 read_unlock(&l->lock);
607}
608
609static int bt_seq_show(struct seq_file *seq, void *v)
610{
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900611 struct bt_seq_state *s = seq->private;
612 struct bt_sock_list *l = s->l;
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900613
614 if (v == SEQ_START_TOKEN) {
Marcel Holtmannc5605752013-10-14 02:05:25 -0700615 seq_puts(seq ,"sk RefCnt Rmem Wmem User Inode Parent");
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900616
617 if (l->custom_seq_show) {
618 seq_putc(seq, ' ');
619 l->custom_seq_show(seq, v);
620 }
621
622 seq_putc(seq, '\n');
623 } else {
Andrei Emeltchenko09d5d4a2012-08-07 18:05:04 +0300624 struct sock *sk = sk_entry(v);
625 struct bt_sock *bt = bt_sk(sk);
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900626
Andrei Emeltchenko7028a882012-09-25 12:49:45 +0300627 seq_printf(seq,
Marcel Holtmann5f6cd792013-10-13 10:34:03 -0700628 "%pK %-6d %-6u %-6u %-6u %-6lu %-6lu",
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900629 sk,
630 atomic_read(&sk->sk_refcnt),
631 sk_rmem_alloc_get(sk),
632 sk_wmem_alloc_get(sk),
Eric W. Biederman1bbb3092012-10-03 20:32:17 -0700633 from_kuid(seq_user_ns(seq), sock_i_uid(sk)),
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900634 sock_i_ino(sk),
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900635 bt->parent? sock_i_ino(bt->parent): 0LU);
636
637 if (l->custom_seq_show) {
638 seq_putc(seq, ' ');
639 l->custom_seq_show(seq, v);
640 }
641
642 seq_putc(seq, '\n');
643 }
644 return 0;
645}
646
Fabian Frederick26b0f4e2014-06-30 19:26:23 +0200647static const struct seq_operations bt_seq_ops = {
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900648 .start = bt_seq_start,
649 .next = bt_seq_next,
650 .stop = bt_seq_stop,
651 .show = bt_seq_show,
652};
653
654static int bt_seq_open(struct inode *inode, struct file *file)
655{
656 struct bt_sock_list *sk_list;
657 struct bt_seq_state *s;
658
Al Virod9dda782013-03-31 18:16:14 -0400659 sk_list = PDE_DATA(inode);
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900660 s = __seq_open_private(file, &bt_seq_ops,
661 sizeof(struct bt_seq_state));
Andrei Emeltchenko31f47072012-08-07 18:05:06 +0300662 if (!s)
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900663 return -ENOMEM;
664
665 s->l = sk_list;
666 return 0;
667}
668
Al Viro14805352013-04-04 19:12:06 -0400669static const struct file_operations bt_fops = {
670 .open = bt_seq_open,
671 .read = seq_read,
672 .llseek = seq_lseek,
673 .release = seq_release_private
674};
675
Al Virob0316612013-04-04 19:14:33 -0400676int bt_procfs_init(struct net *net, const char *name,
Prasanna Karthikf37590b2015-11-17 11:06:53 +0000677 struct bt_sock_list *sk_list,
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900678 int (* seq_show)(struct seq_file *, void *))
679{
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900680 sk_list->custom_seq_show = seq_show;
681
Al Viro4d006262013-04-04 19:16:06 -0400682 if (!proc_create_data(name, 0, net->proc_net, &bt_fops, sk_list))
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900683 return -ENOMEM;
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900684 return 0;
685}
686
687void bt_procfs_cleanup(struct net *net, const char *name)
688{
Gao fengece31ff2013-02-18 01:34:56 +0000689 remove_proc_entry(name, net->proc_net);
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900690}
691#else
Al Virob0316612013-04-04 19:14:33 -0400692int bt_procfs_init(struct net *net, const char *name,
Prasanna Karthikf37590b2015-11-17 11:06:53 +0000693 struct bt_sock_list *sk_list,
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900694 int (* seq_show)(struct seq_file *, void *))
695{
696 return 0;
697}
698
699void bt_procfs_cleanup(struct net *net, const char *name)
700{
701}
702#endif
703EXPORT_SYMBOL(bt_procfs_init);
704EXPORT_SYMBOL(bt_procfs_cleanup);
705
Linus Torvalds1da177e2005-04-16 15:20:36 -0700706static struct net_proto_family bt_sock_family_ops = {
707 .owner = THIS_MODULE,
708 .family = PF_BLUETOOTH,
709 .create = bt_sock_create,
710};
711
Marcel Holtmannffcecac2013-10-17 17:24:18 -0700712struct dentry *bt_debugfs;
713EXPORT_SYMBOL_GPL(bt_debugfs);
714
Linus Torvalds1da177e2005-04-16 15:20:36 -0700715static int __init bt_init(void)
716{
Marcel Holtmann27d35282006-07-03 10:02:37 +0200717 int err;
718
Eyal Birgerb4772ef2015-03-01 14:58:29 +0200719 sock_skb_cb_check_size(sizeof(struct bt_skb_cb));
Marcel Holtmann7cb9d202014-09-14 22:50:46 +0200720
Marcel Holtmanndd315062015-11-08 07:47:12 +0100721 BT_INFO("Core ver %s", BT_SUBSYS_VERSION);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700722
Marcel Holtmannee485292014-12-29 20:48:35 -0800723 err = bt_selftest();
724 if (err < 0)
725 return err;
726
Marcel Holtmannffcecac2013-10-17 17:24:18 -0700727 bt_debugfs = debugfs_create_dir("bluetooth", NULL);
728
Marcel Holtmann27d35282006-07-03 10:02:37 +0200729 err = bt_sysfs_init();
730 if (err < 0)
731 return err;
732
733 err = sock_register(&bt_sock_family_ops);
734 if (err < 0) {
735 bt_sysfs_cleanup();
736 return err;
737 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700738
739 BT_INFO("HCI device and connection manager initialized");
740
Gustavo F. Padovan64274512011-02-07 20:08:52 -0200741 err = hci_sock_init();
742 if (err < 0)
743 goto error;
744
745 err = l2cap_init();
Anand Gadiyar0ed54da2011-02-22 12:43:26 +0530746 if (err < 0)
Gustavo F. Padovan64274512011-02-07 20:08:52 -0200747 goto sock_err;
Gustavo F. Padovan64274512011-02-07 20:08:52 -0200748
749 err = sco_init();
750 if (err < 0) {
751 l2cap_exit();
752 goto sock_err;
753 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700754
Johan Hedberg6d785aa32015-03-06 21:08:51 +0200755 err = mgmt_init();
756 if (err < 0) {
757 sco_exit();
758 l2cap_exit();
759 goto sock_err;
760 }
761
Linus Torvalds1da177e2005-04-16 15:20:36 -0700762 return 0;
Gustavo F. Padovan64274512011-02-07 20:08:52 -0200763
764sock_err:
765 hci_sock_cleanup();
766
767error:
768 sock_unregister(PF_BLUETOOTH);
769 bt_sysfs_cleanup();
770
771 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700772}
773
774static void __exit bt_exit(void)
775{
Johan Hedberg6d785aa32015-03-06 21:08:51 +0200776 mgmt_exit();
777
Gustavo F. Padovan64274512011-02-07 20:08:52 -0200778 sco_exit();
779
780 l2cap_exit();
781
Linus Torvalds1da177e2005-04-16 15:20:36 -0700782 hci_sock_cleanup();
783
Linus Torvalds1da177e2005-04-16 15:20:36 -0700784 sock_unregister(PF_BLUETOOTH);
Marcel Holtmann27d35282006-07-03 10:02:37 +0200785
786 bt_sysfs_cleanup();
Marcel Holtmannffcecac2013-10-17 17:24:18 -0700787
788 debugfs_remove_recursive(bt_debugfs);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700789}
790
791subsys_initcall(bt_init);
792module_exit(bt_exit);
793
Marcel Holtmann63fbd242008-08-18 13:23:53 +0200794MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
Marcel Holtmanndd315062015-11-08 07:47:12 +0100795MODULE_DESCRIPTION("Bluetooth Core ver " BT_SUBSYS_VERSION);
796MODULE_VERSION(BT_SUBSYS_VERSION);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700797MODULE_LICENSE("GPL");
798MODULE_ALIAS_NETPROTO(PF_BLUETOOTH);