cFE icon indicating copy to clipboard operation
cFE copied to clipboard

EDS is missing full big endian attribute on CCSDS header.

Open thesamprice opened this issue 4 months ago • 3 comments

Describe the bug Was Generating python ctypes from the eds schema.

I was trying to scan all fields in a struct, if all fields are big endian then make the parent big endian.

VersionId, SecHdrFlags, SeqFlag are missing the big endian attribute.


class BaseHdr(ectypes.LittleEndianExtendedStructure):
    """Space packet protocol header"""
    _pack_ = 1
    _fields_ = [
        ('VersionId', ectypes.c_uint16, {'bits': 3, 'is_bitfield': True, 'bitfield_container_id': 0, 'description': 'CCSDS Version number'}),
        ('SecHdrFlags', ectypes.c_uint16, {'bits': 2, 'is_bitfield': True, 'bitfield_container_id': 0, 'description': 'Secondary Header Presence and Type Flags'}),
        ('AppId', ectypes.c_uint16, {'bits': 11, 'is_bitfield': True, 'bitfield_container_id': 0, 'endianness': 'bigEndian', 'description': 'Packet identifier word (stream ID)'}),
        ('SeqFlag', ectypes.c_uint16, {'bits': 2, 'is_bitfield': True, 'bitfield_container_id': 1, 'description': 'packet sequence word'}),
        ('Sequence', ectypes.c_uint16, {'bits': 14, 'is_bitfield': True, 'bitfield_container_id': 1, 'endianness': 'bigEndian', 'description': 'packet sequence word'}),
    ]

To Reproduce Steps to reproduce the behavior:

  1. Go to '...'
  2. Click on '....'
  3. Scroll down to '....'
  4. See error

Expected behavior A clear and concise description of what you expected to happen.

Code snips If applicable, add references to the software.

System observed on:

  • Hardware
  • OS: [e.g. Linux 4.4]
  • Versions [e.g. cFE 6.6, OSAL 4.2, PSP 1.3 for mcp750, any related apps]

Additional context Add any other context about the problem here.

Reporter Info Full name and company/organization if applicable

thesamprice avatar Oct 10 '25 20:10 thesamprice

They don't need it ....

The "littleEndian" attribute can only be applied to fields which are a multiple of 8 bits. Otherwise it is ambiguous and invalid. All fields in EDS containers are always packed in the specified order so there is nothing to do there.

I see that "LengthType" (which is 16 bits) does have the byteOrder="bigEndian" attribute.

The SeqCount (14 bits) and AppId (11 bits) also have the attribute but it is irrelevant because bigEndian is the default and it would cause an error if set to littleEndian.

In general a field that is not byte aligned (both in its own size and where it sits in the parent container) cannot be packed as littleEndian. In general littleEndian really shouldn't be used for anything, it exists only as a compatibility bridge.

jphickey avatar Nov 14 '25 21:11 jphickey

Python / c / cosmos / etc do allow for some notation of bitfields, and their implementation changes if you are using a big or little endian struct.

Cosmos allows for setting the endianness of the packet, field. field position changes if little endian is defined. Python allows for setting of the structure type.

Note there is no spec on how a compiler implements bitfields, which makes it not cross platform compatible. clang / gcc mostly agree.

Should I assume any structure that has a bitfield in it, then the whole structure should be treated as big endian? Majority of the fields on my process are little endian (Minus the ccsds headers / misc network parts).

Feel free to close thie issue.

thesamprice avatar Nov 17 '25 20:11 thesamprice

Should I assume any structure that has a bitfield in it, then the whole structure should be treated as big endian? Majority of the fields on my process are little endian (Minus the ccsds headers / misc network parts).

A struct/container or bitfields cannot be "little endian". Members of a container always appear in memory in the same order they appear in the container definition (this is true for C and EDS). The first member of a container always gets the same address as the container itself, and the C spec says this.

In C structs cannot directly have bit fields as a member. Using the bit field syntax you are not really adding a bit field directly, you are adding a full size integer member (be it unsigned char, unsigned short, unsigned int or unsigned long) and then dividing that integer into parts that will be shifted and masked upon access. This integer is what is little or big endian, and the compiler is also free to choose whether it gets packed left to right or right to left in addition to that. If I'm not mistaken, I think even some compiler flags can affect how this is packed. (note that left to right vs. right to left packing is not endianness, as endianness applies to octets, not bits. You have both things going on in bitfields).

In the end, because of these wide variations, a bitfield in a C struct should never appear in anything intended to be used in an IPC or I/O context. Its fine for local use within your own program, so long as everything that accesses the struct is compiled with the same compiler and running on the same platform. But for I/O, don't use them.

jphickey avatar Nov 18 '25 13:11 jphickey