Re: j1939: discussion: RX path

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, 27 Jun 2019 12:59:01 +0200
Oleksij Rempel <o.rempel@xxxxxxxxxxxxxx> wrote:

> On Thu, Jun 27, 2019 at 11:33:53AM +0200, Kurt Van Dijck wrote:
> > > > > Thanks for your feedback. I understand it may sound counter-intuitive, but it
> > > > > really isn't. What we are trying to accomplish is for SocketCAN with J1939 to
> > > > > behave much like a network adapter with TCP/IP.    
> > > > 
> > > > J1939 is a datagram system, so more like UDP/IP.  
> > > 
> > > In some aspects it is more like UDP, but unlike UDP, J1939 does have have
> > > handshaking (in hardware) and is considered reliable.  
> 
> You probably mean the way the CAN bus works, which is not specific to
> J1939.

Yes. J1939 relies on the reliability of CAN (no pun intended).
Side-note: We also have a J1939 implementation on top of TCP/IP... not UDP for
obvious reasons ;-)

> > > Also the transport protocol implements handshakes and reliability for bigger
> > > "datagrams".  
> > 
> > There is no handshaking, and by far not in hardware.  
> 
> I think David means the collision avoid on the CAN bus...

CAN collision avoidance, priority, message reception ACK and corrupted message
NACK/destroy, etc...
Of course there IS handshaking in CAN hardware. And J1939 obviously relies on
it!
In theory though, CAN is not 100% airtight, but in practice these guarantees
in hardware are enough for it to be considered "robust" for all but the most
critical use-cases.

> > The only handshaking that exists is for non-broadcast TP.  
> 
> Yes, on the J1939 level, there's only handshaking inclusive RTS/CTS/EOMA
> for (E)TP.

The J1939 handshaking for (E)TP is mainly necessary for dealing with different
hardware limitations confronted with big(ish) amount of incoming bulk data.

> > Broadcast TP and <=8byte datagrams are sent unreliably, just as regular
> > CAN.  
> 
> It's fire and forget, but the most (?) people consider the underlying
> CAN bus reliable (enough). :)

Indeed.

> > > On top of that, many applications (like the ISObus fileserver, or the ISObus
> > > VT) behave much more like a connection-oriented server, thus benefiting more
> > > from the TCP/IP server analogy. I.e. there is a "client" who establishes a
> > > connection with a "server" and from then on they semantically communicate over
> > > a point to point channel, akin to a connected TCP/IP socket.  
> > 
> > If you create a server where different sockets are used for different
> > DST+PGNs, and you want to avoid receiving the same thing in your own
> > sockets, then you should be more precise in your applied filters.  
> 
> Yes, but...
> 
> For David's use case you want to receive the initial message by the
> client, the you create a new socket()/bind()/connect() it. While the
> newly created socket is active, you don't want to receive any messages
> from that client on the server socket. This might be done by modifying
> the filters. As soon as you close the dedicated client socket, you have
> to modify the filers again. These are two separate operations, thus
> racy by design. If you do it right, you don't loose any messages, but
> receive them in both sockets. (Which makes user space handling more
> complex).
> 
> > Unlike TCP and UDP, most J1939 applications are not designed with
> > 1 or few PGNs in mind, but use a huge range of PGN's. That is why
> > filter lists are common in CAN / J1939 and not in TCP / UDP.
> > The 'server' example is the exception, not the standard.  
> 
> We'd like to have an API that supports the whole spectrum of use cases.

AFAICS, the current API covers all use-cases. For the strictly
datagram-oriented use-cases, there is always recvfrom() and sendto() on a
single socket.

> > > True. But like I said above, in ISObus there are use-cases where a
> > > connection-oriented approach is used, even though there is no formal
> > > handshaking of the establishment and closing of a connection in the link layer.  
> > 
> > A 'server' socket that 'listens' for new 'connections' need not
> > listening to all PGNs, does it? IMHO, it needs 1 or a few PGNs, and the
> > point-to-point socket needs the rest.  
> 
> The server socket may listen on as many PGNs as it wants to. The
> dedicated socket to the client uses one tuple only (SRC/DST/PGN), which
> is a point-to-point connection.

Correct. I don't know about J1939, but on ISObus there are quite a few
application protocols that work that way (file-server, virtual terminal).

> > So, worst cast, the point-to-point socket receives also the packets that
> > trigger connection construction/destruction for 1 specific destination,
> > and more specifically, it needs those in order to close your virtual
> > 'connection'.  
> 
> ACK

In the example of a VT or file-server, there are no "specific" packets that
trigger connection/disconnection.
A "connection" is established on first contact from the client, and held
"active" as long as the implement sends periodic "Working Set Maintenance"
messages (in case of a VT) or "Client Connection Maintenance" messages
(fileserver client).

> > If this is not feasible, then adapt your listening socket's filters
> > accordingly.
> 
> I don't like this, due to the raciness of the approach.
> 
> We just prototyped a sock option for "server" sockets. The options is
> disabled by default, when enabled all packets that are received in a
> connect()ed socket are ignored on this socket.

Switching filters on reception of a message is inherently racy and should
always be avoided.

> > > > I'm not aware of the complexity that has been added recently for the
> > > > ETP, but that should not break multiuser operation, i.e.,
> > > > if I write 'a' program, then that program should receive the same thing
> > > > regardless of the presence of other sockets on the local system, with or
> > > > withing the same process.
> > > > I would not plan to violate that rule.
> > > > I seriously would not.  
> > > 
> > > That rule is not violated as long as these processes have their own address
> > > (and NAME). If they share the same address and NAME, they are part of the same
> > > control-function. In that case, as long as they do not connect() and only use
> > > sendto() and recvfrom() that rule also holds true.
> > > It is only when you use connect() to establish a 1:1 connection with another
> > > peer. The only difference with TCP/IP sockets in that case is that you use
> > > connect() on both ends instead of listen()/accept(), and the
> > > establishment/tear-down of the connection is thus left to the application.  
> > 
> > Then you must redesign/redefine the filters because they are no more
> > coherent.  
> 
> regards,
> Oleksij & Marc
> 

Best regards,

-- 
David Jander
Protonic Holland.



[Index of Archives]     [Automotive Discussions]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]     [CAN Bus]

  Powered by Linux