[TCP]: Add Scalable TCP congestion control module.
[linux-2.6/verdex.git] / net / bluetooth / af_bluetooth.c
blob12b43345b54ff3fa21d3a76433e96433086997e9
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/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>
40 #include <net/sock.h>
42 #if defined(CONFIG_KMOD)
43 #include <linux/kmod.h>
44 #endif
46 #include <net/bluetooth/bluetooth.h>
48 #ifndef CONFIG_BT_SOCK_DEBUG
49 #undef BT_DBG
50 #define BT_DBG(D...)
51 #endif
53 #define VERSION "2.7"
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)
65 return -EINVAL;
67 if (bt_proto[proto])
68 return -EEXIST;
70 bt_proto[proto] = ops;
71 return 0;
73 EXPORT_SYMBOL(bt_sock_register);
75 int bt_sock_unregister(int proto)
77 if (proto < 0 || proto >= BT_MAX_PROTO)
78 return -EINVAL;
80 if (!bt_proto[proto])
81 return -ENOENT;
83 bt_proto[proto] = NULL;
84 return 0;
86 EXPORT_SYMBOL(bt_sock_unregister);
88 static int bt_sock_create(struct socket *sock, int proto)
90 int err = 0;
92 if (proto < 0 || proto >= BT_MAX_PROTO)
93 return -EINVAL;
95 #if defined(CONFIG_KMOD)
96 if (!bt_proto[proto]) {
97 request_module("bt-proto-%d", proto);
99 #endif
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);
105 return err;
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);
128 sock_hold(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;
142 sock_put(sk);
144 EXPORT_SYMBOL(bt_accept_unlink);
146 struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock)
148 struct list_head *p, *n;
149 struct sock *sk;
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);
156 lock_sock(sk);
158 /* FIXME: Is this check still needed */
159 if (sk->sk_state == BT_CLOSED) {
160 release_sock(sk);
161 bt_accept_unlink(sk);
162 continue;
165 if (sk->sk_state == BT_CONNECTED || !newsock) {
166 bt_accept_unlink(sk);
167 if (newsock)
168 sock_graft(sk, newsock);
169 release_sock(sk);
170 return sk;
173 release_sock(sk);
175 return NULL;
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;
184 struct sk_buff *skb;
185 size_t copied;
186 int err;
188 BT_DBG("sock %p sk %p len %d", sock, sk, len);
190 if (flags & (MSG_OOB))
191 return -EOPNOTSUPP;
193 if (!(skb = skb_recv_datagram(sk, flags, noblock, &err))) {
194 if (sk->sk_shutdown & RCV_SHUTDOWN)
195 return 0;
196 return err;
199 msg->msg_namelen = 0;
201 copied = skb->len;
202 if (len < copied) {
203 msg->msg_flags |= MSG_TRUNC;
204 copied = len;
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;
219 struct sock *sk;
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;
227 return 0;
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))
243 mask |= POLLERR;
245 if (sk->sk_shutdown == SHUTDOWN_MASK)
246 mask |= POLLHUP;
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)
253 mask |= POLLHUP;
255 if (sk->sk_state == BT_CONNECT ||
256 sk->sk_state == BT_CONNECT2 ||
257 sk->sk_state == BT_CONFIG)
258 return mask;
260 if (sock_writeable(sk))
261 mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
262 else
263 set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
265 return mask;
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);
272 int err = 0;
274 BT_DBG("sk %p", sk);
276 add_wait_queue(sk->sk_sleep, &wait);
277 while (sk->sk_state != state) {
278 set_current_state(TASK_INTERRUPTIBLE);
280 if (!timeo) {
281 err = -EAGAIN;
282 break;
285 if (signal_pending(current)) {
286 err = sock_intr_errno(timeo);
287 break;
290 release_sock(sk);
291 timeo = schedule_timeout(timeo);
292 lock_sock(sk);
294 if (sk->sk_err) {
295 err = sock_error(sk);
296 break;
299 set_current_state(TASK_RUNNING);
300 remove_wait_queue(sk->sk_sleep, &wait);
301 return err;
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);
322 if (proc_bt)
323 proc_bt->owner = THIS_MODULE;
325 sock_register(&bt_sock_family_ops);
327 BT_INFO("HCI device and connection manager initialized");
329 bt_sysfs_init();
331 hci_sock_init();
333 return 0;
336 static void __exit bt_exit(void)
338 hci_sock_cleanup();
340 bt_sysfs_cleanup();
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);