BLF reader CAN_MESSAGE and CAN_MESSAGE2 incomplete
pratik-mahamuni opened this issue · 1 comments
Describe the bug
The class BLFReader
from can.io.blf
is implemented using Toby Lorenz's Vector_BLF. The implementation for reading CAN messages especially for CAN_MESSAGE
and CAN_MESSAGE2
is incorrect.
In this library
The code in this library related to this is as follows:
if obj_type in (CAN_MESSAGE, CAN_MESSAGE2):
channel, flags, dlc, can_id, can_data = unpack_can_msg(data, pos)
yield Message(
timestamp=timestamp,
arbitration_id=can_id & 0x1FFFFFFF,
is_extended_id=bool(can_id & CAN_MSG_EXT),
is_remote_frame=bool(flags & REMOTE_FLAG),
is_rx=not bool(flags & DIR),
dlc=dlc,
data=can_data[:dlc],
channel=channel - 1,
)
data=can_data[:dlc]
uses the data length code to slice data bytes.
In Vector_BLF
For CAN_MESSAGE
:
void CanMessage::read(AbstractFile & is) {
ObjectHeader::read(is);
is.read(reinterpret_cast<char *>(&channel), sizeof(channel));
is.read(reinterpret_cast<char *>(&flags), sizeof(flags));
is.read(reinterpret_cast<char *>(&dlc), sizeof(dlc));
is.read(reinterpret_cast<char *>(&id), sizeof(id));
is.read(reinterpret_cast<char *>(data.data()), static_cast<std::streamsize>(data.size()));
}
For CAN_MESSAGE2
:
void CanMessage2::read(AbstractFile & is) {
ObjectHeader::read(is);
is.read(reinterpret_cast<char *>(&channel), sizeof(channel));
is.read(reinterpret_cast<char *>(&flags), sizeof(flags));
is.read(reinterpret_cast<char *>(&dlc), sizeof(dlc));
is.read(reinterpret_cast<char *>(&id), sizeof(id));
data.resize(objectSize - calculateObjectSize()); // all remaining data
is.read(reinterpret_cast<char *>(data.data()), static_cast<std::streamsize>(data.size()));
is.read(reinterpret_cast<char *>(&frameLength), sizeof(frameLength));
is.read(reinterpret_cast<char *>(&bitCount), sizeof(bitCount));
is.read(reinterpret_cast<char *>(&reservedCanMessage1), sizeof(reservedCanMessage1));
is.read(reinterpret_cast<char *>(&reservedCanMessage2), sizeof(reservedCanMessage2));
}
Both versions have a is.read(reinterpret_cast<char *>(data.data()), static_cast<std::streamsize>(data.size()));
that does not slice the data based on DLC.
To Reproduce
Instantiate the BLFReader
class:
data = BLFReader(blffile_path)
Expected behavior
Bytes extracted from the data should be 8 bytes
bytearray(b'\xff\x00\xff\x00\x00\x00\x08\x00')
In the current version:
Bytes extracted from the data are 3 bytes because of the DLC slicing
bytearray(b'\xff\x00\xff')
This causes errors in decoding the data using cantools which reads the length of data as 8 bytes from the DBC file.
Additional context
OS and version: Ubuntu 22.04
Python version: 3.10.12
python-can version: 4.4.2
python-can interface/s (if applicable):
python-can behaves correctly. According to your blf, there are only 3 valid bytes in your message. So this is either an issue with your ECU or your dbc file. Either way, cantools has a allow_truncated
parameter for this.