On Sat, Feb 27, 2010 at 07:26:46PM +0100, Oliver Hartkopp wrote:
> I just wanted to say, that from the protocols view it is not relevant whether
> >> Is the socket collapsing after sending a socket error?
> > collapsing? I don't understand the word.
>
>
> E.g. some sockets are set in an unusable state, when an error occurred on it's
> specific transport protocol.
>
> E.g. the userspace app get's a socket error on a socket (e.g. -ETIMEO(ut)) and
> then you need to close this socket and create a new one, if you still want to
> communicate ...
>
non-collapsing.
[...]
>
> Thanks for all you explanation. Indeed the 64 bit 'name' seems to be a vital
No problem. It forced me to rethink the API too :-). So, thank you.
> knowledge to ensure a proper dynamic address handling (& recovery).
>
> Btw. dynamic addressing is not an *essential* functionality for all J1939
> applications, that only like to communicate using J1939 protocols, right?
Ack.
>
> Having
>
> struct {
> uint8_t sa, da;
> uint8_t priority;
> uint32_t pgn;
> } j1939;
1. during this discussion, I learned that combining source & destination
in 1 sockaddr is bad. I turned my code into a seperate source &
destination, with only PGN duplicated. It avoids some other confusion,
like which fields are used/filled out in: bind(), connect(),
recvfrom(), sendto()
2. To know the exact destination address of an incoming message, I added
a sockopt to add the original destination sockaddr into a cmsg.
so, a recvfrom(), you must suppose you're a receiver, but don't know
if it were a broadcast or not. with recvmsg(), you can find out.
3. Since priority is an option, I turned that into a sockopt
(potentially reusing the existing SO_PRIORITY option). for receiving,
the priority is only usefull in debugging, and I put it into a cmsg
entry in recvmsg().
(1), (2) & (3) lead to
struct {
uint8_t addr;
uint32_t pgn;
} j1939;
which is very clean.
I know most j1939 users will ask where the DA has gone, but existing
socket API's have different structs for source & destination.
To come to this stripped version, a few cmsg entries are added to allow
debugging tools get all information, but those entries are IMO not used
in everyday communication.
Some socketoptions will be used in everyday applications, but that does
not make the code (using a j1939 socket) much more complex.
>
> and
>
> uint64_t name;
>
> in /one/ structure IMO could lead to confusion and therefore to potential
> misusage.
would
struct sockaddr_can {
union {
struct {
uint8_t addr;
uint32_t pgn;
} j1939;
struct {
uint8_t addr;
uint32_t pgn;
uint64_t name;
} j1939_dyn;
} can_addr;
};
make things better then? IMO not.
when the 8byte name is added to the sockaddr, like
struct {
uint64_t name;
uint8_t addr;
uint32_t pgn;
} j1939;
I doubt there would be confusion.
leaving the name empty (0) would ignore dynamic addressing, having the name
non-empty would disable the addr (for transmissions).
For receiving, the name would be filled out when available, the addr
would be filled out always.
The possible misusage I can imagine is that the name is set to something
(non-empty) when a statis SA was meant, so an error would probably
occur indicating the 8byte name is not known in the system.
It's like stuffing a sockaddr_in with random values. You won't get the
result you expected, but the stack (in the j1939 case) is able to report clean
errors.
This latter is IMHO a crucial part of a good API, since people make
mistakes anywhere.
If name is required to be 0, that not a real obstacle, IMO. having the
addr defaulting to 0xff is more obstacle.
>
> I would suggest to have the shown j1939 struct in sockaddr_can to handle the
> J1939 communication without dynamic addressing.
IMO, my replacement (without da & priority) matches better the original socket
API
in the way that source & destination are seperated ...
>
> By setting the uint64_t name with a socketoption the behaviour of the selected
> socket changes in the way that ...
>
> - the source address (sa) is set dynamically depending on the name
When this 8byte name is stripped from the sockaddr,
this would work as sender (definitely), but would not work as good for
receiving.
An extra cmsg would work, but I doubt such API (for standard
usage) is a good API.
When one would move from static to dynamic addressing, that means one is forced
to use recvmsg() over recv() & recvfrom(), which looks to me as a way too big
constraint
(read: being forced is a big constraint).
given the small step you're taking. IMO, this proves the API being rude
to users of dynamic addressed busses.
> - the sockets data structures are updated according the dynamic addressing
> - any other things that differ when using the J1939 name
Filtering on a dynamic bus, would not base on SA, but
on 8byte name. As such, the 8byte name is used all over the API _but_
the sockaddr, which sounds strange to me.
>
> Would this work for you?
I'm glad you started the discussion on the API, you made me clean it up.
Now I've come the the smallest version (still bigger that current
sockaddr_can).
I do understand that my proposition extends the original sockaddr_can.
This would not be the first time it changes.
My original patch (starting this thread) solves the problems related with
extending it.
Up to now, I've only had some well crafted C programs.
Some time in the future, I would have some reallife j1939 (dynamically
addressed) example, or a Documentation/j1939.txt, to demonstrate
the API, and the need to have the 8byte name in sockaddr_can.
>
> Regards,
> Oliver
>
Regards,
Kurt
_______________________________________________
Socketcan-core mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/socketcan-core