On Wed, Feb 09, 2011 at 08:31:06PM +0100, Oliver Hartkopp wrote:
> On 03.02.2011 10:39, Kurt Van Dijck wrote:
> > This contains the j1939 documentation.
> > 
> 
> > +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.
> 
> As it is in many industrial setups.
ack.
dynamic addressing is used in marine setups, agriculture, ..., mainly the 
derived
standards like NMEA2000, ISO11783 etc.
> 
> > +
> > +  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.
> 
> Do you mean bind() and connect() here?
and sendto().
> 
> I think that is not the intention of bind() and connect(), as you don't
> necessarily need to perform a bind() before connect() as you do to define the
> source address and the destination address.
The semantics I applied are IMHO correct.
My colleague and I have studied some time on those man pages.

The statement you make here is applicable on IPv4 sockets, which do 'autobind'
when necessary. You should try the same thing (communicating with datagram, not 
stream)
over unix sockets. You'll see what I mean.
My recently explored wpa_supplicant, where a bind()+connect() is _necessary_.
> 
> IMO the sockaddr_can must be capable to define all these settings by only
> invoking connect(). So the src & dest addresses are able to be specified with
> one syscall. It took some time to me to get behind this fact and it was not
> very intuitive.
IMO it must not. But I suggest we don't argue here on that. That is something 
for
netdev mailing list.
> 
> 
> > +  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.
> 
> Yep. Only SOCK_SEQPACKET could be candidate ... but DGRAM simply fits here.
SEQPACKET supposes 'reliable', which I'm not sure of. I just don't know yet.
> 
> > +
> > +  After the successful creation of the socket, you would normally use the
> > +  bind(2) 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 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.
> > +
> > +  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.
> 
> Ugh! What's that for?
$ ip link set canX j1939 on?
On ethernet, things are simple: each protocol has a unique ID, embedded in each 
packet.
On CAN, one may run other 29bit CAN traffic that is not j1939 at all. It would 
be
not good to have the j1939 stack complaining then.
> 
> > +  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.
> 
> This is a bad approach. connect() should be able to do the job in one step.
see above.
> 
> > +  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.
> 
> Aehmmmm, yes?
> 
> Can you see what i think is not easy to understand?
Yes, I see. The thing is, I did not invent these semantics. I fitted j1939 to 
existing
ones. The difference with raw CAN is that j1939 has an 'ecu addressing' scheme.
> 
> 
> > +4.3 Address Claiming
> > +
> > +  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.
> 
> Can there be an inconsistency when the userspace process sends PGNs like this?
Note: userspace is the only one that sends these.
we kept this kind of policy choosing stuff out of kernel.
The kernel just keep the timeouts correct.
> 
> > +  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.
> 
> Why EPROTO?
you're about to commit a protocol violation?
> 
> 
> > +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.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));
> 
> I think this also belongs to the fact, that you are attaching j1939 addresses
> to network interfaces, right?
It is a consequence of having the addressing concept. Traffic not destined for
the 'localhost' should be dropped normally, but with this 'engineering' option,
one can spy the bus for others traffic too.
> 
> > +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.
> 
> Why this option? Is using recvmsg() not enough to detect this info to be
> retrieved?
recvmsg() normally supplies the source address. The destination address would be
yourself, unless you're spying...
call it an engineering option as above.
> 
> > +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.
> 
> Why is the priority not part of sockaddr_can in the same way as the PGN?
in j1939, the priority is _not_ part of the address!
the pgn identifies data, the priority does not. The priority field
should not be used to sort data.
> 
> > +6. /proc Interface.
> > +--------------------------------
> > +
> > +6.4 /proc/net/j1939/stack
> > +
> > +  The internal j1939 is build with a stack of code blocks. This blocks are
> > +  passed for each packet (both RX & TX).
> > +  this file gives an insight view on this stack.
> > +  - prio : level, priority
> 
> Why has the _stack_ a priority?
it's more like an 'order'.
> 
> > +
> > +6.6 /proc/sys/net/j1939 - SYSCTL
> > +
> > +  Via these sysctl files, several parameters of the j1939 module can be 
> > tuned.
> > +
> > +  - /proc/sys/net/j1939/loop [bool]:
> > +    Control if packets with local source _and_ local destination may be 
> > (true)
> > +    loopback'd (injected directly in the receive path from the transmit 
> > path)
> > +    or (false, default) must be sent on CAN via the regular transmit path.
> 
> Is done by sockopts - don't specify two interfaces for one functionality.
I'll look.
This does not control the CAN loopback, but more the J1939 loopback.
ie. when a message is not required to appear on CAN (ie. from local to local), 
should
it appear on loopback CAN sockets?
Not sure here.
> 
> > +
> > +  - /proc/sys/net/j1939/promisc [bool]:
> > +    Specifies PROMISC mode for the whole stack, i.e. _all_ J1939-sockets. 
> > The
> > +    PROMISC mode is normally set per socket via setsockopt(2).
> 
> Dito. Here you already detected the problem by yourself :-)
ack. one interface should hold.
I'll remove that.
> 
> 
> > +  - /proc/sys/net/j1939/tp/max_packet_size [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).
> 
> What's that for?
> Why is it a global setting and not a sockopt?
Since packets may grow to several megabytes, it seemed wise to cut a limit 
there.
And since they are assembled way before consulting sockets, I don't see how to 
turn
it into a sockopt.
> 
> > +  - /proc/sys/net/j1939/tp/preferred_block_count [int]:
> > +    Controls how many data packets the TP & ETP will receive before 
> > requiring
> > +    flow control packets.
> 
> Why is it a global setting and not a sockopt?
> Make it a constant that can be overridden via sockopt.
dito.
> 
> > +
> > +  - /proc/sys/net/j1939/tp/queue_len [int]:
> > +    Controls how many pending packets the TP module may queue before 
> > returning
> > +    ENOBUFS to sender. Note this is not the only source of ENOBUFS, the CAN
> > +    device driver may also return ENOBUFS.
> 
> Make it a constant - or at least a Kconfig option
does it hurt that much ? :-)
> 
> > +  - /proc/sys/net/j1939/tp/retry_ms [int]:
> > +    Controls how many time to wait before retrying to send an individual TP
> > +    flow or data packet after transmission failure.
> 
> Make it a constant that can be overridden via sockopt.
IMO it's very 'system' dependant, not application dependant. But both are
good.
> 
> If it's clear to me as a j1939 newbie, then it's probably mature enough. So
> far the socket API is confusing me.
I think the biggest problem from doing such j1939 is using the addressing 
concept
that BSD socket provides semantics for. You're sure not the only one that is
experienced with CAN, but uncomfortable with addressing.
Yet, I think the addressing is a leap forward. I'm very interested in netdev 
remarks
on the precise details.

You're right in that you're quite some prototype of a potential user. So, it 
should
be clear to you, and apparently, I've yet some documentation to do :-).
> 
> Thanks,
> Oliver
Kurt
_______________________________________________
Socketcan-core mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/socketcan-core

Reply via email to