Skip to content
This repository was archived by the owner on May 7, 2025. It is now read-only.
This repository was archived by the owner on May 7, 2025. It is now read-only.

swap_uint_length improperly does byte-level swap in bit mode when little endian is selected #1110

@eacmen

Description

@eacmen

When a CAN mapping is configured in bit mode and the data on the bus is formatted Least Significant Bit the swap_uint_length function does an endian (byte level) swap when in fact it needs to be doing a Most Significant Bit to Least Significant Bit conversion.

Lets use the decimal number 4099 as an example. 4099 encoded in binary is:
1000000000011 (13 bits Most Significant Bit)

"On the wire" it will be:
1100000000001 (13 bits Least Significant Bit)

Entering the canmapping_extract_value function that Least Significant Bit value will be embedded in that 64bit uint somewhere (as indicated by length/offset), carved out by a bitmask to a uint_32 native to the host processor.

What I believe is happening is the swap_uint_length is treating that 13 bit value as a 16 bit short and doing a byte swap so swap_unit_length is basically doing the following

00011000 00000001 (0-padded to 16 bit value from above)
00000001 00011000 (byte swapped)

which equals 280 not 4099

What I believe needs to happen is that the whole uint_16 needs to be shifted left to a byte boundary (in this case 3 bits) and the order of the BITS in each byte reversed. Then the bytes themselves need to be swapped.

Demonstrated:
00011000 00000001 (0-padded to 16 bit value from above)
11000000 00001000 (whole uint_16 value shifted left by 3 bits to)
00000011 00010000 (both upper and lower bytes BITS rotated)
00010000 00000011 (byte swapped)

raw_value = swap_uint_length(raw_value, length);

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions