Hi all,
please take a look at this patches. It is UAPI extension and it is good to know if it is
sane way to track/recognize send packages.
On 25.04.19 13:46, Oleksij Rempel wrote:
With this patches user space application is able to track the
status of (E)TP transfers. If this option is needed, application
should construct control message with PKTINFO->cookie set to some
value (for example pointer or sequence number). To get transmit status,
application should use recvmsg(..., MSG_ERRQUEUE). As response it will
get PKTINFO->cookie and error value if transfer was aborted. On success
error is set to zero.
This example can be used to send data with attached control message and
cookie.
static ssize_t jcat_sendto_flags(int fd, void *buf, size_t buf_size, int flags,
struct sockaddr *dest_addr,
socklen_t addrlen, __u64 cookie)
{
struct msghdr msgheader;
struct cmsghdr *control_msg;
struct iovec msg_iov;
char control_buf[256];
struct j1939_pktinfo *info;
ssize_t count;
/* Set up iov and msgheader */
memset(&msgheader, 0, sizeof(struct msghdr));
msg_iov.iov_base = buf;
msg_iov.iov_len = buf_size;
msgheader.msg_name = dest_addr;
msgheader.msg_namelen = addrlen;
msgheader.msg_iov = &msg_iov;
msgheader.msg_iovlen = 1;
msgheader.msg_flags = 0;
msgheader.msg_control = control_buf;
msgheader.msg_controllen = sizeof(control_buf);
control_msg = CMSG_FIRSTHDR(&msgheader);
control_msg->cmsg_level = SOL_CAN_J1939;
control_msg->cmsg_type = SCM_J1939_PKTINFO;
control_msg->cmsg_len = CMSG_LEN(sizeof(*info));
info = (struct j1939_pktinfo *)CMSG_DATA(control_msg);
memset(info, 0, sizeof(*info));
info->cookie = cookie;
msgheader.msg_controllen = control_msg->cmsg_len;
if (((count = sendmsg(fd, &msgheader, flags))) < 0)
error(1, errno, "sendmsg error");
return count;
}
This example can be used to receive transfer status report.
static int jcat_recv_err(struct jcat_priv *priv)
{
struct sock_extended_err *serr;
struct msghdr msg = {};
struct iovec iov[1];
struct j1939_pktinfo info;
struct cmsghdr *cm;
int ret;
char control[100];
iov[0].iov_base = &info;
iov[0].iov_len = sizeof(info);
msg.msg_iov = iov ;
msg.msg_iovlen = 1 ;
msg.msg_control = control;
msg.msg_controllen = sizeof(control);
ret = recvmsg(priv->sock, &msg, MSG_ERRQUEUE);
if (ret == -1 && errno == EAGAIN)
return false;
if (ret == -1)
error(1, errno, "recvmsg notification: %i", errno);
if (msg.msg_flags & MSG_CTRUNC)
error(1, errno, "recvmsg notification: truncated");
cm = CMSG_FIRSTHDR(&msg);
if (!cm)
error(1, 0, "cmsg: no cmsg");
if (!(cm->cmsg_level == SOL_CAN_J1939 && cm->cmsg_type == SCM_J1939_RECVERR))
error(1, 0, "serr: wrong type: %d.%d",
cm->cmsg_level, cm->cmsg_type);
serr = (void *) CMSG_DATA(cm);
if (serr->ee_origin != SO_EE_ORIGIN_TXSTATUS)
error(1, 0, "serr: wrong origin: %u", serr->ee_origin);
if (serr->ee_errno)
warnx("serr: tx error: %i, %s", serr->ee_errno,
strerror(serr->ee_errno));
warnx("pktinfo: cookie: 0x%llx", info.cookie);
return serr->ee_errno;
}
Oleksij Rempel (2):
j1939: add MSG_ERRQUEUE support
j1939: check supported recv*() flags
include/uapi/linux/can/j1939.h | 6 ++++
net/can/j1939/j1939-priv.h | 2 ++
net/can/j1939/socket.c | 51 ++++++++++++++++++++++++++++++++--
net/can/j1939/transport.c | 33 ++++++++++++++++++++--
4 files changed, 86 insertions(+), 6 deletions(-)
Kind regards,
Oleksij Rempel
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |