Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 99eb8558 authored by Dmitry Eremin-Solenikov's avatar Dmitry Eremin-Solenikov Committed by David S. Miller
Browse files

af_ieee802154: add support for WANT_ACK socket option

parent 74eda55d
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -54,4 +54,9 @@ struct sockaddr_ieee802154 {
	struct ieee802154_addr addr;
};

/* get/setsockopt */
#define SOL_IEEE802154	0

#define WPAN_WANTACK	0

#endif
+54 −4
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ struct dgram_sock {
	struct ieee802154_addr dst_addr;

	unsigned bound:1;
	unsigned want_ack:1;
};

static inline struct dgram_sock *dgram_sk(const struct sock *sk)
@@ -51,7 +52,6 @@ static inline struct dgram_sock *dgram_sk(const struct sock *sk)
	return container_of(sk, struct dgram_sock, sk);
}


static void dgram_hash(struct sock *sk)
{
	write_lock_bh(&dgram_lock);
@@ -74,6 +74,7 @@ static int dgram_init(struct sock *sk)

	ro->dst_addr.addr_type = IEEE802154_ADDR_LONG;
	ro->dst_addr.pan_id = 0xffff;
	ro->want_ack = 1;
	memset(&ro->dst_addr.hwaddr, 0xff, sizeof(ro->dst_addr.hwaddr));
	return 0;
}
@@ -237,7 +238,10 @@ static int dgram_sendmsg(struct kiocb *iocb, struct sock *sk,

	skb_reset_network_header(skb);

	mac_cb(skb)->flags = IEEE802154_FC_TYPE_DATA | MAC_CB_FLAG_ACKREQ;
	mac_cb(skb)->flags = IEEE802154_FC_TYPE_DATA;
	if (ro->want_ack)
		mac_cb(skb)->flags |= MAC_CB_FLAG_ACKREQ;

	mac_cb(skb)->seq = ieee802154_mlme_ops(dev)->get_dsn(dev);
	err = dev_hard_header(skb, dev, ETH_P_IEEE802154, &ro->dst_addr,
			ro->bound ? &ro->src_addr : NULL, size);
@@ -382,13 +386,59 @@ int ieee802154_dgram_deliver(struct net_device *dev, struct sk_buff *skb)
static int dgram_getsockopt(struct sock *sk, int level, int optname,
		    char __user *optval, int __user *optlen)
{
	struct dgram_sock *ro = dgram_sk(sk);

	int val, len;

	if (level != SOL_IEEE802154)
		return -EOPNOTSUPP;

	if (get_user(len, optlen))
		return -EFAULT;

	len = min_t(unsigned int, len, sizeof(int));

	switch (optname) {
	case WPAN_WANTACK:
		val = ro->want_ack;
		break;
	default:
		return -ENOPROTOOPT;
	}

	if (put_user(len, optlen))
		return -EFAULT;
	if (copy_to_user(optval, &val, len))
		return -EFAULT;
	return 0;
}

static int dgram_setsockopt(struct sock *sk, int level, int optname,
		    char __user *optval, int __user optlen)
{
	return -EOPNOTSUPP;
	struct dgram_sock *ro = dgram_sk(sk);
	int val;
	int err = 0;

	if (optlen < sizeof(int))
		return -EINVAL;

	if (get_user(val, (int __user *)optval))
		return -EFAULT;

	lock_sock(sk);

	switch (optname) {
	case WPAN_WANTACK:
		ro->want_ack = !!val;
		break;
	default:
		err = -ENOPROTOOPT;
		break;
	}

	release_sock(sk);
	return err;
}

struct proto ieee802154_dgram_prot = {