On Fri, Feb 26, 2010 at 08:58:45AM +0100, Oliver Hartkopp wrote:
> >> Kurt says:
>
> >> * bind() will assign local address.
> >> * connect() assigns destination address.
> Would this be a "write only" socket then? IMO "connect" also requires the
> local address.
Yes, since connect() only sets the destination address, no local address
has been set, unless bind() is issued.
To make the API easier, I'd think it's usefull to have the kernel take
the first 'local address assigned' when local address is missing at the
time of send.
IMO, bind() should not be necessary for receiving too.
>
> >> * recvfrom() will put all info in the sockaddr_can.
> >> * sendto() will use the sockaddr_can for header info (SA, DA, PGN, ...)
> Which might be used on connected/bound sockets then?
>
> >>
> >> * bind, connect & sendto all influence the final outgoing packet. IMO,
> >> it is as designed with regard to the socket API.
> >>
> >> * We want to extend the j1939 bus into the
> >> linux kernel, so different sockets can be logically different
> >> entities, just as can_raw does for can.
> What is an entity here?
I tried to avoid using J1939 specific terms, but here it goes.
J1939 talks about ECU (electronic control module) that claims a single
SA. an ECU may be regarded as a single controller on the CAN bus, but a
single controller may implement several (virtual) ECU's too.
>
> A socket is a communication endpoint that can hold e.g. a communication
> relation from a local address to a specific destination address.
>
> >> A major point of attention is that we also want to be able to have
> >> different sockets cooperate to form 1 logical entity on the bus,
> >> where
> >> a logical entity means '1 source address'.
> To ensure this, you need to manage different sockets in userspace - not in the
> kernel.
>
> >> This way, we can seperate common funcionalities, found in many
> >> logical
> >> entities (such as error reporting, version reporting) and
> >> core functionality in different processes.
> >> Therefore, bind allows to share the same SA.
> This can be done with sockets.
>
> >>
> >> * A filtering similar to CAN is applied, but on PGN & SA level.
> >>
> >> Up to here, we need a layout similar to:
> >> struct sockaddr_can {
> >> ...
> >> union {
> >> struct {
> >> uint8_t sa, da;
> >> uint8_t priority;
> >> uint32_t pgn;
> >> } j1939;
> >> } can_addr;
> >> };
>
> > Lenadro says:
> >
> > Name and Address are two things that are related. Like you mention after in
> > this email, is important to have a dynamic list for tracking, ECU's
> > NAME<->Source Address.
> >
> > In the other hand. You need other separated structure information to
> > send/receive messages containing:
> > Priority, PGN (PDU1, PDU2 and Source address), length, and Data.
> >
>
> I think, when you defined a socket with all these information in the
> connect(), you should be able to write just 8 bytes into the socket and let
> the system create the J1939 message.
Ack, but I would not limit it to 8bytes. 1byte is ok, 0 bytes need to be
considered yet, more than 8bytes instantiates a transport protocol
session, more than 1785 bytes initiates a extended transport protocol
session.
no destiniation address means broadcast, etc etc....
>
>
> >> where not all fields are necessarily used in all api calls.
> >> note that this does go further than only implementing the transport
> >> protocol, but the transport protocols do not need extensions for their
> >> own! In our current implementation, just doing sendto() with more than
> >> 8
> >> bytes data result in a transport protocol session setup, transparently.
>
> This is the major point for me and picks up my last comment above.
> When you send more than 8 bytes to a connected socket (that has both the local
> and the destination address) the multipart message is generated transparently.
>
> IMO defining communication relations (via addresses) and let the kernel do the
> transport protocol is the API we should create on the J1939 sockets.
>
> In general, we could alternatively think about using raw-sockets for all types
> of unsegmented J1939 communication ... just an idea.
different sockets, based on the size of the communication, is a bad
thing. On that level, I do not want to keep track of which socket to
use.
>
> >> Note that the transport protocol in j1939 uses 2 pgns, but such thing
> >> should still be described with (SA, DA, PGN, PRIORITY).
> >>
> >> After reading the relevant man pages & looking at the sockaddr_can
> >> above, the only debate I see is wether to set SA from connect(), and DA
> >> from bind(). That the only documenting up to here.
> >>
> >> When you say 'redundant parts', I can suggest
> >> that sa & da do not necessarily be in the same structure. uint8_t addr
> >> would be sufficient too. in bind(), it means SA, in connect() it means
> >> DA, etc, etc.
> >> For getting the precise DA in recvfrom, a getsockopt could be used
> >> (similar to timestamps).
> >> struct sockaddr_can {
> >> ...
> >> union {
> >> struct {
> >> uint8_t addr;
> >> uint8_t priority;
> >> uint32_t pgn;
> >> } j1939;
> >> } can_addr;
> >> };
> >>
> >> At the next level, j1939 describes a dynamic addressing scheme (the
> >> above is working fine with static addresses only). That's especially
> >> used a lot in agriculture (our main market).
> >> At that point, SA & DA are not persistent anymore, but the 8byte name
> >> is.
> >> We intent not to let kernel code participate in this dynamic
> >> addressing,
> >> but let the kernel code follow the actions on the bus. Since a single
> >> instance must decide which name an SA belongs to & vice versa, the
> >> kernel is the perfect place.
> No.
>
> I checked the idea of the Dynamic Address Configuration in SAE J1939 here
>
> http://www.can-wiki.info/SaeJ1939
>
> and this is definitely something that has to be handled outside the kernel.
Like I mentioned, the actions are taken in userspace, but the kernel
should track when a SA is valid and when not.
>
> >> To participate in dynamic addressing, userspace code is needed.
> >> But userspace programs cooperating to a single entity on the bus, must
> >> not both participate in managing dynamic addresses. That's where the
> >> uint64_t came up in the sockaddr_can. This name is used by kernel code
> >> to find the current SA according to the 8byte name.
> >> This setup results in 1 extra process managing the SA of a particular
> >> 8byte
> >> name, and all others operating on that name level.
>
> Better write a daemon and/or library for that like for DNS in IP.
ack, 1 daemon per SA or so was our plan
>
> > Lenadro says:
> >
> > My suggestion for the J1939 stack is, a user space library with emphasis in
> > the decoupling of the application protocol (in this case the J1939 protocol)
> > from the under laying library, make it dependant only of the most
> > minimalistic API possible (easy to be ported) for configure, get status,
> > send and receive messages (in this case socketcan).
>
> I can follow many of your thoughts but this would base on can-raw sockets
> entirely.
ack
>
> IMO we should use the kernel at least where it could help us to meet the
> timing requirements (e.g. the 50ms) for the J1939 specific transport of
> segmented information.
ack
help in: transport sessions & address claim tracking
>
> A stated above i might make sense to use the CAN filters of the can-raw
> socket(s) to handle all the single frame communication (including the address
> configuration). An to handle the raw/j1939 sockets transparently could be the
> job for the userspace library.
but different processes using the same SA with different PGN suffer
collisions when they use transport protocol.
>
> For the segmented data transfer the ISO15765-2 implementation in the SVN could
> be a good starting point for an implementation.
see above. to avoid specially crafted programs, I'd put also <8byte
messages via such socket.
another point is collisions between different transport sessions of the
same SA. the ISO15765-2 works on a single set of can_id's, that can
collide anyway, so no problem is introduced there.
With j1939 transport implemented the same way, you suggest a user that
it works, but a possible collision(no, bad word, corruption) is
introduced if it were not aware of other users.
When a user want j1939 communication, he/she should be able to just open
the socket, do bind()/connect() as he/she pleases, and start sending.
A common mistake when using j1939 (at least I found that) is to deal
with CAN raw messages instead of j1939 packets. This works like a brake
on applications. One should be able to ignore the actual CAN raw
messages, and work with J1939 packets instead.
>
> Am i missing something?
>
> Regards,
> Oliver
Kurt
>
_______________________________________________
Socketcan-core mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/socketcan-core