diff options
author | Marcel Holtmann <marcel@holtmann.org> | 2008-07-14 14:13:50 -0400 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2008-07-14 14:13:50 -0400 |
commit | 3241ad820dbb172021e0268b5611031991431626 (patch) | |
tree | 628c3fbdc88f9de6c996358ebcb551176da38f1f | |
parent | 40be492fe4fab829951681860c2bb26fa1d5fe4a (diff) |
[Bluetooth] Add timestamp support to L2CAP, RFCOMM and SCO
Enable the common timestamp functionality that the network subsystem
provides for L2CAP, RFCOMM and SCO sockets. It is possible to either
use SO_TIMESTAMP or the IOCTLs to retrieve the timestamp of the
current packet.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
-rw-r--r-- | include/net/bluetooth/bluetooth.h | 1 | ||||
-rw-r--r-- | net/bluetooth/af_bluetooth.c | 28 | ||||
-rw-r--r-- | net/bluetooth/l2cap.c | 2 | ||||
-rw-r--r-- | net/bluetooth/rfcomm/sock.c | 15 | ||||
-rw-r--r-- | net/bluetooth/sco.c | 2 |
5 files changed, 42 insertions, 6 deletions
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h index 750648df13f4..6f8418bf4241 100644 --- a/include/net/bluetooth/bluetooth.h +++ b/include/net/bluetooth/bluetooth.h | |||
@@ -121,6 +121,7 @@ void bt_sock_link(struct bt_sock_list *l, struct sock *s); | |||
121 | void bt_sock_unlink(struct bt_sock_list *l, struct sock *s); | 121 | void bt_sock_unlink(struct bt_sock_list *l, struct sock *s); |
122 | int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags); | 122 | int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags); |
123 | uint bt_sock_poll(struct file * file, struct socket *sock, poll_table *wait); | 123 | uint bt_sock_poll(struct file * file, struct socket *sock, poll_table *wait); |
124 | int bt_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg); | ||
124 | int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo); | 125 | int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo); |
125 | 126 | ||
126 | void bt_accept_enqueue(struct sock *parent, struct sock *sk); | 127 | void bt_accept_enqueue(struct sock *parent, struct sock *sk); |
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index d366423c8392..88afe25003d8 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/init.h> | 36 | #include <linux/init.h> |
37 | #include <linux/poll.h> | 37 | #include <linux/poll.h> |
38 | #include <net/sock.h> | 38 | #include <net/sock.h> |
39 | #include <asm/ioctls.h> | ||
39 | 40 | ||
40 | #if defined(CONFIG_KMOD) | 41 | #if defined(CONFIG_KMOD) |
41 | #include <linux/kmod.h> | 42 | #include <linux/kmod.h> |
@@ -266,6 +267,8 @@ int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
266 | 267 | ||
267 | skb_reset_transport_header(skb); | 268 | skb_reset_transport_header(skb); |
268 | err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied); | 269 | err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied); |
270 | if (err == 0) | ||
271 | sock_recv_timestamp(msg, sk, skb); | ||
269 | 272 | ||
270 | skb_free_datagram(sk, skb); | 273 | skb_free_datagram(sk, skb); |
271 | 274 | ||
@@ -329,6 +332,31 @@ unsigned int bt_sock_poll(struct file * file, struct socket *sock, poll_table *w | |||
329 | } | 332 | } |
330 | EXPORT_SYMBOL(bt_sock_poll); | 333 | EXPORT_SYMBOL(bt_sock_poll); |
331 | 334 | ||
335 | int bt_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | ||
336 | { | ||
337 | struct sock *sk = sock->sk; | ||
338 | int err; | ||
339 | |||
340 | BT_DBG("sk %p cmd %x arg %lx", sk, cmd, arg); | ||
341 | |||
342 | switch (cmd) { | ||
343 | case SIOCGSTAMP: | ||
344 | err = sock_get_timestamp(sk, (struct timeval __user *) arg); | ||
345 | break; | ||
346 | |||
347 | case SIOCGSTAMPNS: | ||
348 | err = sock_get_timestampns(sk, (struct timespec __user *) arg); | ||
349 | break; | ||
350 | |||
351 | default: | ||
352 | err = -ENOIOCTLCMD; | ||
353 | break; | ||
354 | } | ||
355 | |||
356 | return err; | ||
357 | } | ||
358 | EXPORT_SYMBOL(bt_sock_ioctl); | ||
359 | |||
332 | int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo) | 360 | int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo) |
333 | { | 361 | { |
334 | DECLARE_WAITQUEUE(wait, current); | 362 | DECLARE_WAITQUEUE(wait, current); |
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index 30ad59b717d5..4fcf24af7590 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c | |||
@@ -2388,9 +2388,9 @@ static const struct proto_ops l2cap_sock_ops = { | |||
2388 | .sendmsg = l2cap_sock_sendmsg, | 2388 | .sendmsg = l2cap_sock_sendmsg, |
2389 | .recvmsg = bt_sock_recvmsg, | 2389 | .recvmsg = bt_sock_recvmsg, |
2390 | .poll = bt_sock_poll, | 2390 | .poll = bt_sock_poll, |
2391 | .ioctl = bt_sock_ioctl, | ||
2391 | .mmap = sock_no_mmap, | 2392 | .mmap = sock_no_mmap, |
2392 | .socketpair = sock_no_socketpair, | 2393 | .socketpair = sock_no_socketpair, |
2393 | .ioctl = sock_no_ioctl, | ||
2394 | .shutdown = l2cap_sock_shutdown, | 2394 | .shutdown = l2cap_sock_shutdown, |
2395 | .setsockopt = l2cap_sock_setsockopt, | 2395 | .setsockopt = l2cap_sock_setsockopt, |
2396 | .getsockopt = l2cap_sock_getsockopt | 2396 | .getsockopt = l2cap_sock_getsockopt |
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index cacb1ab51f99..c3ed076481d8 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c | |||
@@ -690,6 +690,8 @@ static int rfcomm_sock_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
690 | copied += chunk; | 690 | copied += chunk; |
691 | size -= chunk; | 691 | size -= chunk; |
692 | 692 | ||
693 | sock_recv_timestamp(msg, sk, skb); | ||
694 | |||
693 | if (!(flags & MSG_PEEK)) { | 695 | if (!(flags & MSG_PEEK)) { |
694 | atomic_sub(chunk, &sk->sk_rmem_alloc); | 696 | atomic_sub(chunk, &sk->sk_rmem_alloc); |
695 | 697 | ||
@@ -795,15 +797,20 @@ static int rfcomm_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned lon | |||
795 | struct sock *sk = sock->sk; | 797 | struct sock *sk = sock->sk; |
796 | int err; | 798 | int err; |
797 | 799 | ||
798 | lock_sock(sk); | 800 | BT_DBG("sk %p cmd %x arg %lx", sk, cmd, arg); |
799 | 801 | ||
802 | err = bt_sock_ioctl(sock, cmd, arg); | ||
803 | |||
804 | if (err == -ENOIOCTLCMD) { | ||
800 | #ifdef CONFIG_BT_RFCOMM_TTY | 805 | #ifdef CONFIG_BT_RFCOMM_TTY |
801 | err = rfcomm_dev_ioctl(sk, cmd, (void __user *)arg); | 806 | lock_sock(sk); |
807 | err = rfcomm_dev_ioctl(sk, cmd, (void __user *) arg); | ||
808 | release_sock(sk); | ||
802 | #else | 809 | #else |
803 | err = -EOPNOTSUPP; | 810 | err = -EOPNOTSUPP; |
804 | #endif | 811 | #endif |
812 | } | ||
805 | 813 | ||
806 | release_sock(sk); | ||
807 | return err; | 814 | return err; |
808 | } | 815 | } |
809 | 816 | ||
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index b0d487e2db20..1ad226c9788c 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c | |||
@@ -921,7 +921,7 @@ static const struct proto_ops sco_sock_ops = { | |||
921 | .sendmsg = sco_sock_sendmsg, | 921 | .sendmsg = sco_sock_sendmsg, |
922 | .recvmsg = bt_sock_recvmsg, | 922 | .recvmsg = bt_sock_recvmsg, |
923 | .poll = bt_sock_poll, | 923 | .poll = bt_sock_poll, |
924 | .ioctl = sock_no_ioctl, | 924 | .ioctl = bt_sock_ioctl, |
925 | .mmap = sock_no_mmap, | 925 | .mmap = sock_no_mmap, |
926 | .socketpair = sock_no_socketpair, | 926 | .socketpair = sock_no_socketpair, |
927 | .shutdown = sock_no_shutdown, | 927 | .shutdown = sock_no_shutdown, |