From 4ffb7fe5c75a8f15109168bf81c3310ffff51b02 Mon Sep 17 00:00:00 2001 From: Oliver Hartkopp Date: Sun, 16 Nov 2014 20:38:31 +0100 Subject: [PATCH] isotp: added support for separate extended address in rx path As requested by Laurent Vaudoit the extended address can be different in the tx and he rx path: (..) how can i have a segmented transfer like this: 0x6a7 0x55 0x10 0x08 ........ 0x687 0xAA 0x30 0x00 0x00 0x6a7 0x55 0x21 ..... The connection i need is between two ECU, using IDs 0x6a7/687 and one has adress extension 0x55, the other 0xAA (this adressing method is used on some FIAT ECUs for example). http://marc.info/?l=linux-can&m=140354647413513&w=2 Signed-off-by: Oliver Hartkopp --- include/linux/can/isotp.h | 4 ++++ isotpdump.c | 23 +++++++++++++++++-- isotprecv.c | 13 ++++++++++- isotpsend.c | 15 +++++++++++-- isotpsniffer.c | 47 ++++++++++++++++++++++++++++----------- 5 files changed, 84 insertions(+), 18 deletions(-) diff --git a/include/linux/can/isotp.h b/include/linux/can/isotp.h index dd767ec..0381506 100644 --- a/include/linux/can/isotp.h +++ b/include/linux/can/isotp.h @@ -82,6 +82,9 @@ struct can_isotp_options { __u8 rxpad_content; /* set content of padding byte (rx) */ /* __u8 value : content on rx path */ + + __u8 rx_ext_address; /* set address for extended addressing */ + /* __u8 value : extended address (rx) */ }; struct can_isotp_fc_options { @@ -112,6 +115,7 @@ struct can_isotp_fc_options { #define CAN_ISOTP_HALF_DUPLEX 0x040 /* half duplex error state handling */ #define CAN_ISOTP_FORCE_TXSTMIN 0x080 /* ignore stmin from received FC */ #define CAN_ISOTP_FORCE_RXSTMIN 0x100 /* ignore CFs depending on rx stmin */ +#define CAN_ISOTP_RX_EXT_ADDR 0x200 /* different rx extended addressing */ /* default values */ diff --git a/isotpdump.c b/isotpdump.c index 72cb121..b2de8c2 100644 --- a/isotpdump.c +++ b/isotpdump.c @@ -67,6 +67,7 @@ void print_usage(char *prg) fprintf(stderr, "Options: -s (source can_id. Use 8 digits for extended IDs)\n"); fprintf(stderr, " -d (destination can_id. Use 8 digits for extended IDs)\n"); fprintf(stderr, " -x (extended addressing mode. Use 'any' for all addresses)\n"); + fprintf(stderr, " -X (extended addressing mode (rx addr). Use 'any' for all)\n"); fprintf(stderr, " -c (color mode)\n"); fprintf(stderr, " -a (print data also in ASCII-chars)\n"); fprintf(stderr, " -t (timestamp: (a)bsolute/(d)elta/(z)ero/(A)bsolute w date)\n"); @@ -86,6 +87,9 @@ int main(int argc, char **argv) int ext = 0; int extaddr = 0; int extany = 0; + int rx_ext = 0; + int rx_extaddr = 0; + int rx_extany = 0; int asc = 0; int color = 0; int timestamp = 0; @@ -99,7 +103,7 @@ int main(int argc, char **argv) last_tv.tv_sec = 0; last_tv.tv_usec = 0; - while ((opt = getopt(argc, argv, "s:d:ax:ct:?")) != -1) { + while ((opt = getopt(argc, argv, "s:d:ax:X:ct:?")) != -1) { switch (opt) { case 's': src = strtoul(optarg, (char **)NULL, 16); @@ -127,7 +131,14 @@ int main(int argc, char **argv) extany = 1; else extaddr = strtoul(optarg, (char **)NULL, 16) & 0xFF; + break; + case 'X': + rx_ext = 1; + if (!strncmp(optarg, "any", 3)) + rx_extany = 1; + else + rx_extaddr = strtoul(optarg, (char **)NULL, 16) & 0xFF; break; case 't': @@ -153,6 +164,11 @@ int main(int argc, char **argv) } } + if (rx_ext && !ext) { + print_usage(basename(argv[0])); + exit(0); + } + if ((argc - optind) != 1 || src == NO_CAN_ID || dst == NO_CAN_ID) { print_usage(basename(argv[0])); exit(0); @@ -204,7 +220,10 @@ int main(int argc, char **argv) return 1; } else { - if (ext && !extany && extaddr != frame.data[0]) + if (frame.can_id == src && ext && !extany && extaddr != frame.data[0]) + continue; + + if (frame.can_id == dst && rx_ext && !rx_extany && rx_extaddr != frame.data[0]) continue; if (color) diff --git a/isotprecv.c b/isotprecv.c index a43a25a..a0934ba 100644 --- a/isotprecv.c +++ b/isotprecv.c @@ -64,6 +64,7 @@ void print_usage(char *prg) fprintf(stderr, "Options: -s (source can_id. Use 8 digits for extended IDs)\n"); fprintf(stderr, " -d (destination can_id. Use 8 digits for extended IDs)\n"); fprintf(stderr, " -x (extended addressing mode.)\n"); + fprintf(stderr, " -X (extended addressing mode (rx addr).)\n"); fprintf(stderr, " -p (set and enable padding byte)\n"); fprintf(stderr, " -P (check padding in SF/CF. (l)ength (c)ontent (a)ll)\n"); fprintf(stderr, " -b (blocksize. 0 = off)\n"); @@ -93,7 +94,7 @@ int main(int argc, char **argv) addr.can_addr.tp.tx_id = addr.can_addr.tp.rx_id = NO_CAN_ID; - while ((opt = getopt(argc, argv, "s:d:x:p:P:b:m:w:f:l?")) != -1) { + while ((opt = getopt(argc, argv, "s:d:x:X:p:P:b:m:w:f:l?")) != -1) { switch (opt) { case 's': addr.can_addr.tp.tx_id = strtoul(optarg, (char **)NULL, 16); @@ -112,6 +113,11 @@ int main(int argc, char **argv) opts.ext_address = strtoul(optarg, (char **)NULL, 16) & 0xFF; break; + case 'X': + opts.flags |= CAN_ISOTP_RX_EXT_ADDR; + opts.rx_ext_address = strtoul(optarg, (char **)NULL, 16) & 0xFF; + break; + case 'p': opts.flags |= CAN_ISOTP_RX_PADDING; opts.rxpad_content = strtoul(optarg, (char **)NULL, 16) & 0xFF; @@ -172,6 +178,11 @@ int main(int argc, char **argv) exit(1); } + if ((opts.flags & CAN_ISOTP_RX_EXT_ADDR) && (!(opts.flags & CAN_ISOTP_EXTEND_ADDR))) { + print_usage(basename(argv[0])); + exit(1); + } + if ((s = socket(PF_CAN, SOCK_DGRAM, CAN_ISOTP)) < 0) { perror("socket"); exit(1); diff --git a/isotpsend.c b/isotpsend.c index 3ac3417..7b48ec2 100644 --- a/isotpsend.c +++ b/isotpsend.c @@ -63,7 +63,8 @@ void print_usage(char *prg) fprintf(stderr, "\nUsage: %s [options] \n", prg); fprintf(stderr, "Options: -s (source can_id. Use 8 digits for extended IDs)\n"); fprintf(stderr, " -d (destination can_id. Use 8 digits for extended IDs)\n"); - fprintf(stderr, " -x (extended addressing mode. Use 'any' for all addresses)\n"); + fprintf(stderr, " -x (extended addressing mode)\n"); + fprintf(stderr, " -X (extended addressing mode - rx addr)\n"); fprintf(stderr, " -p (set and enable padding byte)\n"); fprintf(stderr, " -P (check padding in FC. (l)ength (c)ontent (a)ll)\n"); fprintf(stderr, " -t