DLC value usage/definition not according to ISO11898
While reading the standards and checking the ixxat interface for fd support, I've seen that the definition of the dlc of the message class in not as in the ISO standard and not as the common unterstanding is. The length of the data is already encoded in the message data itself, so storing it additionally is reduntant and may lead to errors. As well the behavior of the classes regarding the data and dlc is somewhat undefinded. So please agree, that the dlc should be used as in the ISO standard. With the folloeing definitions: dlc | length of data 0 .. 8 | 0 .. 8 9 | 12 10 | 16 11 | 20 12 | 24 13 | 32 14 | 48 15 | 64
I agree that it is a bit misleading. The reason I let the dlc attribute mean number of bytes:
- The DLC is rarely interesting in itself, it is usually the length that is and most applications probably assumes this already. Remote frames may have a length but no data so you can’t rely on checking len(data).
- Both SocketCAN and Kvaser which I implemented support for translated the DLC to a length automatically.
- Kvaser kept calling it dlc even though it was the length so I figured it was already an established convention.
- The documentation defines that the dlc is really a length.
I’m open to discuss if the API can be changed to avoid mistakes.
I had a look into the code of many interfaces already. There are many points where dlc are used misleadingly. We should change the API to match to the standard AND name the variables in the API correctly. DLC was never data length, it was data length CODE At least renaming the variables can be done easily. The other thing is that the most applications assume this because the mapping for 0 to 8 data bytes was an identity mapping. Additionally the Message class should not accept dlc values that are not in the allowed ones. The _check function can be shrinked and integrated into the other code.
The behavior of the API to the interfaces when passing more/less data is not consistent too... What happens when somone passes 9, 10, 11, ... 63 bytes? Some interfaces just copy 8 bytes, but they support FD (Meovi for example).
Suggested behavior: DLC defines the length of the message (as in ISO standard). The length of the data is in the data itself -> No redundancy More data is allowed, So passing 9 bytes with an dlc of 8 or less is allowed. The same applies to lets say 32 bytes. If you set dlc to 8 then the lowest 8 bytes is used, if you set dlc to 9 then the lowest 12 bytes are used. -> Compliant with standard and handles the case more data delivered to init of Message Less data is not allowed. This should raise a ValueError.
@hardbyte Any thoughts on this? e.g. moving towards the standard?
Without causing compatibility issues, I would suggest adding two properties to the Message class to wrap an ISO-compliant dlc.
class BetterMessage(can.Message):
ISO_DLC = (0, 1, 2, 3, 4, 5, 6, 7, 8, 12, 16, 20, 24, 32, 48, 64)
@property
def iso_dlc(self) -> int:
return self.ISO_DLC.index(self.dlc)
@iso_dlc.setter
def iso_dlc(self, value: int) -> None:
self.dlc = self.ISO_DLC[value]
This should be proposed as a PR, but I'm not quite sure if the maintainers like this.