• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/net/bluetooth/
1/*
2   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
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.
19
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.
23*/
24
25/* Bluetooth address family and sockets. */
26
27#include <linux/module.h>
28
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/skbuff.h>
35#include <linux/init.h>
36#include <linux/poll.h>
37#include <net/sock.h>
38#include <asm/ioctls.h>
39#include <linux/kmod.h>
40
41#include <net/bluetooth/bluetooth.h>
42
43#define VERSION "2.15"
44
45/* Bluetooth sockets */
46#define BT_MAX_PROTO	8
47static const struct net_proto_family *bt_proto[BT_MAX_PROTO];
48static DEFINE_RWLOCK(bt_proto_lock);
49
50static struct lock_class_key bt_lock_key[BT_MAX_PROTO];
51static const char *const bt_key_strings[BT_MAX_PROTO] = {
52	"sk_lock-AF_BLUETOOTH-BTPROTO_L2CAP",
53	"sk_lock-AF_BLUETOOTH-BTPROTO_HCI",
54	"sk_lock-AF_BLUETOOTH-BTPROTO_SCO",
55	"sk_lock-AF_BLUETOOTH-BTPROTO_RFCOMM",
56	"sk_lock-AF_BLUETOOTH-BTPROTO_BNEP",
57	"sk_lock-AF_BLUETOOTH-BTPROTO_CMTP",
58	"sk_lock-AF_BLUETOOTH-BTPROTO_HIDP",
59	"sk_lock-AF_BLUETOOTH-BTPROTO_AVDTP",
60};
61
62static struct lock_class_key bt_slock_key[BT_MAX_PROTO];
63static const char *const bt_slock_key_strings[BT_MAX_PROTO] = {
64	"slock-AF_BLUETOOTH-BTPROTO_L2CAP",
65	"slock-AF_BLUETOOTH-BTPROTO_HCI",
66	"slock-AF_BLUETOOTH-BTPROTO_SCO",
67	"slock-AF_BLUETOOTH-BTPROTO_RFCOMM",
68	"slock-AF_BLUETOOTH-BTPROTO_BNEP",
69	"slock-AF_BLUETOOTH-BTPROTO_CMTP",
70	"slock-AF_BLUETOOTH-BTPROTO_HIDP",
71	"slock-AF_BLUETOOTH-BTPROTO_AVDTP",
72};
73
74static inline void bt_sock_reclassify_lock(struct socket *sock, int proto)
75{
76	struct sock *sk = sock->sk;
77
78	if (!sk)
79		return;
80
81	BUG_ON(sock_owned_by_user(sk));
82
83	sock_lock_init_class_and_name(sk,
84			bt_slock_key_strings[proto], &bt_slock_key[proto],
85				bt_key_strings[proto], &bt_lock_key[proto]);
86}
87
88int bt_sock_register(int proto, const struct net_proto_family *ops)
89{
90	int err = 0;
91
92	if (proto < 0 || proto >= BT_MAX_PROTO)
93		return -EINVAL;
94
95	write_lock(&bt_proto_lock);
96
97	if (bt_proto[proto])
98		err = -EEXIST;
99	else
100		bt_proto[proto] = ops;
101
102	write_unlock(&bt_proto_lock);
103
104	return err;
105}
106EXPORT_SYMBOL(bt_sock_register);
107
108int bt_sock_unregister(int proto)
109{
110	int err = 0;
111
112	if (proto < 0 || proto >= BT_MAX_PROTO)
113		return -EINVAL;
114
115	write_lock(&bt_proto_lock);
116
117	if (!bt_proto[proto])
118		err = -ENOENT;
119	else
120		bt_proto[proto] = NULL;
121
122	write_unlock(&bt_proto_lock);
123
124	return err;
125}
126EXPORT_SYMBOL(bt_sock_unregister);
127
128static int bt_sock_create(struct net *net, struct socket *sock, int proto,
129			  int kern)
130{
131	int err;
132
133	if (net != &init_net)
134		return -EAFNOSUPPORT;
135
136	if (proto < 0 || proto >= BT_MAX_PROTO)
137		return -EINVAL;
138
139	if (!bt_proto[proto])
140		request_module("bt-proto-%d", proto);
141
142	err = -EPROTONOSUPPORT;
143
144	read_lock(&bt_proto_lock);
145
146	if (bt_proto[proto] && try_module_get(bt_proto[proto]->owner)) {
147		err = bt_proto[proto]->create(net, sock, proto, kern);
148		bt_sock_reclassify_lock(sock, proto);
149		module_put(bt_proto[proto]->owner);
150	}
151
152	read_unlock(&bt_proto_lock);
153
154	return err;
155}
156
157void bt_sock_link(struct bt_sock_list *l, struct sock *sk)
158{
159	write_lock_bh(&l->lock);
160	sk_add_node(sk, &l->head);
161	write_unlock_bh(&l->lock);
162}
163EXPORT_SYMBOL(bt_sock_link);
164
165void bt_sock_unlink(struct bt_sock_list *l, struct sock *sk)
166{
167	write_lock_bh(&l->lock);
168	sk_del_node_init(sk);
169	write_unlock_bh(&l->lock);
170}
171EXPORT_SYMBOL(bt_sock_unlink);
172
173void bt_accept_enqueue(struct sock *parent, struct sock *sk)
174{
175	BT_DBG("parent %p, sk %p", parent, sk);
176
177	sock_hold(sk);
178	list_add_tail(&bt_sk(sk)->accept_q, &bt_sk(parent)->accept_q);
179	bt_sk(sk)->parent = parent;
180	parent->sk_ack_backlog++;
181}
182EXPORT_SYMBOL(bt_accept_enqueue);
183
184void bt_accept_unlink(struct sock *sk)
185{
186	BT_DBG("sk %p state %d", sk, sk->sk_state);
187
188	list_del_init(&bt_sk(sk)->accept_q);
189	bt_sk(sk)->parent->sk_ack_backlog--;
190	bt_sk(sk)->parent = NULL;
191	sock_put(sk);
192}
193EXPORT_SYMBOL(bt_accept_unlink);
194
195struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock)
196{
197	struct list_head *p, *n;
198	struct sock *sk;
199
200	BT_DBG("parent %p", parent);
201
202	list_for_each_safe(p, n, &bt_sk(parent)->accept_q) {
203		sk = (struct sock *) list_entry(p, struct bt_sock, accept_q);
204
205		lock_sock(sk);
206
207		if (sk->sk_state == BT_CLOSED) {
208			release_sock(sk);
209			bt_accept_unlink(sk);
210			continue;
211		}
212
213		if (sk->sk_state == BT_CONNECTED || !newsock ||
214						bt_sk(parent)->defer_setup) {
215			bt_accept_unlink(sk);
216			if (newsock)
217				sock_graft(sk, newsock);
218			release_sock(sk);
219			return sk;
220		}
221
222		release_sock(sk);
223	}
224	return NULL;
225}
226EXPORT_SYMBOL(bt_accept_dequeue);
227
228int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
229				struct msghdr *msg, size_t len, int flags)
230{
231	int noblock = flags & MSG_DONTWAIT;
232	struct sock *sk = sock->sk;
233	struct sk_buff *skb;
234	size_t copied;
235	int err;
236
237	BT_DBG("sock %p sk %p len %zu", sock, sk, len);
238
239	if (flags & (MSG_OOB))
240		return -EOPNOTSUPP;
241
242	if (!(skb = skb_recv_datagram(sk, flags, noblock, &err))) {
243		if (sk->sk_shutdown & RCV_SHUTDOWN)
244			return 0;
245		return err;
246	}
247
248	msg->msg_namelen = 0;
249
250	copied = skb->len;
251	if (len < copied) {
252		msg->msg_flags |= MSG_TRUNC;
253		copied = len;
254	}
255
256	skb_reset_transport_header(skb);
257	err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
258	if (err == 0)
259		sock_recv_ts_and_drops(msg, sk, skb);
260
261	skb_free_datagram(sk, skb);
262
263	return err ? : copied;
264}
265EXPORT_SYMBOL(bt_sock_recvmsg);
266
267static inline unsigned int bt_accept_poll(struct sock *parent)
268{
269	struct list_head *p, *n;
270	struct sock *sk;
271
272	list_for_each_safe(p, n, &bt_sk(parent)->accept_q) {
273		sk = (struct sock *) list_entry(p, struct bt_sock, accept_q);
274		if (sk->sk_state == BT_CONNECTED ||
275					(bt_sk(parent)->defer_setup &&
276						sk->sk_state == BT_CONNECT2))
277			return POLLIN | POLLRDNORM;
278	}
279
280	return 0;
281}
282
283unsigned int bt_sock_poll(struct file * file, struct socket *sock, poll_table *wait)
284{
285	struct sock *sk = sock->sk;
286	unsigned int mask = 0;
287
288	BT_DBG("sock %p, sk %p", sock, sk);
289
290	poll_wait(file, sk_sleep(sk), wait);
291
292	if (sk->sk_state == BT_LISTEN)
293		return bt_accept_poll(sk);
294
295	if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue))
296		mask |= POLLERR;
297
298	if (sk->sk_shutdown & RCV_SHUTDOWN)
299		mask |= POLLRDHUP;
300
301	if (sk->sk_shutdown == SHUTDOWN_MASK)
302		mask |= POLLHUP;
303
304	if (!skb_queue_empty(&sk->sk_receive_queue) ||
305			(sk->sk_shutdown & RCV_SHUTDOWN))
306		mask |= POLLIN | POLLRDNORM;
307
308	if (sk->sk_state == BT_CLOSED)
309		mask |= POLLHUP;
310
311	if (sk->sk_state == BT_CONNECT ||
312			sk->sk_state == BT_CONNECT2 ||
313			sk->sk_state == BT_CONFIG)
314		return mask;
315
316	if (sock_writeable(sk))
317		mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
318	else
319		set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
320
321	return mask;
322}
323EXPORT_SYMBOL(bt_sock_poll);
324
325int bt_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
326{
327	struct sock *sk = sock->sk;
328	struct sk_buff *skb;
329	long amount;
330	int err;
331
332	BT_DBG("sk %p cmd %x arg %lx", sk, cmd, arg);
333
334	switch (cmd) {
335	case TIOCOUTQ:
336		if (sk->sk_state == BT_LISTEN)
337			return -EINVAL;
338
339		amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk);
340		if (amount < 0)
341			amount = 0;
342		err = put_user(amount, (int __user *) arg);
343		break;
344
345	case TIOCINQ:
346		if (sk->sk_state == BT_LISTEN)
347			return -EINVAL;
348
349		lock_sock(sk);
350		skb = skb_peek(&sk->sk_receive_queue);
351		amount = skb ? skb->len : 0;
352		release_sock(sk);
353		err = put_user(amount, (int __user *) arg);
354		break;
355
356	case SIOCGSTAMP:
357		err = sock_get_timestamp(sk, (struct timeval __user *) arg);
358		break;
359
360	case SIOCGSTAMPNS:
361		err = sock_get_timestampns(sk, (struct timespec __user *) arg);
362		break;
363
364	default:
365		err = -ENOIOCTLCMD;
366		break;
367	}
368
369	return err;
370}
371EXPORT_SYMBOL(bt_sock_ioctl);
372
373int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo)
374{
375	DECLARE_WAITQUEUE(wait, current);
376	int err = 0;
377
378	BT_DBG("sk %p", sk);
379
380	add_wait_queue(sk_sleep(sk), &wait);
381	while (sk->sk_state != state) {
382		set_current_state(TASK_INTERRUPTIBLE);
383
384		if (!timeo) {
385			err = -EINPROGRESS;
386			break;
387		}
388
389		if (signal_pending(current)) {
390			err = sock_intr_errno(timeo);
391			break;
392		}
393
394		release_sock(sk);
395		timeo = schedule_timeout(timeo);
396		lock_sock(sk);
397
398		err = sock_error(sk);
399		if (err)
400			break;
401	}
402	set_current_state(TASK_RUNNING);
403	remove_wait_queue(sk_sleep(sk), &wait);
404	return err;
405}
406EXPORT_SYMBOL(bt_sock_wait_state);
407
408static struct net_proto_family bt_sock_family_ops = {
409	.owner	= THIS_MODULE,
410	.family	= PF_BLUETOOTH,
411	.create	= bt_sock_create,
412};
413
414static int __init bt_init(void)
415{
416	int err;
417
418	BT_INFO("Core ver %s", VERSION);
419
420	err = bt_sysfs_init();
421	if (err < 0)
422		return err;
423
424	err = sock_register(&bt_sock_family_ops);
425	if (err < 0) {
426		bt_sysfs_cleanup();
427		return err;
428	}
429
430	BT_INFO("HCI device and connection manager initialized");
431
432	hci_sock_init();
433
434	return 0;
435}
436
437static void __exit bt_exit(void)
438{
439	hci_sock_cleanup();
440
441	sock_unregister(PF_BLUETOOTH);
442
443	bt_sysfs_cleanup();
444}
445
446subsys_initcall(bt_init);
447module_exit(bt_exit);
448
449MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
450MODULE_DESCRIPTION("Bluetooth Core ver " VERSION);
451MODULE_VERSION(VERSION);
452MODULE_LICENSE("GPL");
453MODULE_ALIAS_NETPROTO(PF_BLUETOOTH);
454