Skip to content

Commit

Permalink
ieee802154: add rx LQI from userspace
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: Clément Peron <[email protected]>
Signed-off-by: Stefan Schmidt <[email protected]>
  • Loading branch information
Romuald CARI authored and Stefan-Schmidt committed Jul 13, 2018
1 parent 430ac34 commit 811e299
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 0 deletions.
1 change: 1 addition & 0 deletions include/net/af_ieee802154.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ struct sockaddr_ieee802154 {
#define WPAN_WANTACK 0
#define WPAN_SECURITY 1
#define WPAN_SECURITY_LEVEL 2
#define WPAN_WANTLQI 3

#define WPAN_SECURITY_DEFAULT 0
#define WPAN_SECURITY_OFF 1
Expand Down
17 changes: 17 additions & 0 deletions net/ieee802154/socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)) {
Expand Down

0 comments on commit 811e299

Please sign in to comment.