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/config.h>
28 #include <linux/module.h>
30 #include <linux/types.h>
31 #include <linux/list.h>
32 #include <linux/errno.h>
33 #include <linux/kernel.h>
34 #include <linux/sched.h>
35 #include <linux/slab.h>
36 #include <linux/skbuff.h>
37 #include <linux/init.h>
38 #include <linux/poll.h>
39 #include <linux/proc_fs.h>
42 #if defined(CONFIG_KMOD)
43 #include <linux/kmod.h>
46 #include <net/bluetooth/bluetooth.h>
48 #ifndef CONFIG_BT_SOCK_DEBUG
55 struct proc_dir_entry *proc_bt;
56 EXPORT_SYMBOL(proc_bt);
58 /* Bluetooth sockets */
59 #define BT_MAX_PROTO 8
60 static struct net_proto_family *bt_proto[BT_MAX_PROTO];
62 int bt_sock_register(int proto, struct net_proto_family *ops)
64 if (proto < 0 || proto >= BT_MAX_PROTO)
70 bt_proto[proto] = ops;
73 EXPORT_SYMBOL(bt_sock_register);
75 int bt_sock_unregister(int proto)
77 if (proto < 0 || proto >= BT_MAX_PROTO)
83 bt_proto[proto] = NULL;
86 EXPORT_SYMBOL(bt_sock_unregister);
88 static int bt_sock_create(struct socket *sock, int proto)
92 if (proto < 0 || proto >= BT_MAX_PROTO)
95 #if defined(CONFIG_KMOD)
96 if (!bt_proto[proto]) {
97 request_module("bt-proto-%d", proto);
100 err = -EPROTONOSUPPORT;
101 if (bt_proto[proto] && try_module_get(bt_proto[proto]->owner)) {
102 err = bt_proto[proto]->create(sock, proto);
103 module_put(bt_proto[proto]->owner);
108 void bt_sock_link(struct bt_sock_list *l, struct sock *sk)
110 write_lock_bh(&l->lock);
111 sk_add_node(sk, &l->head);
112 write_unlock_bh(&l->lock);
114 EXPORT_SYMBOL(bt_sock_link);
116 void bt_sock_unlink(struct bt_sock_list *l, struct sock *sk)
118 write_lock_bh(&l->lock);
119 sk_del_node_init(sk);
120 write_unlock_bh(&l->lock);
122 EXPORT_SYMBOL(bt_sock_unlink);
124 void bt_accept_enqueue(struct sock *parent, struct sock *sk)
126 BT_DBG("parent %p, sk %p", parent, sk);
129 list_add_tail(&bt_sk(sk)->accept_q, &bt_sk(parent)->accept_q);
130 bt_sk(sk)->parent = parent;
131 parent->sk_ack_backlog++;
133 EXPORT_SYMBOL(bt_accept_enqueue);
135 void bt_accept_unlink(struct sock *sk)
137 BT_DBG("sk %p state %d", sk, sk->sk_state);
139 list_del_init(&bt_sk(sk)->accept_q);
140 bt_sk(sk)->parent->sk_ack_backlog--;
141 bt_sk(sk)->parent = NULL;
144 EXPORT_SYMBOL(bt_accept_unlink);
146 struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock)
148 struct list_head *p, *n;
151 BT_DBG("parent %p", parent);
153 list_for_each_safe(p, n, &bt_sk(parent)->accept_q) {
154 sk = (struct sock *) list_entry(p, struct bt_sock, accept_q);
158 /* FIXME: Is this check still needed */
159 if (sk->sk_state == BT_CLOSED) {
161 bt_accept_unlink(sk);
165 if (sk->sk_state == BT_CONNECTED || !newsock) {
166 bt_accept_unlink(sk);
168 sock_graft(sk, newsock);
177 EXPORT_SYMBOL(bt_accept_dequeue);
179 int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
180 struct msghdr *msg, size_t len, int flags)
182 int noblock = flags & MSG_DONTWAIT;
183 struct sock *sk = sock->sk;
188 BT_DBG("sock %p sk %p len %d", sock, sk, len);
190 if (flags & (MSG_OOB))
193 if (!(skb = skb_recv_datagram(sk, flags, noblock, &err))) {
194 if (sk->sk_shutdown & RCV_SHUTDOWN)
199 msg->msg_namelen = 0;
203 msg->msg_flags |= MSG_TRUNC;
207 skb->h.raw = skb->data;
208 err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
210 skb_free_datagram(sk, skb);
212 return err ? : copied;
214 EXPORT_SYMBOL(bt_sock_recvmsg);
216 static inline unsigned int bt_accept_poll(struct sock *parent)
218 struct list_head *p, *n;
221 list_for_each_safe(p, n, &bt_sk(parent)->accept_q) {
222 sk = (struct sock *) list_entry(p, struct bt_sock, accept_q);
223 if (sk->sk_state == BT_CONNECTED)
224 return POLLIN | POLLRDNORM;
230 unsigned int bt_sock_poll(struct file * file, struct socket *sock, poll_table *wait)
232 struct sock *sk = sock->sk;
233 unsigned int mask = 0;
235 BT_DBG("sock %p, sk %p", sock, sk);
237 poll_wait(file, sk->sk_sleep, wait);
239 if (sk->sk_state == BT_LISTEN)
240 return bt_accept_poll(sk);
242 if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue))
245 if (sk->sk_shutdown == SHUTDOWN_MASK)
248 if (!skb_queue_empty(&sk->sk_receive_queue) ||
249 (sk->sk_shutdown & RCV_SHUTDOWN))
250 mask |= POLLIN | POLLRDNORM;
252 if (sk->sk_state == BT_CLOSED)
255 if (sk->sk_state == BT_CONNECT ||
256 sk->sk_state == BT_CONNECT2 ||
257 sk->sk_state == BT_CONFIG)
260 if (sock_writeable(sk))
261 mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
263 set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
267 EXPORT_SYMBOL(bt_sock_poll);
269 int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo)
271 DECLARE_WAITQUEUE(wait, current);
276 add_wait_queue(sk->sk_sleep, &wait);
277 while (sk->sk_state != state) {
278 set_current_state(TASK_INTERRUPTIBLE);
285 if (signal_pending(current)) {
286 err = sock_intr_errno(timeo);
291 timeo = schedule_timeout(timeo);
295 err = sock_error(sk);
299 set_current_state(TASK_RUNNING);
300 remove_wait_queue(sk->sk_sleep, &wait);
303 EXPORT_SYMBOL(bt_sock_wait_state);
305 static struct net_proto_family bt_sock_family_ops = {
306 .owner = THIS_MODULE,
307 .family = PF_BLUETOOTH,
308 .create = bt_sock_create,
311 extern int hci_sock_init(void);
312 extern int hci_sock_cleanup(void);
314 extern int bt_sysfs_init(void);
315 extern int bt_sysfs_cleanup(void);
317 static int __init bt_init(void)
319 BT_INFO("Core ver %s", VERSION);
321 proc_bt = proc_mkdir("bluetooth", NULL);
323 proc_bt->owner = THIS_MODULE;
325 sock_register(&bt_sock_family_ops);
327 BT_INFO("HCI device and connection manager initialized");
336 static void __exit bt_exit(void)
342 sock_unregister(PF_BLUETOOTH);
344 remove_proc_entry("bluetooth", NULL);
347 subsys_initcall(bt_init);
348 module_exit(bt_exit);
350 MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>, Marcel Holtmann <marcel@holtmann.org>");
351 MODULE_DESCRIPTION("Bluetooth Core ver " VERSION);
352 MODULE_VERSION(VERSION);
353 MODULE_LICENSE("GPL");
354 MODULE_ALIAS_NETPROTO(PF_BLUETOOTH);