lib: make parse_canframe CAN XL aware
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>pull/504/head
parent
3644a54d5b
commit
34a1cfad29
|
|
@ -306,6 +306,11 @@ int main(int argc, char **argv)
|
||||||
struct sockaddr_can addr = {
|
struct sockaddr_can addr = {
|
||||||
.can_family = AF_CAN,
|
.can_family = AF_CAN,
|
||||||
};
|
};
|
||||||
|
struct can_raw_vcid_options vcid_opts = {
|
||||||
|
.flags = CAN_RAW_XL_VCID_RX_FILTER,
|
||||||
|
.rx_vcid = 0,
|
||||||
|
.rx_vcid_mask = 0,
|
||||||
|
};
|
||||||
char ctrlmsg[CMSG_SPACE(sizeof(struct timeval)) +
|
char ctrlmsg[CMSG_SPACE(sizeof(struct timeval)) +
|
||||||
CMSG_SPACE(3 * sizeof(struct timespec)) +
|
CMSG_SPACE(3 * sizeof(struct timespec)) +
|
||||||
CMSG_SPACE(sizeof(__u32))];
|
CMSG_SPACE(sizeof(__u32))];
|
||||||
|
|
@ -601,6 +606,9 @@ int main(int argc, char **argv)
|
||||||
/* try to switch the socket into CAN XL mode */
|
/* try to switch the socket into CAN XL mode */
|
||||||
setsockopt(obj->s, SOL_CAN_RAW, CAN_RAW_XL_FRAMES, &canfx_on, sizeof(canfx_on));
|
setsockopt(obj->s, SOL_CAN_RAW, CAN_RAW_XL_FRAMES, &canfx_on, sizeof(canfx_on));
|
||||||
|
|
||||||
|
/* try to enable the CAN XL VCID pass through mode */
|
||||||
|
setsockopt(obj->s, SOL_CAN_RAW, CAN_RAW_XL_VCID_OPTS, &vcid_opts, sizeof(vcid_opts));
|
||||||
|
|
||||||
if (rcvbuf_size) {
|
if (rcvbuf_size) {
|
||||||
int curr_rcvbuf_size;
|
int curr_rcvbuf_size;
|
||||||
socklen_t curr_rcvbuf_size_len = sizeof(curr_rcvbuf_size);
|
socklen_t curr_rcvbuf_size_len = sizeof(curr_rcvbuf_size);
|
||||||
|
|
|
||||||
31
canplayer.c
31
canplayer.c
|
|
@ -71,7 +71,7 @@ struct assignment {
|
||||||
char rxif[IFNAMSIZ];
|
char rxif[IFNAMSIZ];
|
||||||
};
|
};
|
||||||
static struct assignment asgn[CHANNELS];
|
static struct assignment asgn[CHANNELS];
|
||||||
const int canfd_on = 1;
|
const int canfx_on = 1;
|
||||||
|
|
||||||
extern int optind, opterr, optopt;
|
extern int optind, opterr, optopt;
|
||||||
|
|
||||||
|
|
@ -239,9 +239,12 @@ int add_assignment(char *mode, int socket, char *txname, char *rxname, int verbo
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
static char buf[BUFSZ], device[BUFSZ], ascframe[BUFSZ];
|
static char buf[BUFSZ], device[BUFSZ], ascframe[10000];
|
||||||
struct sockaddr_can addr;
|
struct sockaddr_can addr;
|
||||||
static struct canfd_frame frame;
|
struct can_raw_vcid_options vcid_opts = {
|
||||||
|
.flags = CAN_RAW_XL_VCID_TX_PASS,
|
||||||
|
};
|
||||||
|
static cu_t cu;
|
||||||
static struct timeval today_tv, log_tv, last_log_tv, diff_tv;
|
static struct timeval today_tv, log_tv, last_log_tv, diff_tv;
|
||||||
struct timespec sleep_ts;
|
struct timespec sleep_ts;
|
||||||
int s; /* CAN_RAW socket */
|
int s; /* CAN_RAW socket */
|
||||||
|
|
@ -360,7 +363,13 @@ int main(int argc, char **argv)
|
||||||
setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, NULL, 0);
|
setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, NULL, 0);
|
||||||
|
|
||||||
/* try to switch the socket into CAN FD mode */
|
/* try to switch the socket into CAN FD mode */
|
||||||
setsockopt(s, SOL_CAN_RAW, CAN_RAW_FD_FRAMES, &canfd_on, sizeof(canfd_on));
|
setsockopt(s, SOL_CAN_RAW, CAN_RAW_FD_FRAMES, &canfx_on, sizeof(canfx_on));
|
||||||
|
|
||||||
|
/* try to switch the socket into CAN XL mode */
|
||||||
|
setsockopt(s, SOL_CAN_RAW, CAN_RAW_XL_FRAMES, &canfx_on, sizeof(canfx_on));
|
||||||
|
|
||||||
|
/* try to enable the CAN XL VCID pass through mode */
|
||||||
|
setsockopt(s, SOL_CAN_RAW, CAN_RAW_XL_VCID_OPTS, &vcid_opts, sizeof(vcid_opts));
|
||||||
|
|
||||||
if (loopback_disable) {
|
if (loopback_disable) {
|
||||||
int loopback = 0;
|
int loopback = 0;
|
||||||
|
|
@ -470,26 +479,28 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
} else if (txidx > 0) { /* only send to valid CAN devices */
|
} else if (txidx > 0) { /* only send to valid CAN devices */
|
||||||
|
|
||||||
txmtu = parse_canframe(ascframe, &frame); /* dual-use frame */
|
txmtu = parse_canframe(ascframe, &cu); /* dual-use frame */
|
||||||
if (!txmtu) {
|
if (!txmtu) {
|
||||||
fprintf(stderr, "wrong CAN frame format: '%s'!", ascframe);
|
fprintf(stderr, "wrong CAN frame format: '%s'!", ascframe);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* CAN XL frames need real frame length for sending */
|
||||||
|
if (txmtu == CANXL_MTU)
|
||||||
|
txmtu = CANXL_HDR_SIZE + cu.xl.len;
|
||||||
|
|
||||||
addr.can_family = AF_CAN;
|
addr.can_family = AF_CAN;
|
||||||
addr.can_ifindex = txidx; /* send via this interface */
|
addr.can_ifindex = txidx; /* send via this interface */
|
||||||
|
|
||||||
if (sendto(s, &frame, txmtu, 0, (struct sockaddr *)&addr, sizeof(addr)) != txmtu) {
|
if (sendto(s, &cu, txmtu, 0, (struct sockaddr *)&addr, sizeof(addr)) != txmtu) {
|
||||||
perror("sendto");
|
perror("sendto");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
static char abuf[10000]; /* ASCII buf FIXME - use calculated value */
|
|
||||||
|
|
||||||
printf("%s (%s) ", get_txname(device), device);
|
printf("%s (%s) ", get_txname(device), device);
|
||||||
sprint_long_canframe(abuf, (cu_t *)&frame, CANLIB_VIEW_INDENT_SFF);
|
sprint_long_canframe(ascframe, &cu, CANLIB_VIEW_INDENT_SFF);
|
||||||
printf("%s\n", abuf);
|
printf("%s\n", ascframe);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count && (--count == 0))
|
if (count && (--count == 0))
|
||||||
|
|
|
||||||
44
cansend.c
44
cansend.c
|
|
@ -92,9 +92,12 @@ int main(int argc, char **argv)
|
||||||
int s; /* can raw socket */
|
int s; /* can raw socket */
|
||||||
int required_mtu;
|
int required_mtu;
|
||||||
int mtu;
|
int mtu;
|
||||||
int enable_canfd = 1;
|
int enable_canfx = 1;
|
||||||
struct sockaddr_can addr;
|
struct sockaddr_can addr;
|
||||||
struct canfd_frame frame;
|
struct can_raw_vcid_options vcid_opts = {
|
||||||
|
.flags = CAN_RAW_XL_VCID_TX_PASS,
|
||||||
|
};
|
||||||
|
static cu_t cu;
|
||||||
struct ifreq ifr;
|
struct ifreq ifr;
|
||||||
|
|
||||||
/* check command line options */
|
/* check command line options */
|
||||||
|
|
@ -104,7 +107,7 @@ int main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* parse CAN frame */
|
/* parse CAN frame */
|
||||||
required_mtu = parse_canframe(argv[2], &frame);
|
required_mtu = parse_canframe(argv[2], &cu);
|
||||||
if (!required_mtu) {
|
if (!required_mtu) {
|
||||||
fprintf(stderr, "\nWrong CAN-frame format!\n\n");
|
fprintf(stderr, "\nWrong CAN-frame format!\n\n");
|
||||||
print_usage(argv[0]);
|
print_usage(argv[0]);
|
||||||
|
|
@ -137,21 +140,38 @@ int main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
mtu = ifr.ifr_mtu;
|
mtu = ifr.ifr_mtu;
|
||||||
|
|
||||||
if (mtu != CANFD_MTU && mtu != CANXL_MTU) {
|
if (mtu == CANFD_MTU) {
|
||||||
printf("CAN interface is only Classical CAN capable - sorry.\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* interface is ok - try to switch the socket into CAN FD mode */
|
/* interface is ok - try to switch the socket into CAN FD mode */
|
||||||
if (setsockopt(s, SOL_CAN_RAW, CAN_RAW_FD_FRAMES,
|
if (setsockopt(s, SOL_CAN_RAW, CAN_RAW_FD_FRAMES,
|
||||||
&enable_canfd, sizeof(enable_canfd))){
|
&enable_canfx, sizeof(enable_canfx))){
|
||||||
printf("error when enabling CAN FD support\n");
|
printf("error when enabling CAN FD support\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mtu >= CANXL_MIN_MTU) {
|
||||||
|
/* interface is ok - try to switch the socket into CAN XL mode */
|
||||||
|
if (setsockopt(s, SOL_CAN_RAW, CAN_RAW_XL_FRAMES,
|
||||||
|
&enable_canfx, sizeof(enable_canfx))){
|
||||||
|
printf("error when enabling CAN XL support\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/* try to enable the CAN XL VCID pass through mode */
|
||||||
|
if (setsockopt(s, SOL_CAN_RAW, CAN_RAW_XL_VCID_OPTS,
|
||||||
|
&vcid_opts, sizeof(vcid_opts))) {
|
||||||
|
printf("error when enabling CAN XL VCID pass through\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* ensure discrete CAN FD length values 0..8, 12, 16, 20, 24, 32, 64 */
|
/* ensure discrete CAN FD length values 0..8, 12, 16, 20, 24, 32, 64 */
|
||||||
frame.len = can_fd_dlc2len(can_fd_len2dlc(frame.len));
|
if (required_mtu == CANFD_MTU)
|
||||||
}
|
cu.fd.len = can_fd_dlc2len(can_fd_len2dlc(cu.fd.len));
|
||||||
|
|
||||||
|
/* CAN XL frames need real frame length for sending */
|
||||||
|
if (required_mtu == CANXL_MTU)
|
||||||
|
required_mtu = CANXL_HDR_SIZE + cu.xl.len;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* disable default receive filter on this RAW socket This is
|
* disable default receive filter on this RAW socket This is
|
||||||
|
|
@ -167,7 +187,7 @@ int main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* send frame */
|
/* send frame */
|
||||||
if (write(s, &frame, required_mtu) != required_mtu) {
|
if (write(s, &cu, required_mtu) != required_mtu) {
|
||||||
perror("write");
|
perror("write");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
110
lib.c
110
lib.c
|
|
@ -55,6 +55,7 @@
|
||||||
|
|
||||||
#define CANID_DELIM '#'
|
#define CANID_DELIM '#'
|
||||||
#define CC_DLC_DELIM '_'
|
#define CC_DLC_DELIM '_'
|
||||||
|
#define XL_HDR_DELIM ':'
|
||||||
#define DATA_SEPERATOR '.'
|
#define DATA_SEPERATOR '.'
|
||||||
|
|
||||||
const char hex_asc_upper[] = "0123456789ABCDEF";
|
const char hex_asc_upper[] = "0123456789ABCDEF";
|
||||||
|
|
@ -153,78 +154,128 @@ int hexstring2data(char *arg, unsigned char *data, int maxdlen)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int parse_canframe(char *cs, struct canfd_frame *cf)
|
int parse_canframe(char *cs, cu_t *cu)
|
||||||
{
|
{
|
||||||
/* documentation see lib.h */
|
/* documentation see lib.h */
|
||||||
|
|
||||||
int i, idx, dlen, len;
|
int i, idx, dlen, len;
|
||||||
int maxdlen = CAN_MAX_DLEN;
|
int maxdlen = CAN_MAX_DLEN;
|
||||||
int ret = CAN_MTU;
|
int mtu = CAN_MTU;
|
||||||
|
__u8 *data = cu->fd.data; /* fill CAN CC/FD data by default */
|
||||||
canid_t tmp;
|
canid_t tmp;
|
||||||
|
|
||||||
len = strlen(cs);
|
len = strlen(cs);
|
||||||
//printf("'%s' len %d\n", cs, len);
|
//printf("'%s' len %d\n", cs, len);
|
||||||
|
|
||||||
memset(cf, 0, sizeof(*cf)); /* init CAN FD frame, e.g. LEN = 0 */
|
memset(cu, 0, sizeof(*cu)); /* init CAN CC/FD/XL frame, e.g. LEN = 0 */
|
||||||
|
|
||||||
if (len < 4)
|
if (len < 4)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (cs[3] == CANID_DELIM) { /* 3 digits */
|
if (cs[3] == CANID_DELIM) { /* 3 digits SFF */
|
||||||
|
|
||||||
idx = 4;
|
idx = 4;
|
||||||
for (i = 0; i < 3; i++) {
|
for (i = 0; i < 3; i++) {
|
||||||
if ((tmp = asc2nibble(cs[i])) > 0x0F)
|
if ((tmp = asc2nibble(cs[i])) > 0x0F)
|
||||||
return 0;
|
return 0;
|
||||||
cf->can_id |= (tmp << (2 - i) * 4);
|
cu->cc.can_id |= (tmp << (2 - i) * 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (cs[8] == CANID_DELIM) { /* 8 digits */
|
} else if (cs[5] == CANID_DELIM) { /* 5 digits CAN XL VCID/PRIO*/
|
||||||
|
|
||||||
|
idx = 6;
|
||||||
|
for (i = 0; i < 5; i++) {
|
||||||
|
if ((tmp = asc2nibble(cs[i])) > 0x0F)
|
||||||
|
return 0;
|
||||||
|
cu->xl.prio |= (tmp << (4 - i) * 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* the VCID starts at bit position 16 */
|
||||||
|
tmp = (cu->xl.prio << 4) & CANXL_VCID_MASK;
|
||||||
|
cu->xl.prio &= CANXL_PRIO_MASK;
|
||||||
|
cu->xl.prio |= tmp;
|
||||||
|
|
||||||
|
} else if (cs[8] == CANID_DELIM) { /* 8 digits EFF */
|
||||||
|
|
||||||
idx = 9;
|
idx = 9;
|
||||||
for (i = 0; i < 8; i++) {
|
for (i = 0; i < 8; i++) {
|
||||||
if ((tmp = asc2nibble(cs[i])) > 0x0F)
|
if ((tmp = asc2nibble(cs[i])) > 0x0F)
|
||||||
return 0;
|
return 0;
|
||||||
cf->can_id |= (tmp << (7 - i) * 4);
|
cu->cc.can_id |= (tmp << (7 - i) * 4);
|
||||||
}
|
}
|
||||||
if (!(cf->can_id & CAN_ERR_FLAG)) /* 8 digits but no errorframe? */
|
if (!(cu->cc.can_id & CAN_ERR_FLAG)) /* 8 digits but no errorframe? */
|
||||||
cf->can_id |= CAN_EFF_FLAG; /* then it is an extended frame */
|
cu->cc.can_id |= CAN_EFF_FLAG; /* then it is an extended frame */
|
||||||
|
|
||||||
} else
|
} else
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if ((cs[idx] == 'R') || (cs[idx] == 'r')) { /* RTR frame */
|
if ((cs[idx] == 'R') || (cs[idx] == 'r')) { /* RTR frame */
|
||||||
cf->can_id |= CAN_RTR_FLAG;
|
cu->cc.can_id |= CAN_RTR_FLAG;
|
||||||
|
|
||||||
/* check for optional DLC value for CAN 2.0B frames */
|
/* check for optional DLC value for CAN 2.0B frames */
|
||||||
if (cs[++idx] && (tmp = asc2nibble(cs[idx++])) <= CAN_MAX_DLEN) {
|
if (cs[++idx] && (tmp = asc2nibble(cs[idx++])) <= CAN_MAX_DLEN) {
|
||||||
cf->len = tmp;
|
cu->cc.len = tmp;
|
||||||
|
|
||||||
/* check for optional raw DLC value for CAN 2.0B frames */
|
/* check for optional raw DLC value for CAN 2.0B frames */
|
||||||
if ((tmp == CAN_MAX_DLEN) && (cs[idx++] == CC_DLC_DELIM)) {
|
if ((tmp == CAN_MAX_DLEN) && (cs[idx++] == CC_DLC_DELIM)) {
|
||||||
tmp = asc2nibble(cs[idx]);
|
tmp = asc2nibble(cs[idx]);
|
||||||
if ((tmp > CAN_MAX_DLEN) && (tmp <= CAN_MAX_RAW_DLC)) {
|
if ((tmp > CAN_MAX_DLEN) && (tmp <= CAN_MAX_RAW_DLC))
|
||||||
struct can_frame *ccf = (struct can_frame *)cf;
|
cu->cc.len8_dlc = tmp;
|
||||||
|
|
||||||
ccf->len8_dlc = tmp;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
return mtu;
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cs[idx] == CANID_DELIM) { /* CAN FD frame escape char '##' */
|
if (cs[idx] == CANID_DELIM) { /* CAN FD frame escape char '##' */
|
||||||
|
|
||||||
maxdlen = CANFD_MAX_DLEN;
|
maxdlen = CANFD_MAX_DLEN;
|
||||||
ret = CANFD_MTU;
|
mtu = CANFD_MTU;
|
||||||
|
|
||||||
/* CAN FD frame <canid>##<flags><data>* */
|
/* CAN FD frame <canid>##<flags><data>* */
|
||||||
if ((tmp = asc2nibble(cs[idx + 1])) > 0x0F)
|
if ((tmp = asc2nibble(cs[idx + 1])) > 0x0F)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
cf->flags = tmp;
|
cu->fd.flags = tmp;
|
||||||
cf->flags |= CANFD_FDF; /* dual-use */
|
cu->fd.flags |= CANFD_FDF; /* dual-use */
|
||||||
idx += 2;
|
idx += 2;
|
||||||
|
|
||||||
|
} else if (cs[idx + 14] == CANID_DELIM) { /* CAN XL frame '#80:00:11223344#' */
|
||||||
|
|
||||||
|
maxdlen = CANXL_MAX_DLEN;
|
||||||
|
mtu = CANXL_MTU;
|
||||||
|
data = cu->xl.data; /* fill CAN XL data */
|
||||||
|
|
||||||
|
if ((cs[idx + 2] != XL_HDR_DELIM) || (cs[idx + 5] != XL_HDR_DELIM))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if ((tmp = asc2nibble(cs[idx++])) > 0x0F)
|
||||||
|
return 0;
|
||||||
|
cu->xl.flags = (tmp << 4);
|
||||||
|
if ((tmp = asc2nibble(cs[idx++])) > 0x0F)
|
||||||
|
return 0;
|
||||||
|
cu->xl.flags |= tmp;
|
||||||
|
|
||||||
|
/* force CAN XL flag if it was missing in the ASCII string */
|
||||||
|
cu->xl.flags |= CANXL_XLF;
|
||||||
|
|
||||||
|
idx++; /* skip XL_HDR_DELIM */
|
||||||
|
|
||||||
|
if ((tmp = asc2nibble(cs[idx++])) > 0x0F)
|
||||||
|
return 0;
|
||||||
|
cu->xl.sdt = (tmp << 4);
|
||||||
|
if ((tmp = asc2nibble(cs[idx++])) > 0x0F)
|
||||||
|
return 0;
|
||||||
|
cu->xl.sdt |= tmp;
|
||||||
|
|
||||||
|
idx++; /* skip XL_HDR_DELIM */
|
||||||
|
|
||||||
|
for (i = 0; i < 8; i++) {
|
||||||
|
if ((tmp = asc2nibble(cs[idx++])) > 0x0F)
|
||||||
|
return 0;
|
||||||
|
cu->xl.af |= (tmp << (7 - i) * 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
idx++; /* skip CANID_DELIM */
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0, dlen = 0; i < maxdlen; i++) {
|
for (i = 0, dlen = 0; i < maxdlen; i++) {
|
||||||
|
|
@ -236,26 +287,27 @@ int parse_canframe(char *cs, struct canfd_frame *cf)
|
||||||
|
|
||||||
if ((tmp = asc2nibble(cs[idx++])) > 0x0F)
|
if ((tmp = asc2nibble(cs[idx++])) > 0x0F)
|
||||||
return 0;
|
return 0;
|
||||||
cf->data[i] = (tmp << 4);
|
data[i] = (tmp << 4);
|
||||||
if ((tmp = asc2nibble(cs[idx++])) > 0x0F)
|
if ((tmp = asc2nibble(cs[idx++])) > 0x0F)
|
||||||
return 0;
|
return 0;
|
||||||
cf->data[i] |= tmp;
|
data[i] |= tmp;
|
||||||
dlen++;
|
dlen++;
|
||||||
}
|
}
|
||||||
cf->len = dlen;
|
|
||||||
|
if (mtu == CANXL_MTU)
|
||||||
|
cu->xl.len = dlen;
|
||||||
|
else
|
||||||
|
cu->fd.len = dlen;
|
||||||
|
|
||||||
/* 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 ((maxdlen == CAN_MAX_DLEN) && (dlen == CAN_MAX_DLEN) && (cs[idx++] == CC_DLC_DELIM)) {
|
if ((maxdlen == CAN_MAX_DLEN) && (dlen == CAN_MAX_DLEN) && (cs[idx++] == CC_DLC_DELIM)) {
|
||||||
unsigned char dlc = asc2nibble(cs[idx]);
|
unsigned char dlc = asc2nibble(cs[idx]);
|
||||||
|
|
||||||
if ((dlc > CAN_MAX_DLEN) && (dlc <= CAN_MAX_RAW_DLC)) {
|
if ((dlc > CAN_MAX_DLEN) && (dlc <= CAN_MAX_RAW_DLC))
|
||||||
struct can_frame *ccf = (struct can_frame *)cf;
|
cu->cc.len8_dlc = dlc;
|
||||||
|
|
||||||
ccf->len8_dlc = dlc;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return mtu;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sprint_canframe(char *buf, cu_t *cu, int sep)
|
int sprint_canframe(char *buf, cu_t *cu, int sep)
|
||||||
|
|
|
||||||
3
lib.h
3
lib.h
|
|
@ -111,8 +111,7 @@ int hexstring2data(char *arg, unsigned char *data, int maxdlen);
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct canfd_frame;
|
int parse_canframe(char *cs, cu_t *cu);
|
||||||
int parse_canframe(char *cs, struct canfd_frame *cf);
|
|
||||||
/*
|
/*
|
||||||
* Transfers a valid ASCII string describing a CAN frame into struct canfd_frame.
|
* Transfers a valid ASCII string describing a CAN frame into struct canfd_frame.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
19
log2asc.c
19
log2asc.c
|
|
@ -183,9 +183,9 @@ void canfd_asc(struct canfd_frame *cf, int devno, int mtu, char *extra_info, FIL
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
static char buf[BUFSZ], device[BUFSZ], ascframe[BUFSZ], extra_info[BUFSZ];
|
static char buf[BUFSZ], device[BUFSZ], ascframe[10000], extra_info[BUFSZ];
|
||||||
|
|
||||||
struct canfd_frame cf;
|
static cu_t cu;
|
||||||
static struct timeval tv, start_tv;
|
static struct timeval tv, start_tv;
|
||||||
FILE *infile = stdin;
|
FILE *infile = stdin;
|
||||||
FILE *outfile = stdout;
|
FILE *outfile = stdout;
|
||||||
|
|
@ -286,20 +286,23 @@ int main(int argc, char **argv)
|
||||||
(crlf)?"\r\n":"\n");
|
(crlf)?"\r\n":"\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i=0, devno=0; i<maxdev; i++) {
|
for (i = 0, devno = 0; i < maxdev; i++) {
|
||||||
if (!strcmp(device, argv[optind+i])) {
|
if (!strcmp(device, argv[optind+i])) {
|
||||||
devno = i+1; /* start with channel '1' */
|
devno = i + 1; /* start with channel '1' */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (devno) { /* only convert for selected CAN devices */
|
if (devno) { /* only convert for selected CAN devices */
|
||||||
mtu = parse_canframe(ascframe, &cf);
|
|
||||||
|
mtu = parse_canframe(ascframe, &cu);
|
||||||
|
|
||||||
|
/* convert only CAN CC and CAN FD frames */
|
||||||
if ((mtu != CAN_MTU) && (mtu != CANFD_MTU))
|
if ((mtu != CAN_MTU) && (mtu != CANFD_MTU))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
/* we don't support error message frames in CAN FD */
|
/* we don't support error message frames in CAN FD */
|
||||||
if ((mtu == CANFD_MTU) && (cf.can_id & CAN_ERR_FLAG))
|
if ((mtu == CANFD_MTU) && (cu.cc.can_id & CAN_ERR_FLAG))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
tv.tv_sec = tv.tv_sec - start_tv.tv_sec;
|
tv.tv_sec = tv.tv_sec - start_tv.tv_sec;
|
||||||
|
|
@ -315,9 +318,9 @@ int main(int argc, char **argv)
|
||||||
fprintf(outfile, "%4llu.%06llu ", (unsigned long long)tv.tv_sec, (unsigned long long)tv.tv_usec);
|
fprintf(outfile, "%4llu.%06llu ", (unsigned long long)tv.tv_sec, (unsigned long long)tv.tv_usec);
|
||||||
|
|
||||||
if ((mtu == CAN_MTU) && (fdfmt == 0))
|
if ((mtu == CAN_MTU) && (fdfmt == 0))
|
||||||
can_asc(&cf, devno, nortrdlc, extra_info, outfile);
|
can_asc(&cu.fd, devno, nortrdlc, extra_info, outfile);
|
||||||
else
|
else
|
||||||
canfd_asc(&cf, devno, mtu, extra_info, outfile);
|
canfd_asc(&cu.fd, devno, mtu, extra_info, outfile);
|
||||||
|
|
||||||
if (crlf)
|
if (crlf)
|
||||||
fprintf(outfile, "\r");
|
fprintf(outfile, "\r");
|
||||||
|
|
|
||||||
14
log2long.c
14
log2long.c
|
|
@ -55,27 +55,27 @@
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
char buf[BUFSZ], timestamp[BUFSZ], device[BUFSZ], ascframe[BUFSZ];
|
char buf[BUFSZ], timestamp[BUFSZ], device[BUFSZ], ascframe[BUFSZ];
|
||||||
struct canfd_frame cf;
|
static cu_t cu;
|
||||||
int mtu;
|
int mtu;
|
||||||
|
|
||||||
while (fgets(buf, BUFSZ-1, stdin)) {
|
while (fgets(buf, BUFSZ-1, stdin)) {
|
||||||
if (sscanf(buf, "%s %s %s", timestamp, device, ascframe) != 3)
|
if (sscanf(buf, "%s %s %s", timestamp, device, ascframe) != 3)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
mtu = parse_canframe(ascframe, &cf);
|
mtu = parse_canframe(ascframe, &cu);
|
||||||
|
|
||||||
/* mark dual-use struct canfd_frame */
|
/* mark dual-use struct canfd_frame - no CAN_XL support */
|
||||||
if (mtu == CAN_MTU)
|
if (mtu == CAN_MTU)
|
||||||
cf.flags = 0;
|
cu.fd.flags = 0;
|
||||||
else if (mtu == CANFD_MTU)
|
else if (mtu == CANFD_MTU)
|
||||||
cf.flags |= CANFD_FDF;
|
cu.fd.flags |= CANFD_FDF;
|
||||||
else {
|
else {
|
||||||
fprintf(stderr, "read: incomplete CAN frame\n");
|
fprintf(stderr, "read: no valid CAN CC/FD frame\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* with ASCII output */
|
/* with ASCII output */
|
||||||
sprint_long_canframe(ascframe, (cu_t *)&cf,
|
sprint_long_canframe(ascframe, &cu,
|
||||||
(CANLIB_VIEW_INDENT_SFF | CANLIB_VIEW_ASCII));
|
(CANLIB_VIEW_INDENT_SFF | CANLIB_VIEW_ASCII));
|
||||||
|
|
||||||
printf("%s %s %s\n", timestamp, device, ascframe);
|
printf("%s %s %s\n", timestamp, device, ascframe);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue