def get_user_definition(settings): if ( settings.system_options.user_code_length_6 or settings.system_options.user_code_length_flexible ): code = ExprAdapter( Bytes(3), lambda obj, path: binascii.hexlify(obj) .decode() .rstrip("0") .replace("a", "0") or None, lambda obj, path: binascii.unhexlify(obj.replace("0", "a")), ) else: code = ExprAdapter( Bytes(3), lambda obj, path: binascii.hexlify(obj) .decode() .rstrip("0") .replace("a", "0")[:4] or None, lambda obj, path: binascii.unhexlify((obj + obj[:2]).replace("0", "a")), ) return Struct( "code" / code, "options" / BitsSwapped( BitStruct( "type" / Enum(BitsInteger(2), FullMaster=0x3, Master=0x2, Regular=0x0), "duress" / Flag, "bypass" / Flag, "arm_only" / Flag, "stay_instant_arming" / Flag, "force_arming" / Flag, "all_subsystems" / Flag, ) ), "partitions" / BitsSwapped(Bitwise(StatusFlags(8))), "access" / BitStruct("level" / Nibble, "schedule" / Nibble), "access_options" / Bytes(1), "card_serial_number" / Bytes(3), )
def PGMFlags(count, start_index_from=1): return DictArray( count, start_index_from, Bitwise( Struct( "_index" / Computed(this._index + start_index_from), "fire_2_wires" / Default(Flag, False), "normally_closed" / Default(Flag, False), "_unknown1" / BitsInteger(1), "disabled" / ExprSymmetricAdapter( Default(Flag, False), lambda obj, ctx: not obj ), # False when a relay is assigned "_unknown2" / BitsInteger(2), "timer_active" / Default(Flag, False), # when timer is active "on" / Default(Flag, False), # when is activated "time_left" / Bytewise(ByteSwapped(Default(Int24ub, 0))), # byte in seconds ), ), )
RAMDataParserMap = { 1: Struct( "_weekday" / Int8ub, "pgm_flags" / BitStruct( # TODO: Do we need BitsSwapped here? "chime_zone_partition" / BitsSwapped(StatusFlags(4)), "power_smoke" / Flag, "ground_start" / Flag, "kiss_off" / Flag, "line_ring" / Flag, "bell_partition" / BitsSwapped(StatusFlags(8)), "fire_alarm" / BitsSwapped(StatusFlags(8)), "open_close_kiss_off" / BitsSwapped(StatusFlags(8)), ), "key-switch_triggered" / BitsSwapped(Bitwise(StatusFlags(32))), "door_open" / BitsSwapped(Bitwise(StatusFlags(32))), "system" / Struct( "troubles" / BitStruct( "system_trouble" / Flag, "dialer_trouble" / Flag, "module_trouble" / Flag, "bus_com_trouble" / Flag, # BusCom "zone_tamper_trouble" / Flag, "zone_low_battery_trouble" / Flag, "zone_fault_trouble" / Flag, "time_lost_trouble" / Flag, "ac_trouble" / Flag, "battery_failure_trouble" / Flag,
'command' / Bytes(2), 'ssrc' / Int32ub, 'count' / Int8ub, 'padding' / Padding(3), 'timestamp_1' / Int64ub, 'timestamp_2' / Int64ub, 'timestamp_3' / Int64ub, ) MIDIPacketHeader = Struct( '_name' / Computed('MIDIPacketHeader'), 'rtp_header' / Struct( 'flags' / Bitwise(Struct( 'v' / BitsInteger(2), # always 0x2 'p' / Flag, # always 0 'x' / Flag, # always 0 'cc' / Nibble, # always 0 'm' / Flag, # always 0x1 'pt' / BitsInteger(7), # always 0x61 )), 'sequence_number' / Int16ub, # always 'K' ), 'timestamp' / Int32ub, 'ssrc' / Int32ub, ) MIDINote = Enum(Byte, Cn1=0, Csn1=1, Dn1=2, Dsn1=3, En1=4,
"block_colors": Color, "block_genres": Genre, "block_keys": Key, "block_labels": Label, #"strange": StrangePage, }, default = Computed("page type not implemented")), ) ) # unfortunately, the entry_enabled field contains even unexistant entries: # entry_enabled[:-1] matches revidx[:-1], # but len(entry_enabled)==16 while len(revidx)<=16 FirstReverseIndexArray = Struct( "entries" / Array(this._._.entry_count%16, ReverseIndexedEntry), "entry_enabled" / ByteSwapped(Bitwise(Array(16, Flag))), # may start with unexistant entries, see above! "entry_enabled_override" / ByteSwapped(Bitwise(Array(16, Flag))) # may start with unexistant entries, see above! ) FullReverseIndexArray = Struct( "entries" / Array(16, ReverseIndexedEntry), "entry_enabled" / ByteSwapped(Bitwise(Array(16, Flag))), "entry_enabled_override" / ByteSwapped(Bitwise(Array(16, Flag))) ) PageEndHeader = Sequence( FirstReverseIndexArray, Embedded(Array(this._.entry_count//16, FullReverseIndexArray)) ) PageHeader = Struct( # 40 bytes
def BitList(size, *, reversed=False): return BitListAdapter(Bitwise(Bit[size * 8]), reversed)
def BitList(size): return BitListAdapter(Bitwise(Bit[size * 8]))
construct.Flag("overflow"), construct.Flag("valid"), construct.Flag("ack"), construct.BitField("ip_addr", 32), construct.BitField("data", 64)) # the snap block immediately after the x-engine snap_xengine_vacc = construct.BitStruct("snap_vacc0", construct.BitField("data", 32)) if construct.version[1] > 6: # f-engine adc control register_fengine_adc_control = BitStruct( 'enable' / Flag, # 31 Enable input channel on KAT ADC. Padding(32 - 6 - 1), # 6-30 'atten' / Bitwise(BitsInteger(6))) # 0-5 KAT ADC channel attenuation setting. # f-engine status register_fengine_fstatus = BitStruct( 'coarse_bits' / Bitwise(BitsInteger(5)), # 27-31 2^x - the number of points in the coarse FFT. 'fine_bits' / Bitwise(BitsInteger(5)), # 22-26 2^y - the number of points in the fine FFT. 'sync_val' / Bitwise(BitsInteger(2)), # 20-21 On which ADC cycle did the sync happen? Padding(2), # 18-19 'xaui_lnkdn' / Flag, # 17 The 10GBE link is down. 'xaui_over' / Flag, # 16 The 10GBE link has overflows. Padding(9), # 7-15 'clk_err' / Flag, # 6 The board frequency is calculated out of bounds. 'adc_disabled' / Flag, # 5 The ADC has been disabled. 'ct_error' / Flag, # 4 There is a QDR error from the corner-turner. 'adc_overrange' / Flag, # 3 The ADC is reporting over-ranging. 'fine_fft_overrange' / Flag, # 2 Not used currently.
def to_bits(bytes): return list(Bitwise(Bit[8 * len(bytes)]).parse(bytes))
def test_parsing_gsm7(data, message): assert Bitwise(Gsm7Adapter(GreedyBytes)).parse(data) == message
def test_building_gsm7(message, expected): assert Bitwise(Gsm7Adapter(GreedyBytes)).build(message) == expected
zones = list([i in obj for i in range(1, 193)]) return self.subcon._build(zones, stream, context, path) PerformZoneAction = Struct( "fields" / RawCopy( Struct( "po" / Struct("command" / Const(0xd0, Int8ub)), "packet_length" / Rebuild( Int8ub, lambda this: this._root._subcons.fields.sizeof() + this ._root._subcons.checksum.sizeof()), "flags" / ZoneFlagBitStruct, "operation" / ZoneActionBitOperation, "_not_used" / Padding(2), "zones" / ZoneAdapter(BitsSwapped(Bitwise(Array(192, Flag)))), )), "checksum" / Checksum( Bytes(1), lambda data: calculate_checksum(data), this.fields.data)) PerformZoneActionResponse = Struct( "fields" / RawCopy( Struct( "po" / BitStruct( "command" / Const(0xd, Nibble), "status" / Struct("reserved" / Flag, "alarm_reporting_pending" / Flag, "Winload_connected" / Flag, "NeWare_connected" / Flag)), "packet_length" / Rebuild( Int8ub, lambda this: this._root._subcons.fields.sizeof() + this ._root._subcons.checksum.sizeof()), "flags" / ZoneFlagBitStruct, "operation" / ZoneActionBitOperation,
Padding(16 - 13 - 1), # 14 - 15 'adc_protect_disable' / Flag, # 13 'flasher_en' / Flag, # 12 Padding(12 - 9 - 1), # 10 - 11 'gbe_enable' / Flag, # 9 'gbe_rst' / Flag, # 8 Padding(8 - 3 - 1), # 4 - 7 'clr_status' / Flag, # 3 'arm' / Flag, # 2 'soft_sync' / Flag, # 1 'mrst' / Flag # 0 ) # f-engine status register_fengine_fstatus = BitStruct( Padding(32 - 29 - 1), # 30 - 31 "sync_val" / Bitwise(BitsInteger(2)), # 28 - 29 Padding(28 - 17 - 1), # 18 - 27 'xaui_lnkdn' / Flag, # 17 'xaui_over' / Flag, # 16 Padding(16 - 6 - 1), # 7 - 15 'dram_err' / Flag, # 6 'clk_err' / Flag, # 5 'adc_disabled' / Flag, # 4 'ct_error' / Flag, # 3 'adc_overrange' / Flag, # 2 'fft_overrange' / Flag, # 1 'quant_overrange' / Flag # 0 ) # x-engine control register register_xengine_control = BitStruct( Padding(32 - 16 - 1), # 17 - 31
from construct import Bit, BitStruct, Bitwise, Const, Int16ub, Int8ub, Nibble, Struct from ledbadger.image import bytes_to_image from ledbadger.message import Message from ledbadger.utils import pad_buffer ShowModeAndSpeed = BitStruct( 'speed' / Nibble, 'show_mode' / Nibble, ) HeaderFormat = Struct( 'signature' / Const(b'wang'), 'zero1' / Const(0, Int8ub), 'brightnesses' / Bitwise(Bit[8]), 'flashes' / Bitwise(Bit[8]), 'borders' / Bitwise(Bit[8]), 'show_modes_and_speeds' / ShowModeAndSpeed[8], 'lengths' / Int16ub[8], 'zero2' / Const(0, Int8ub), 'zero3' / Const(0, Int8ub), 'address_mode' / Int8ub, 'address' / Int16ub, 'zero4' / Const(0, Int8ub), 'year_div_100' / Int8ub, 'month' / Int8ub, 'day' / Int8ub, 'hour' / Int8ub, 'minute' / Int8ub, 'second' / Int8ub,
from construct import (Bitwise, Bytes, Computed, Container, Default, Flag, Struct, this) from paradox.hardware.evo.adapters import DictArray, EventAdapter TestParser = Bitwise( DictArray( 8, 1, Struct("_index" / Computed(this._index + 1), "enabled" / Default(Flag, False)), )) TestParser2 = Bitwise( DictArray( 8, 65, Struct("_index" / Computed(this._index + 65), "enabled" / Default(Flag, False)), )) TestPickerParser = Bitwise( DictArray( 8, 1, Struct("_index" / Computed(this._index + 1), "enabled" / Default(Flag, False)), pick_key="enabled", ))
'_name' / Computed('AppleMIDITimestampPacket'), 'preamble' / Const(b'\xff\xff'), 'command' / Bytes(2), 'ssrc' / Int32ub, 'count' / Int8ub, 'padding' / Padding(3), 'timestamp_1' / Int64ub, 'timestamp_2' / Int64ub, 'timestamp_3' / Int64ub, ) MIDIPacketHeaderFlags = Bitwise( Struct( 'v' / BitsInteger(2), # always 0x2 'p' / Flag, # always 0 'x' / Flag, # always 0 'cc' / Nibble, # always 0 'm' / Flag, # always 0x1 'pt' / BitsInteger(7), # always 0x61 ) ) RTPHeader = Struct( 'flags' / MIDIPacketHeaderFlags, 'sequence_number' / Int16ub, # always 'K' ) MIDIPacketHeader = Struct( '_name' / Computed('MIDIPacketHeader'), 'rtp_header' / RTPHeader, 'timestamp' / Int32ub, 'ssrc' / Int32ub,
RAMDataParserMap = { 1: Struct( "_weekday" / Int8ub, "pgm_flags" / BitStruct( # TODO: Do we need BitsSwapped here? 'chime_zone_partition' / BitsSwapped(StatusFlags(4)), 'power_smoke' / Flag, 'ground_start' / Flag, 'kiss_off' / Flag, 'line_ring' / Flag, 'bell_partition' / BitsSwapped(StatusFlags(8)), 'fire_alarm' / BitsSwapped(StatusFlags(8)), 'open_close_kiss_off' / BitsSwapped(StatusFlags(8)), ), "key-switch_triggered" / BitsSwapped(Bitwise(StatusFlags(32))), "door_open" / BitsSwapped(Bitwise(StatusFlags(32))), "system" / Struct( "troubles" / BitStruct( "system_trouble" / Flag, "dialer_trouble" / Flag, "module_trouble" / Flag, "bus_com_trouble" / Flag, # BusCom "zone_tamper_trouble" / Flag, "zone_low_battery_trouble" / Flag, "zone_fault_trouble" / Flag, "time_lost_trouble" / Flag, "ac_trouble" / Flag, "battery_failure_trouble" / Flag, "aux_limit_trouble" / Flag, "bell_limit_trouble" / Flag,
"block_labels": Label, #"strange": StrangePage, }, default=Computed("page type not implemented")), )) # unfortunately, the entry_enabled field contains unexistant entries for the last entry # entry_enabled[:-1] matches revidx[:-1], # but len(entry_enabled)==16 while len(revidx)<=16 ReverseIndexArray = Struct( "entry_count" / Computed(lambda ctx: min([16, ctx._.entry_count - 16 * ctx._._index])), Seek(-4 - 2 * this.entry_count, 1), # jump back the size of this struct "entries" / Array(this.entry_count, ReverseIndexedEntry), "entry_enabled" / ByteSwapped(Bitwise(Array(16, Flag))), "entry_enabled_override" / ByteSwapped(Bitwise(Array(16, Flag))), Seek(-36 if this.entry_count == 16 else 0, 1) # jump back once again for the next read or 0 if finished ) PageFooter = RepeatUntil(lambda x, lst, ctx: len(lst) * 16 > ctx.entry_count, ReverseIndexArray) PageHeader = Struct( # 40 bytes Padding(4), # always 0 "index" / Int32ul, # in units of 4096 bytes "page_type" / PageTypeEnum, "next_index" / Int32ul, # in units of 4096 bytes, finally points to empty page, even outside of file "u1" / Int32ul, # sequence number (0->1: 8->13, 1->2: 22, 2->3: 27)