]> rtime.felk.cvut.cz Git - can-utils.git/commitdiff
isotp: added support for separate extended address in rx path
authorOliver Hartkopp <socketcan@hartkopp.net>
Sun, 16 Nov 2014 19:38:31 +0000 (20:38 +0100)
committerOliver Hartkopp <socketcan@hartkopp.net>
Sun, 16 Nov 2014 19:38:31 +0000 (20:38 +0100)
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 <socketcan@hartkopp.net>
include/linux/can/isotp.h
isotpdump.c
isotprecv.c
isotpsend.c
isotpsniffer.c

index dd767ec6988f2df4680516da52559e0a92e11d4b..03815066f3903bea11e886907a3221ef125d1720 100644 (file)
@@ -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 */
index 72cb121222911c8c0278da5d224a43fcd6624208..b2de8c23275d38831ae76ad6dfa58abd83069257 100644 (file)
@@ -67,6 +67,7 @@ void print_usage(char *prg)
        fprintf(stderr, "Options: -s <can_id> (source can_id. Use 8 digits for extended IDs)\n");
        fprintf(stderr, "         -d <can_id> (destination can_id. Use 8 digits for extended IDs)\n");
        fprintf(stderr, "         -x <addr>   (extended addressing mode. Use 'any' for all addresses)\n");
+       fprintf(stderr, "         -X <addr>   (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 <type>   (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)
index a43a25afb8a6cdb96d26561d64e53af5718f3587..a0934ba87c72fae01e3638a99c672b10d1ecdc5e 100644 (file)
@@ -64,6 +64,7 @@ void print_usage(char *prg)
        fprintf(stderr, "Options: -s <can_id>  (source can_id. Use 8 digits for extended IDs)\n");
        fprintf(stderr, "         -d <can_id>  (destination can_id. Use 8 digits for extended IDs)\n");
        fprintf(stderr, "         -x <addr>    (extended addressing mode.)\n");
+       fprintf(stderr, "         -X <addr>    (extended addressing mode (rx addr).)\n");
        fprintf(stderr, "         -p <byte>    (set and enable padding byte)\n");
        fprintf(stderr, "         -P <mode>    (check padding in SF/CF. (l)ength (c)ontent (a)ll)\n");
        fprintf(stderr, "         -b <bs>      (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);
index 3ac3417a5bd92872b2be637ed962293aceab6363..7b48ec266045a2d6d06dd6591d08b84ab3cc94f8 100644 (file)
@@ -63,7 +63,8 @@ void print_usage(char *prg)
        fprintf(stderr, "\nUsage: %s [options] <CAN interface>\n", prg);
        fprintf(stderr, "Options: -s <can_id>  (source can_id. Use 8 digits for extended IDs)\n");
        fprintf(stderr, "         -d <can_id>  (destination can_id. Use 8 digits for extended IDs)\n");
-       fprintf(stderr, "         -x <addr>    (extended addressing mode. Use 'any' for all addresses)\n");
+       fprintf(stderr, "         -x <addr>    (extended addressing mode)\n");
+       fprintf(stderr, "         -X <addr>    (extended addressing mode - rx addr)\n");
        fprintf(stderr, "         -p <byte>    (set and enable padding byte)\n");
        fprintf(stderr, "         -P <mode>    (check padding in FC. (l)ength (c)ontent (a)ll)\n");
        fprintf(stderr, "         -t <time ns> (frame transmit time (N_As) in nanosecs)\n");
@@ -90,7 +91,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:t:f:D:?")) != -1) {
+    while ((opt = getopt(argc, argv, "s:d:x:X:p:P:t:f:D:?")) != -1) {
            switch (opt) {
            case 's':
                    addr.can_addr.tp.tx_id = strtoul(optarg, (char **)NULL, 16);
@@ -109,6 +110,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_TX_PADDING;
                    opts.txpad_content = strtoul(optarg, (char **)NULL, 16) & 0xFF;
@@ -165,6 +171,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);
index 84d39a2a9d46695b0eacb7b9307afb656f48b2f8..7618dca549a04b50453e8d47291fb6e02a9775cb 100644 (file)
@@ -68,7 +68,8 @@ void print_usage(char *prg)
        fprintf(stderr, "\nUsage: %s [options] <CAN interface>\n", prg);
        fprintf(stderr, "Options: -s <can_id> (source can_id. Use 8 digits for extended IDs)\n");
        fprintf(stderr, "         -d <can_id> (destination can_id. Use 8 digits for extended IDs)\n");
-       fprintf(stderr, "         -x <addr>   (extended addressing mode.)\n");
+       fprintf(stderr, "         -x <addr>   (extended addressing mode)\n");
+       fprintf(stderr, "         -X <addr>   (extended addressing mode - rx addr)\n");
        fprintf(stderr, "         -c          (color mode)\n");
        fprintf(stderr, "         -t <type>   (timestamp: (a)bsolute/(d)elta/(z)ero/(A)bsolute w date)\n");
        fprintf(stderr, "         -f <format> (1 = HEX, 2 = ASCII, 3 = HEX & ASCII - default: %d)\n", FORMAT_DEFAULT);
@@ -189,7 +190,7 @@ int main(int argc, char **argv)
        unsigned char buffer[4096];
        int nbytes;
 
-       while ((opt = getopt(argc, argv, "s:d:x:h:ct:f:?")) != -1) {
+       while ((opt = getopt(argc, argv, "s:d:x:X:h:ct:f:?")) != -1) {
                switch (opt) {
                case 's':
                        src = strtoul(optarg, (char **)NULL, 16);
@@ -208,6 +209,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 'f':
                        format = (atoi(optarg) & (FORMAT_ASCII | FORMAT_HEX));
                        break;
@@ -248,6 +254,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);
@@ -260,16 +271,15 @@ int main(int argc, char **argv)
 
        opts.flags |= CAN_ISOTP_LISTEN_MODE;
 
-       setsockopt(s, SOL_CAN_ISOTP, CAN_ISOTP_OPTS, &opts, sizeof(opts));
-       setsockopt(t, SOL_CAN_ISOTP, CAN_ISOTP_OPTS, &opts, sizeof(opts));
-
        addr.can_family = AF_CAN;
        strcpy(ifr.ifr_name, argv[optind]);
        ioctl(s, SIOCGIFINDEX, &ifr);
        addr.can_ifindex = ifr.ifr_ifindex;
 
-       addr.can_addr.tp.tx_id = dst;
-       addr.can_addr.tp.rx_id = src;
+       setsockopt(s, SOL_CAN_ISOTP, CAN_ISOTP_OPTS, &opts, sizeof(opts));
+
+       addr.can_addr.tp.tx_id = src;
+       addr.can_addr.tp.rx_id = dst;
 
        if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
                perror("bind");
@@ -277,8 +287,19 @@ int main(int argc, char **argv)
                exit(1);
        }
 
-       addr.can_addr.tp.tx_id = src;
-       addr.can_addr.tp.rx_id = dst;
+       if (opts.flags & CAN_ISOTP_RX_EXT_ADDR) {
+               /* flip extended address info due to separate rx ext addr */
+               __u8 tmpext;
+
+               tmpext = opts.ext_address;
+               opts.ext_address = opts.rx_ext_address;
+               opts.rx_ext_address = tmpext;
+       }
+
+       setsockopt(t, SOL_CAN_ISOTP, CAN_ISOTP_OPTS, &opts, sizeof(opts));
+
+       addr.can_addr.tp.tx_id = dst;
+       addr.can_addr.tp.rx_id = src;
 
        if (bind(t, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
                perror("bind");
@@ -312,8 +333,8 @@ int main(int argc, char **argv)
                        }
                        if (nbytes > 4095)
                                return -1;
-                       printbuf(buffer, nbytes, color?1:0, timestamp, format,
-                                &tv, &last_tv, src, s, ifr.ifr_name, head);
+                       printbuf(buffer, nbytes, color?2:0, timestamp, format,
+                                &tv, &last_tv, dst, s, ifr.ifr_name, head);
                }
 
                if (FD_ISSET(t, &rdfs)) {
@@ -324,8 +345,8 @@ int main(int argc, char **argv)
                        }
                        if (nbytes > 4095)
                                return -1;
-                       printbuf(buffer, nbytes, color?2:0, timestamp, format,
-                                &tv, &last_tv, dst, t, ifr.ifr_name, head);
+                       printbuf(buffer, nbytes, color?1:0, timestamp, format,
+                                &tv, &last_tv, src, t, ifr.ifr_name, head);
                }
        }