[Bluetooth] Add timestamp support to L2CAP, RFCOMM and SCO
authorMarcel Holtmann <marcel@holtmann.org>
Mon, 14 Jul 2008 18:13:50 +0000 (20:13 +0200)
committerMarcel Holtmann <marcel@holtmann.org>
Mon, 14 Jul 2008 18:13:50 +0000 (20:13 +0200)
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>
include/net/bluetooth/bluetooth.h
net/bluetooth/af_bluetooth.c
net/bluetooth/l2cap.c
net/bluetooth/rfcomm/sock.c
net/bluetooth/sco.c

index 750648df13f4785cee631985648966a602daf58b..6f8418bf42417c218b112a4ae46b5b942c7863ee 100644 (file)
@@ -121,6 +121,7 @@ void bt_sock_link(struct bt_sock_list *l, struct sock *s);
 void bt_sock_unlink(struct bt_sock_list *l, struct sock *s);
 int  bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags);
 uint bt_sock_poll(struct file * file, struct socket *sock, poll_table *wait);
+int  bt_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
 int  bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo);
 
 void bt_accept_enqueue(struct sock *parent, struct sock *sk);
index d366423c8392473e43c8cf2248e33a626bee3eaa..88afe25003d89cd42d4aa0306f3a55c96166b8aa 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/init.h>
 #include <linux/poll.h>
 #include <net/sock.h>
+#include <asm/ioctls.h>
 
 #if defined(CONFIG_KMOD)
 #include <linux/kmod.h>
@@ -266,6 +267,8 @@ int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
 
        skb_reset_transport_header(skb);
        err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
+       if (err == 0)
+               sock_recv_timestamp(msg, sk, skb);
 
        skb_free_datagram(sk, skb);
 
@@ -329,6 +332,31 @@ unsigned int bt_sock_poll(struct file * file, struct socket *sock, poll_table *w
 }
 EXPORT_SYMBOL(bt_sock_poll);
 
+int bt_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
+{
+       struct sock *sk = sock->sk;
+       int err;
+
+       BT_DBG("sk %p cmd %x arg %lx", sk, cmd, arg);
+
+       switch (cmd) {
+       case SIOCGSTAMP:
+               err = sock_get_timestamp(sk, (struct timeval __user *) arg);
+               break;
+
+       case SIOCGSTAMPNS:
+               err = sock_get_timestampns(sk, (struct timespec __user *) arg);
+               break;
+
+       default:
+               err = -ENOIOCTLCMD;
+               break;
+       }
+
+       return err;
+}
+EXPORT_SYMBOL(bt_sock_ioctl);
+
 int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo)
 {
        DECLARE_WAITQUEUE(wait, current);
index 30ad59b717d5e53e042817d7cee7f6f5bb3b2d7b..4fcf24af7590be87ef405a38b8f1bf850b5d65e1 100644 (file)
@@ -2388,9 +2388,9 @@ static const struct proto_ops l2cap_sock_ops = {
        .sendmsg        = l2cap_sock_sendmsg,
        .recvmsg        = bt_sock_recvmsg,
        .poll           = bt_sock_poll,
+       .ioctl          = bt_sock_ioctl,
        .mmap           = sock_no_mmap,
        .socketpair     = sock_no_socketpair,
-       .ioctl          = sock_no_ioctl,
        .shutdown       = l2cap_sock_shutdown,
        .setsockopt     = l2cap_sock_setsockopt,
        .getsockopt     = l2cap_sock_getsockopt
index cacb1ab51f997e105c2495f9222140a5fc2ffd67..c3ed076481d8c34e3e2b5affc20ca76547552279 100644 (file)
@@ -690,6 +690,8 @@ static int rfcomm_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
                copied += chunk;
                size   -= chunk;
 
+               sock_recv_timestamp(msg, sk, skb);
+
                if (!(flags & MSG_PEEK)) {
                        atomic_sub(chunk, &sk->sk_rmem_alloc);
 
@@ -795,15 +797,20 @@ static int rfcomm_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned lon
        struct sock *sk = sock->sk;
        int err;
 
-       lock_sock(sk);
+       BT_DBG("sk %p cmd %x arg %lx", sk, cmd, arg);
 
+       err = bt_sock_ioctl(sock, cmd, arg);
+
+       if (err == -ENOIOCTLCMD) {
 #ifdef CONFIG_BT_RFCOMM_TTY
-       err = rfcomm_dev_ioctl(sk, cmd, (void __user *)arg);
+               lock_sock(sk);
+               err = rfcomm_dev_ioctl(sk, cmd, (void __user *) arg);
+               release_sock(sk);
 #else
-       err = -EOPNOTSUPP;
+               err = -EOPNOTSUPP;
 #endif
+       }
 
-       release_sock(sk);
        return err;
 }
 
index b0d487e2db206899576b26a62ed0f245673b339c..1ad226c9788c8a1010383a07b937dcd6f3991107 100644 (file)
@@ -921,7 +921,7 @@ static const struct proto_ops sco_sock_ops = {
        .sendmsg        = sco_sock_sendmsg,
        .recvmsg        = bt_sock_recvmsg,
        .poll           = bt_sock_poll,
-       .ioctl          = sock_no_ioctl,
+       .ioctl          = bt_sock_ioctl,
        .mmap           = sock_no_mmap,
        .socketpair     = sock_no_socketpair,
        .shutdown       = sock_no_shutdown,