|
@@ -45,6 +45,7 @@ struct dgram_sock {
|
|
|
struct ieee802154_addr dst_addr;
|
|
|
|
|
|
unsigned int bound:1;
|
|
|
+ unsigned int connected:1;
|
|
|
unsigned int want_ack:1;
|
|
|
};
|
|
|
|
|
@@ -73,10 +74,7 @@ static int dgram_init(struct sock *sk)
|
|
|
{
|
|
|
struct dgram_sock *ro = dgram_sk(sk);
|
|
|
|
|
|
- ro->dst_addr.mode = IEEE802154_ADDR_LONG;
|
|
|
- ro->dst_addr.pan_id = cpu_to_le16(IEEE802154_PANID_BROADCAST);
|
|
|
ro->want_ack = 1;
|
|
|
- memset(&ro->dst_addr.extended_addr, 0xff, IEEE802154_ADDR_LEN);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -183,6 +181,7 @@ static int dgram_connect(struct sock *sk, struct sockaddr *uaddr,
|
|
|
}
|
|
|
|
|
|
ieee802154_addr_from_sa(&ro->dst_addr, &addr->addr);
|
|
|
+ ro->connected = 1;
|
|
|
|
|
|
out:
|
|
|
release_sock(sk);
|
|
@@ -194,10 +193,7 @@ static int dgram_disconnect(struct sock *sk, int flags)
|
|
|
struct dgram_sock *ro = dgram_sk(sk);
|
|
|
|
|
|
lock_sock(sk);
|
|
|
-
|
|
|
- ro->dst_addr.mode = IEEE802154_ADDR_LONG;
|
|
|
- memset(&ro->dst_addr.extended_addr, 0xff, IEEE802154_ADDR_LEN);
|
|
|
-
|
|
|
+ ro->connected = 0;
|
|
|
release_sock(sk);
|
|
|
|
|
|
return 0;
|
|
@@ -211,6 +207,7 @@ static int dgram_sendmsg(struct kiocb *iocb, struct sock *sk,
|
|
|
struct sk_buff *skb;
|
|
|
struct ieee802154_mac_cb *cb;
|
|
|
struct dgram_sock *ro = dgram_sk(sk);
|
|
|
+ struct ieee802154_addr dst_addr;
|
|
|
int hlen, tlen;
|
|
|
int err;
|
|
|
|
|
@@ -219,6 +216,11 @@ static int dgram_sendmsg(struct kiocb *iocb, struct sock *sk,
|
|
|
return -EOPNOTSUPP;
|
|
|
}
|
|
|
|
|
|
+ if (!ro->connected && !msg->msg_name)
|
|
|
+ return -EDESTADDRREQ;
|
|
|
+ else if (ro->connected && msg->msg_name)
|
|
|
+ return -EISCONN;
|
|
|
+
|
|
|
if (!ro->bound)
|
|
|
dev = dev_getfirstbyhwtype(sock_net(sk), ARPHRD_IEEE802154);
|
|
|
else
|
|
@@ -254,8 +256,16 @@ static int dgram_sendmsg(struct kiocb *iocb, struct sock *sk,
|
|
|
cb->type = IEEE802154_FC_TYPE_DATA;
|
|
|
cb->ackreq = ro->want_ack;
|
|
|
|
|
|
- err = dev_hard_header(skb, dev, ETH_P_IEEE802154, &ro->dst_addr,
|
|
|
- ro->bound ? &ro->src_addr : NULL, size);
|
|
|
+ if (msg->msg_name) {
|
|
|
+ DECLARE_SOCKADDR(struct sockaddr_ieee802154*, daddr, msg->msg_name);
|
|
|
+
|
|
|
+ ieee802154_addr_from_sa(&dst_addr, &daddr->addr);
|
|
|
+ } else {
|
|
|
+ dst_addr = ro->dst_addr;
|
|
|
+ }
|
|
|
+
|
|
|
+ err = dev_hard_header(skb, dev, ETH_P_IEEE802154, &dst_addr,
|
|
|
+ ro->bound ? &ro->src_addr : NULL, size);
|
|
|
if (err < 0)
|
|
|
goto out_skb;
|
|
|
|