[PATCH v1 0/2] provide status handlers for (E)TP

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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(-)

-- 
2.20.1




[Index of Archives]     [Automotive Discussions]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]     [CAN Bus]

  Powered by Linux