summaryrefslogtreecommitdiffstats
path: root/net/ieee802154
diff options
context:
space:
mode:
authorRomuald CARI <romuald.cari@devialet.com>2018-06-07 16:08:02 +0200
committerStefan Schmidt <stefan@datenfreihafen.org>2018-07-13 12:18:18 -0400
commit811e299f4645588cc7a1b78d97b6847c155324b9 (patch)
treeab73de5d56f6d2ac75a1cecc4096184abe6dda5f /net/ieee802154
parent430ac34de9693bfe4bea0bab830e0ca0be9ef4b9 (diff)
downloadlinux-811e299f4645588cc7a1b78d97b6847c155324b9.tar.gz
linux-811e299f4645588cc7a1b78d97b6847c155324b9.tar.bz2
linux-811e299f4645588cc7a1b78d97b6847c155324b9.zip
ieee802154: add rx LQI from userspace
The Link Quality Indication data exposed by drivers could not be accessed from userspace. Since this data is per-datagram received, it makes sense to make it available to userspace application through the ancillary data mechanism in recvmsg rather than through ioctls. This can be activated using the socket option WPAN_WANTLQI under SOL_IEEE802154 protocol. This LQI data is available in the ancillary data buffer under the SOL_IEEE802154 level as the type WPAN_LQI. The value is an unsigned byte indicating the link quality with values ranging 0-255. Signed-off-by: Romuald Cari <romuald.cari@devialet.com> Signed-off-by: Clément Peron <clement.peron@devialet.com> Signed-off-by: Stefan Schmidt <stefan@datenfreihafen.org>
Diffstat (limited to 'net/ieee802154')
-rw-r--r--net/ieee802154/socket.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/net/ieee802154/socket.c b/net/ieee802154/socket.c
index a60658c85a9a..bc6b912603f1 100644
--- a/net/ieee802154/socket.c
+++ b/net/ieee802154/socket.c
@@ -25,6 +25,7 @@
#include <linux/termios.h> /* For TIOCOUTQ/INQ */
#include <linux/list.h>
#include <linux/slab.h>
+#include <linux/socket.h>
#include <net/datalink.h>
#include <net/psnap.h>
#include <net/sock.h>
@@ -452,6 +453,7 @@ struct dgram_sock {
unsigned int bound:1;
unsigned int connected:1;
unsigned int want_ack:1;
+ unsigned int want_lqi:1;
unsigned int secen:1;
unsigned int secen_override:1;
unsigned int seclevel:3;
@@ -486,6 +488,7 @@ static int dgram_init(struct sock *sk)
struct dgram_sock *ro = dgram_sk(sk);
ro->want_ack = 1;
+ ro->want_lqi = 0;
return 0;
}
@@ -713,6 +716,7 @@ static int dgram_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
size_t copied = 0;
int err = -EOPNOTSUPP;
struct sk_buff *skb;
+ struct dgram_sock *ro = dgram_sk(sk);
DECLARE_SOCKADDR(struct sockaddr_ieee802154 *, saddr, msg->msg_name);
skb = skb_recv_datagram(sk, flags, noblock, &err);
@@ -744,6 +748,13 @@ static int dgram_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
*addr_len = sizeof(*saddr);
}
+ if (ro->want_lqi) {
+ err = put_cmsg(msg, SOL_IEEE802154, WPAN_WANTLQI,
+ sizeof(uint8_t), &(mac_cb(skb)->lqi));
+ if (err)
+ goto done;
+ }
+
if (flags & MSG_TRUNC)
copied = skb->len;
done:
@@ -847,6 +858,9 @@ static int dgram_getsockopt(struct sock *sk, int level, int optname,
case WPAN_WANTACK:
val = ro->want_ack;
break;
+ case WPAN_WANTLQI:
+ val = ro->want_lqi;
+ break;
case WPAN_SECURITY:
if (!ro->secen_override)
val = WPAN_SECURITY_DEFAULT;
@@ -892,6 +906,9 @@ static int dgram_setsockopt(struct sock *sk, int level, int optname,
case WPAN_WANTACK:
ro->want_ack = !!val;
break;
+ case WPAN_WANTLQI:
+ ro->want_lqi = !!val;
+ break;
case WPAN_SECURITY:
if (!ns_capable(net->user_ns, CAP_NET_ADMIN) &&
!ns_capable(net->user_ns, CAP_NET_RAW)) {