Commit 3241ad82 authored by Marcel Holtmann's avatar Marcel Holtmann
Browse files

[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: default avatarMarcel Holtmann <marcel@holtmann.org>
parent 40be492f
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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);
+28 −0
Original line number Diff line number Diff line
@@ -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);
+1 −1
Original line number Diff line number Diff line
@@ -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
+11 −4
Original line number Diff line number Diff line
@@ -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
		lock_sock(sk);
		err = rfcomm_dev_ioctl(sk, cmd, (void __user *) arg);
		release_sock(sk);
#else
		err = -EOPNOTSUPP;
#endif
	}

	release_sock(sk);
	return err;
}

+1 −1
Original line number Diff line number Diff line
@@ -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,