import ctypes class UDP1553Header(ctypes.Structure): """ Represents the proprietary UDP header wrapping the MIL-STD-1553 frames. Standard ctypes.Structure uses host endianness (Little Endian on x86/x64). """ _pack_ = 1 _fields_ = [ ("marker1553", ctypes.c_uint16), ("vmajor", ctypes.c_uint8), ("vminor", ctypes.c_uint8), ("otype", ctypes.c_uint16), ("ta", ctypes.c_uint8), ("flags", ctypes.c_uint8), ("fcounter", ctypes.c_uint32), ("mcounter", ctypes.c_uint32), ("scounter", ctypes.c_uint32), ("mmiss", ctypes.c_uint32), ("smiss", ctypes.c_uint32), ("ltt", ctypes.c_uint32), ("errors", ctypes.c_uint32), ("bc_reserved", ctypes.c_uint32 * 2), ("rt_reserved", ctypes.c_uint32 * 2), ("spare", ctypes.c_uint32 * 3) ] # Constants identifying the packet structure MARKER_1553 = 0x1553 MARKER_END_1553 = 0x5315 OTYPE_BC = 0x4342 OTYPE_RT = 0x5452 # Error codes ERR_UNSUPPORTED_VERSION = 1 ERR_INVALID_SOURCE = 2 ERR_INVALID_LEN = 3 ERR_MISSED_MSG_MARKER = 4 def __init__(self, **kwargs): super().__init__(**kwargs) if "marker1553" not in kwargs: self.marker1553 = self.MARKER_1553 if "otype" not in kwargs: self.otype = self.OTYPE_BC class CommandWordStruct(ctypes.Structure): """ Bit-field representation of a 1553 Command Word. Standard Little Endian packing: LSB is first in the bitfield. Matches C++ struct: wc:5, sa:5, tr:1, rt:5 """ _pack_ = 1 _fields_ = [ ("word_count", ctypes.c_uint16, 5), # Bits 0-4 ("subaddress", ctypes.c_uint16, 5), # Bits 5-9 ("tr_bit", ctypes.c_uint16, 1), # Bit 10 ("remote_terminal", ctypes.c_uint16, 5) # Bits 11-15 ] class CommandWordUnion(ctypes.Union): """ Union to access Command Word as raw integer or bit-fields. """ _pack_ = 1 _fields_ = [ ("raw", ctypes.c_uint16), ("struct", CommandWordStruct) ] def __init__(self, rt_addr=0, sub_addr=0, word_count=0, transmit=False): super().__init__() self.struct.remote_terminal = rt_addr self.struct.subaddress = sub_addr self.struct.word_count = word_count & 0x1F self.struct.tr_bit = 1 if transmit else 0 class UDP1553MessageHeader(ctypes.Structure): """ Header for a single 1553 Message inside the UDP packet payload. """ _pack_ = 1 _fields_ = [ ("marker", ctypes.c_uint16), ("command_word", CommandWordUnion), ("status_word", ctypes.c_uint16), ("error_code", ctypes.c_uint16) ] MARKER_BEGIN = 0x3C3C MARKER_END = 0x3E3E def __init__(self, command_word_union=None): super().__init__() self.marker = self.MARKER_BEGIN if command_word_union: self.command_word = command_word_union self.error_code = 0