From mboxrd@z Thu Jan 1 00:00:00 1970 From: Kurt Van Dijck Subject: [RFC v3 5/6] j1939: add documentation and MAINTAINERS Date: Mon, 14 Mar 2011 14:59:17 +0100 Message-ID: <20110314135917.GF333@e-circ.dyndns.org> References: <20110314132004.GA333@e-circ.dyndns.org> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: socketcan-core-0fE9KPoRgkgATYTw5x5z8w@public.gmane.org, netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org Return-path: Content-Disposition: inline In-Reply-To: <20110314132004.GA333-MxZ6Iy/zr/UdbCeoMzGj59i2O/JbrIOy@public.gmane.org> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: socketcan-core-bounces-0fE9KPoRgkgATYTw5x5z8w@public.gmane.org Errors-To: socketcan-core-bounces-0fE9KPoRgkgATYTw5x5z8w@public.gmane.org List-Id: netdev.vger.kernel.org This patch adds the documentation and MAINTAINERS. This is seperated from 4/6 for size constraints on berlios' SocketCAN mailing list. Signed-off-by: Kurt Van Dijck --- diff --git a/Documentation/networking/j1939.txt b/Documentation/networking/j1939.txt new file mode 100644 index 0000000..690e0a0 --- /dev/null +++ b/Documentation/networking/j1939.txt @@ -0,0 +1,532 @@ +============================================================================ + +j1939.txt + +Readme file for the J1939 Protocol + +This file contains + + 1 Overview / What is j1939 + 1.1 specifications used + + 2 Motivation + + 3 J1939 concepts + 3.1 socket type + 3.2 addressing + 3.3 priority + 3.4 PGN + 3.5 filtering + 3.6 destinations with dynamic address + + 4 How to use J1939 + 4.1 rtnetlink interface + 4.2 API calls + 4.2.1 Message flags during sendmsg + 4.3 dynamic addressing + + 5 socket options + 5.1 SO_J1939_FILTER + 5.2 SO_J1939_PROMISC + 5.3 SO_J1939_RECV_OWN + 5.4 SO_J1939_RECV_DEST + 5.5 SO_J1939_RECV_PRIO + 5.6 SO_J1939_SEND_PRIO + 5.7 SO_J1939_DEST_MASK + + 6 can-j1939 procfs interface + 6.1 /proc/net/can-j1939/ecu + 6.2 /proc/net/can-j1939/filter + 6.3 /proc/net/can-j1939/sock + 6.4 /proc/net/can-j1939/transport + + 7 can-j1939 SYSCTL + 7.1 /proc/sys/net/can-j1939/transport_max_payload_in_bytes + 7.2 /proc/sys/net/can-j1939/transport_cts_nr_of_frames + 7.3 /proc/sys/net/can-j1939/transport_tx_retry_ms + + 8 Credits + +============================================================================ + +1. Introduction +-------------------------------- + + SAE J1939 defines a higher layer protocol on CAN. It implements a more + sophisticated addressing scheme and extends the maximum packet size above + 8 bytes. Several derived specifications exists, which differ from the + original j1939 on the application level, like MilCAN, NMEA2000 and + especially ISO-11783 (ISOBUS). This last one specifies the so-called ETP + (Extended Transport Protocol) which is has been included in this + implementation. This inclusion results in a maximum packet size of + ((2^24)-1)*7 bytes + + +1.1 specifications used + + SAE J1939-21 : data link layer + SAE J1939-81 : network management + ISO 11783-6 : Virtual Terminal (Extended Transport Protocol) + + +2. Motivation +-------------------------------- + + Given the fact there's something like SocketCAN with an API similar to BSD + sockets, we found some reasons to justify a kernel implementation for the + addressing and transport methods used by J1939. + + * addressing: + When a process on an ECU communicates via j1939, it should not necessarily + know its source address. Although at least 1 process per ECU should know + the source address. Other processes should be able to reuse that address. + This way, address parameters for different processes cooperating for the + same ECU, are not duplicated. + This way of working is closely related to the unix concept where programs + do just 1 thing, and do it well. + + * dynamic addressing: + Address Claiming in J1939 is time critical. Furthermore data transport + should be handled properly during the address negotiation. Putting these + functionality in the kernel eliminates this functionality as a requirement + for _every_ userspace process that communicates via J1939. This results in + a consistent J1939 bus with proper addressing. + + * transport: + Both TP & ETP reuse some PGN's to relay big packets over them. Different + processes may thus use the same TP & ETP PGN's without actually knowing it. + The individual TP & ETP sessions _must_ be serialized (synchronised) + between different processes. The kernel solves this problem properly, and + eliminates the serialisation (synchronisation) as a requirement for + _every_ userspace process that communicates via J1939. + + J1939 defines some other features (relaying, gateway, Fast Packet transport, + ...). In-kernel code for these would not contribute to protocol stability. + Therefore, these parts are left to userspace. + + The j1939 sockets operate on CAN network devices (see SocketCAN). Any j1939 + userspace library operating on CAN raw sockets will still operate properly. + Since such library does not communicate with the in-kernel implementation, + care must be taken that these 2 do not interfere. In practice, this means + they cannot share ECU addresses. A single ECU (or virtual ECU) address is + used by the library exclusively, or by the in-kernel system exclusively. + + +3. J1939 concepts +-------------------------------- + +3.1 PGN + + The PGN (Parameter Group Number) is a number to identify a packet. The PGN + is composed as follows: + 1 bit : Reserved Bit + 1 bit : Data Page + 8 bits : PF (PDU Format) + 8 bits : PS (PDU Specific) + + In J1939-21, distinction is made between PDU1 Format (where PF < 240) and + PDU2 Format (where PF >= 240). Furthermore, when using PDU2 Format, the + PS-field contains a so-called Group Extension, which is part of the PGN. + When using PDU2 Format, the Group Extension is set in the PS-field. + + On the other hand, when using PDU1 Format, the PS-field contains a so-called + Destination Address, which is _not_ part of the PGN. When communicating a + PGN from userspace to kernel (or visa versa) and PDU2 Format is used, the + PS-field of the PGN shall be set to zero. The Destination Address shall be + set elsewhere. + + Regarding PGN mapping to 29-bit CAN identifier, the Destination Address + shall be get/set from/to the apropriate bits of the identifier by the kernel. + + +3.2 addressing + + Both static and dynamic addressing methods can be used. + + For static addresses, no extra checks are made by the kernel, and provided + addresses are considered right. This responsibility is for the OEM or system + integrator. + + For dynamic addressing, so-called Address Claiming, extra support is forseen + in the kernel. In J1939 any ECU is known by it's 64-bit NAME. At the moment + of succesfull address claim, the kernel keeps track of both NAME and source + address being claimed. This serves as a base for filter schemes. By default, + packets with a destination that is not locally, will be rejected soon after + reception. + + Mixed mode packets (from a static to a dynamic address or vice versa) are + allowed. The BSD sockets define seperate API calls for getting/setting the + local & remote address and are applicable for J1939 sockets. + + +3.3 Filtering + + Similar to SocketCAN, j1939 defines filters per socket that a user can set + in order to receive a subset of the j1939 traffic. Filtering can base on + * SA + * NAME + * PGN + + There is a semantic difference with SocketCAN with regard to filtering. + When multiple filters are in place for a single socket, and a packet comes + in that matches several of those filters, the packet is only received once + for that socket. + The rationale behind this difference originates in the filter capabilities. + Where SocketCAN filters on only 1 orthogonal (can id), J1939 can filter + on 3 orthogonal properties (sa, name, pgn). + + When a filter on the SA is set, j1939 traffic with a matching SA, but with + its NAME set (aka having claimed SA successfully) will match, although + the filter would not match its NAME. + + Filtering on priority is _not_ supported. + + +4. How to use J1939 +-------------------------------- + +4.1 rtnetlink interface + + Per default j1939 is not active. Specifying can_ifindex != 0 in bind(2) + or connect(2) needs an active j1939 on that interface. You must have done + $ ip link set canX j1939 on + on that interface. + + $ ip link set canX j1939 down + disables j1939 on canX. + + Assigning addresses is done via + $ ip addr add dev canX j1939 0xXX + statically or + $ ip addr add dev canX j1939 name 0xXX + dynamically. In the latter case, address claiming must take place + before other traffic can leave. + + Removing addresses is done similarly via + $ ip addr del dev canX j1939 0xXX + $ ip addr del dev canX j1939 name 0xXX + + A static address cannot be assigned together with a 64bit name. + +4.2 API calls + + Like TCP/IP and CAN, you first need to open a socket for communicating over a + CAN network. To use j1939, include . From there, + will be included too. + To open a socket, you would write + + s = socket(PF_CAN, SOCK_DGRAM, CAN_J1939); + + J1939 does use SOCK_DGRAM sockets. In the j1939 specification, connections are + mentioned in the context of transport protocol sessions. These still deliver + packets to the other end (using several CAN packets). + SOCK_STREAM is never appropriate. + + After the successful creation of the socket, you would normally use the + bind(2) and/or connect(2) system call to bind the socket to a CAN interface + (which is different from TCP/IP due to different addressing) After binding + and/or connecting the socket, you can read(2) and write(2) from/to the socket + or use send(2), sendto(2), sendmsg(2) and the recv* counterpart operations on + the socket as usual. There are also J1939 specific socket options described + below. + + In order to send data, a bind(2) must have succeeded. bind(2) assigns a local + address to a socket. For this to succeed, you can only choose addresses + that have been assigned earlier (see 4.1). When an empty address is assigned + (ie. SA=0xff && name=0), a default is taken for the device that is bound to. + + Different from CAN is that the payload data is just the data that get send, + without it's header info. The header info is derived from the sockaddr + supplied to bind(2), connect(2), sendto(2) and recvfrom(2). A write(2) with + size 4 will result in a packet with 4 bytes. + + The sockaddr structure has extensions for use with j1939 as specified below: + struct sockaddr_can { + sa_family_t can_family; + int can_ifindex; + union { + struct { + __u64 name; + __u32 pgn; + __u8 addr; + } j1939; + } can_addr; + } + + can_family & can_ifindex serve the same purpose as for other SocketCAN sockets. + + can_addr.j1939.pgn specifies the PGN (max 0x3ffff). Individual bits are + specified above. + + can_addr.j1939.name contains the 64-bit J1939 NAME. + + can_addr.j1939.addr contains the source address. + + When sending data, the source address is applied as follows: If + can_addr.j1939.name != 0 the NAME is looked up by the kernel and the + corresponding Source Address is used. If can_addr.j1939.name == 0, + can_addr.j1939.addr is used. + + After a bind(2), the local address is assigned, i.e. the source address. + After a connect(2), the remote address is assigned, i.e. the destination + address. + + Both write(2) and send(2) will send a packet with local address from bind, + remote address from connect(2). When the address was not set, a broadcast is + sent. The PGN is used from bind(2) or overruled with sendto(2), which will + override the destination address when valid, and the PGN when valid. + + Both read(2) and recv(2) will receive packets matching the sockets filters. + recvfrom(2) will receive these packets with originator's address. + + When creating a socket, reasonable defaults have been set. Some options can be + modified with setsockopt(2) & getsockopt(2). + +4.2.1 Message flags during sendmsg + + send(2), sendto(2) and sendmsg(2) take a 'flags' argument. J1939 interpretes + these flags during outgoing traffic: + + * MSG_DONTWAIT determines nonblocking operation. When a packet must wait for + any reason, -EAGAIN is returned. + + * MSG_SYN + Packets flagged with MSG_SYN will wait for all pending packets on a socket + to be sent before trying to send. This means that if a socket just started + a Transport Protocol session, a packet with MSG_SYN will wait for that + session to complete before proceeding. + Traffic without MSG_SYN (on that very same socket) will still continue. + +4.3 Dynamic Addressing + + Distinction has to be made in and using the claimed address and doing an + address claim. To use an already claimed address, one has to fill in the + j1939.name member and provide it to bind(2). If the name had claimed an + address earlier, all further PGN's being sent will use that address. And the + j1939.addr member will be ignored. + + An exception on this is pgn 0x0ee00. This is the "Address Claim/Cannot Claim + Address" message and when the kernel will use the j1939.addr member for that + pgn if necessary. + + To claim an address, bind(2) with: + j1939.pgn set to 0x0ee00 + j1939.addr set to the desired Source Address. + j1939.name set to the NAME you want the Source Address to claim to. + + Afterwards do a write(2) with data set to the NAME (Little Endian). If the + NAME provided, does not match the j1939.name provided to bind(2), EPROTO + will be returned. One might use sendto(2) also to send the Addres Claim. In + that case, the j1939.addr member must be set to the broadcast address (255) + and the j1939.pgn must be set to 0x0ee00. If This combination is not given, + EPROTO is returned. + + If no-one else contest the address claim within 250ms after transmission, the + kernel marks the NAME-SA assignment as valid. The valid assignment will be + kept, among other valid NAME-SA assignments. From that point, any socket + bound to the NAME can send packets. + + If another ECU claims the address, the kernel will mark the NAME-SA expired. + No socket bound to the NAME can send packets (other than address claims). + To claim another address, some socket bound to NAME, must bind(2) again, + but with only j1939.addr changed to the new SA, and must then send a + valid address claim packet. This restarts the state machine in the kernel + (and any other participant on the bus) for this NAME. + + +5 Socket Options +-------------------------------- + + j1939 sockets have some options that are configurable via setsockopt(2). + Each of those options is initialized with a reasonable default. + + +5.1 SO_J1939_FILTER + + As mentioned above, J1939 supports filtering in both NAME, Source Address + and PGN. All members must match. + + struct j1939_filter filter = { + .name = ... + .name_mask = ... + .addr = ... + .addr_mask = ... + .pgn = ... + .pgn_mask = ... + } + + setsockopt(s, SOL_CAN_J1939, SO_J1939_FILTER, &filter, sizeof(filter)); + + +5.2 SO_J1939_PROMISC + + When set, j1939 will receive all packets, not just those with a destination + on the local system. + default off. + + int promisc = 1; /* 0 = disabled (default), 1 = enabled */ + + setsockopt(s, SOL_CAN_J1939, SO_J1939_PROMISC, &promisc, sizeof(promisc)); + + +5.3 SO_J1939_RECV_OWN + + All the sent j1939 packets are looped back in the system. + The reception of the j1939 packets on the same socket that was + sending the j1939 packet is assumed to be unwanted and therefore + disabled by default. This default behaviour may be changed on + demand: + + int recv_own_msgs = 1; /* 0 = disabled (default), 1 = enabled */ + + setsockopt(s, SOL_CAN_J1939, SO_J1939_RECV_OWN, + &recv_own_msgs, sizeof(recv_own_msgs)); + + +5.4 SO_J1939_RECV_DEST + + Received j1939 packets that make their way up to the socket, had a destination + address matching the socket's local address. This can have several reasons: + - broadcast packet. + - destination spec matches the local address + - destination spec matches _a_ local address on the system, and the socket + had no local address defined. + - SO_J1939_PROMISC was set + If the user is interested in the original destination spec, SO_J1939_RECV_DEST + can be changed to 1 to receive the destination spec with each packet. + The destination is attached to the msghdr in the recvmsg(2) call. + It can be extracted using cmsg(3) macros, with + cmsg_level == SOL_J1939 && cmsg_type == SCM_J1939_DEST. + the returned data is a struct sockaddr_can, with the regular j1939 fields + stuffed. Mind that PGN is the same as the PGN in sockaddr after recvfrom. + + +5.5 SO_J1939_RECV_PRIO + + As stated earlier, the priority field is stripped very soon. In order to + allow retreiving the packet's priority, SO_J1939_RECV_PRIO can be set to 1. + + As a result, an extra int will be attached during recvmsg(2), similar + as in SO_J1939_RECV_DEST, but with cmsg_type == SCM_J1939_PRIO + +6.6 SO_J1939_SEND_PRIO + + To set the priority field for outgoing packets, the SO_J1939_SEND_PRIO can + be changed. This int field specifies the priority that will be used. + j1939 defines a priority between 0 and 7 inclusive, + with 7 the lowest priority. + Per default, the priority is set to 6 (conforming J1939). + This priority socket option operates on the same value that is modified + with + + setsockopt(s, SOL_SOCKET, SO_PRIORITY, &pri, sizeof(pri)) + + socketoption, with a difference that SOL_SOCKET/SO_PRIORITY is defined with + 0 the lowest priority. SOL_CAN_J1939/SO_J1939_SEND_PRIO inverts this value + for you. + +5.7 SO_J1939_DEST_MASK + + When a destination is specified by its name (and thus using dynamic addressing), + and such name should be unique amongst the world, it may be hard to predict the + name of eg. a gearbox controller on the bus, although its type and manufacturer + are know. This is because the serial number is part of the name. + To simplify specifying a destination, a per-socket destination mask is provided + that is activated whenever a destination name is wanted. Any bits cleared in + this mask are ignored during the lookup. As a result, more than 1 ECU may match + this name/mask pair. In all cases, the first match is used. + The API is thus capable of specifying a name for eg. the gearbox controller, + without knowing its serial number. + This mask can mask out any part in the name. Note there's only 1 mask per socket. + + this mask is default set to mask the serial number. + + when can_addr.j1939.name is used for destination in outgoing packets + (see bind(2), sendto(2)), the exact name is often not known due to serial + numbers in it. + Therefore, SO_J1939_DEST_MASK sets an uint64_t mask that will be used + for resolving these names. Only the bits set to 1 in the mask will be + evaluated for find the destination name. + Per default, the mask is set to mask out the serial number + (0xffffffffffe00000ULL) + + to mask out only the manufacturer code (bits 21-31), do + + uint64_t mask = 0xffffffff001fffffULL; + + setsockopt(s, SOL_CAN_J1939, SO_J1939_DEST_MASK, &mask, sizeof(mask)); + + +6. /proc/net/can-j1939 Interface. +-------------------------------- + + Files giving you a view on the in-kernel operation of J1939 are located at: + /proc/net/j1939. + +6.1 /proc/net/can-j1939/ecu + + This file gives an overview of the known ECU's to the kernel. + - iface : network interface they operate on. + - SA : current address. + - name : 64bit NAME + - flags : 'L' = local, 'R' = remote + +6.2 /proc/net/can-j1939/filter + +6.3 /proc/net/can-j1939/sock + + This file gives a list of all j1939 sockets currently open. + - iface : network interface + - flags : + 'b' : bound + 'c' : connected + 'P' : PROMISC + 'o' : RECV_OWN + 'd' : RECV_DEST + 'p' : RECV_PRIO + - local: [NAME],SA + - remote: [NAME]/MASK,DA + - pgn : PGN + - prio : priority + - pending : # packets pending (see MSG_SYN on 4.2.1) + +6.4 /proc/net/can-j1939/transport + + This file shows a list of pending transport sessions + - iface + - src : XX (addr) or XXXXXXXXXXXXXXXX (name) + - dst : XX or XXXXXXXXXXXXXXXX or '-' (broadcast) + - pgn : + - done/total : current # transferred bytes / total + + +7. /proc/sys/net/can-j1939 - SYSCTL +-------------------------------- + + Via these sysctl files, some parameters of the j1939 module can be tuned. + +7.1 /proc/sys/net/can-j1939/transport_max_payload_in_bytes [int] + + Is the maximum packet size to accept on both transmit & receive side. + Bigger packets will be rejected (local sender), aborted (local receiver) + or ignored (broadcasts & remote recievers in PROMISC). + +7.2 /proc/sys/net/can-j1939/transport_cts_nr_frames [int] + + Controls the number of packets to allow between consecutive CTS frames + (default 255). + This number is communicated within the CTS frame from receiver to transmitter. + Setting this has effect on received transport sessions only. + +7.3 /proc/sys/net/can-j1939/transport_tx_retry_ms [int] + + Controls how many time to wait before retrying to send an individual TP + flow or data packet after transmission failure (default 20). + + +8. Credits +-------------------------------- + + Kurt Van Dijck (j1939 core, transport protocol, API) + Pieter Beyens (j1939 core, address claiming) + diff --git a/MAINTAINERS b/MAINTAINERS index 75760e7..a7d7c17 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1631,6 +1631,14 @@ F: include/linux/can/error.h F: include/linux/can/netlink.h F: include/linux/can/platform/ +CAN-J1939 NETWORK LAYER +M: Kurt Van Dijck +L: socketcan-core-0fE9KPoRgkgATYTw5x5z8w@public.gmane.org +L: netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org +S: Maintained +F: net/can/j1939/ +F: include/linux/can/j1939.h + CELL BROADBAND ENGINE ARCHITECTURE M: Arnd Bergmann L: linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org