Committer: Michael Beasley <mike@snafu.setup>
[mikesnafu-overlay.git] / net / bluetooth / af_bluetooth.c
blobd366423c8392473e43c8cf2248e33a626bee3eaa
1 /*
2 BlueZ - Bluetooth protocol stack for Linux
3 Copyright (C) 2000-2001 Qualcomm Incorporated
5 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
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;
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
15 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
18 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
21 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
22 SOFTWARE IS DISCLAIMED.
25 /* Bluetooth address family and sockets. */
27 #include <linux/module.h>
29 #include <linux/types.h>
30 #include <linux/list.h>
31 #include <linux/errno.h>
32 #include <linux/kernel.h>
33 #include <linux/sched.h>
34 #include <linux/slab.h>
35 #include <linux/skbuff.h>
36 #include <linux/init.h>
37 #include <linux/poll.h>
38 #include <net/sock.h>
40 #if defined(CONFIG_KMOD)
41 #include <linux/kmod.h>
42 #endif
44 #include <net/bluetooth/bluetooth.h>
46 #ifndef CONFIG_BT_SOCK_DEBUG
47 #undef BT_DBG
48 #define BT_DBG(D...)
49 #endif
51 #define VERSION "2.11"
53 /* Bluetooth sockets */
54 #define BT_MAX_PROTO 8
55 static struct net_proto_family *bt_proto[BT_MAX_PROTO];
57 static struct lock_class_key bt_slock_key[BT_MAX_PROTO];
58 static struct lock_class_key bt_lock_key[BT_MAX_PROTO];
59 static const char *bt_key_strings[BT_MAX_PROTO] = {
60 "sk_lock-AF_BLUETOOTH-BTPROTO_L2CAP",
61 "sk_lock-AF_BLUETOOTH-BTPROTO_HCI",
62 "sk_lock-AF_BLUETOOTH-BTPROTO_SCO",
63 "sk_lock-AF_BLUETOOTH-BTPROTO_RFCOMM",
64 "sk_lock-AF_BLUETOOTH-BTPROTO_BNEP",
65 "sk_lock-AF_BLUETOOTH-BTPROTO_CMTP",
66 "sk_lock-AF_BLUETOOTH-BTPROTO_HIDP",
67 "sk_lock-AF_BLUETOOTH-BTPROTO_AVDTP",
70 static const char *bt_slock_key_strings[BT_MAX_PROTO] = {
71 "slock-AF_BLUETOOTH-BTPROTO_L2CAP",
72 "slock-AF_BLUETOOTH-BTPROTO_HCI",
73 "slock-AF_BLUETOOTH-BTPROTO_SCO",
74 "slock-AF_BLUETOOTH-BTPROTO_RFCOMM",
75 "slock-AF_BLUETOOTH-BTPROTO_BNEP",
76 "slock-AF_BLUETOOTH-BTPROTO_CMTP",
77 "slock-AF_BLUETOOTH-BTPROTO_HIDP",
78 "slock-AF_BLUETOOTH-BTPROTO_AVDTP",
80 static DEFINE_RWLOCK(bt_proto_lock);
82 int bt_sock_register(int proto, struct net_proto_family *ops)
84 int err = 0;
86 if (proto < 0 || proto >= BT_MAX_PROTO)
87 return -EINVAL;
89 write_lock(&bt_proto_lock);
91 if (bt_proto[proto])
92 err = -EEXIST;
93 else
94 bt_proto[proto] = ops;
96 write_unlock(&bt_proto_lock);
98 return err;
100 EXPORT_SYMBOL(bt_sock_register);
102 int bt_sock_unregister(int proto)
104 int err = 0;
106 if (proto < 0 || proto >= BT_MAX_PROTO)
107 return -EINVAL;
109 write_lock(&bt_proto_lock);
111 if (!bt_proto[proto])
112 err = -ENOENT;
113 else
114 bt_proto[proto] = NULL;
116 write_unlock(&bt_proto_lock);
118 return err;
120 EXPORT_SYMBOL(bt_sock_unregister);
122 static void bt_reclassify_sock_lock(struct socket *sock, int proto)
124 struct sock *sk = sock->sk;
126 if (!sk)
127 return;
128 BUG_ON(sock_owned_by_user(sk));
130 sock_lock_init_class_and_name(sk,
131 bt_slock_key_strings[proto],
132 &bt_slock_key[proto],
133 bt_key_strings[proto],
134 &bt_lock_key[proto]);
137 static int bt_sock_create(struct net *net, struct socket *sock, int proto)
139 int err;
141 if (net != &init_net)
142 return -EAFNOSUPPORT;
144 if (proto < 0 || proto >= BT_MAX_PROTO)
145 return -EINVAL;
147 #if defined(CONFIG_KMOD)
148 if (!bt_proto[proto]) {
149 request_module("bt-proto-%d", proto);
151 #endif
153 err = -EPROTONOSUPPORT;
155 read_lock(&bt_proto_lock);
157 if (bt_proto[proto] && try_module_get(bt_proto[proto]->owner)) {
158 err = bt_proto[proto]->create(net, sock, proto);
159 bt_reclassify_sock_lock(sock, proto);
160 module_put(bt_proto[proto]->owner);
163 read_unlock(&bt_proto_lock);
165 return err;
168 void bt_sock_link(struct bt_sock_list *l, struct sock *sk)
170 write_lock_bh(&l->lock);
171 sk_add_node(sk, &l->head);
172 write_unlock_bh(&l->lock);
174 EXPORT_SYMBOL(bt_sock_link);
176 void bt_sock_unlink(struct bt_sock_list *l, struct sock *sk)
178 write_lock_bh(&l->lock);
179 sk_del_node_init(sk);
180 write_unlock_bh(&l->lock);
182 EXPORT_SYMBOL(bt_sock_unlink);
184 void bt_accept_enqueue(struct sock *parent, struct sock *sk)
186 BT_DBG("parent %p, sk %p", parent, sk);
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++;
193 EXPORT_SYMBOL(bt_accept_enqueue);
195 void bt_accept_unlink(struct sock *sk)
197 BT_DBG("sk %p state %d", sk, sk->sk_state);
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);
204 EXPORT_SYMBOL(bt_accept_unlink);
206 struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock)
208 struct list_head *p, *n;
209 struct sock *sk;
211 BT_DBG("parent %p", parent);
213 list_for_each_safe(p, n, &bt_sk(parent)->accept_q) {
214 sk = (struct sock *) list_entry(p, struct bt_sock, accept_q);
216 lock_sock(sk);
218 /* FIXME: Is this check still needed */
219 if (sk->sk_state == BT_CLOSED) {
220 release_sock(sk);
221 bt_accept_unlink(sk);
222 continue;
225 if (sk->sk_state == BT_CONNECTED || !newsock) {
226 bt_accept_unlink(sk);
227 if (newsock)
228 sock_graft(sk, newsock);
229 release_sock(sk);
230 return sk;
233 release_sock(sk);
235 return NULL;
237 EXPORT_SYMBOL(bt_accept_dequeue);
239 int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
240 struct msghdr *msg, size_t len, int flags)
242 int noblock = flags & MSG_DONTWAIT;
243 struct sock *sk = sock->sk;
244 struct sk_buff *skb;
245 size_t copied;
246 int err;
248 BT_DBG("sock %p sk %p len %d", sock, sk, len);
250 if (flags & (MSG_OOB))
251 return -EOPNOTSUPP;
253 if (!(skb = skb_recv_datagram(sk, flags, noblock, &err))) {
254 if (sk->sk_shutdown & RCV_SHUTDOWN)
255 return 0;
256 return err;
259 msg->msg_namelen = 0;
261 copied = skb->len;
262 if (len < copied) {
263 msg->msg_flags |= MSG_TRUNC;
264 copied = len;
267 skb_reset_transport_header(skb);
268 err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
270 skb_free_datagram(sk, skb);
272 return err ? : copied;
274 EXPORT_SYMBOL(bt_sock_recvmsg);
276 static inline unsigned int bt_accept_poll(struct sock *parent)
278 struct list_head *p, *n;
279 struct sock *sk;
281 list_for_each_safe(p, n, &bt_sk(parent)->accept_q) {
282 sk = (struct sock *) list_entry(p, struct bt_sock, accept_q);
283 if (sk->sk_state == BT_CONNECTED)
284 return POLLIN | POLLRDNORM;
287 return 0;
290 unsigned int bt_sock_poll(struct file * file, struct socket *sock, poll_table *wait)
292 struct sock *sk = sock->sk;
293 unsigned int mask = 0;
295 BT_DBG("sock %p, sk %p", sock, sk);
297 poll_wait(file, sk->sk_sleep, wait);
299 if (sk->sk_state == BT_LISTEN)
300 return bt_accept_poll(sk);
302 if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue))
303 mask |= POLLERR;
305 if (sk->sk_shutdown & RCV_SHUTDOWN)
306 mask |= POLLRDHUP;
308 if (sk->sk_shutdown == SHUTDOWN_MASK)
309 mask |= POLLHUP;
311 if (!skb_queue_empty(&sk->sk_receive_queue) ||
312 (sk->sk_shutdown & RCV_SHUTDOWN))
313 mask |= POLLIN | POLLRDNORM;
315 if (sk->sk_state == BT_CLOSED)
316 mask |= POLLHUP;
318 if (sk->sk_state == BT_CONNECT ||
319 sk->sk_state == BT_CONNECT2 ||
320 sk->sk_state == BT_CONFIG)
321 return mask;
323 if (sock_writeable(sk))
324 mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
325 else
326 set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
328 return mask;
330 EXPORT_SYMBOL(bt_sock_poll);
332 int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo)
334 DECLARE_WAITQUEUE(wait, current);
335 int err = 0;
337 BT_DBG("sk %p", sk);
339 add_wait_queue(sk->sk_sleep, &wait);
340 while (sk->sk_state != state) {
341 set_current_state(TASK_INTERRUPTIBLE);
343 if (!timeo) {
344 err = -EINPROGRESS;
345 break;
348 if (signal_pending(current)) {
349 err = sock_intr_errno(timeo);
350 break;
353 release_sock(sk);
354 timeo = schedule_timeout(timeo);
355 lock_sock(sk);
357 err = sock_error(sk);
358 if (err)
359 break;
361 set_current_state(TASK_RUNNING);
362 remove_wait_queue(sk->sk_sleep, &wait);
363 return err;
365 EXPORT_SYMBOL(bt_sock_wait_state);
367 static struct net_proto_family bt_sock_family_ops = {
368 .owner = THIS_MODULE,
369 .family = PF_BLUETOOTH,
370 .create = bt_sock_create,
373 static int __init bt_init(void)
375 int err;
377 BT_INFO("Core ver %s", VERSION);
379 err = bt_sysfs_init();
380 if (err < 0)
381 return err;
383 err = sock_register(&bt_sock_family_ops);
384 if (err < 0) {
385 bt_sysfs_cleanup();
386 return err;
389 BT_INFO("HCI device and connection manager initialized");
391 hci_sock_init();
393 return 0;
396 static void __exit bt_exit(void)
398 hci_sock_cleanup();
400 sock_unregister(PF_BLUETOOTH);
402 bt_sysfs_cleanup();
405 subsys_initcall(bt_init);
406 module_exit(bt_exit);
408 MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>, Marcel Holtmann <marcel@holtmann.org>");
409 MODULE_DESCRIPTION("Bluetooth Core ver " VERSION);
410 MODULE_VERSION(VERSION);
411 MODULE_LICENSE("GPL");
412 MODULE_ALIAS_NETPROTO(PF_BLUETOOTH);