From 198c5801ecf3dd62398923119239eccc04c026d9 Mon Sep 17 00:00:00 2001 From: Kurt Van Dijck Date: Mon, 18 Nov 2013 23:30:46 +0100 Subject: [PATCH 02/23] import sample program & help page --- Makefile | 11 ++ j1939.page | 327 ++++++++++++++++++++++++++++++++++++++++++++++++++++ page.theme | 21 ++++ style.css | 68 +++++++++++ testj1939.c | 200 ++++++++++++++++++++++++++++++++ 5 files changed, 627 insertions(+) create mode 100644 Makefile create mode 100644 j1939.page create mode 100644 page.theme create mode 100644 style.css create mode 100644 testj1939.c diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..ee9b43c --- /dev/null +++ b/Makefile @@ -0,0 +1,11 @@ + +OUTPUT = j1939.html testj1939 +default: $(OUTPUT) + +%.html: %.page page.theme + theme -f -o $@ $< -p "$*" + +CFLAGS = -Wall -g3 -O0 + +clean: + rm -f $(wildcard *.o) $(OUTPUT) diff --git a/j1939.page b/j1939.page new file mode 100644 index 0000000..1a8f2a5 --- /dev/null +++ b/j1939.page @@ -0,0 +1,327 @@ +# CAN-J1939 on linux + +## CAN on linux + +See [Wikipedia:socketcan](http://en.wikipedia.org/wiki/Socketcan) + +## J1939 networking in short + +* Add addressing on top of CAN (destination address & broadcast) + +* Any (max 1780) length packets. + Packets of 9 or more use **Transport Protocol** (fragmentation) + Such packets use different CANid for the same PGN. + +* only **29**bit, non-**RTR** CAN frames + +* CAN id is composed of + * 0..8: SA (source address) + * 9..26: + * PDU1: PGN+DA (destionation address) + * PDU2: PGN + * 27..29: PRIO + +* SA / DA may be dynamically assigned via j1939-81 + Fixed rules of precedence in Specification, no master necessary + +## J1939 on SocketCAN + +J1939 is *just another protocol* that fits +in the Berkely sockets. + + socket(AF_CAN, SOCK_DGRAM, CAN_J1939) + +## differences from CAN_RAW +### addressing + +SA, DA & PGN are used, not CAN id. + +Berkeley socket API is used to communicate these to userspace: + + * SA+PGN is put in sockname ([getsockname](http://man7.org/linux/man-pages/man2/getsockname.2.html)) + * DA+PGN is put in peername ([getpeername](http://man7.org/linux/man-pages/man2/getpeername.2.html)) + PGN is put in both structs + +PRIO is a datalink property, and irrelevant for interpretation +Therefore, PRIO is not in *sockname* or *peername*. + +The *data* that is [recv][recvfrom] or [send][sendto] is the real payload. +Unlike CAN_RAW, where addressing info is data. + +### Packet size + +J1939 handles packets of 8+ bytes with **Transport Protocol** fragmentation transparently. +No fixed data size is necessary. + + send(sock, data, 8, 0); + +will emit a single CAN frame. + + send(sock, data, 9, 0); + +will use fragementation, emitting 1+ CAN frames. + +# Enable j1939 + +CAN has no protocol id field. +Enabling protocols must be done manually + +### netlink + + ip link set can0 j1939 on + +### procfs for legacy kernel (2.6.25) + +This API is dropped for kernels with netlink support! + + echo can0 > /proc/net/can-j1939/net + +# Using J1939 + +## BSD socket implementation +* socket +* bind / connect +* recvfrom / sendto +* getsockname / getpeername + +## Modified *struct sockaddr_can* + + struct sockaddr_can { + sa_family_t can_family; + int can_ifindex; + union { + struct { + __u64 name; + __u32 pgn; + __u8 addr; + } j1939; + } can_addr; + } + +* *can_addr.j1939.pgn* is PGN + +* *can_addr.j1939.addr* & *can_addr.j1939.name* + determine the ECU + + * receiving address information, + *addr* is always set, + *name* is set when available. + + * When providing address information, + *name* != 0 indicates dynamic addressing + +## iproute2 + +### Static addressing + + ip addr add j1939 0x80 dev can0 + +### Dynamic addressing + + ip addr add j1939 name 0x012345678abcdef dev can0 + +# First steps with j1939 + +Use [testj1939](testj1939.c) + +Load modules, when vcan & can-j1939 are not in-kernel + + modprobe vcan + modprobe can-j1939 + +### create virtual CAN bus + +Make sure *can0* is available, or replace *can0* with *vcan0* + + ip link add can0 type vcan + +### enable CAN + + ip link set can0 up + +### enable j1939 + + modprobe can-j1939 + +### receive without source address + +Do in terminal 1 + + ./testj1939 -r can0: + +Send raw CAN in terminal 2 + + cansend can0 1823ff40#0123 + +You should have this output in terminal 1 + + 40 02300: 01 23 + +This means, from NAME 0, SA 40, PGN 02300 was received, +with 2 databytes, *01* & *02*. + +now emit this CAN message: + + cansend can0 18234140#0123 + +In J1939, this means that ECU 0x40 sends directly to ECU 0x41 +Since we did not bind to address 0x41, this traffic +is not meant for us. + +### Use source address + + ./testj1939 can0:0x80 + +will say + + ./testj1939: bind(): Cannot assign requested address + +Since J1939 maintains addressing, **0x80** has not yet been assigned +as an address on **can0** . This behaviour is very similar to IP +addressing: you cannot bind to an address that is not your own. + +Now tell the kernel that we *own* address 0x80. +It will be available from now on. + + ip addr add j1939 0x80 dev can0 + ./testj1939 can0:0x80 + +now succeeds. + +### receive with source address + +Terminal 1: + + ./testj1939 -r can0:0x80 + +Terminal 2: + + cansend can0 18238040#0123 + +Will emit this output + + 40 02300: 01 23 + +This is because the traffic had destination address __0x80__ . + +### send + +Open in terminal 1: + + candump -L can0 + +And to these test in another terminal + + ./testj1939 -s can0:0x80 + +This produces **1BFFFF80#0123456789ABCDEF** on CAN. + +### Multiple source addresses on 1 CAN device + + ip addr add j1939 0x90 dev can0 + + ./testj1939 -s can0:0x90 + +produces **1BFFFF90#0123456789ABCDEF** , + + ./testj1939 -s can0: + +still produces **1BFFFF80#0123456789ABCDEF** , since **0x80** +is the default _source address_. +Check + + ip addr show can0 + +emits + + X: can0: mtu 16 qdisc noqueue state UNKNOWN + link/can + can-j1939 0x80 scope link + can-j1939 0x90 scope link + +0x80 is the first address on can0. + +### Use specific PGN + + ./testj1939 -s can0:,0x12345 + +emits **1923FF80#0123456789ABCDEF** . + +Note that the real PGN is **0x12300**, and destination address is **0xff**. + +### Emit destination specific packets + +The destination field may be set during sendto(). +*testj1939* implements that like this + + ./testj1939 -s can0:,0x12345 can0:0x40 + +emits **19234080#0123456789ABCDEF** . + +The destination CAN iface __must__ always match the source CAN iface. +Specifing one during bind is therefore sufficient. + + ./testj1939 -s can0:,0x12300 :0x40 + +emits the very same. + +### Emit different PGNs using the same socket + +The PGN is provided in both __bind( *sockname* )__ and +__sendto( *peername* )__ , and only one is used. +*peername* PGN has highest precedence. + + ./testj1939 -s can0:,0x12300 :0x40,0x32100 + +emits **1B214080#0123456789ABCDEF** . +It makes sometimes sense to omit the PGN in __bind( *sockname* )__ . + +### Larger packets + +J1939 transparently switches to *Transport Protocol* when packets +do not fit into single CAN packets. + + ./testj1939 -s20 can0:0x80 :,0x12300 + +emits: + + 18ECFF80#20140003FF002301 + 18EBFF80#010123456789ABCD + 18EBFF80#02EF0123456789AB + 18EBFF80#03CDEF01234567 + +The fragments for broadcasted *Transport Protocol* are seperated +__50ms__ from each other. +Destination specific *Transport Protocol* applies flow control +and may emit CAN packets much faster. + + ./testj1939 -s20 can0:0x80 :0x90,0x12300 + +emits: + + 18EC9080#1014000303002301 + 18EC8090#110301FFFF002301 + 18EB9080#010123456789ABCD + 18EB9080#02EF0123456789AB + 18EB9080#03CDEF01234567 + 18EC8090#13140003FF002301 + +The flow control causes a bit overhead. +This overhead scales very good for larger J1939 packets. + +# Advanced topics with j1939 + +### Change priority of J1939 packets + + ./testj1939 -s can0:0x80,0x0100 + ./testj1939 -s -p3 can0:0x80,0x0200 + +emits + + 1801FF80#0123456789ABCDEF + 0C02FF80#0123456789ABCDEF + +### using connect + +## dynamic addressing + diff --git a/page.theme b/page.theme new file mode 100644 index 0000000..e850a9b --- /dev/null +++ b/page.theme @@ -0,0 +1,21 @@ + + + + page: <?theme title?> + + + + +
+ +
+ + + + + diff --git a/style.css b/style.css new file mode 100644 index 0000000..6be67d2 --- /dev/null +++ b/style.css @@ -0,0 +1,68 @@ +* { + font-family: Helvetica Neue, Helvetica, Arial, sans-serif; +} +body { + max-width: 60em; + margin: 0 auto; + color: #111; +} + +pre, code { + font-family: Monaco, Courier New, monospace; + font-size: 11px; +} + +h1 { + color: rgb(43,105,145); + font-weight: bold; + font-size: 40px; + letter-spacing: -1px; + margin-bottom: -5px; + margin: 0; +} +h1 code { + font-size: 32px; +} + +h2 { + color: rgb(43,105,145); + font-weight: bold; + margin-bottom: -5px; +} +h2 code { + font-size: 22px; +} + +h3 { + margin-bottom: -5px; +} +h3 code { + font-size: 16px; +} + +a { + color: blue; + text-decoration: none; +} +a:visited { + color: navy; +} +a:hover { + text-decoration: underline; +} + +pre { + border-width: 1px; + border-color: #777; + border-style: solid; + padding: 0.5em; + background-color: #ccc; + overflow: auto; + color: #000; + font-weight: bold; +} + +p, li { + font-size: 13px; + line-height: 18px; +} diff --git a/testj1939.c b/testj1939.c new file mode 100644 index 0000000..fb3cba1 --- /dev/null +++ b/testj1939.c @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2013 EIA Electronics + * + * Authors: + * Kurt Van Dijck + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the version 2 of the GNU General Public License + * as published by the Free Software Foundation + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +static const char help_msg[] = + "testj1939: demonstrate j1939 use\n" + "Usage: testj1939 FROM TO\n" + " FROM / TO - or [IFACE][:[SA][,[PGN][,NAME]]]\n" + "Options:\n" + " -s[=LEN] Initial send of LEN bytes dummy data\n" + " -r Receive (and print) data\n" + " -e Echo incoming packets back\n" + " This atually receives packets\n" + " -c Issue connect()\n" + " -p=PRIO Set priority to PRIO\n" + " -n Emit 64bit NAMEs in output\n" + "\n" + "Example:\n" + "testj1939 can1 20\n" + "\n" + ; + +static const char optstring[] = "?vs::rep:cn"; + +static void parse_canaddr(char *spec, struct sockaddr_can *paddr) +{ + char *str; + + str = strsep(&spec, ":"); + if (strlen(str)) + paddr->can_ifindex = if_nametoindex(str); + + str = strsep(&spec, ","); + if (str && strlen(str)) + paddr->can_addr.j1939.addr = strtoul(str, NULL, 0); + + str = strsep(&spec, ","); + if (str && strlen(str)) + paddr->can_addr.j1939.pgn = strtoul(str, NULL, 0); + + str = strsep(&spec, ","); + if (str && strlen(str)) + paddr->can_addr.j1939.name = strtoul(str, NULL, 0); +} + +/* main */ +int main(int argc, char *argv[]) +{ + int ret, sock, opt, j; + socklen_t peernamelen; + struct sockaddr_can sockname = { + .can_family = AF_CAN, + .can_addr.j1939 = { + .addr = J1939_NO_ADDR, + .name = J1939_NO_NAME, + .pgn = J1939_NO_PGN, + }, + }, peername = { + .can_family = AF_CAN, + .can_addr.j1939 = { + .addr = J1939_NO_ADDR, + .name = J1939_NO_NAME, + .pgn = J1939_NO_PGN, + }, + }; + uint8_t dat[128]; + int todo_send = 0, todo_recv = 0, todo_echo = 0, todo_prio = -1; + int todo_connect = 0, todo_names = 0; + + /* argument parsing */ + while ((opt = getopt(argc, argv, optstring)) != -1) + switch (opt) { + case 's': + todo_send = strtoul(optarg ?: "8", NULL, 0); + break; + case 'r': + todo_recv = 1; + break; + case 'e': + todo_echo = 1; + break; + case 'p': + todo_prio = strtoul(optarg, NULL, 0); + break; + case 'c': + todo_connect = 1; + break; + case 'n': + todo_names = 1; + break; + default: + fputs(help_msg, stderr); + exit(1); + break; + } + + if (argv[optind]) { + if (strcmp("-", argv[optind])) + parse_canaddr(argv[optind], &sockname); + ++optind; + } + + if (argv[optind]) { + if (strcmp("-", argv[optind])) + parse_canaddr(argv[optind], &peername); + ++optind; + } + + /* open socket */ + sock = ret = socket(PF_CAN, SOCK_DGRAM, CAN_J1939); + if (ret < 0) + error(1, errno, "socket(j1939)"); + + if (todo_prio >= 0) { + ret = setsockopt(sock, SOL_CAN_J1939, SO_J1939_SEND_PRIO, + &todo_prio, sizeof(todo_prio)); + if (ret < 0) + error(1, errno, "set priority %i", todo_prio); + } + + ret = bind(sock, (void *)&sockname, sizeof(sockname)); + if (ret < 0) + error(1, errno, "bind()"); + + if (todo_connect) { + ret = connect(sock, (void *)&peername, sizeof(peername)); + if (ret < 0) + error(1, errno, "connect()"); + } + + if (todo_send) { + /* initialize test vector */ + for (j = 0; j < sizeof(dat); ++j) + dat[j] = ((2*j) << 4) + ((2*j+1) & 0xf); + + /* send data */ + ret = sendto(sock, dat, todo_send, 0, + (void *)&peername, sizeof(peername)); + if (ret < 0) + error(1, errno, "sendto"); + } + + /* main loop */ + while (todo_echo || todo_recv) { + /* + * re-use peername for storing the sender's peername of + * received packets + */ + peernamelen = sizeof(peername); + ret = recvfrom(sock, dat, sizeof(dat), 0, + (void *)&peername, &peernamelen); + if (ret < 0) { + if (EINTR == errno) + continue; + error(1, errno, "recvfrom()"); + } + + if (todo_echo) { + ret = sendto(sock, dat, ret, 0, + (void *)&peername, peernamelen); + if (ret < 0) + error(1, errno, "sendto"); + } + if (todo_recv) { + if (todo_names && peername.can_addr.j1939.name) + printf("%016llx ", peername.can_addr.j1939.name); + printf("%02x %05x:", peername.can_addr.j1939.addr, + peername.can_addr.j1939.pgn); + for (j = 0; j < ret; ++j) + printf(" %02x", dat[j]); + printf("\n"); + } + } + return 0; +} + From 77c08edead0227b5246003c8d0fbbcf75336d80c Mon Sep 17 00:00:00 2001 From: Kurt Van Dijck Date: Wed, 20 Nov 2013 11:20:24 +0100 Subject: [PATCH 03/23] add .gitignore --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..eeaa484 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +# output +testj1939 +j1939.html From d66e6ce4eea1db529a765e73243b842edc8d1756 Mon Sep 17 00:00:00 2001 From: Kurt Van Dijck Date: Wed, 20 Nov 2013 11:17:27 +0100 Subject: [PATCH 04/23] testj1939: remember if peername was provided When peername was not provided, the program uses send() rather than sendto() so the API calls are better demonstrated --- testj1939.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/testj1939.c b/testj1939.c index fb3cba1..aa9ca20 100644 --- a/testj1939.c +++ b/testj1939.c @@ -88,6 +88,7 @@ int main(int argc, char *argv[]) }, }; uint8_t dat[128]; + int valid_peername = 0; int todo_send = 0, todo_recv = 0, todo_echo = 0, todo_prio = -1; int todo_connect = 0, todo_names = 0; @@ -125,8 +126,10 @@ int main(int argc, char *argv[]) } if (argv[optind]) { - if (strcmp("-", argv[optind])) + if (strcmp("-", argv[optind])) { parse_canaddr(argv[optind], &peername); + valid_peername = 1; + } ++optind; } @@ -147,6 +150,8 @@ int main(int argc, char *argv[]) error(1, errno, "bind()"); if (todo_connect) { + if (!valid_peername) + error(1, 0, "no peername supplied"); ret = connect(sock, (void *)&peername, sizeof(peername)); if (ret < 0) error(1, errno, "connect()"); @@ -158,8 +163,16 @@ int main(int argc, char *argv[]) dat[j] = ((2*j) << 4) + ((2*j+1) & 0xf); /* send data */ - ret = sendto(sock, dat, todo_send, 0, - (void *)&peername, sizeof(peername)); + if (valid_peername) + ret = sendto(sock, dat, todo_send, 0, + (void *)&peername, sizeof(peername)); + else + /* + * we may do sendto(sock, dat, todo_send, 0, NULL, 0) + * as well, but using send() demonstrates the API better + */ + ret = send(sock, dat, todo_send, 0); + if (ret < 0) error(1, errno, "sendto"); } From 854f47fa84879ef4778e444ec61c7b11f8c878f7 Mon Sep 17 00:00:00 2001 From: Kurt Van Dijck Date: Wed, 20 Nov 2013 11:19:40 +0100 Subject: [PATCH 05/23] testj1939: use send() when connect()ed When using connect(), don't re-use the peername but use send() without destination information --- testj1939.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/testj1939.c b/testj1939.c index aa9ca20..f3b61df 100644 --- a/testj1939.c +++ b/testj1939.c @@ -163,7 +163,11 @@ int main(int argc, char *argv[]) dat[j] = ((2*j) << 4) + ((2*j+1) & 0xf); /* send data */ - if (valid_peername) + /* + * when using connect, do not provide additional + * destination information and use send() + */ + if (valid_peername && !todo_connect) ret = sendto(sock, dat, todo_send, 0, (void *)&peername, sizeof(peername)); else From 7fb5f009fd5b172f264666fc6a565264bfd5d629 Mon Sep 17 00:00:00 2001 From: Kurt Van Dijck Date: Thu, 28 Nov 2013 09:56:37 +0100 Subject: [PATCH 06/23] j1939.page: restructure --- j1939.page | 63 ++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 44 insertions(+), 19 deletions(-) diff --git a/j1939.page b/j1939.page index 1a8f2a5..9ab6ba4 100644 --- a/j1939.page +++ b/j1939.page @@ -120,29 +120,38 @@ This API is dropped for kernels with netlink support! ip addr add j1939 name 0x012345678abcdef dev can0 -# First steps with j1939 +# Kickstart guide to j1939 on linux + +## Prepare using VCAN + +You may skip this step entirely if you have a functional +**can0** bus on your system. + +Load module, when *vcan* is not in-kernel + + modprobe vcan + +Create a virtual can0 device and start the device + + ip link add can0 type vcan + ip link set can0 up + +## First steps with j1939 Use [testj1939](testj1939.c) -Load modules, when vcan & can-j1939 are not in-kernel - - modprobe vcan - modprobe can-j1939 - -### create virtual CAN bus - -Make sure *can0* is available, or replace *can0* with *vcan0* - - ip link add can0 type vcan - -### enable CAN - - ip link set can0 up - -### enable j1939 +When *can-j1939* is compiled as module, load it. modprobe can-j1939 +Enable the j1939 protocol stack on the CAN device + + ip link set can0 j1939 on + +Most of the subsequent examples will use 2 sockets programs (in 2 terminals). +One will use CAN_J1939 sockets using *testj1939*, +and the other will use CAN_RAW sockets using cansend+candump. + ### receive without source address Do in terminal 1 @@ -166,7 +175,7 @@ now emit this CAN message: In J1939, this means that ECU 0x40 sends directly to ECU 0x41 Since we did not bind to address 0x41, this traffic -is not meant for us. +is not meant for us and *testj1939* does not receive it. ### Use source address @@ -216,6 +225,11 @@ And to these test in another terminal This produces **1BFFFF80#0123456789ABCDEF** on CAN. + ./testj1939 -s can0: + +will produce exactly the same because **0x80** is the only +address currently assigned to **can0:** and is used by default. + ### Multiple source addresses on 1 CAN device ip addr add j1939 0x90 dev can0 @@ -271,9 +285,18 @@ The PGN is provided in both __bind( *sockname* )__ and __sendto( *peername* )__ , and only one is used. *peername* PGN has highest precedence. +For broadcasted transmissions + + ./testj1939 -s can0:,0x12300 :,0x32100 + +emits **1B21FF80#0123456789ABCDEF** rather than 1923FF80#012345678ABCDEF + +Desitination specific transmissions + ./testj1939 -s can0:,0x12300 :0x40,0x32100 emits **1B214080#0123456789ABCDEF** . + It makes sometimes sense to omit the PGN in __bind( *sockname* )__ . ### Larger packets @@ -309,7 +332,7 @@ emits: The flow control causes a bit overhead. This overhead scales very good for larger J1939 packets. -# Advanced topics with j1939 +## Advanced topics with j1939 ### Change priority of J1939 packets @@ -323,5 +346,7 @@ emits ### using connect +### advanced filtering + ## dynamic addressing From 234729507ee07174237908cd5d78cc4d1c740369 Mon Sep 17 00:00:00 2001 From: Kurt Van Dijck Date: Thu, 28 Nov 2013 09:56:54 +0100 Subject: [PATCH 07/23] j1939.page: add relevant API calls --- j1939.page | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/j1939.page b/j1939.page index 9ab6ba4..f9c593e 100644 --- a/j1939.page +++ b/j1939.page @@ -152,6 +152,10 @@ Most of the subsequent examples will use 2 sockets programs (in 2 terminals). One will use CAN_J1939 sockets using *testj1939*, and the other will use CAN_RAW sockets using cansend+candump. +Where I think it's relevant, I added the core API calls that *testj1939* used +because *testj1939* may look too generic to appreciate the degree of control +that the API exposes. + ### receive without source address Do in terminal 1 @@ -177,6 +181,14 @@ In J1939, this means that ECU 0x40 sends directly to ECU 0x41 Since we did not bind to address 0x41, this traffic is not meant for us and *testj1939* does not receive it. +*testj1939* used these calls: + + sock = ret = socket(PF_CAN, SOCK_DGRAM, CAN_J1939); + ret = bind(sock, (void *)&sockname, sizeof(sockname)); + while (1) + ret = recvfrom(sock, dat, sizeof(dat), 0, + (void *)&peername, &peernamelen); + ### Use source address ./testj1939 can0:0x80 @@ -230,6 +242,12 @@ This produces **1BFFFF80#0123456789ABCDEF** on CAN. will produce exactly the same because **0x80** is the only address currently assigned to **can0:** and is used by default. +*testj1939* used these calls: + + sock = ret = socket(PF_CAN, SOCK_DGRAM, CAN_J1939); + ret = bind(sock, (void *)&sockname, sizeof(sockname)); + ret = send(sock, dat, todo_send, 0); + ### Multiple source addresses on 1 CAN device ip addr add j1939 0x90 dev can0 @@ -279,6 +297,13 @@ Specifing one during bind is therefore sufficient. emits the very same. +*testj1939* used these calls: + + sock = ret = socket(PF_CAN, SOCK_DGRAM, CAN_J1939); + ret = bind(sock, (void *)&sockname, sizeof(sockname)); + ret = sendto(sock, dat, todo_send, 0, + (void *)&peername, sizeof(peername)); + ### Emit different PGNs using the same socket The PGN is provided in both __bind( *sockname* )__ and @@ -299,6 +324,13 @@ emits **1B214080#0123456789ABCDEF** . It makes sometimes sense to omit the PGN in __bind( *sockname* )__ . +*testj1939* used these calls, even for the broadcasted transmission: + + sock = ret = socket(PF_CAN, SOCK_DGRAM, CAN_J1939); + ret = bind(sock, (void *)&sockname, sizeof(sockname)); + ret = sendto(sock, dat, todo_send, 0, + (void *)&peername, sizeof(peername)); + ### Larger packets J1939 transparently switches to *Transport Protocol* when packets @@ -313,6 +345,13 @@ emits: 18EBFF80#02EF0123456789AB 18EBFF80#03CDEF01234567 +*testj1939* used these same calls: + + sock = ret = socket(PF_CAN, SOCK_DGRAM, CAN_J1939); + ret = bind(sock, (void *)&sockname, sizeof(sockname)); + ret = sendto(sock, dat, todo_send, 0, + (void *)&peername, sizeof(peername)); + The fragments for broadcasted *Transport Protocol* are seperated __50ms__ from each other. Destination specific *Transport Protocol* applies flow control @@ -344,6 +383,14 @@ emits 1801FF80#0123456789ABCDEF 0C02FF80#0123456789ABCDEF +*testj1939* used these calls for modified priority: + + sock = ret = socket(PF_CAN, SOCK_DGRAM, CAN_J1939); + ret = setsockopt(sock, SOL_CAN_J1939, SO_J1939_SEND_PRIO, + &todo_prio, sizeof(todo_prio)); + ret = bind(sock, (void *)&sockname, sizeof(sockname)); + ret = send(sock, dat, todo_send, 0); + ### using connect ### advanced filtering From 75dfd666c4eb355532ee753ccf89f5c7d62579e7 Mon Sep 17 00:00:00 2001 From: Kurt Van Dijck Date: Thu, 28 Nov 2013 10:12:00 +0100 Subject: [PATCH 08/23] testj1939: print API calls --- testj1939.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 52 insertions(+), 4 deletions(-) diff --git a/testj1939.c b/testj1939.c index f3b61df..8524f5b 100644 --- a/testj1939.c +++ b/testj1939.c @@ -31,6 +31,7 @@ static const char help_msg[] = "Usage: testj1939 FROM TO\n" " FROM / TO - or [IFACE][:[SA][,[PGN][,NAME]]]\n" "Options:\n" + " -v Print relevant API calls\n" " -s[=LEN] Initial send of LEN bytes dummy data\n" " -r Receive (and print) data\n" " -e Echo incoming packets back\n" @@ -67,10 +68,32 @@ static void parse_canaddr(char *spec, struct sockaddr_can *paddr) paddr->can_addr.j1939.name = strtoul(str, NULL, 0); } +static const char *canaddr2str(const struct sockaddr_can *paddr) +{ + static char buf[128]; + char *str = buf; + char ifname[IF_NAMESIZE]; + + if (paddr->can_ifindex) + str += sprintf(str, "%s", if_indextoname(paddr->can_ifindex, ifname)); + *str++ = ':'; + + if (paddr->can_addr.j1939.addr != J1939_NO_ADDR) + str += sprintf(str, "%02x", paddr->can_addr.j1939.addr); + *str++ = ','; + if (paddr->can_addr.j1939.pgn != J1939_NO_PGN) + str += sprintf(str, "%05x", paddr->can_addr.j1939.pgn); + *str++ = ','; + if (paddr->can_addr.j1939.name != J1939_NO_NAME) + str += sprintf(str, "%016llx", paddr->can_addr.j1939.name); + *str++ = 0; + return buf; +} + /* main */ int main(int argc, char *argv[]) { - int ret, sock, opt, j; + int ret, sock, opt, j, verbose; socklen_t peernamelen; struct sockaddr_can sockname = { .can_family = AF_CAN, @@ -95,6 +118,9 @@ int main(int argc, char *argv[]) /* argument parsing */ while ((opt = getopt(argc, argv, optstring)) != -1) switch (opt) { + case 'v': + verbose = 1; + break; case 's': todo_send = strtoul(optarg ?: "8", NULL, 0); break; @@ -134,17 +160,23 @@ int main(int argc, char *argv[]) } /* open socket */ + if (verbose) + fprintf(stderr, "- socket(PF_CAN, SOCK_DGRAM, CAN_J1939);\n"); sock = ret = socket(PF_CAN, SOCK_DGRAM, CAN_J1939); if (ret < 0) error(1, errno, "socket(j1939)"); if (todo_prio >= 0) { + if (verbose) + fprintf(stderr, "- setsockopt(, SOL_CAN_J1939, SO_J1939_SEND_PRIO, &%i);\n", todo_prio); ret = setsockopt(sock, SOL_CAN_J1939, SO_J1939_SEND_PRIO, &todo_prio, sizeof(todo_prio)); if (ret < 0) error(1, errno, "set priority %i", todo_prio); } + if (verbose) + fprintf(stderr, "- bind(, %s, %li);\n", canaddr2str(&sockname), sizeof(sockname)); ret = bind(sock, (void *)&sockname, sizeof(sockname)); if (ret < 0) error(1, errno, "bind()"); @@ -152,6 +184,8 @@ int main(int argc, char *argv[]) if (todo_connect) { if (!valid_peername) error(1, 0, "no peername supplied"); + if (verbose) + fprintf(stderr, "- connect(, %s, %li);\n", canaddr2str(&peername), sizeof(peername)); ret = connect(sock, (void *)&peername, sizeof(peername)); if (ret < 0) error(1, errno, "connect()"); @@ -167,36 +201,50 @@ int main(int argc, char *argv[]) * when using connect, do not provide additional * destination information and use send() */ - if (valid_peername && !todo_connect) + if (valid_peername && !todo_connect) { + if (verbose) + fprintf(stderr, "- sendto(, , %i, 0, %s, %li);\n", todo_send, canaddr2str(&peername), sizeof(peername)); ret = sendto(sock, dat, todo_send, 0, (void *)&peername, sizeof(peername)); - else + } else { /* * we may do sendto(sock, dat, todo_send, 0, NULL, 0) * as well, but using send() demonstrates the API better */ + if (verbose) + fprintf(stderr, "- send(, , %i, 0);\n", todo_send); ret = send(sock, dat, todo_send, 0); + } if (ret < 0) error(1, errno, "sendto"); } /* main loop */ + if ((todo_echo || todo_recv) && verbose) + fprintf(stderr, "- while (1)\n"); while (todo_echo || todo_recv) { /* * re-use peername for storing the sender's peername of * received packets */ + if (verbose) + fprintf(stderr, "- recvfrom(, , %li, 0, &, %li);\n", sizeof(peername), sizeof(peername)); peernamelen = sizeof(peername); ret = recvfrom(sock, dat, sizeof(dat), 0, (void *)&peername, &peernamelen); if (ret < 0) { - if (EINTR == errno) + if (EINTR == errno) { + if (verbose) + fprintf(stderr, "-\t\n"); continue; + } error(1, errno, "recvfrom()"); } if (todo_echo) { + if (verbose) + fprintf(stderr, "- sendto(, , %i, 0, %s, %i);\n", ret, canaddr2str(&peername), peernamelen); ret = sendto(sock, dat, ret, 0, (void *)&peername, peernamelen); if (ret < 0) From 8e199945be50c349f3fcd64f707f726c5d2eddad Mon Sep 17 00:00:00 2001 From: Kurt Van Dijck Date: Thu, 28 Nov 2013 11:00:19 +0100 Subject: [PATCH 09/23] Revert "j1939.page: add relevant API calls" This reverts commit 234729507ee07174237908cd5d78cc4d1c740369. --- j1939.page | 47 +---------------------------------------------- 1 file changed, 1 insertion(+), 46 deletions(-) diff --git a/j1939.page b/j1939.page index f9c593e..b9592e8 100644 --- a/j1939.page +++ b/j1939.page @@ -152,9 +152,7 @@ Most of the subsequent examples will use 2 sockets programs (in 2 terminals). One will use CAN_J1939 sockets using *testj1939*, and the other will use CAN_RAW sockets using cansend+candump. -Where I think it's relevant, I added the core API calls that *testj1939* used -because *testj1939* may look too generic to appreciate the degree of control -that the API exposes. +testj1939 can be told to print the used API calls by adding **-v** program argument. ### receive without source address @@ -181,14 +179,6 @@ In J1939, this means that ECU 0x40 sends directly to ECU 0x41 Since we did not bind to address 0x41, this traffic is not meant for us and *testj1939* does not receive it. -*testj1939* used these calls: - - sock = ret = socket(PF_CAN, SOCK_DGRAM, CAN_J1939); - ret = bind(sock, (void *)&sockname, sizeof(sockname)); - while (1) - ret = recvfrom(sock, dat, sizeof(dat), 0, - (void *)&peername, &peernamelen); - ### Use source address ./testj1939 can0:0x80 @@ -242,12 +232,6 @@ This produces **1BFFFF80#0123456789ABCDEF** on CAN. will produce exactly the same because **0x80** is the only address currently assigned to **can0:** and is used by default. -*testj1939* used these calls: - - sock = ret = socket(PF_CAN, SOCK_DGRAM, CAN_J1939); - ret = bind(sock, (void *)&sockname, sizeof(sockname)); - ret = send(sock, dat, todo_send, 0); - ### Multiple source addresses on 1 CAN device ip addr add j1939 0x90 dev can0 @@ -297,13 +281,6 @@ Specifing one during bind is therefore sufficient. emits the very same. -*testj1939* used these calls: - - sock = ret = socket(PF_CAN, SOCK_DGRAM, CAN_J1939); - ret = bind(sock, (void *)&sockname, sizeof(sockname)); - ret = sendto(sock, dat, todo_send, 0, - (void *)&peername, sizeof(peername)); - ### Emit different PGNs using the same socket The PGN is provided in both __bind( *sockname* )__ and @@ -324,13 +301,6 @@ emits **1B214080#0123456789ABCDEF** . It makes sometimes sense to omit the PGN in __bind( *sockname* )__ . -*testj1939* used these calls, even for the broadcasted transmission: - - sock = ret = socket(PF_CAN, SOCK_DGRAM, CAN_J1939); - ret = bind(sock, (void *)&sockname, sizeof(sockname)); - ret = sendto(sock, dat, todo_send, 0, - (void *)&peername, sizeof(peername)); - ### Larger packets J1939 transparently switches to *Transport Protocol* when packets @@ -345,13 +315,6 @@ emits: 18EBFF80#02EF0123456789AB 18EBFF80#03CDEF01234567 -*testj1939* used these same calls: - - sock = ret = socket(PF_CAN, SOCK_DGRAM, CAN_J1939); - ret = bind(sock, (void *)&sockname, sizeof(sockname)); - ret = sendto(sock, dat, todo_send, 0, - (void *)&peername, sizeof(peername)); - The fragments for broadcasted *Transport Protocol* are seperated __50ms__ from each other. Destination specific *Transport Protocol* applies flow control @@ -383,14 +346,6 @@ emits 1801FF80#0123456789ABCDEF 0C02FF80#0123456789ABCDEF -*testj1939* used these calls for modified priority: - - sock = ret = socket(PF_CAN, SOCK_DGRAM, CAN_J1939); - ret = setsockopt(sock, SOL_CAN_J1939, SO_J1939_SEND_PRIO, - &todo_prio, sizeof(todo_prio)); - ret = bind(sock, (void *)&sockname, sizeof(sockname)); - ret = send(sock, dat, todo_send, 0); - ### using connect ### advanced filtering From a14f4448ee1b664bc930258117f2a04191d14d23 Mon Sep 17 00:00:00 2001 From: Kurt Van Dijck Date: Fri, 11 Dec 2015 04:09:40 +0100 Subject: [PATCH 10/23] Initial commit --- LICENSE | 675 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 675 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..733c072 --- /dev/null +++ b/LICENSE @@ -0,0 +1,675 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + {project} Copyright (C) {year} {fullname} + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. + From 4f1026e9ffc0097595962e862da884bcf3135289 Mon Sep 17 00:00:00 2001 From: Kurt Van Dijck Date: Fri, 11 Dec 2015 04:16:31 +0100 Subject: [PATCH 11/23] prepare for github --- .gitignore | 2 +- Makefile | 8 ++++---- j1939.page => Readme.md | 0 3 files changed, 5 insertions(+), 5 deletions(-) rename j1939.page => Readme.md (100%) diff --git a/.gitignore b/.gitignore index eeaa484..43182eb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ # output testj1939 -j1939.html +Readme.html diff --git a/Makefile b/Makefile index ee9b43c..06bf09a 100644 --- a/Makefile +++ b/Makefile @@ -1,11 +1,11 @@ -OUTPUT = j1939.html testj1939 -default: $(OUTPUT) +default: testj1939 +all: default j1939.html -%.html: %.page page.theme +%.html: %.md page.theme theme -f -o $@ $< -p "$*" CFLAGS = -Wall -g3 -O0 clean: - rm -f $(wildcard *.o) $(OUTPUT) + rm -f testj1939 j1939.html diff --git a/j1939.page b/Readme.md similarity index 100% rename from j1939.page rename to Readme.md From 7644a013cd2f9ac79efa63ab75a706381efca171 Mon Sep 17 00:00:00 2001 From: Kurt Van Dijck Date: Fri, 11 Dec 2015 04:22:19 +0100 Subject: [PATCH 12/23] split in Readme+Kickstart guide --- Makefile | 2 +- Readme.md | 234 +---------------------------------------- can-j1939-kickstart.md | 232 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 235 insertions(+), 233 deletions(-) create mode 100644 can-j1939-kickstart.md diff --git a/Makefile b/Makefile index 06bf09a..ba2b089 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ default: testj1939 -all: default j1939.html +all: default $(patsubst %.md, %.html, $(wildcard *.md)) %.html: %.md page.theme theme -f -o $@ $< -p "$*" diff --git a/Readme.md b/Readme.md index b9592e8..0a23ca6 100644 --- a/Readme.md +++ b/Readme.md @@ -1,5 +1,7 @@ # CAN-J1939 on linux +The [can-j1939-kickstart](Kickstart guide is here) + ## CAN on linux See [Wikipedia:socketcan](http://en.wikipedia.org/wiki/Socketcan) @@ -120,235 +122,3 @@ This API is dropped for kernels with netlink support! ip addr add j1939 name 0x012345678abcdef dev can0 -# Kickstart guide to j1939 on linux - -## Prepare using VCAN - -You may skip this step entirely if you have a functional -**can0** bus on your system. - -Load module, when *vcan* is not in-kernel - - modprobe vcan - -Create a virtual can0 device and start the device - - ip link add can0 type vcan - ip link set can0 up - -## First steps with j1939 - -Use [testj1939](testj1939.c) - -When *can-j1939* is compiled as module, load it. - - modprobe can-j1939 - -Enable the j1939 protocol stack on the CAN device - - ip link set can0 j1939 on - -Most of the subsequent examples will use 2 sockets programs (in 2 terminals). -One will use CAN_J1939 sockets using *testj1939*, -and the other will use CAN_RAW sockets using cansend+candump. - -testj1939 can be told to print the used API calls by adding **-v** program argument. - -### receive without source address - -Do in terminal 1 - - ./testj1939 -r can0: - -Send raw CAN in terminal 2 - - cansend can0 1823ff40#0123 - -You should have this output in terminal 1 - - 40 02300: 01 23 - -This means, from NAME 0, SA 40, PGN 02300 was received, -with 2 databytes, *01* & *02*. - -now emit this CAN message: - - cansend can0 18234140#0123 - -In J1939, this means that ECU 0x40 sends directly to ECU 0x41 -Since we did not bind to address 0x41, this traffic -is not meant for us and *testj1939* does not receive it. - -### Use source address - - ./testj1939 can0:0x80 - -will say - - ./testj1939: bind(): Cannot assign requested address - -Since J1939 maintains addressing, **0x80** has not yet been assigned -as an address on **can0** . This behaviour is very similar to IP -addressing: you cannot bind to an address that is not your own. - -Now tell the kernel that we *own* address 0x80. -It will be available from now on. - - ip addr add j1939 0x80 dev can0 - ./testj1939 can0:0x80 - -now succeeds. - -### receive with source address - -Terminal 1: - - ./testj1939 -r can0:0x80 - -Terminal 2: - - cansend can0 18238040#0123 - -Will emit this output - - 40 02300: 01 23 - -This is because the traffic had destination address __0x80__ . - -### send - -Open in terminal 1: - - candump -L can0 - -And to these test in another terminal - - ./testj1939 -s can0:0x80 - -This produces **1BFFFF80#0123456789ABCDEF** on CAN. - - ./testj1939 -s can0: - -will produce exactly the same because **0x80** is the only -address currently assigned to **can0:** and is used by default. - -### Multiple source addresses on 1 CAN device - - ip addr add j1939 0x90 dev can0 - - ./testj1939 -s can0:0x90 - -produces **1BFFFF90#0123456789ABCDEF** , - - ./testj1939 -s can0: - -still produces **1BFFFF80#0123456789ABCDEF** , since **0x80** -is the default _source address_. -Check - - ip addr show can0 - -emits - - X: can0: mtu 16 qdisc noqueue state UNKNOWN - link/can - can-j1939 0x80 scope link - can-j1939 0x90 scope link - -0x80 is the first address on can0. - -### Use specific PGN - - ./testj1939 -s can0:,0x12345 - -emits **1923FF80#0123456789ABCDEF** . - -Note that the real PGN is **0x12300**, and destination address is **0xff**. - -### Emit destination specific packets - -The destination field may be set during sendto(). -*testj1939* implements that like this - - ./testj1939 -s can0:,0x12345 can0:0x40 - -emits **19234080#0123456789ABCDEF** . - -The destination CAN iface __must__ always match the source CAN iface. -Specifing one during bind is therefore sufficient. - - ./testj1939 -s can0:,0x12300 :0x40 - -emits the very same. - -### Emit different PGNs using the same socket - -The PGN is provided in both __bind( *sockname* )__ and -__sendto( *peername* )__ , and only one is used. -*peername* PGN has highest precedence. - -For broadcasted transmissions - - ./testj1939 -s can0:,0x12300 :,0x32100 - -emits **1B21FF80#0123456789ABCDEF** rather than 1923FF80#012345678ABCDEF - -Desitination specific transmissions - - ./testj1939 -s can0:,0x12300 :0x40,0x32100 - -emits **1B214080#0123456789ABCDEF** . - -It makes sometimes sense to omit the PGN in __bind( *sockname* )__ . - -### Larger packets - -J1939 transparently switches to *Transport Protocol* when packets -do not fit into single CAN packets. - - ./testj1939 -s20 can0:0x80 :,0x12300 - -emits: - - 18ECFF80#20140003FF002301 - 18EBFF80#010123456789ABCD - 18EBFF80#02EF0123456789AB - 18EBFF80#03CDEF01234567 - -The fragments for broadcasted *Transport Protocol* are seperated -__50ms__ from each other. -Destination specific *Transport Protocol* applies flow control -and may emit CAN packets much faster. - - ./testj1939 -s20 can0:0x80 :0x90,0x12300 - -emits: - - 18EC9080#1014000303002301 - 18EC8090#110301FFFF002301 - 18EB9080#010123456789ABCD - 18EB9080#02EF0123456789AB - 18EB9080#03CDEF01234567 - 18EC8090#13140003FF002301 - -The flow control causes a bit overhead. -This overhead scales very good for larger J1939 packets. - -## Advanced topics with j1939 - -### Change priority of J1939 packets - - ./testj1939 -s can0:0x80,0x0100 - ./testj1939 -s -p3 can0:0x80,0x0200 - -emits - - 1801FF80#0123456789ABCDEF - 0C02FF80#0123456789ABCDEF - -### using connect - -### advanced filtering - -## dynamic addressing - diff --git a/can-j1939-kickstart.md b/can-j1939-kickstart.md new file mode 100644 index 0000000..b0b4485 --- /dev/null +++ b/can-j1939-kickstart.md @@ -0,0 +1,232 @@ +# Kickstart guide to can-j1939 on linux + +## Prepare using VCAN + +You may skip this step entirely if you have a functional +**can0** bus on your system. + +Load module, when *vcan* is not in-kernel + + modprobe vcan + +Create a virtual can0 device and start the device + + ip link add can0 type vcan + ip link set can0 up + +## First steps with j1939 + +Use [testj1939](testj1939.c) + +When *can-j1939* is compiled as module, load it. + + modprobe can-j1939 + +Enable the j1939 protocol stack on the CAN device + + ip link set can0 j1939 on + +Most of the subsequent examples will use 2 sockets programs (in 2 terminals). +One will use CAN_J1939 sockets using *testj1939*, +and the other will use CAN_RAW sockets using cansend+candump. + +testj1939 can be told to print the used API calls by adding **-v** program argument. + +### receive without source address + +Do in terminal 1 + + ./testj1939 -r can0: + +Send raw CAN in terminal 2 + + cansend can0 1823ff40#0123 + +You should have this output in terminal 1 + + 40 02300: 01 23 + +This means, from NAME 0, SA 40, PGN 02300 was received, +with 2 databytes, *01* & *02*. + +now emit this CAN message: + + cansend can0 18234140#0123 + +In J1939, this means that ECU 0x40 sends directly to ECU 0x41 +Since we did not bind to address 0x41, this traffic +is not meant for us and *testj1939* does not receive it. + +### Use source address + + ./testj1939 can0:0x80 + +will say + + ./testj1939: bind(): Cannot assign requested address + +Since J1939 maintains addressing, **0x80** has not yet been assigned +as an address on **can0** . This behaviour is very similar to IP +addressing: you cannot bind to an address that is not your own. + +Now tell the kernel that we *own* address 0x80. +It will be available from now on. + + ip addr add j1939 0x80 dev can0 + ./testj1939 can0:0x80 + +now succeeds. + +### receive with source address + +Terminal 1: + + ./testj1939 -r can0:0x80 + +Terminal 2: + + cansend can0 18238040#0123 + +Will emit this output + + 40 02300: 01 23 + +This is because the traffic had destination address __0x80__ . + +### send + +Open in terminal 1: + + candump -L can0 + +And to these test in another terminal + + ./testj1939 -s can0:0x80 + +This produces **1BFFFF80#0123456789ABCDEF** on CAN. + + ./testj1939 -s can0: + +will produce exactly the same because **0x80** is the only +address currently assigned to **can0:** and is used by default. + +### Multiple source addresses on 1 CAN device + + ip addr add j1939 0x90 dev can0 + + ./testj1939 -s can0:0x90 + +produces **1BFFFF90#0123456789ABCDEF** , + + ./testj1939 -s can0: + +still produces **1BFFFF80#0123456789ABCDEF** , since **0x80** +is the default _source address_. +Check + + ip addr show can0 + +emits + + X: can0: mtu 16 qdisc noqueue state UNKNOWN + link/can + can-j1939 0x80 scope link + can-j1939 0x90 scope link + +0x80 is the first address on can0. + +### Use specific PGN + + ./testj1939 -s can0:,0x12345 + +emits **1923FF80#0123456789ABCDEF** . + +Note that the real PGN is **0x12300**, and destination address is **0xff**. + +### Emit destination specific packets + +The destination field may be set during sendto(). +*testj1939* implements that like this + + ./testj1939 -s can0:,0x12345 can0:0x40 + +emits **19234080#0123456789ABCDEF** . + +The destination CAN iface __must__ always match the source CAN iface. +Specifing one during bind is therefore sufficient. + + ./testj1939 -s can0:,0x12300 :0x40 + +emits the very same. + +### Emit different PGNs using the same socket + +The PGN is provided in both __bind( *sockname* )__ and +__sendto( *peername* )__ , and only one is used. +*peername* PGN has highest precedence. + +For broadcasted transmissions + + ./testj1939 -s can0:,0x12300 :,0x32100 + +emits **1B21FF80#0123456789ABCDEF** rather than 1923FF80#012345678ABCDEF + +Desitination specific transmissions + + ./testj1939 -s can0:,0x12300 :0x40,0x32100 + +emits **1B214080#0123456789ABCDEF** . + +It makes sometimes sense to omit the PGN in __bind( *sockname* )__ . + +### Larger packets + +J1939 transparently switches to *Transport Protocol* when packets +do not fit into single CAN packets. + + ./testj1939 -s20 can0:0x80 :,0x12300 + +emits: + + 18ECFF80#20140003FF002301 + 18EBFF80#010123456789ABCD + 18EBFF80#02EF0123456789AB + 18EBFF80#03CDEF01234567 + +The fragments for broadcasted *Transport Protocol* are seperated +__50ms__ from each other. +Destination specific *Transport Protocol* applies flow control +and may emit CAN packets much faster. + + ./testj1939 -s20 can0:0x80 :0x90,0x12300 + +emits: + + 18EC9080#1014000303002301 + 18EC8090#110301FFFF002301 + 18EB9080#010123456789ABCD + 18EB9080#02EF0123456789AB + 18EB9080#03CDEF01234567 + 18EC8090#13140003FF002301 + +The flow control causes a bit overhead. +This overhead scales very good for larger J1939 packets. + +## Advanced topics with j1939 + +### Change priority of J1939 packets + + ./testj1939 -s can0:0x80,0x0100 + ./testj1939 -s -p3 can0:0x80,0x0200 + +emits + + 1801FF80#0123456789ABCDEF + 0C02FF80#0123456789ABCDEF + +### using connect + +### advanced filtering + +## dynamic addressing + From bbb2f9af04461cd9412dd65134737dfab381fb96 Mon Sep 17 00:00:00 2001 From: Kurt Van Dijck Date: Fri, 11 Dec 2015 04:23:18 +0100 Subject: [PATCH 13/23] fix link --- Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index 0a23ca6..4fbe567 100644 --- a/Readme.md +++ b/Readme.md @@ -1,6 +1,6 @@ # CAN-J1939 on linux -The [can-j1939-kickstart](Kickstart guide is here) +The [Kickstart guide is here](can-j1939-kickstart) ## CAN on linux From 61b18e7ff13c44a3270000e19fd74848d03232ef Mon Sep 17 00:00:00 2001 From: Kurt Van Dijck Date: Fri, 11 Dec 2015 04:23:58 +0100 Subject: [PATCH 14/23] fix link --- Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index 4fbe567..0331514 100644 --- a/Readme.md +++ b/Readme.md @@ -1,6 +1,6 @@ # CAN-J1939 on linux -The [Kickstart guide is here](can-j1939-kickstart) +The [Kickstart guide is here](can-j1939-kickstart.md) ## CAN on linux From 047356608b2484359782c3f524311ad0b1c410c0 Mon Sep 17 00:00:00 2001 From: Kurt Van Dijck Date: Fri, 11 Dec 2015 04:45:54 +0100 Subject: [PATCH 15/23] update for dropped rtnetlink --- Readme.md | 15 ++++++++- can-j1939-kickstart.md | 74 +++++++++++++----------------------------- 2 files changed, 36 insertions(+), 53 deletions(-) diff --git a/Readme.md b/Readme.md index 0331514..a1f4e85 100644 --- a/Readme.md +++ b/Readme.md @@ -66,12 +66,20 @@ will use fragementation, emitting 1+ CAN frames. # Enable j1939 CAN has no protocol id field. -Enabling protocols must be done manually +Actions need to be performed to enable can-j1939 for a network device + +### on socket connect + +Open a socket and bind to a network interface. + +This is the latest method, and preferred for mainline inclusion ### netlink ip link set can0 j1939 on +This method is obsoleted in favor of _on socket connect_. + ### procfs for legacy kernel (2.6.25) This API is dropped for kernels with netlink support! @@ -114,6 +122,11 @@ This API is dropped for kernels with netlink support! ## iproute2 +Older versions of can-j1939 used a modified iproute2 +for manipulating the kernel lists of current addresses. + +This is now obsolete! + ### Static addressing ip addr add j1939 0x80 dev can0 diff --git a/can-j1939-kickstart.md b/can-j1939-kickstart.md index b0b4485..1ec184a 100644 --- a/can-j1939-kickstart.md +++ b/can-j1939-kickstart.md @@ -18,14 +18,11 @@ Create a virtual can0 device and start the device Use [testj1939](testj1939.c) -When *can-j1939* is compiled as module, load it. +When *can-j1939* is compiled as module, opening a socket will load it, +__or__ you can load it manually modprobe can-j1939 -Enable the j1939 protocol stack on the CAN device - - ip link set can0 j1939 on - Most of the subsequent examples will use 2 sockets programs (in 2 terminals). One will use CAN_J1939 sockets using *testj1939*, and the other will use CAN_RAW sockets using cansend+candump. @@ -59,23 +56,12 @@ is not meant for us and *testj1939* does not receive it. ### Use source address +Binding a can-j1939 socket to a source address will register +allow you to send packets. + ./testj1939 can0:0x80 -will say - - ./testj1939: bind(): Cannot assign requested address - -Since J1939 maintains addressing, **0x80** has not yet been assigned -as an address on **can0** . This behaviour is very similar to IP -addressing: you cannot bind to an address that is not your own. - -Now tell the kernel that we *own* address 0x80. -It will be available from now on. - - ip addr add j1939 0x80 dev can0 - ./testj1939 can0:0x80 - -now succeeds. +Your system had, for a small moment, source address 0x80 assigned. ### receive with source address @@ -101,54 +87,30 @@ Open in terminal 1: And to these test in another terminal - ./testj1939 -s can0:0x80 + ./testj1939 -s can0:0x80,0x3ffff This produces **1BFFFF80#0123456789ABCDEF** on CAN. - ./testj1939 -s can0: - -will produce exactly the same because **0x80** is the only -address currently assigned to **can0:** and is used by default. - ### Multiple source addresses on 1 CAN device - ip addr add j1939 0x90 dev can0 - - ./testj1939 -s can0:0x90 + ./testj1939 -s can0:0x90,0x3ffff produces **1BFFFF90#0123456789ABCDEF** , - ./testj1939 -s can0: +### Use PDU1 PGN -still produces **1BFFFF80#0123456789ABCDEF** , since **0x80** -is the default _source address_. -Check - - ip addr show can0 - -emits - - X: can0: mtu 16 qdisc noqueue state UNKNOWN - link/can - can-j1939 0x80 scope link - can-j1939 0x90 scope link - -0x80 is the first address on can0. - -### Use specific PGN - - ./testj1939 -s can0:,0x12345 + ./testj1939 -s can0:0x80,0x12345 emits **1923FF80#0123456789ABCDEF** . Note that the real PGN is **0x12300**, and destination address is **0xff**. -### Emit destination specific packets +### Use destination address info The destination field may be set during sendto(). *testj1939* implements that like this - ./testj1939 -s can0:,0x12345 can0:0x40 + ./testj1939 -s can0:0x80,0x12345 can0:0x40 emits **19234080#0123456789ABCDEF** . @@ -167,13 +129,13 @@ __sendto( *peername* )__ , and only one is used. For broadcasted transmissions - ./testj1939 -s can0:,0x12300 :,0x32100 + ./testj1939 -s can0:0x80,0x12300 :,0x32100 emits **1B21FF80#0123456789ABCDEF** rather than 1923FF80#012345678ABCDEF Desitination specific transmissions - ./testj1939 -s can0:,0x12300 :0x40,0x32100 + ./testj1939 -s can0:0x80,0x12300 :0x40,0x32100 emits **1B214080#0123456789ABCDEF** . @@ -198,6 +160,14 @@ __50ms__ from each other. Destination specific *Transport Protocol* applies flow control and may emit CAN packets much faster. +First assign 0x90 to the local system. +This becomes important because the kernel must interact in the +transport protocol sessions before the complete packet is delivered. + + ./testj1939 can0:0x90 -r & + +Now test: + ./testj1939 -s20 can0:0x80 :0x90,0x12300 emits: From 6d717b8a404bd474722e8012d76a64fdd01b5819 Mon Sep 17 00:00:00 2001 From: Kurt Van Dijck Date: Tue, 23 Feb 2016 09:37:46 +0100 Subject: [PATCH 16/23] update for obsolete enable/disable using netlink --- Readme.md | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/Readme.md b/Readme.md index a1f4e85..3e8fcfb 100644 --- a/Readme.md +++ b/Readme.md @@ -63,16 +63,13 @@ will emit a single CAN frame. will use fragementation, emitting 1+ CAN frames. -# Enable j1939 +## Enable j1939 (obsolete!) CAN has no protocol id field. -Actions need to be performed to enable can-j1939 for a network device +The can-j1939 stack only activates when a socket opens +for a network device. -### on socket connect - -Open a socket and bind to a network interface. - -This is the latest method, and preferred for mainline inclusion +The methods described here existed in earlier implementations. ### netlink @@ -120,13 +117,11 @@ This API is dropped for kernels with netlink support! * When providing address information, *name* != 0 indicates dynamic addressing -## iproute2 +## iproute2 (obsolete!) Older versions of can-j1939 used a modified iproute2 for manipulating the kernel lists of current addresses. -This is now obsolete! - ### Static addressing ip addr add j1939 0x80 dev can0 From 215ca91d26d0d7e818023ebc0175f86b3186f0e9 Mon Sep 17 00:00:00 2001 From: Kurt Van Dijck Date: Tue, 23 Feb 2016 09:38:13 +0100 Subject: [PATCH 17/23] Makefile: remove .html's with make clean --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index ba2b089..3c3e570 100644 --- a/Makefile +++ b/Makefile @@ -8,4 +8,4 @@ all: default $(patsubst %.md, %.html, $(wildcard *.md)) CFLAGS = -Wall -g3 -O0 clean: - rm -f testj1939 j1939.html + rm -f testj1939 $(wildcard *.html) From 1ffa9a16a48791cd0ddc83585bf5c321361ccc87 Mon Sep 17 00:00:00 2001 From: Kurt Van Dijck Date: Tue, 23 Feb 2016 09:40:17 +0100 Subject: [PATCH 18/23] testj1939: add -w option to keep program open --- testj1939.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/testj1939.c b/testj1939.c index 8524f5b..cebd38a 100644 --- a/testj1939.c +++ b/testj1939.c @@ -39,13 +39,14 @@ static const char help_msg[] = " -c Issue connect()\n" " -p=PRIO Set priority to PRIO\n" " -n Emit 64bit NAMEs in output\n" + " -w[TIME] Return after TIME (default 1) seconds\n" "\n" "Example:\n" "testj1939 can1 20\n" "\n" ; -static const char optstring[] = "?vs::rep:cn"; +static const char optstring[] = "?vs::rep:cnw::"; static void parse_canaddr(char *spec, struct sockaddr_can *paddr) { @@ -90,6 +91,22 @@ static const char *canaddr2str(const struct sockaddr_can *paddr) return buf; } +static void onsigalrm(int sig) +{ + error(0, 0, "exit as requested"); + exit(0); +} + +static void schedule_oneshot_itimer(double delay) +{ + struct itimerval it = {}; + + it.it_value.tv_sec = delay; + it.it_value.tv_usec = (long)(delay * 1e6) % 1000000; + if (setitimer(ITIMER_REAL, &it, NULL) < 0) + error(1, errno, "schedule itimer %.3lfs", delay); +} + /* main */ int main(int argc, char *argv[]) { @@ -113,7 +130,7 @@ int main(int argc, char *argv[]) uint8_t dat[128]; int valid_peername = 0; int todo_send = 0, todo_recv = 0, todo_echo = 0, todo_prio = -1; - int todo_connect = 0, todo_names = 0; + int todo_connect = 0, todo_names = 0, todo_wait = 0; /* argument parsing */ while ((opt = getopt(argc, argv, optstring)) != -1) @@ -139,6 +156,11 @@ int main(int argc, char *argv[]) case 'n': todo_names = 1; break; + case 'w': + schedule_oneshot_itimer(strtod(optarg ?: "1", NULL)); + signal(SIGALRM, onsigalrm); + todo_wait = 1; + break; default: fputs(help_msg, stderr); exit(1); @@ -260,6 +282,9 @@ int main(int argc, char *argv[]) printf("\n"); } } + if (todo_wait) + for (;;) + sleep(1); return 0; } From 0e3611464ba1a9c37d759ed8f8f16059e7424283 Mon Sep 17 00:00:00 2001 From: Kurt Van Dijck Date: Tue, 23 Feb 2016 11:01:38 +0100 Subject: [PATCH 19/23] use -w option for transport protocol examples --- can-j1939-kickstart.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/can-j1939-kickstart.md b/can-j1939-kickstart.md index 1ec184a..7ea75ff 100644 --- a/can-j1939-kickstart.md +++ b/can-j1939-kickstart.md @@ -148,6 +148,20 @@ do not fit into single CAN packets. ./testj1939 -s20 can0:0x80 :,0x12300 +emits: + + 18ECFF80#20140003FF002301 + +This is the first fragment for broadcasted *Transport Protocol*. +_testj1939_ returns before the subsequent packets can leave, and +as the last socket on the system closes, can-j1939 effectively +cleans up all resources. Real-world applications will run like forever, +and will not encounter this side-effect. + +Try again, and instruct _testj1939_ to keep the socket open for 1 second. + + ./testj1939 -w1.0 -s20 can0:0x80 :,0x12300 + emits: 18ECFF80#20140003FF002301 From 07daafc8256b7eb7bf5bded9efde8e29e0a5cd5c Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Tue, 4 Oct 2016 14:24:49 +0200 Subject: [PATCH 20/23] testj1939: fix warning on 32 bit systems testj1939.c: In function 'main': testj1939.c:201:3: warning: format '%li' expects argument of type 'long int', but argument 4 has type 'unsigned int' [-Wformat=] fprintf(stderr, "- bind(, %s, %li);\n", canaddr2str(&sockname), sizeof(sockname)); ^ testj1939.c:210:4: warning: format '%li' expects argument of type 'long int', but argument 4 has type 'unsigned int' [-Wformat=] fprintf(stderr, "- connect(, %s, %li);\n", canaddr2str(&peername), sizeof(peername)); ^ testj1939.c:228:5: warning: format '%li' expects argument of type 'long int', but argument 5 has type 'unsigned int' [-Wformat=] fprintf(stderr, "- sendto(, , %i, 0, %s, %li);\n", todo_send, canaddr2str(&peername), sizeof(peername)); ^ testj1939.c:254:4: warning: format '%li' expects argument of type 'long int', but argument 3 has type 'unsigned int' [-Wformat=] fprintf(stderr, "- recvfrom(, , %li, 0, &, %li);\n", sizeof(peername), sizeof(peername)); ^ testj1939.c:254:4: warning: format '%li' expects argument of type 'long int', but argument 4 has type 'unsigned int' [-Wformat=] Use 'z' as correct modifier to print sizeof(). Signed-off-by: Marc Kleine-Budde --- testj1939.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/testj1939.c b/testj1939.c index cebd38a..e602477 100644 --- a/testj1939.c +++ b/testj1939.c @@ -198,7 +198,7 @@ int main(int argc, char *argv[]) } if (verbose) - fprintf(stderr, "- bind(, %s, %li);\n", canaddr2str(&sockname), sizeof(sockname)); + fprintf(stderr, "- bind(, %s, %zi);\n", canaddr2str(&sockname), sizeof(sockname)); ret = bind(sock, (void *)&sockname, sizeof(sockname)); if (ret < 0) error(1, errno, "bind()"); @@ -207,7 +207,7 @@ int main(int argc, char *argv[]) if (!valid_peername) error(1, 0, "no peername supplied"); if (verbose) - fprintf(stderr, "- connect(, %s, %li);\n", canaddr2str(&peername), sizeof(peername)); + fprintf(stderr, "- connect(, %s, %zi);\n", canaddr2str(&peername), sizeof(peername)); ret = connect(sock, (void *)&peername, sizeof(peername)); if (ret < 0) error(1, errno, "connect()"); @@ -225,7 +225,7 @@ int main(int argc, char *argv[]) */ if (valid_peername && !todo_connect) { if (verbose) - fprintf(stderr, "- sendto(, , %i, 0, %s, %li);\n", todo_send, canaddr2str(&peername), sizeof(peername)); + fprintf(stderr, "- sendto(, , %i, 0, %s, %zi);\n", todo_send, canaddr2str(&peername), sizeof(peername)); ret = sendto(sock, dat, todo_send, 0, (void *)&peername, sizeof(peername)); } else { @@ -251,7 +251,7 @@ int main(int argc, char *argv[]) * received packets */ if (verbose) - fprintf(stderr, "- recvfrom(, , %li, 0, &, %li);\n", sizeof(peername), sizeof(peername)); + fprintf(stderr, "- recvfrom(, , %zi, 0, &, %zi);\n", sizeof(peername), sizeof(peername)); peernamelen = sizeof(peername); ret = recvfrom(sock, dat, sizeof(dat), 0, (void *)&peername, &peernamelen); From 0a1372cc22e64c14c689af69091e88dfcf38bcca Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Tue, 4 Oct 2016 14:26:48 +0200 Subject: [PATCH 21/23] userspace headers: import userspace headers to simplify compilation Signed-off-by: Marc Kleine-Budde --- Makefile | 1 + include/uapi/linux/can.h | 220 +++++++++++++++++++++++++++++++ include/uapi/linux/can/bcm.h | 103 +++++++++++++++ include/uapi/linux/can/error.h | 124 +++++++++++++++++ include/uapi/linux/can/gw.h | 208 +++++++++++++++++++++++++++++ include/uapi/linux/can/j1939.h | 93 +++++++++++++ include/uapi/linux/can/netlink.h | 135 +++++++++++++++++++ include/uapi/linux/can/raw.h | 63 +++++++++ 8 files changed, 947 insertions(+) create mode 100644 include/uapi/linux/can.h create mode 100644 include/uapi/linux/can/bcm.h create mode 100644 include/uapi/linux/can/error.h create mode 100644 include/uapi/linux/can/gw.h create mode 100644 include/uapi/linux/can/j1939.h create mode 100644 include/uapi/linux/can/netlink.h create mode 100644 include/uapi/linux/can/raw.h diff --git a/Makefile b/Makefile index 3c3e570..91017f0 100644 --- a/Makefile +++ b/Makefile @@ -6,6 +6,7 @@ all: default $(patsubst %.md, %.html, $(wildcard *.md)) theme -f -o $@ $< -p "$*" CFLAGS = -Wall -g3 -O0 +CPPFLAGS += -Iinclude/uapi clean: rm -f testj1939 $(wildcard *.html) diff --git a/include/uapi/linux/can.h b/include/uapi/linux/can.h new file mode 100644 index 0000000..fe6a6bf --- /dev/null +++ b/include/uapi/linux/can.h @@ -0,0 +1,220 @@ +/* + * linux/can.h + * + * Definitions for CAN network layer (socket addr / CAN frame / CAN filter) + * + * Authors: Oliver Hartkopp + * Urs Thuermann + * Copyright (c) 2002-2007 Volkswagen Group Electronic Research + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Volkswagen nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Alternatively, provided that this notice is retained in full, this + * software may be distributed under the terms of the GNU General + * Public License ("GPL") version 2, in which case the provisions of the + * GPL apply INSTEAD OF those given above. + * + * The provided data structures and external interfaces from this code + * are not restricted to be used by modules with a GPL compatible license. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +#ifndef _UAPI_CAN_H +#define _UAPI_CAN_H + +#include +#include + +/* controller area network (CAN) kernel definitions */ + +/* special address description flags for the CAN_ID */ +#define CAN_EFF_FLAG 0x80000000U /* EFF/SFF is set in the MSB */ +#define CAN_RTR_FLAG 0x40000000U /* remote transmission request */ +#define CAN_ERR_FLAG 0x20000000U /* error message frame */ + +/* valid bits in CAN ID for frame formats */ +#define CAN_SFF_MASK 0x000007FFU /* standard frame format (SFF) */ +#define CAN_EFF_MASK 0x1FFFFFFFU /* extended frame format (EFF) */ +#define CAN_ERR_MASK 0x1FFFFFFFU /* omit EFF, RTR, ERR flags */ + +/* + * Controller Area Network Identifier structure + * + * bit 0-28 : CAN identifier (11/29 bit) + * bit 29 : error message frame flag (0 = data frame, 1 = error message) + * bit 30 : remote transmission request flag (1 = rtr frame) + * bit 31 : frame format flag (0 = standard 11 bit, 1 = extended 29 bit) + */ +typedef __u32 canid_t; + +#define CAN_SFF_ID_BITS 11 +#define CAN_EFF_ID_BITS 29 + +/* + * Controller Area Network Error Message Frame Mask structure + * + * bit 0-28 : error class mask (see include/linux/can/error.h) + * bit 29-31 : set to zero + */ +typedef __u32 can_err_mask_t; + +/* CAN payload length and DLC definitions according to ISO 11898-1 */ +#define CAN_MAX_DLC 8 +#define CAN_MAX_DLEN 8 + +/* CAN FD payload length and DLC definitions according to ISO 11898-7 */ +#define CANFD_MAX_DLC 15 +#define CANFD_MAX_DLEN 64 + +/** + * struct can_frame - basic CAN frame structure + * @can_id: CAN ID of the frame and CAN_*_FLAG flags, see canid_t definition + * @can_dlc: frame payload length in byte (0 .. 8) aka data length code + * N.B. the DLC field from ISO 11898-1 Chapter 8.4.2.3 has a 1:1 + * mapping of the 'data length code' to the real payload length + * @__pad: padding + * @__res0: reserved / padding + * @__res1: reserved / padding + * @data: CAN frame payload (up to 8 byte) + */ +struct can_frame { + canid_t can_id; /* 32 bit CAN_ID + EFF/RTR/ERR flags */ + __u8 can_dlc; /* frame payload length in byte (0 .. CAN_MAX_DLEN) */ + __u8 __pad; /* padding */ + __u8 __res0; /* reserved / padding */ + __u8 __res1; /* reserved / padding */ + __u8 data[CAN_MAX_DLEN] __attribute__((aligned(8))); +}; + +/* + * defined bits for canfd_frame.flags + * + * The use of struct canfd_frame implies the Extended Data Length (EDL) bit to + * be set in the CAN frame bitstream on the wire. The EDL bit switch turns + * the CAN controllers bitstream processor into the CAN FD mode which creates + * two new options within the CAN FD frame specification: + * + * Bit Rate Switch - to indicate a second bitrate is/was used for the payload + * Error State Indicator - represents the error state of the transmitting node + * + * As the CANFD_ESI bit is internally generated by the transmitting CAN + * controller only the CANFD_BRS bit is relevant for real CAN controllers when + * building a CAN FD frame for transmission. Setting the CANFD_ESI bit can make + * sense for virtual CAN interfaces to test applications with echoed frames. + */ +#define CANFD_BRS 0x01 /* bit rate switch (second bitrate for payload data) */ +#define CANFD_ESI 0x02 /* error state indicator of the transmitting node */ + +/** + * struct canfd_frame - CAN flexible data rate frame structure + * @can_id: CAN ID of the frame and CAN_*_FLAG flags, see canid_t definition + * @len: frame payload length in byte (0 .. CANFD_MAX_DLEN) + * @flags: additional flags for CAN FD + * @__res0: reserved / padding + * @__res1: reserved / padding + * @data: CAN FD frame payload (up to CANFD_MAX_DLEN byte) + */ +struct canfd_frame { + canid_t can_id; /* 32 bit CAN_ID + EFF/RTR/ERR flags */ + __u8 len; /* frame payload length in byte */ + __u8 flags; /* additional flags for CAN FD */ + __u8 __res0; /* reserved / padding */ + __u8 __res1; /* reserved / padding */ + __u8 data[CANFD_MAX_DLEN] __attribute__((aligned(8))); +}; + +#define CAN_MTU (sizeof(struct can_frame)) +#define CANFD_MTU (sizeof(struct canfd_frame)) + +/* particular protocols of the protocol family PF_CAN */ +#define CAN_RAW 1 /* RAW sockets */ +#define CAN_BCM 2 /* Broadcast Manager */ +#define CAN_TP16 3 /* VAG Transport Protocol v1.6 */ +#define CAN_TP20 4 /* VAG Transport Protocol v2.0 */ +#define CAN_MCNET 5 /* Bosch MCNet */ +#define CAN_ISOTP 6 /* ISO 15765-2 Transport Protocol */ +#define CAN_J1939 7 /* SAE J1939 */ +#define CAN_NPROTO 8 + +#define SOL_CAN_BASE 100 + +/** + * struct sockaddr_can - the sockaddr structure for CAN sockets + * @can_family: address family number AF_CAN. + * @can_ifindex: CAN network interface index. + * @can_addr: protocol specific address information + */ +struct sockaddr_can { + __kernel_sa_family_t can_family; + int can_ifindex; + union { + /* transport protocol class address information (e.g. ISOTP) */ + struct { + canid_t rx_id; + canid_t tx_id; + } tp; + + /* J1939 address information */ + struct { + /* 8 byte name when using dynamic addressing */ + __u64 name; + /* pgn: + * 8bit: PS in PDU2 case, else 0 + * 8bit: PF + * 1bit: DP + * 1bit: reserved + */ + __u32 pgn; + + /* 1byte address */ + __u8 addr; + } j1939; + + /* reserved for future CAN protocols address information */ + } can_addr; +}; + +/** + * struct can_filter - CAN ID based filter in can_register(). + * @can_id: relevant bits of CAN ID which are not masked out. + * @can_mask: CAN mask (see description) + * + * Description: + * A filter matches, when + * + * & mask == can_id & mask + * + * The filter can be inverted (CAN_INV_FILTER bit set in can_id) or it can + * filter for error message frames (CAN_ERR_FLAG bit set in mask). + */ +struct can_filter { + canid_t can_id; + canid_t can_mask; +}; + +#define CAN_INV_FILTER 0x20000000U /* to be set in can_filter.can_id */ + +#endif /* !_UAPI_CAN_H */ diff --git a/include/uapi/linux/can/bcm.h b/include/uapi/linux/can/bcm.h new file mode 100644 index 0000000..7a291dc --- /dev/null +++ b/include/uapi/linux/can/bcm.h @@ -0,0 +1,103 @@ +/* + * linux/can/bcm.h + * + * Definitions for CAN Broadcast Manager (BCM) + * + * Author: Oliver Hartkopp + * Copyright (c) 2002-2007 Volkswagen Group Electronic Research + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Volkswagen nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Alternatively, provided that this notice is retained in full, this + * software may be distributed under the terms of the GNU General + * Public License ("GPL") version 2, in which case the provisions of the + * GPL apply INSTEAD OF those given above. + * + * The provided data structures and external interfaces from this code + * are not restricted to be used by modules with a GPL compatible license. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +#ifndef _UAPI_CAN_BCM_H +#define _UAPI_CAN_BCM_H + +#include +#include + +struct bcm_timeval { + long tv_sec; + long tv_usec; +}; + +/** + * struct bcm_msg_head - head of messages to/from the broadcast manager + * @opcode: opcode, see enum below. + * @flags: special flags, see below. + * @count: number of frames to send before changing interval. + * @ival1: interval for the first @count frames. + * @ival2: interval for the following frames. + * @can_id: CAN ID of frames to be sent or received. + * @nframes: number of frames appended to the message head. + * @frames: array of CAN frames. + */ +struct bcm_msg_head { + __u32 opcode; + __u32 flags; + __u32 count; + struct bcm_timeval ival1, ival2; + canid_t can_id; + __u32 nframes; + struct can_frame frames[0]; +}; + +enum { + TX_SETUP = 1, /* create (cyclic) transmission task */ + TX_DELETE, /* remove (cyclic) transmission task */ + TX_READ, /* read properties of (cyclic) transmission task */ + TX_SEND, /* send one CAN frame */ + RX_SETUP, /* create RX content filter subscription */ + RX_DELETE, /* remove RX content filter subscription */ + RX_READ, /* read properties of RX content filter subscription */ + TX_STATUS, /* reply to TX_READ request */ + TX_EXPIRED, /* notification on performed transmissions (count=0) */ + RX_STATUS, /* reply to RX_READ request */ + RX_TIMEOUT, /* cyclic message is absent */ + RX_CHANGED /* updated CAN frame (detected content change) */ +}; + +#define SETTIMER 0x0001 +#define STARTTIMER 0x0002 +#define TX_COUNTEVT 0x0004 +#define TX_ANNOUNCE 0x0008 +#define TX_CP_CAN_ID 0x0010 +#define RX_FILTER_ID 0x0020 +#define RX_CHECK_DLC 0x0040 +#define RX_NO_AUTOTIMER 0x0080 +#define RX_ANNOUNCE_RESUME 0x0100 +#define TX_RESET_MULTI_IDX 0x0200 +#define RX_RTR_FRAME 0x0400 + +#endif /* !_UAPI_CAN_BCM_H */ diff --git a/include/uapi/linux/can/error.h b/include/uapi/linux/can/error.h new file mode 100644 index 0000000..1c508be --- /dev/null +++ b/include/uapi/linux/can/error.h @@ -0,0 +1,124 @@ +/* + * linux/can/error.h + * + * Definitions of the CAN error messages to be filtered and passed to the user. + * + * Author: Oliver Hartkopp + * Copyright (c) 2002-2007 Volkswagen Group Electronic Research + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Volkswagen nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Alternatively, provided that this notice is retained in full, this + * software may be distributed under the terms of the GNU General + * Public License ("GPL") version 2, in which case the provisions of the + * GPL apply INSTEAD OF those given above. + * + * The provided data structures and external interfaces from this code + * are not restricted to be used by modules with a GPL compatible license. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +#ifndef _UAPI_CAN_ERROR_H +#define _UAPI_CAN_ERROR_H + +#define CAN_ERR_DLC 8 /* dlc for error message frames */ + +/* error class (mask) in can_id */ +#define CAN_ERR_TX_TIMEOUT 0x00000001U /* TX timeout (by netdevice driver) */ +#define CAN_ERR_LOSTARB 0x00000002U /* lost arbitration / data[0] */ +#define CAN_ERR_CRTL 0x00000004U /* controller problems / data[1] */ +#define CAN_ERR_PROT 0x00000008U /* protocol violations / data[2..3] */ +#define CAN_ERR_TRX 0x00000010U /* transceiver status / data[4] */ +#define CAN_ERR_ACK 0x00000020U /* received no ACK on transmission */ +#define CAN_ERR_BUSOFF 0x00000040U /* bus off */ +#define CAN_ERR_BUSERROR 0x00000080U /* bus error (may flood!) */ +#define CAN_ERR_RESTARTED 0x00000100U /* controller restarted */ + +/* arbitration lost in bit ... / data[0] */ +#define CAN_ERR_LOSTARB_UNSPEC 0x00 /* unspecified */ + /* else bit number in bitstream */ + +/* error status of CAN-controller / data[1] */ +#define CAN_ERR_CRTL_UNSPEC 0x00 /* unspecified */ +#define CAN_ERR_CRTL_RX_OVERFLOW 0x01 /* RX buffer overflow */ +#define CAN_ERR_CRTL_TX_OVERFLOW 0x02 /* TX buffer overflow */ +#define CAN_ERR_CRTL_RX_WARNING 0x04 /* reached warning level for RX errors */ +#define CAN_ERR_CRTL_TX_WARNING 0x08 /* reached warning level for TX errors */ +#define CAN_ERR_CRTL_RX_PASSIVE 0x10 /* reached error passive status RX */ +#define CAN_ERR_CRTL_TX_PASSIVE 0x20 /* reached error passive status TX */ + /* (at least one error counter exceeds */ + /* the protocol-defined level of 127) */ +#define CAN_ERR_CRTL_ACTIVE 0x40 /* recovered to error active state */ + +/* error in CAN protocol (type) / data[2] */ +#define CAN_ERR_PROT_UNSPEC 0x00 /* unspecified */ +#define CAN_ERR_PROT_BIT 0x01 /* single bit error */ +#define CAN_ERR_PROT_FORM 0x02 /* frame format error */ +#define CAN_ERR_PROT_STUFF 0x04 /* bit stuffing error */ +#define CAN_ERR_PROT_BIT0 0x08 /* unable to send dominant bit */ +#define CAN_ERR_PROT_BIT1 0x10 /* unable to send recessive bit */ +#define CAN_ERR_PROT_OVERLOAD 0x20 /* bus overload */ +#define CAN_ERR_PROT_ACTIVE 0x40 /* active error announcement */ +#define CAN_ERR_PROT_TX 0x80 /* error occurred on transmission */ + +/* error in CAN protocol (location) / data[3] */ +#define CAN_ERR_PROT_LOC_UNSPEC 0x00 /* unspecified */ +#define CAN_ERR_PROT_LOC_SOF 0x03 /* start of frame */ +#define CAN_ERR_PROT_LOC_ID28_21 0x02 /* ID bits 28 - 21 (SFF: 10 - 3) */ +#define CAN_ERR_PROT_LOC_ID20_18 0x06 /* ID bits 20 - 18 (SFF: 2 - 0 )*/ +#define CAN_ERR_PROT_LOC_SRTR 0x04 /* substitute RTR (SFF: RTR) */ +#define CAN_ERR_PROT_LOC_IDE 0x05 /* identifier extension */ +#define CAN_ERR_PROT_LOC_ID17_13 0x07 /* ID bits 17-13 */ +#define CAN_ERR_PROT_LOC_ID12_05 0x0F /* ID bits 12-5 */ +#define CAN_ERR_PROT_LOC_ID04_00 0x0E /* ID bits 4-0 */ +#define CAN_ERR_PROT_LOC_RTR 0x0C /* RTR */ +#define CAN_ERR_PROT_LOC_RES1 0x0D /* reserved bit 1 */ +#define CAN_ERR_PROT_LOC_RES0 0x09 /* reserved bit 0 */ +#define CAN_ERR_PROT_LOC_DLC 0x0B /* data length code */ +#define CAN_ERR_PROT_LOC_DATA 0x0A /* data section */ +#define CAN_ERR_PROT_LOC_CRC_SEQ 0x08 /* CRC sequence */ +#define CAN_ERR_PROT_LOC_CRC_DEL 0x18 /* CRC delimiter */ +#define CAN_ERR_PROT_LOC_ACK 0x19 /* ACK slot */ +#define CAN_ERR_PROT_LOC_ACK_DEL 0x1B /* ACK delimiter */ +#define CAN_ERR_PROT_LOC_EOF 0x1A /* end of frame */ +#define CAN_ERR_PROT_LOC_INTERM 0x12 /* intermission */ + +/* error status of CAN-transceiver / data[4] */ +/* CANH CANL */ +#define CAN_ERR_TRX_UNSPEC 0x00 /* 0000 0000 */ +#define CAN_ERR_TRX_CANH_NO_WIRE 0x04 /* 0000 0100 */ +#define CAN_ERR_TRX_CANH_SHORT_TO_BAT 0x05 /* 0000 0101 */ +#define CAN_ERR_TRX_CANH_SHORT_TO_VCC 0x06 /* 0000 0110 */ +#define CAN_ERR_TRX_CANH_SHORT_TO_GND 0x07 /* 0000 0111 */ +#define CAN_ERR_TRX_CANL_NO_WIRE 0x40 /* 0100 0000 */ +#define CAN_ERR_TRX_CANL_SHORT_TO_BAT 0x50 /* 0101 0000 */ +#define CAN_ERR_TRX_CANL_SHORT_TO_VCC 0x60 /* 0110 0000 */ +#define CAN_ERR_TRX_CANL_SHORT_TO_GND 0x70 /* 0111 0000 */ +#define CAN_ERR_TRX_CANL_SHORT_TO_CANH 0x80 /* 1000 0000 */ + +/* controller specific additional information / data[5..7] */ + +#endif /* _UAPI_CAN_ERROR_H */ diff --git a/include/uapi/linux/can/gw.h b/include/uapi/linux/can/gw.h new file mode 100644 index 0000000..5079b9d --- /dev/null +++ b/include/uapi/linux/can/gw.h @@ -0,0 +1,208 @@ +/* + * linux/can/gw.h + * + * Definitions for CAN frame Gateway/Router/Bridge + * + * Author: Oliver Hartkopp + * Copyright (c) 2011 Volkswagen Group Electronic Research + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Volkswagen nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Alternatively, provided that this notice is retained in full, this + * software may be distributed under the terms of the GNU General + * Public License ("GPL") version 2, in which case the provisions of the + * GPL apply INSTEAD OF those given above. + * + * The provided data structures and external interfaces from this code + * are not restricted to be used by modules with a GPL compatible license. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +#ifndef _UAPI_CAN_GW_H +#define _UAPI_CAN_GW_H + +#include +#include + +struct rtcanmsg { + __u8 can_family; + __u8 gwtype; + __u16 flags; +}; + +/* CAN gateway types */ +enum { + CGW_TYPE_UNSPEC, + CGW_TYPE_CAN_CAN, /* CAN->CAN routing */ + __CGW_TYPE_MAX +}; + +#define CGW_TYPE_MAX (__CGW_TYPE_MAX - 1) + +/* CAN rtnetlink attribute definitions */ +enum { + CGW_UNSPEC, + CGW_MOD_AND, /* CAN frame modification binary AND */ + CGW_MOD_OR, /* CAN frame modification binary OR */ + CGW_MOD_XOR, /* CAN frame modification binary XOR */ + CGW_MOD_SET, /* CAN frame modification set alternate values */ + CGW_CS_XOR, /* set data[] XOR checksum into data[index] */ + CGW_CS_CRC8, /* set data[] CRC8 checksum into data[index] */ + CGW_HANDLED, /* number of handled CAN frames */ + CGW_DROPPED, /* number of dropped CAN frames */ + CGW_SRC_IF, /* ifindex of source network interface */ + CGW_DST_IF, /* ifindex of destination network interface */ + CGW_FILTER, /* specify struct can_filter on source CAN device */ + CGW_DELETED, /* number of deleted CAN frames (see max_hops param) */ + CGW_LIM_HOPS, /* limit the number of hops of this specific rule */ + CGW_MOD_UID, /* user defined identifier for modification updates */ + __CGW_MAX +}; + +#define CGW_MAX (__CGW_MAX - 1) + +#define CGW_FLAGS_CAN_ECHO 0x01 +#define CGW_FLAGS_CAN_SRC_TSTAMP 0x02 +#define CGW_FLAGS_CAN_IIF_TX_OK 0x04 + +#define CGW_MOD_FUNCS 4 /* AND OR XOR SET */ + +/* CAN frame elements that are affected by curr. 3 CAN frame modifications */ +#define CGW_MOD_ID 0x01 +#define CGW_MOD_DLC 0x02 +#define CGW_MOD_DATA 0x04 + +#define CGW_FRAME_MODS 3 /* ID DLC DATA */ + +#define MAX_MODFUNCTIONS (CGW_MOD_FUNCS * CGW_FRAME_MODS) + +struct cgw_frame_mod { + struct can_frame cf; + __u8 modtype; +} __attribute__((packed)); + +#define CGW_MODATTR_LEN sizeof(struct cgw_frame_mod) + +struct cgw_csum_xor { + __s8 from_idx; + __s8 to_idx; + __s8 result_idx; + __u8 init_xor_val; +} __attribute__((packed)); + +struct cgw_csum_crc8 { + __s8 from_idx; + __s8 to_idx; + __s8 result_idx; + __u8 init_crc_val; + __u8 final_xor_val; + __u8 crctab[256]; + __u8 profile; + __u8 profile_data[20]; +} __attribute__((packed)); + +/* length of checksum operation parameters. idx = index in CAN frame data[] */ +#define CGW_CS_XOR_LEN sizeof(struct cgw_csum_xor) +#define CGW_CS_CRC8_LEN sizeof(struct cgw_csum_crc8) + +/* CRC8 profiles (compute CRC for additional data elements - see below) */ +enum { + CGW_CRC8PRF_UNSPEC, + CGW_CRC8PRF_1U8, /* compute one additional u8 value */ + CGW_CRC8PRF_16U8, /* u8 value table indexed by data[1] & 0xF */ + CGW_CRC8PRF_SFFID_XOR, /* (can_id & 0xFF) ^ (can_id >> 8 & 0xFF) */ + __CGW_CRC8PRF_MAX +}; + +#define CGW_CRC8PRF_MAX (__CGW_CRC8PRF_MAX - 1) + +/* + * CAN rtnetlink attribute contents in detail + * + * CGW_XXX_IF (length 4 bytes): + * Sets an interface index for source/destination network interfaces. + * For the CAN->CAN gwtype the indices of _two_ CAN interfaces are mandatory. + * + * CGW_FILTER (length 8 bytes): + * Sets a CAN receive filter for the gateway job specified by the + * struct can_filter described in include/linux/can.h + * + * CGW_MOD_(AND|OR|XOR|SET) (length 17 bytes): + * Specifies a modification that's done to a received CAN frame before it is + * send out to the destination interface. + * + * data used as operator + * affected CAN frame elements + * + * CGW_LIM_HOPS (length 1 byte): + * Limit the number of hops of this specific rule. Usually the received CAN + * frame can be processed as much as 'max_hops' times (which is given at module + * load time of the can-gw module). This value is used to reduce the number of + * possible hops for this gateway rule to a value smaller then max_hops. + * + * CGW_MOD_UID (length 4 bytes): + * Optional non-zero user defined routing job identifier to alter existing + * modification settings at runtime. + * + * CGW_CS_XOR (length 4 bytes): + * Set a simple XOR checksum starting with an initial value into + * data[result-idx] using data[start-idx] .. data[end-idx] + * + * The XOR checksum is calculated like this: + * + * xor = init_xor_val + * + * for (i = from_idx .. to_idx) + * xor ^= can_frame.data[i] + * + * can_frame.data[ result_idx ] = xor + * + * CGW_CS_CRC8 (length 282 bytes): + * Set a CRC8 value into data[result-idx] using a given 256 byte CRC8 table, + * a given initial value and a defined input data[start-idx] .. data[end-idx]. + * Finally the result value is XOR'ed with the final_xor_val. + * + * The CRC8 checksum is calculated like this: + * + * crc = init_crc_val + * + * for (i = from_idx .. to_idx) + * crc = crctab[ crc ^ can_frame.data[i] ] + * + * can_frame.data[ result_idx ] = crc ^ final_xor_val + * + * The calculated CRC may contain additional source data elements that can be + * defined in the handling of 'checksum profiles' e.g. shown in AUTOSAR specs + * like http://www.autosar.org/download/R4.0/AUTOSAR_SWS_E2ELibrary.pdf + * E.g. the profile_data[] may contain additional u8 values (called DATA_IDs) + * that are used depending on counter values inside the CAN frame data[]. + * So far only three profiles have been implemented for illustration. + * + * Remark: In general the attribute data is a linear buffer. + * Beware of sending unpacked or aligned structs! + */ + +#endif /* !_UAPI_CAN_GW_H */ diff --git a/include/uapi/linux/can/j1939.h b/include/uapi/linux/can/j1939.h new file mode 100644 index 0000000..4d0d23e --- /dev/null +++ b/include/uapi/linux/can/j1939.h @@ -0,0 +1,93 @@ +/* + * j1939.h + * + * Copyright (c) 2010-2011 EIA Electronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef _UAPI_CAN_J1939_H_ +#define _UAPI_CAN_J1939_H_ + +#include +#include +#include + +#define J1939_IDLE_ADDR 0xfe +#define J1939_NO_ADDR 0xff +#define J1939_NO_NAME 0 +#define J1939_NO_PGN 0x40000 + +/* J1939 Parameter Group Number + * + * bit 0-7 : PDU Specific (PS) + * bit 8-15 : PDU Format (PF) + * bit 16 : Data Page (DP) + * bit 17 : Reserved (R) + * bit 19-31 : set to zero + */ +typedef __u32 pgn_t; + +/* J1939 Priority + * + * bit 0-2 : Priority (P) + * bit 3-7 : set to zero + */ +typedef __u8 priority_t; + +/* J1939 NAME + * + * bit 0-20 : Identity Number + * bit 21-31 : Manufacturer Code + * bit 32-34 : ECU Instance + * bit 35-39 : Function Instance + * bit 40-47 : Function + * bit 48 : Reserved + * bit 49-55 : Vehicle System + * bit 56-59 : Vehicle System Instance + * bit 60-62 : Industry Group + * bit 63 : Arbitrary Address Capable + */ +typedef __u64 name_t; + +/* J1939 socket options */ +#define SOL_CAN_J1939 (SOL_CAN_BASE + CAN_J1939) +enum { + SO_J1939_FILTER = 1, /* set filters */ + SO_J1939_PROMISC = 2, /* set/clr promiscuous mode */ + SO_J1939_RECV_OWN = 3, + SO_J1939_SEND_PRIO = 4, +}; + +enum { + SCM_J1939_DEST_ADDR = 1, + SCM_J1939_DEST_NAME = 2, + SCM_J1939_PRIO = 3, +}; + +struct j1939_filter { + name_t name; + name_t name_mask; + __u8 addr; + __u8 addr_mask; + pgn_t pgn; + pgn_t pgn_mask; +}; + +/* RTNETLINK */ +enum { + IFLA_J1939_UNSPEC, + IFLA_J1939_ENABLE, + IFLA_J1939_MAX, +}; + +enum { + IFA_J1939_UNSPEC, + IFA_J1939_ADDR, + IFA_J1939_NAME, + IFA_J1939_MAX, +}; + +#endif /* !_UAPI_CAN_J1939_H_ */ diff --git a/include/uapi/linux/can/netlink.h b/include/uapi/linux/can/netlink.h new file mode 100644 index 0000000..94ffe0c --- /dev/null +++ b/include/uapi/linux/can/netlink.h @@ -0,0 +1,135 @@ +/* + * linux/can/netlink.h + * + * Definitions for the CAN netlink interface + * + * Copyright (c) 2009 Wolfgang Grandegger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the version 2 of the GNU General Public License + * as published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _UAPI_CAN_NETLINK_H +#define _UAPI_CAN_NETLINK_H + +#include + +/* + * CAN bit-timing parameters + * + * For further information, please read chapter "8 BIT TIMING + * REQUIREMENTS" of the "Bosch CAN Specification version 2.0" + * at http://www.semiconductors.bosch.de/pdf/can2spec.pdf. + */ +struct can_bittiming { + __u32 bitrate; /* Bit-rate in bits/second */ + __u32 sample_point; /* Sample point in one-tenth of a percent */ + __u32 tq; /* Time quanta (TQ) in nanoseconds */ + __u32 prop_seg; /* Propagation segment in TQs */ + __u32 phase_seg1; /* Phase buffer segment 1 in TQs */ + __u32 phase_seg2; /* Phase buffer segment 2 in TQs */ + __u32 sjw; /* Synchronisation jump width in TQs */ + __u32 brp; /* Bit-rate prescaler */ +}; + +/* + * CAN harware-dependent bit-timing constant + * + * Used for calculating and checking bit-timing parameters + */ +struct can_bittiming_const { + char name[16]; /* Name of the CAN controller hardware */ + __u32 tseg1_min; /* Time segement 1 = prop_seg + phase_seg1 */ + __u32 tseg1_max; + __u32 tseg2_min; /* Time segement 2 = phase_seg2 */ + __u32 tseg2_max; + __u32 sjw_max; /* Synchronisation jump width */ + __u32 brp_min; /* Bit-rate prescaler */ + __u32 brp_max; + __u32 brp_inc; +}; + +/* + * CAN clock parameters + */ +struct can_clock { + __u32 freq; /* CAN system clock frequency in Hz */ +}; + +/* + * CAN operational and error states + */ +enum can_state { + CAN_STATE_ERROR_ACTIVE = 0, /* RX/TX error count < 96 */ + CAN_STATE_ERROR_WARNING, /* RX/TX error count < 128 */ + CAN_STATE_ERROR_PASSIVE, /* RX/TX error count < 256 */ + CAN_STATE_BUS_OFF, /* RX/TX error count >= 256 */ + CAN_STATE_STOPPED, /* Device is stopped */ + CAN_STATE_SLEEPING, /* Device is sleeping */ + CAN_STATE_MAX +}; + +/* + * CAN bus error counters + */ +struct can_berr_counter { + __u16 txerr; + __u16 rxerr; +}; + +/* + * CAN controller mode + */ +struct can_ctrlmode { + __u32 mask; + __u32 flags; +}; + +#define CAN_CTRLMODE_LOOPBACK 0x01 /* Loopback mode */ +#define CAN_CTRLMODE_LISTENONLY 0x02 /* Listen-only mode */ +#define CAN_CTRLMODE_3_SAMPLES 0x04 /* Triple sampling mode */ +#define CAN_CTRLMODE_ONE_SHOT 0x08 /* One-Shot mode */ +#define CAN_CTRLMODE_BERR_REPORTING 0x10 /* Bus-error reporting */ +#define CAN_CTRLMODE_FD 0x20 /* CAN FD mode */ +#define CAN_CTRLMODE_PRESUME_ACK 0x40 /* Ignore missing CAN ACKs */ +#define CAN_CTRLMODE_FD_NON_ISO 0x80 /* CAN FD in non-ISO mode */ + +/* + * CAN device statistics + */ +struct can_device_stats { + __u32 bus_error; /* Bus errors */ + __u32 error_warning; /* Changes to error warning state */ + __u32 error_passive; /* Changes to error passive state */ + __u32 bus_off; /* Changes to bus off state */ + __u32 arbitration_lost; /* Arbitration lost errors */ + __u32 restarts; /* CAN controller re-starts */ +}; + +/* + * CAN netlink interface + */ +enum { + IFLA_CAN_UNSPEC, + IFLA_CAN_BITTIMING, + IFLA_CAN_BITTIMING_CONST, + IFLA_CAN_CLOCK, + IFLA_CAN_STATE, + IFLA_CAN_CTRLMODE, + IFLA_CAN_RESTART_MS, + IFLA_CAN_RESTART, + IFLA_CAN_BERR_COUNTER, + IFLA_CAN_DATA_BITTIMING, + IFLA_CAN_DATA_BITTIMING_CONST, + __IFLA_CAN_MAX +}; + +#define IFLA_CAN_MAX (__IFLA_CAN_MAX - 1) + +#endif /* !_UAPI_CAN_NETLINK_H */ diff --git a/include/uapi/linux/can/raw.h b/include/uapi/linux/can/raw.h new file mode 100644 index 0000000..8735f10 --- /dev/null +++ b/include/uapi/linux/can/raw.h @@ -0,0 +1,63 @@ +/* + * linux/can/raw.h + * + * Definitions for raw CAN sockets + * + * Authors: Oliver Hartkopp + * Urs Thuermann + * Copyright (c) 2002-2007 Volkswagen Group Electronic Research + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Volkswagen nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Alternatively, provided that this notice is retained in full, this + * software may be distributed under the terms of the GNU General + * Public License ("GPL") version 2, in which case the provisions of the + * GPL apply INSTEAD OF those given above. + * + * The provided data structures and external interfaces from this code + * are not restricted to be used by modules with a GPL compatible license. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +#ifndef _UAPI_CAN_RAW_H +#define _UAPI_CAN_RAW_H + +#include + +#define SOL_CAN_RAW (SOL_CAN_BASE + CAN_RAW) + +/* for socket options affecting the socket (not the global system) */ + +enum { + CAN_RAW_FILTER = 1, /* set 0 .. n can_filter(s) */ + CAN_RAW_ERR_FILTER, /* set filter for error frames */ + CAN_RAW_LOOPBACK, /* local loopback (default:on) */ + CAN_RAW_RECV_OWN_MSGS, /* receive my own msgs (default:off) */ + CAN_RAW_FD_FRAMES, /* allow CAN FD frames (default:off) */ + CAN_RAW_JOIN_FILTERS, /* all filters must match to trigger */ +}; + +#endif /* !_UAPI_CAN_RAW_H */ From 3881e6f673ab9d6353f7fe345c3a85e8dc0521fa Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Tue, 4 Oct 2016 14:27:13 +0200 Subject: [PATCH 22/23] Makefile: add install stage Signed-off-by: Marc Kleine-Budde --- Makefile | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 91017f0..1c2ba80 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,5 @@ +PREFIX := /usr/local + default: testj1939 all: default $(patsubst %.md, %.html, $(wildcard *.md)) @@ -5,8 +7,11 @@ all: default $(patsubst %.md, %.html, $(wildcard *.md)) %.html: %.md page.theme theme -f -o $@ $< -p "$*" -CFLAGS = -Wall -g3 -O0 +CFLAGS += -Wall -g3 -O0 CPPFLAGS += -Iinclude/uapi +install: + install -D -m 755 testj1939 ${DESTDIR}${PREFIX}/bin/testj1939 + clean: rm -f testj1939 $(wildcard *.html) From 1637db7caaccdec3d82e0f8d068d865cf9477ff9 Mon Sep 17 00:00:00 2001 From: Kurt Van Dijck Date: Thu, 6 Oct 2016 09:00:37 +0200 Subject: [PATCH 23/23] hide kickstart html guide --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 43182eb..dde90ca 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ # output testj1939 Readme.html +/can-j1939-kickstart.html