candump/lib: make sprint_canframe CAN XL aware
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>pull/504/head
parent
57238d5f81
commit
04312e5a10
|
|
@ -82,7 +82,7 @@ void prframe(FILE *file, struct timeval *tv, int dev, struct canfd_frame *cf, ch
|
||||||
else
|
else
|
||||||
fprintf(file, "canX ");
|
fprintf(file, "canX ");
|
||||||
|
|
||||||
sprint_canframe(abuf, cf, 0);
|
sprint_canframe(abuf, (cu_t *)cf, 0);
|
||||||
fprintf(file, "%s%s", abuf, extra_info);
|
fprintf(file, "%s%s", abuf, extra_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
52
candump.c
52
candump.c
|
|
@ -109,7 +109,7 @@ static char *progname;
|
||||||
static char devname[MAXIFNAMES][IFNAMSIZ + 1];
|
static char devname[MAXIFNAMES][IFNAMSIZ + 1];
|
||||||
static int dindex[MAXIFNAMES];
|
static int dindex[MAXIFNAMES];
|
||||||
static int max_devname_len; /* to prevent frazzled device name output */
|
static int max_devname_len; /* to prevent frazzled device name output */
|
||||||
static const int canfd_on = 1;
|
static const int canfx_on = 1;
|
||||||
|
|
||||||
#define MAXANI 4
|
#define MAXANI 4
|
||||||
static const char anichar[MAXANI] = { '|', '/', '-', '\\' };
|
static const char anichar[MAXANI] = { '|', '/', '-', '\\' };
|
||||||
|
|
@ -314,7 +314,7 @@ int main(int argc, char **argv)
|
||||||
struct cmsghdr *cmsg;
|
struct cmsghdr *cmsg;
|
||||||
struct can_filter *rfilter;
|
struct can_filter *rfilter;
|
||||||
can_err_mask_t err_mask;
|
can_err_mask_t err_mask;
|
||||||
struct canfd_frame frame;
|
static cu_t cu; /* union for CAN CC/FD/XL frames */
|
||||||
int nbytes, i;
|
int nbytes, i;
|
||||||
struct ifreq ifr;
|
struct ifreq ifr;
|
||||||
struct timeval tv, last_tv;
|
struct timeval tv, last_tv;
|
||||||
|
|
@ -596,7 +596,10 @@ int main(int argc, char **argv)
|
||||||
} /* if (nptr) */
|
} /* if (nptr) */
|
||||||
|
|
||||||
/* try to switch the socket into CAN FD mode */
|
/* try to switch the socket into CAN FD mode */
|
||||||
setsockopt(obj->s, SOL_CAN_RAW, CAN_RAW_FD_FRAMES, &canfd_on, sizeof(canfd_on));
|
setsockopt(obj->s, SOL_CAN_RAW, CAN_RAW_FD_FRAMES, &canfx_on, sizeof(canfx_on));
|
||||||
|
|
||||||
|
/* try to switch the socket into CAN XL mode */
|
||||||
|
setsockopt(obj->s, SOL_CAN_RAW, CAN_RAW_XL_FRAMES, &canfx_on, sizeof(canfx_on));
|
||||||
|
|
||||||
if (rcvbuf_size) {
|
if (rcvbuf_size) {
|
||||||
int curr_rcvbuf_size;
|
int curr_rcvbuf_size;
|
||||||
|
|
@ -700,7 +703,7 @@ int main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* these settings are static and can be held out of the hot path */
|
/* these settings are static and can be held out of the hot path */
|
||||||
iov.iov_base = &frame;
|
iov.iov_base = &cu;
|
||||||
msg.msg_name = &addr;
|
msg.msg_name = &addr;
|
||||||
msg.msg_iov = &iov;
|
msg.msg_iov = &iov;
|
||||||
msg.msg_iovlen = 1;
|
msg.msg_iovlen = 1;
|
||||||
|
|
@ -726,7 +729,7 @@ int main(int argc, char **argv)
|
||||||
char *extra_info = "";
|
char *extra_info = "";
|
||||||
|
|
||||||
/* these settings may be modified by recvmsg() */
|
/* these settings may be modified by recvmsg() */
|
||||||
iov.iov_len = sizeof(frame);
|
iov.iov_len = sizeof(cu);
|
||||||
msg.msg_namelen = sizeof(addr);
|
msg.msg_namelen = sizeof(addr);
|
||||||
msg.msg_controllen = sizeof(ctrlmsg);
|
msg.msg_controllen = sizeof(ctrlmsg);
|
||||||
msg.msg_flags = 0;
|
msg.msg_flags = 0;
|
||||||
|
|
@ -744,15 +747,28 @@ int main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* mark dual-use struct canfd_frame */
|
/* mark dual-use struct canfd_frame */
|
||||||
if ((size_t)nbytes == CAN_MTU)
|
if (nbytes < CANXL_HDR_SIZE + CANXL_MIN_DLEN) {
|
||||||
frame.flags = 0;
|
fprintf(stderr, "read: no CAN frame\n");
|
||||||
else if ((size_t)nbytes == CANFD_MTU)
|
|
||||||
frame.flags |= CANFD_FDF;
|
|
||||||
else {
|
|
||||||
fprintf(stderr, "read: incomplete CAN frame\n");
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cu.xl.flags & CANXL_XLF) {
|
||||||
|
if (nbytes != CANXL_HDR_SIZE + cu.xl.len) {
|
||||||
|
printf("nbytes = %d\n", nbytes);
|
||||||
|
fprintf(stderr, "read: no CAN XL frame\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (nbytes == CAN_MTU)
|
||||||
|
cu.fd.flags = 0;
|
||||||
|
else if (nbytes == CANFD_MTU)
|
||||||
|
cu.fd.flags |= CANFD_FDF;
|
||||||
|
else {
|
||||||
|
fprintf(stderr, "read: incomplete CAN CC/FD frame\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (count && (--count == 0))
|
if (count && (--count == 0))
|
||||||
running = 0;
|
running = 0;
|
||||||
|
|
||||||
|
|
@ -794,7 +810,7 @@ int main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* once we detected a EFF frame indent SFF frames accordingly */
|
/* once we detected a EFF frame indent SFF frames accordingly */
|
||||||
if (frame.can_id & CAN_EFF_FLAG)
|
if (cu.fd.can_id & CAN_EFF_FLAG)
|
||||||
view |= CANLIB_VIEW_INDENT_SFF;
|
view |= CANLIB_VIEW_INDENT_SFF;
|
||||||
|
|
||||||
if (extra_msg_info) {
|
if (extra_msg_info) {
|
||||||
|
|
@ -813,7 +829,7 @@ int main(int argc, char **argv)
|
||||||
alen += sprintf(abuf + alen, "%*s ",
|
alen += sprintf(abuf + alen, "%*s ",
|
||||||
max_devname_len, devname[idx]);
|
max_devname_len, devname[idx]);
|
||||||
|
|
||||||
alen += sprint_canframe(abuf + alen, &frame, 0);
|
alen += sprint_canframe(abuf + alen, &cu, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* write CAN frame in log file style to logfile */
|
/* write CAN frame in log file style to logfile */
|
||||||
|
|
@ -845,20 +861,20 @@ int main(int argc, char **argv)
|
||||||
if (extra_msg_info) {
|
if (extra_msg_info) {
|
||||||
if (msg.msg_flags & MSG_DONTROUTE)
|
if (msg.msg_flags & MSG_DONTROUTE)
|
||||||
alen += sprintf(abuf + alen, " TX %s",
|
alen += sprintf(abuf + alen, " TX %s",
|
||||||
extra_m_info[frame.flags & 3]);
|
extra_m_info[cu.fd.flags & 3]);
|
||||||
else
|
else
|
||||||
alen += sprintf(abuf + alen, " RX %s",
|
alen += sprintf(abuf + alen, " RX %s",
|
||||||
extra_m_info[frame.flags & 3]);
|
extra_m_info[cu.fd.flags & 3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
alen += sprintf(abuf + alen, "%s ", (color == 1) ? col_off : "");
|
alen += sprintf(abuf + alen, "%s ", (color == 1) ? col_off : "");
|
||||||
alen += sprint_long_canframe(abuf + alen, &frame, view);
|
alen += sprint_long_canframe(abuf + alen, &cu.fd, view);
|
||||||
|
|
||||||
if ((view & CANLIB_VIEW_ERROR) && (frame.can_id & CAN_ERR_FLAG)) {
|
if ((view & CANLIB_VIEW_ERROR) && (cu.fd.can_id & CAN_ERR_FLAG)) {
|
||||||
alen += sprintf(abuf + alen, "\n\t");
|
alen += sprintf(abuf + alen, "\n\t");
|
||||||
alen += snprintf_can_error_frame(abuf + alen,
|
alen += snprintf_can_error_frame(abuf + alen,
|
||||||
sizeof(abuf) - alen,
|
sizeof(abuf) - alen,
|
||||||
&frame, "\n\t");
|
&cu.fd, "\n\t");
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("%s%s\n", abuf, (color > 1) ? col_off : "");
|
printf("%s%s\n", abuf, (color > 1) ? col_off : "");
|
||||||
|
|
|
||||||
2
cangen.c
2
cangen.c
|
|
@ -835,7 +835,7 @@ int main(int argc, char **argv)
|
||||||
if (verbose > 1)
|
if (verbose > 1)
|
||||||
sprint_long_canframe(abuf, &frame, (verbose > 2) ? CANLIB_VIEW_ASCII : 0);
|
sprint_long_canframe(abuf, &frame, (verbose > 2) ? CANLIB_VIEW_ASCII : 0);
|
||||||
else
|
else
|
||||||
sprint_canframe(abuf, &frame, 1);
|
sprint_canframe(abuf, (cu_t *)&frame, 1);
|
||||||
|
|
||||||
printf("%s\n", abuf);
|
printf("%s\n", abuf);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -418,7 +418,7 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
sprintf(temp, "(%llu.%06llu) %*s ",
|
sprintf(temp, "(%llu.%06llu) %*s ",
|
||||||
(unsigned long long)tv.tv_sec, (unsigned long long)tv.tv_usec, max_devname_len, devname[idx]);
|
(unsigned long long)tv.tv_sec, (unsigned long long)tv.tv_usec, max_devname_len, devname[idx]);
|
||||||
sprint_canframe(temp+strlen(temp), &frame, 0);
|
sprint_canframe(temp+strlen(temp), (cu_t *)&frame, 0);
|
||||||
strcat(temp, "\n");
|
strcat(temp, "\n");
|
||||||
|
|
||||||
if (write(accsocket, temp, strlen(temp)) < 0) {
|
if (write(accsocket, temp, strlen(temp)) < 0) {
|
||||||
|
|
|
||||||
64
lib.c
64
lib.c
|
|
@ -258,48 +258,69 @@ int parse_canframe(char *cs, struct canfd_frame *cf)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sprint_canframe(char *buf, struct canfd_frame *cf, int sep)
|
int sprint_canframe(char *buf, cu_t *cu, int sep)
|
||||||
{
|
{
|
||||||
/* documentation see lib.h */
|
/* documentation see lib.h */
|
||||||
|
|
||||||
unsigned char is_canfd = cf->flags;
|
unsigned char is_canfd = cu->fd.flags;
|
||||||
int i, offset;
|
int i, offset;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
/* ensure max length values */
|
/* handle CAN XL frames */
|
||||||
if (is_canfd)
|
if (cu->xl.flags & CANXL_XLF) {
|
||||||
len = (cf->len > CANFD_MAX_DLEN) ? CANFD_MAX_DLEN : cf->len;
|
len = cu->xl.len;
|
||||||
else
|
|
||||||
len = (cf->len > CAN_MAX_DLEN) ? CAN_MAX_DLEN : cf->len;
|
|
||||||
|
|
||||||
if (cf->can_id & CAN_ERR_FLAG) {
|
/* print prio and CAN XL header content */
|
||||||
put_eff_id(buf, cf->can_id & (CAN_ERR_MASK | CAN_ERR_FLAG));
|
offset = sprintf(buf, "%02X%03X#%02X:%02X:%08X#",
|
||||||
|
(canid_t)(cu->xl.prio & CANXL_VCID_MASK) >> CANXL_VCID_OFFSET,
|
||||||
|
(canid_t)(cu->xl.prio & CANXL_PRIO_MASK),
|
||||||
|
cu->xl.flags, cu->xl.sdt, cu->xl.af);
|
||||||
|
|
||||||
|
/* data */
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
put_hex_byte(buf + offset, cu->xl.data[i]);
|
||||||
|
offset += 2;
|
||||||
|
if (sep && (i + 1 < len))
|
||||||
|
buf[offset++] = '.';
|
||||||
|
}
|
||||||
|
|
||||||
|
buf[offset] = 0;
|
||||||
|
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* handle CAN CC/FD frames - ensure max length values */
|
||||||
|
if (is_canfd)
|
||||||
|
len = (cu->fd.len > CANFD_MAX_DLEN) ? CANFD_MAX_DLEN : cu->fd.len;
|
||||||
|
else
|
||||||
|
len = (cu->fd.len > CAN_MAX_DLEN) ? CAN_MAX_DLEN : cu->fd.len;
|
||||||
|
|
||||||
|
if (cu->fd.can_id & CAN_ERR_FLAG) {
|
||||||
|
put_eff_id(buf, cu->fd.can_id & (CAN_ERR_MASK | CAN_ERR_FLAG));
|
||||||
buf[8] = '#';
|
buf[8] = '#';
|
||||||
offset = 9;
|
offset = 9;
|
||||||
} else if (cf->can_id & CAN_EFF_FLAG) {
|
} else if (cu->fd.can_id & CAN_EFF_FLAG) {
|
||||||
put_eff_id(buf, cf->can_id & CAN_EFF_MASK);
|
put_eff_id(buf, cu->fd.can_id & CAN_EFF_MASK);
|
||||||
buf[8] = '#';
|
buf[8] = '#';
|
||||||
offset = 9;
|
offset = 9;
|
||||||
} else {
|
} else {
|
||||||
put_sff_id(buf, cf->can_id & CAN_SFF_MASK);
|
put_sff_id(buf, cu->fd.can_id & CAN_SFF_MASK);
|
||||||
buf[3] = '#';
|
buf[3] = '#';
|
||||||
offset = 4;
|
offset = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* CAN CC frames may have RTR enabled. There are no ERR frames with RTR */
|
/* CAN CC frames may have RTR enabled. There are no ERR frames with RTR */
|
||||||
if (!(is_canfd) && cf->can_id & CAN_RTR_FLAG) {
|
if (!(is_canfd) && cu->fd.can_id & CAN_RTR_FLAG) {
|
||||||
buf[offset++] = 'R';
|
buf[offset++] = 'R';
|
||||||
/* print a given CAN 2.0B DLC if it's not zero */
|
/* print a given CAN 2.0B DLC if it's not zero */
|
||||||
if (len && len <= CAN_MAX_DLEN) {
|
if (len && len <= CAN_MAX_DLEN) {
|
||||||
buf[offset++] = hex_asc_upper_lo(cf->len);
|
buf[offset++] = hex_asc_upper_lo(cu->fd.len);
|
||||||
|
|
||||||
/* check for optional raw DLC value for CAN 2.0B frames */
|
/* check for optional raw DLC value for CAN 2.0B frames */
|
||||||
if (len == CAN_MAX_DLEN) {
|
if (len == CAN_MAX_DLEN) {
|
||||||
struct can_frame *ccf = (struct can_frame *)cf;
|
if ((cu->cc.len8_dlc > CAN_MAX_DLEN) && (cu->cc.len8_dlc <= CAN_MAX_RAW_DLC)) {
|
||||||
|
|
||||||
if ((ccf->len8_dlc > CAN_MAX_DLEN) && (ccf->len8_dlc <= CAN_MAX_RAW_DLC)) {
|
|
||||||
buf[offset++] = CC_DLC_DELIM;
|
buf[offset++] = CC_DLC_DELIM;
|
||||||
buf[offset++] = hex_asc_upper_lo(ccf->len8_dlc);
|
buf[offset++] = hex_asc_upper_lo(cu->cc.len8_dlc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -312,14 +333,14 @@ int sprint_canframe(char *buf, struct canfd_frame *cf, int sep)
|
||||||
if (is_canfd) {
|
if (is_canfd) {
|
||||||
/* add CAN FD specific escape char and flags */
|
/* add CAN FD specific escape char and flags */
|
||||||
buf[offset++] = '#';
|
buf[offset++] = '#';
|
||||||
buf[offset++] = hex_asc_upper_lo(cf->flags);
|
buf[offset++] = hex_asc_upper_lo(cu->fd.flags);
|
||||||
if (sep && len)
|
if (sep && len)
|
||||||
buf[offset++] = '.';
|
buf[offset++] = '.';
|
||||||
}
|
}
|
||||||
|
|
||||||
/* data */
|
/* data */
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
put_hex_byte(buf + offset, cf->data[i]);
|
put_hex_byte(buf + offset, cu->fd.data[i]);
|
||||||
offset += 2;
|
offset += 2;
|
||||||
if (sep && (i + 1 < len))
|
if (sep && (i + 1 < len))
|
||||||
buf[offset++] = '.';
|
buf[offset++] = '.';
|
||||||
|
|
@ -327,8 +348,7 @@ int sprint_canframe(char *buf, struct canfd_frame *cf, int sep)
|
||||||
|
|
||||||
/* check for extra DLC when having a Classic CAN with 8 bytes payload */
|
/* check for extra DLC when having a Classic CAN with 8 bytes payload */
|
||||||
if (!(is_canfd) && (len == CAN_MAX_DLEN)) {
|
if (!(is_canfd) && (len == CAN_MAX_DLEN)) {
|
||||||
struct can_frame *ccf = (struct can_frame *)cf;
|
unsigned char dlc = cu->cc.len8_dlc;
|
||||||
unsigned char dlc = ccf->len8_dlc;
|
|
||||||
|
|
||||||
if ((dlc > CAN_MAX_DLEN) && (dlc <= CAN_MAX_RAW_DLC)) {
|
if ((dlc > CAN_MAX_DLEN) && (dlc <= CAN_MAX_RAW_DLC)) {
|
||||||
buf[offset++] = CC_DLC_DELIM;
|
buf[offset++] = CC_DLC_DELIM;
|
||||||
|
|
|
||||||
10
lib.h
10
lib.h
|
|
@ -46,6 +46,7 @@
|
||||||
#define CAN_UTILS_LIB_H
|
#define CAN_UTILS_LIB_H
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
|
@ -55,6 +56,13 @@ __attribute__((format (printf, 1, 2)))
|
||||||
static inline int pr_debug(const char* fmt, ...) {return 0;}
|
static inline int pr_debug(const char* fmt, ...) {return 0;}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* CAN CC/FD/XL frame union */
|
||||||
|
typedef union {
|
||||||
|
struct can_frame cc;
|
||||||
|
struct canfd_frame fd;
|
||||||
|
struct canxl_frame xl;
|
||||||
|
} cu_t;
|
||||||
|
|
||||||
/* buffer sizes for CAN frame string representations */
|
/* buffer sizes for CAN frame string representations */
|
||||||
|
|
||||||
#define CL_ID (sizeof("12345678##1"))
|
#define CL_ID (sizeof("12345678##1"))
|
||||||
|
|
@ -160,7 +168,7 @@ int parse_canframe(char *cs, struct canfd_frame *cf);
|
||||||
* - CAN FD frames do not have a RTR bit
|
* - CAN FD frames do not have a RTR bit
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int sprint_canframe(char *buf , struct canfd_frame *cf, int sep);
|
int sprint_canframe(char *buf , cu_t *cu, int sep);
|
||||||
/*
|
/*
|
||||||
* Creates a CAN frame hexadecimal output in compact format.
|
* Creates a CAN frame hexadecimal output in compact format.
|
||||||
* The CAN data[] is separated by '.' when sep != 0.
|
* The CAN data[] is separated by '.' when sep != 0.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue