def create_xrf_struct(self, control_record): shift = control_record.shift Int32s, BitStructWrapper = { "big": (Int32sb, lambda x: x), "little": (Int32sl, ByteSwapped), }[self.endianness] return FocusedSeq( "data", "data" / DictSegSeq( idx_field=Int32s, subcon=BitStructWrapper( BitStruct( "block" / Default(BitsInteger(21 + shift, signed=True), 0), "is_new" / Default(Flag, False), "is_updated" / Default(Flag, False), "offset" / Default( ExprAdapter( BitsInteger(9 - shift), lambda obj, context: obj << shift, lambda obj, context: obj >> shift, ), 0), )), block_size=127, # Not counting the index field empty_item={}, check_nonempty=lambda item: any([ item.block, item.offset, item.is_new, item.is_updated, ]), ), Terminated, )
def __init__(self, encoded=(None, None), decoded=(None, None)): self._encoded_request, self._encoded_response = encoded self._decoded_request, self._decoded_response = decoded self._check_sanity() # `msgid` improves request / response mapping # It will be included in `self.encoded_request`, but not in `self.decoded_request`. # Each time the request is encoded, a new msgid will be assigned msgid = Struct('_msgid' / Int16ul) # `opcode` is defined as a private variable in request. # it will be included in `self.encoded_request`, but not in `self.decoded_request`. # `opcode` values are linked to the class, and will never deviate from the class-defined value. opcode_val = self.__class__._OPCODE opcode = Struct('_opcode' / Const(OpcodeEnum.encmapping[opcode_val], Byte)) # `errcode` is defined as a private variable in response. # It will be included in `self.encoded_response`, but not in `self.decoded_response`. # `errcode` value is linked to the call, but defaults to OK when calling `Command.from_decoded()`. # When decoding, errors will be converted to Python exceptions errcode = Struct('_errcode' / Default(ErrorcodeEnum, ErrorcodeEnum.OK)) request = self.__class__._REQUEST or Struct() self._request = msgid + opcode + request response = self.__class__._RESPONSE or Struct() self._response = errcode + response values = self.__class__._VALUES or (None, None) self._values_key = values[0] self._values_type = values[1]
def ZoneFlags(count, start_index_from=1): return DictArray(count, start_index_from, BitStruct( "_index" / Computed(this._index + start_index_from), "generated_alarm" / Default(Flag, False), "presently_in_alarm" / Default(Flag, False), "activated_entry_delay" / Default(Flag, False), "activated_intellizone_delay" / Default(Flag, False), "bypassed" / Default(Flag, False), "shutted_down" / Default(Flag, False), "tx_delay" / Default(Flag, False), "supervision_trouble" / Default(Flag, False), ))
def StatusFlags(count, start_index_from=1): return DictArray( count, start_index_from, Struct( "_index" / Computed(this._index + start_index_from), "flag" / Default(Flag, False), ), pick_key="flag", )
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 ), ), )
# dependency between AnlzTag and AnlzTagCueObject AnlzCuePoint = Struct( "type" / Const("PCPT", String(4, encoding="ascii")), "head_size" / Int32ub, "tag_size" / Int32ub, "hotcue_number" / Int32ub, # 0 for memory "status" / AnlzCuePointStatus, "u1" / Const(0x10000, Int32ub), "order_first" / Int16ub, # 0xffff for first cue, 0,1,3 for next "order_last" / Int16ub, # 1,2,3 for first, second, third cue, 0xffff for last "type" / AnlzCuePointType, Padding(1), "u3" / Const(1000, Int16ub), "time" / Int32ub, "time_end" / Default(Int32ub, -1), Padding(16)) AnlzTagCueObjectType = Enum(Int32ub, memory=0, hotcue=1) AnlzTagCueObject = Struct("type" / AnlzTagCueObjectType, "count" / Int32ub, "memory_count" / Int32ub, "entries" / Array(this.count, AnlzCuePoint)) AnlzCuePoint2 = Struct( "type" / Const("PCP2", String(4, encoding="ascii")), "head_size" / Int32ub, "tag_size" / Int32ub, "hotcue_number" / Int32ub, # 0 for memory "u2" / Int32ub, # spotted: 0x010003e8 0x020003e8 "time" / Int32ub,
"_not_used0" / BitsInteger(3), "neware_answer" / Flag, "_not_used1" / BitsInteger(4), ), "callback" / Int16ub, ) ), "checksum" / PacketChecksum(Bytes(1)), ) InitializeCommunication = Struct( "fields" / RawCopy( Struct( "po" / Struct("command" / Const(0x00, Int8ub)), "module_address" / Default(Int8ub, 0x00), # (00= panel/module) "_not_used0" / Padding(2), "product_id" / ProductIdEnum, "firmware" / Struct("version" / Int8ub, "revision" / Int8ub, "build" / Int8ub), "panel_id" / Int16ub, "pc_password" / Default(Bytes(2), b"0000"), "modem_speed" / Bytes(1), "source_method" / Default( Enum(Int8ub, Winload_Connection=0x00, NEware_Connection=0x55), 0x00 ), "user_code" / Default(Int24ub, 0x000000), "serial_number" / Bytes(4), "system_options" / BitsSwapped(
stype_change=0x29, stype_status_mixer=0x00 # djm 900 nxs sends this stype on type_status ) DeviceType = Enum(Int8ub, djm=1, cdj=2, rekordbox=3) PlayerNumberAssignment = Enum(Int8ub, auto=1, manual=2) # received on udp port 50000 KeepAlivePacket = Struct( "magic" / Const(b'Qspt1WmJOL', String(10)), "type" / KeepAlivePacketType, # pairs with subtype Padding(1), "model" / Padded(20, CString(encoding="ascii")), "u1" / Const(1, Int8ub), "device_type" / Default(DeviceType, "cdj"), Padding(1), "subtype" / KeepAlivePacketSubtype, Embedded( Switch( this.type, { # type=0x0a, request for other players to propose a player number? "type_hello": Struct("u2" / Default(Int8ub, 1)), # cdjs send 1, djm900nxs sends 3 # type=0x04, publishing a proposed player number, check if anyone else has it? iteration goes 1..2..3 "type_number": Struct("proposed_player_number" / Int8ub, "iteration" / Int8ub), # type=0x00, publishing mac address, iteration goes 1..2..3 again
VS_FIXEFILEINFO_SIGNATURE = 0xFEEF04BD SystemInfoStream = 7 Memory64ListStream = 9 MemoryInfoListStream = 16 ModuleListStream = 4 MimikatzStream = 0x1337 minidump_location_descriptor = Struct( "DataSize" / Int32ul, "RVA" / Int32ul ) # https://docs.microsoft.com/en-us/windows/win32/api/minidumpapiset/ns-minidumpapiset-minidump_system_info MINIDUMP_SYSTEM_INFO = Struct( "ProcessorArchitecture" / Default(Int16ul, 9), "ProcessorLevel" / Default(Int16ul, 6), "ProcessorRevision" / Default(Int16ul, 0), "NumberOfProcessors" / Default(Int8ul, 1), "ProductType" / Default(Int8ul, 0), "MajorVersion" / Int32ul, "MinorVersion" / Int32ul, "BuildNumber" / Int32ul, "PlatformId" / Default(Int32ul, 0), "CSDVersionRva" / Hex(Int32ul), "Reserved1" / Default(Int32ul, 0), "CPUInformation" / Default(Int32ul[6], [0,0,0,0,0,0]) #"CSDVersion" / Pointer(this.CSDVersionRVA, PascalString(Int32ul, "utf-16")) #"CSDVersion" / Rebuild(Computed(lambda this: get_string(Pointer(this.CSDVersionRVA, PascalString(Int32ul, "utf-16")))), 0) )
def StatusFlags(count): return DictArray(count, 1, Struct( "_index" / Computed(this._index + 1), "flag" / Default(Flag, False) ), pick_key="flag")
from ..common import CommunicationSourceIDEnum, PacketChecksum, ProductIdEnum from .adapters import (DateAdapter, ModuleSerialAdapter, PartitionStatusAdapter, SignalStrengthAdapter, StatusAdapter, ZoneStatusAdapter, PGMDefinitionAdapter, PGMStatusAdapter) InitializeCommunication = Struct( "fields" / RawCopy( Struct( "po" / Struct("command" / Const(0x00, Int8ub)), "_not_used0" / Padding(3), "product_id" / ProductIdEnum, "firmware" / Struct("version" / Int8ub, "revision" / Int8ub, "build" / Int8ub), "panel_id" / Int16ub, "pc_password" / Default(Bytes(2), b"0000"), "_not_used1" / Bytes(1), "source_method" / Default( Enum(Int8ub, Winload_Connection=0x00, NEware_Connection=0x55), 0x00), "user_code" / Default(Int32ub, 0x00000000), "_not_used2" / Padding(15), "source_id" / Default(CommunicationSourceIDEnum, 1), "user_id" / Default(Int16ul, 0), )), "checksum" / PacketChecksum(Bytes(1)), ) InitializeCommunicationResponse = Struct( "fields" / RawCopy( Struct(
return normalize(struct.parse(byte_val)) # Reoccurring data types - can be used as a macro _GROUP_LIST = Struct(GROUP_LIST_KEY / GroupListAdapter()) _OBJECT_ID = Struct(OBJECT_NID_KEY / Int16ul) _OBJECT_INTERFACE = Struct(OBJECT_INTERFACE_KEY / Int16ul) _OBJECT_TYPE = Struct(OBJECT_TYPE_KEY / Int16ul) _OBJECT_DATA = Struct(OBJECT_DATA_KEY / GreedyBytes) _OBJECT = _OBJECT_ID + _GROUP_LIST + _OBJECT_TYPE + _OBJECT_DATA _DISCOVERY = _OBJECT_ID + _OBJECT_INTERFACE # Special cases _CREATE_ID = Struct(OBJECT_NID_KEY / Default(Int16ul, 0)) # 0 == assigned by controller class ReadObjectCommand(Command): _OPCODE = OpcodeEnum.READ_OBJECT _REQUEST = _OBJECT_ID _RESPONSE = _OBJECT _VALUES = None class WriteObjectCommand(Command): _OPCODE = OpcodeEnum.WRITE_OBJECT _REQUEST = _OBJECT _RESPONSE = _OBJECT _VALUES = None
from paradox.lib.crypto import encrypt, decrypt from paradox.lib.async_message_manager import RAWMessageHandler import asyncio from paradox.config import config as cfg logger = logging.getLogger('PAI').getChild(__name__) ip_message = Struct( "header" / Aligned( 16, Struct( "sof" / Const(0xaa, Int8ub), "length" / Int16ul, "unknown0" / Default(Int8ub, 0x01), "flags" / Int8ub, "command" / Int8ub, "sub_command" / Default(Int8ub, 0x00), 'unknown1' / Default(Int8ub, 0x00), 'encrypt' / Default(Int8ub, 0x03), ), b'\xee'), "payload" / Aligned(16, GreedyBytes, b'\xee')) ip_payload_connect_response = Struct( 'command' / Const(0x00, Int8ub), 'key' / Bytes(16), 'major' / Int8ub, 'minor' / Int8ub, 'ip_major' / Default(Int8ub, 5), 'ip_minor' / Default(Int8ub, 2), 'unknown' / Default(Int8ub, 0x00), 'unknown2' / Default(Int8ub, 0x00), 'unknown3' / Default(Int8ub, 0x00), 'unknown4' / Default(Int8ub, 0xee))
"period" / Int16ul ) NetworkDiagnosticServerSubscriptionStatus = Struct( "destination" / UnicastUnassignedGroupAddress, "period" / Int16ul, "max_record_count" / Const(MAX_RECORD_COUNT, Int8ul), "record" / GreedyRange(RegistryRecord) ) NetworkDiagnosticServerPayload = Struct( "subopcode" / EnumAdapter(Int8ul, NetworkDiagnosticServerSubOpcode), "payload" / Default(Switch( this.subopcode, { NetworkDiagnosticServerSubOpcode.SUBSCRIPTION_SET: NetworkDiagnosticServerSubscriptionSet, NetworkDiagnosticServerSubOpcode.SUBSCRIPTION_SET_UNACK: NetworkDiagnosticServerSubscriptionSet, NetworkDiagnosticServerSubOpcode.SUBSCRIPTION_STATUS: NetworkDiagnosticServerSubscriptionStatus } ), None) ) NetworkDiagnosticSetupServerPayload = Struct( "subopcode" / EnumAdapter(Int8ul, NetworkDiagnosticSetupServerSubOpcode), "payload" / Default(Switch( this.subopcode, { NetworkDiagnosticSetupServerSubOpcode.PUBLICATION_SET: NetworkDiagnosticSetupServerPublicationSet, NetworkDiagnosticSetupServerSubOpcode.PUBLICATION_STATUS: NetworkDiagnosticSetupServerPublicationStatus, } ), None) )
import enum from construct import (Int8ul, Int16ul, Int16ub, Default, Enum, Struct, Switch, GreedyRange, Padding, Default, ExprValidator, obj_, this) from .util import EnumAdapter, Opcode FaultTest = Struct( "test_id" / Int8ul, "company_id" / Int16ul, ) FaultStatus = Struct("test_id" / Int8ul, "company_id" / Int16ul, "fault_array" / Default(GreedyRange(Int8ul), [])) FastPeriodDivisor = Struct("fast_period_divisor" / ExprValidator(Int8ul, obj_ <= 15)) Attention = Struct("attention" / Int8ul) CompanyId = Struct("company_id" / Int16ul) HealthCurrentStatus = FaultStatus HealthFaultGet = CompanyId HealthFaultClear = CompanyId HealthFaultTest = FaultTest
garbage_args=4) RpcRejectStat = Enum(Int32ub, rpc_mismatch=0, auth_error=1) RpcAuthStat = Enum(Int32ub, badcred=0, rejectedcred=1, badverf=2, rejectedverf=3, tooweak=4) RpcAuthFlavor = Enum(Int32ub, null=0, unix=1, short=2, des=3) RpcAuthUnix = Struct( "stamp" / Int32ub, "machine_name" / Default(PascalString(Int32ub, encoding="ascii"), ""), "uid" / Default(Int32ub, 0), "gid" / Default(Int32ub, 0), "gids" / Default(Int32ub, 0) # should be length-prefixed array? ) RpcAuthShort = Pass RpcAuthDes = Pass RpcOpaqueAuth = Struct( "flavor" / Default(RpcAuthFlavor, "null"), Embedded( Prefixed( Int32ub, Switch( this.flavor, {
) LightExtendedControllerPropertyStatus = Struct( "id" / EnumAdapter(Int16ul, LightExtendedControllerProperty), "value" / LightExtendedControllerPropertyValue, ) LightExtendedControllerSyncIntegralStatus = Struct( "sync_integral" / Int16ul, ) LightExtendedControllerPayload = Struct( "subopcode" / EnumAdapter(Int8ul, LightExtendedControllerSubOpcode), "payload" / Default(Switch( this.subopcode, { LightExtendedControllerSubOpcode.PROPERTY_GET: LightExtendedControllerPropertyGet, LightExtendedControllerSubOpcode.PROPERTY_SET: LightExtendedControllerPropertySet, LightExtendedControllerSubOpcode.PROPERTY_SET_UNACKNOWLEDGED: LightExtendedControllerPropertySet, LightExtendedControllerSubOpcode.PROPERTY_STATUS: LightExtendedControllerPropertyStatus, LightExtendedControllerSubOpcode.SYNC_INTEGRAL_STATUS: LightExtendedControllerSyncIntegralStatus, }, ), None) ) LightExtendedControllerMessage = Struct( "opcode" / Const(LightExtendedControllerOpcode.SILVAIR_LEC, Opcode(LightExtendedControllerOpcode)), "params" / LightExtendedControllerPayload ) # fmt: on
"conn_state" / EnumAdapter(BitsInteger(3), ConnState), "link_status" / EnumAdapter(BitsInteger(1), LinkStatus), "last_error" / EnumAdapter(BitsInteger(4), LastError) ) ) GatewayConfigPayload = Struct( "subopcode" / EnumAdapter(Int8ul, GatewayConfigServerSubOpcode), "payload" / Default(Switch( this.subopcode, { GatewayConfigServerSubOpcode.GATEWAY_CONFIGURATION_SET: ConfigurationSet, GatewayConfigServerSubOpcode.MTU_SIZE_SET: ConfigurationSetMtu, GatewayConfigServerSubOpcode.ETHERNET_MAC_ADDRESS_SET: ConfigurationSetMacAddr, GatewayConfigServerSubOpcode.SERVER_ADDRESS_AND_PORT_NUMBER_SET: ConfigurationSetServerAddrAndPortNr, GatewayConfigServerSubOpcode.RECONNECT_INTERVAL_SET: ConfigurationSetReconnectInterval, GatewayConfigServerSubOpcode.DNS_IP_ADDRESS_SET: ConfigurationSetDnsIpAddr, GatewayConfigServerSubOpcode.IP_ADDRESS_SET: ConfigurationSetIpAddr, GatewayConfigServerSubOpcode.GATEWAY_IP_ADDRESS_SET: ConfigurationSetGatewayIpAddr, GatewayConfigServerSubOpcode.NETMASK_SET: ConfigurationSetNetmask, GatewayConfigServerSubOpcode.GATEWAY_CONFIGURATION_STATUS: ConfigurationStatus, GatewayConfigServerSubOpcode.GATEWAY_PACKETS_STATUS: PacketsStatus, }, ), None) ) GatewayConfigMessage = Struct( "opcode" / Const(GatewayConfigServerOpcode.OPCODE, Opcode(GatewayConfigServerOpcode)), "params" / GatewayConfigPayload ) # fmt: on
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", ))
Bytes, Bytewise, Const, Default, Enum, Flag, Int24sl, Int32sb, Int32ub, Int8ul, Padded, Padding, Struct, ) EnableFlag = Default(Flag, False) SPIRead = BitStruct( "write" / Const(False, Flag), "address" / BitsInteger(7), Padding(32), ) SPIWrite = BitStruct( "write" / Const(True, Flag), "address" / BitsInteger(7), "payload" / Bytewise(Bytes(4)), ) SPIStatus = BitStruct( "reset_flag" / Flag,
def ZoneFlags(count, start_index_from=1): return DictArray(count, start_index_from, BitStruct( "_index" / Computed(this._index + start_index_from), "generated_alarm" / Default(Flag, False), "presently_in_alarm" / Default(Flag, False), "activated_entry_delay" / Default(Flag, False), "activated_intellizone_delay" / Default(Flag, False), "bypassed" / Default(Flag, False), "shutted_down" / Default(Flag, False), "tx_delay" / Default(Flag, False), "supervision_trouble" / Default(Flag, False), )) ZoneFlagBitStruct = BitStruct( "generated_alarm" / Default(Flag, False), "presently_in_alarm" / Default(Flag, False), "activated_entry_delay" / Default(Flag, False), "activated_intellizone_delay" / Default(Flag, False), "bypassed" / Default(Flag, False), "shutted_down" / Default(Flag, False), "tx_delay" / Default(Flag, False), "supervision_trouble" / Default(Flag, False), ) class PartitionStatus(Subconstruct): first2 = BitStruct( 'fire_alarm' / Flag, 'audible_alarm' / Flag, 'silent_alarm' / Flag,
decrypted = decrypted.rstrip(b"\x00") except Exception as ex: _LOGGER.debug("Unable to decrypt, returning raw bytes.") return obj try: jsoned = json.loads(decrypted.decode('utf-8')) except: _LOGGER.error("unable to parse json, was: %s", decrypted) jsoned = b'{}' raise return jsoned Message = Struct( # for building we need data before anything else. "data" / Pointer(32, RawCopy(EncryptionAdapter(GreedyBytes))), "header" / RawCopy( Struct( Const(Int16ub, 0x2131), "length" / Rebuild(Int16ub, Utils.get_length), "unknown" / Default(Int32ub, 0x00000000), "devtype" / Enum(Default(Int16ub, 0x02c1), default=Pass, **xiaomi_devices), "serial" / Default(Int16ub, 0xa40d), "ts" / TimeAdapter(Default(Int32ub, datetime.datetime.utcnow())))), "checksum" / IfThenElse(Utils.is_hello, Bytes(16), Checksum(Bytes(16), Utils.md5, Utils.checksum_field_bytes)), )
"fields" / RawCopy( Struct( "po" / BitStruct( "command" / Const(0x1, Nibble), "status" / Struct("reserved" / Flag, "alarm_reporting_pending" / Flag, "Winload_connected" / Flag, "NeWare_connected" / Flag)), "length" / PacketLength(Int8ub), "result" / BitStruct("_not_used0" / BitsInteger(4), "partition_2" / Flag, "_not_used1" / BitsInteger(3)), "callback" / Int16ub)), "checksum" / PacketChecksum(Bytes(1))) InitializeCommunication = Struct( "fields" / RawCopy( Struct( "po" / Struct("command" / Const(0x00, Int8ub)), "module_address" / Default(Int8ub, 0x00), # (00= panel/module) "_not_used0" / Padding(2), "product_id" / ProductIdEnum, "firmware" / Struct("version" / Int8ub, "revision" / Int8ub, "build" / Int8ub), "panel_id" / Int16ub, "pc_password" / Default(Bytes(2), b'0000'), "modem_speed" / Bytes(1), "source_method" / Default( Enum(Int8ub, Winload_Connection=0x00, NEware_Connection=0x55), 0x00), "user_code" / Default(Int24ub, 0x000000), "serial_number" / Bytes(4), "system_options" / BitsSwapped( BitStruct( Embedded(
_LOGGER.debug("Unable to decrypt, returning raw bytes.") return obj try: jsoned = json.loads(decrypted.decode('utf-8')) except: _LOGGER.error("unable to parse json, was: %s", decrypted) jsoned = b'{}' raise return jsoned Message = Struct( # for building we need data before anything else. "data" / Pointer(32, RawCopy(EncryptionAdapter(GreedyBytes))), "header" / RawCopy( Struct( Const(Int16ub, 0x2131), "length" / Rebuild(Int16ub, Utils.get_length), "unknown" / Default(Int32ub, 0x00000000), "devtype" / Enum(Default(Int16ub, 0x02C1), default=Pass, **xiaomi_devices), "serial" / Default(Int16ub, 0xa40d), "ts" / Default(Int32ub, 0x00000000), )), "checksum" / IfThenElse(Utils.is_hello, Bytes(16), Checksum(Bytes(16), Utils.md5, Utils.checksum_field_bytes)), )
"serial_number" / Bytes(4), "hardware" / Struct("version" / Int8ub, "revision" / Int8ub), "bootloader" / Struct("version" / Int8ub, "revision" / Int8ub, "build" / Int8ub, "day" / Int8ub, "month" / Int8ub, "year" / Int8ub), "processor_id" / Int8ub, "encryption_id" / Int8ub, "reserved0" / Bytes(2), "label" / Bytes(8))), "checksum" / Checksum(Bytes(1), lambda data: calculate_checksum(data), this.fields.data)) StartCommunication = Struct( "fields" / RawCopy( Struct( "po" / Struct("command" / Const(0x5F, Int8ub)), "validation" / Const(0x20, Int8ub), "_not_used0" / Padding(31), "source_id" / Default(CommunicationSourceIDEnum, 1), "user_id" / Struct("high" / Default(Int8ub, 0), "low" / Default(Int8ub, 0)), )), "checksum" / Checksum( Bytes(1), lambda data: calculate_checksum(data), this.fields.data)) StartCommunicationResponse = Struct( "fields" / RawCopy( Struct( "po" / BitStruct( "command" / Const(0, Nibble), "status" / Struct( "reserved" / Flag, "alarm_reporting_pending" / Flag, "Windload_connected" / Flag, "NeWare_connected" / Flag)), "_not_used0" / Bytes(3), "product_id" / ProductIdEnum, "firmware" /
"bitrate" / Int32ul, "track_number" / Int32ul, "bpm_100" / Int32ul, "genre_id" / Int32ul, "album_id" / Int32ul, # album artist is set in album entry "artist_id" / Int32ul, "id" / Int32ul, # the rekordbox track id "disc_number" / Int16ul, "play_count" / Int16ul, "year" / Int16ul, "sample_depth" / Int16ul, # not sure "duration" / Int16ul, "u4" / Int16ul, # always 41? "color_id" / Int8ul, "rating" / Int8ul, "u5" / Default(Int16ul, 1), # always 1? "u6" / Int16ul, # alternating 2 or 3 "str_idx" / Array(21, Int16ul), "str_u1" / IndexedPioString(0), # empty "texter" / IndexedPioString(1), "str_u2" / IndexedPioString(2), # thought tracknumber -> wrong! "str_u3" / IndexedPioString( 3 ), # strange strings, often zero length, sometimes low binary values 0x01/0x02 as content "str_u4" / IndexedPioString( 4 ), # strange strings, often zero length, sometimes low binary values 0x01/0x02 as content "message" / IndexedPioString(5), "unknown_switch" / IndexedPioString(6), # "ON" or empty "autoload_hotcues" / IndexedPioString(7), # "ON" or empty "str_u5" / IndexedPioString(8), # 8
for i, quirk in enumerate(decrypted_quirks): decoded = quirk(decrypted).decode('utf-8') try: return json.loads(decoded) except Exception as ex: # log the error when decrypted bytes couldn't be loaded # after trying all quirk adaptions if i == len(decrypted_quirks) - 1: _LOGGER.error("unable to parse json '%s': %s", decoded, ex) return None Message = Struct( # for building we need data before anything else. "data" / Pointer(32, RawCopy(EncryptionAdapter(GreedyBytes))), "header" / RawCopy(Struct( Const(0x2131, Int16ub), "length" / Rebuild(Int16ub, Utils.get_length), "unknown" / Default(Int32ub, 0x00000000), "device_id" / Hex(Bytes(4)), "ts" / TimeAdapter(Default(Int32ub, datetime.datetime.utcnow())) )), "checksum" / IfThenElse( Utils.is_hello, Bytes(16), Checksum(Bytes(16), Utils.md5, Utils.checksum_field_bytes)), )
'fragmentCount' / Int16ul, 'length' / Int32ul, 'identifier' / Int32ul, 'conversationIndex' / Int32ul, 'channelCode' / Int32sl, 'expectsReply' / Int32ul, ) dtx_message_payload_header_struct = Struct( 'flags' / Int32ul, 'auxiliaryLength' / Int32ul, 'totalLength' / Int64ul, ) message_aux_t_struct = Struct( 'magic' / Default(Int64ul, 0x1f0), 'aux' / Prefixed( Int64ul, GreedyRange( Struct( '_empty_dictionary' / Select(Const(0xa, Int32ul), Int32ul), 'type' / Int32ul, 'value' / Switch(this.type, { 2: BplitAdapter(Prefixed(Int32ul, GreedyBytes)), 3: Int32ul, 4: Int64ul }, default=GreedyBytes), ))))
DebugPayload = Struct( "subopcode" / EnumAdapter(Int8ul, DebugSubOpcode), "data" / Default(Switch( this.subopcode, { DebugSubOpcode.RSSI_THRESHOLD_SET: RssiThreshold, DebugSubOpcode.RSSI_THRESHOLD_STATUS: RssiThreshold, DebugSubOpcode.RADIO_TEST: RadioTest, DebugSubOpcode.TIMESLOT_TX_POWER_SET: TxPower, DebugSubOpcode.TIMESLOT_TX_POWER_STATUS: TxPower, DebugSubOpcode.SOFTDEVICE_TX_POWER_SET: TxPower, DebugSubOpcode.SOFTDEVICE_TX_POWER_STATUS: TxPower, DebugSubOpcode.UPTIME_STATUS: UptimeStatus, DebugSubOpcode.LAST_SW_FAULT_STATUS: LastFault, DebugSubOpcode.SYSTEM_STATS_STATUS: SystemStats, DebugSubOpcode.LAST_MALLOC_FAULT_STATUS: LastFault, DebugSubOpcode.LAST_FDS_FAULT_STATUS: LastFault, DebugSubOpcode.BYTES_BEFORE_GARBAGE_COLLECTOR_STATUS: GarbageCollector, DebugSubOpcode.PROVISIONED_APP_VERSION_STATUS: AppVersion, DebugSubOpcode.FULL_FIRMWARE_VERSION_STATUS: FirmwareVersion, DebugSubOpcode.IV_INDEX_STATUS: IvIndex, DebugSubOpcode.GARBAGE_COLLECTOR_COUNTER_STATUS: GarbageCollectorCounter, DebugSubOpcode.ARAP_LIST_SIZE_STATUS: ArapSize, DebugSubOpcode.ARAP_LIST_CONTENT_GET: ArapContentGet, DebugSubOpcode.ARAP_LIST_CONTENT_STATUS: ArapContent, }, ), None) ) DebugMessage = Struct(
def __init__(self, endianity='<'): if endianity == '<': Int8u = Int8ul Int16u = Int16ul Int32u = Int32ul else: Int8u = Int8ub Int16u = Int16ub Int32u = Int32ub self.Elf_Class = Enum( Hex(Int8u), ELFCLASSNONE=elf_consts.ELFCLASSNONE, ELFCLASS32=elf_consts.ELFCLASS32, ELFCLASS64=elf_consts.ELFCLASS64, ELFCLASSNUM=elf_consts.ELFCLASSNUM, ) self.Elf_Data = Enum( Hex(Int8u), ELFDATANONE=elf_consts.ELFDATANONE, ELFDATA2LSB=elf_consts.ELFDATA2LSB, ELFDATA2MSB=elf_consts.ELFDATA2MSB, ) self.Elf_Machine = Enum( Int16u, EM_NONE=elf_consts.EM_NONE, EM_M32=elf_consts.EM_M32, EM_SPARC=elf_consts.EM_SPARC, EM_386=elf_consts.EM_386, EM_68K=elf_consts.EM_68K, EM_88K=elf_consts.EM_88K, EM_IAMCU=elf_consts.EM_IAMCU, EM_860=elf_consts.EM_860, EM_MIPS=elf_consts.EM_MIPS, EM_S370=elf_consts.EM_S370, EM_MIPS_RS3_LE=elf_consts.EM_MIPS_RS3_LE, EM_PARISC=elf_consts.EM_PARISC, EM_VPP500=elf_consts.EM_VPP500, EM_SPARC32PLUS=elf_consts.EM_SPARC32PLUS, EM_960=elf_consts.EM_960, EM_PPC=elf_consts.EM_PPC, EM_PPC64=elf_consts.EM_PPC64, EM_S390=elf_consts.EM_S390, EM_SPU=elf_consts.EM_SPU, EM_V800=elf_consts.EM_V800, EM_FR20=elf_consts.EM_FR20, EM_RH32=elf_consts.EM_RH32, EM_RCE=elf_consts.EM_RCE, EM_ARM=elf_consts.EM_ARM, EM_ALPHA=elf_consts.EM_ALPHA, EM_SH=elf_consts.EM_SH, EM_SPARCV9=elf_consts.EM_SPARCV9, EM_TRICORE=elf_consts.EM_TRICORE, EM_ARC=elf_consts.EM_ARC, EM_H8_300=elf_consts.EM_H8_300, EM_H8_300H=elf_consts.EM_H8_300H, EM_H8S=elf_consts.EM_H8S, EM_H8_500=elf_consts.EM_H8_500, EM_IA_64=elf_consts.EM_IA_64, EM_MIPS_X=elf_consts.EM_MIPS_X, EM_COLDFIRE=elf_consts.EM_COLDFIRE, EM_68HC12=elf_consts.EM_68HC12, EM_MMA=elf_consts.EM_MMA, EM_PCP=elf_consts.EM_PCP, EM_NCPU=elf_consts.EM_NCPU, EM_NDR1=elf_consts.EM_NDR1, EM_STARCORE=elf_consts.EM_STARCORE, EM_ME16=elf_consts.EM_ME16, EM_ST100=elf_consts.EM_ST100, EM_TINYJ=elf_consts.EM_TINYJ, EM_X86_64=elf_consts.EM_X86_64, EM_PDSP=elf_consts.EM_PDSP, EM_PDP10=elf_consts.EM_PDP10, EM_PDP11=elf_consts.EM_PDP11, EM_FX66=elf_consts.EM_FX66, EM_ST9PLUS=elf_consts.EM_ST9PLUS, EM_ST7=elf_consts.EM_ST7, EM_68HC16=elf_consts.EM_68HC16, EM_68HC11=elf_consts.EM_68HC11, EM_68HC08=elf_consts.EM_68HC08, EM_68HC05=elf_consts.EM_68HC05, EM_SVX=elf_consts.EM_SVX, EM_ST19=elf_consts.EM_ST19, EM_VAX=elf_consts.EM_VAX, EM_CRIS=elf_consts.EM_CRIS, EM_JAVELIN=elf_consts.EM_JAVELIN, EM_FIREPATH=elf_consts.EM_FIREPATH, EM_ZSP=elf_consts.EM_ZSP, EM_MMIX=elf_consts.EM_MMIX, EM_HUANY=elf_consts.EM_HUANY, EM_PRISM=elf_consts.EM_PRISM, EM_AVR=elf_consts.EM_AVR, EM_FR30=elf_consts.EM_FR30, EM_D10V=elf_consts.EM_D10V, EM_D30V=elf_consts.EM_D30V, EM_V850=elf_consts.EM_V850, EM_M32R=elf_consts.EM_M32R, EM_MN10300=elf_consts.EM_MN10300, EM_MN10200=elf_consts.EM_MN10200, EM_PJ=elf_consts.EM_PJ, EM_OPENRISC=elf_consts.EM_OPENRISC, EM_ARC_COMPACT=elf_consts.EM_ARC_COMPACT, EM_XTENSA=elf_consts.EM_XTENSA, EM_VIDEOCORE=elf_consts.EM_VIDEOCORE, EM_TMM_GPP=elf_consts.EM_TMM_GPP, EM_NS32K=elf_consts.EM_NS32K, EM_TPC=elf_consts.EM_TPC, EM_SNP1K=elf_consts.EM_SNP1K, EM_ST200=elf_consts.EM_ST200, EM_IP2K=elf_consts.EM_IP2K, EM_MAX=elf_consts.EM_MAX, EM_CR=elf_consts.EM_CR, EM_F2MC16=elf_consts.EM_F2MC16, EM_MSP430=elf_consts.EM_MSP430, EM_BLACKFIN=elf_consts.EM_BLACKFIN, EM_SE_C33=elf_consts.EM_SE_C33, EM_SEP=elf_consts.EM_SEP, EM_ARCA=elf_consts.EM_ARCA, EM_UNICORE=elf_consts.EM_UNICORE, EM_EXCESS=elf_consts.EM_EXCESS, EM_DXP=elf_consts.EM_DXP, EM_ALTERA_NIOS2=elf_consts.EM_ALTERA_NIOS2, EM_CRX=elf_consts.EM_CRX, EM_XGATE=elf_consts.EM_XGATE, EM_C166=elf_consts.EM_C166, EM_M16C=elf_consts.EM_M16C, EM_DSPIC30F=elf_consts.EM_DSPIC30F, EM_CE=elf_consts.EM_CE, EM_M32C=elf_consts.EM_M32C, EM_TSK3000=elf_consts.EM_TSK3000, EM_RS08=elf_consts.EM_RS08, EM_SHARC=elf_consts.EM_SHARC, EM_ECOG2=elf_consts.EM_ECOG2, EM_SCORE7=elf_consts.EM_SCORE7, EM_DSP24=elf_consts.EM_DSP24, EM_VIDEOCORE3=elf_consts.EM_VIDEOCORE3, EM_LATTICEMICO32=elf_consts.EM_LATTICEMICO32, EM_SE_C17=elf_consts.EM_SE_C17, EM_TI_C6000=elf_consts.EM_TI_C6000, EM_TI_C2000=elf_consts.EM_TI_C2000, EM_TI_C5500=elf_consts.EM_TI_C5500, EM_TI_ARP32=elf_consts.EM_TI_ARP32, EM_TI_PRU=elf_consts.EM_TI_PRU, EM_MMDSP_PLUS=elf_consts.EM_MMDSP_PLUS, EM_CYPRESS_M8C=elf_consts.EM_CYPRESS_M8C, EM_R32C=elf_consts.EM_R32C, EM_TRIMEDIA=elf_consts.EM_TRIMEDIA, EM_QDSP6=elf_consts.EM_QDSP6, EM_8051=elf_consts.EM_8051, EM_STXP7X=elf_consts.EM_STXP7X, EM_NDS32=elf_consts.EM_NDS32, EM_ECOG1=elf_consts.EM_ECOG1, EM_ECOG1X=elf_consts.EM_ECOG1X, EM_MAXQ30=elf_consts.EM_MAXQ30, EM_XIMO16=elf_consts.EM_XIMO16, EM_MANIK=elf_consts.EM_MANIK, EM_CRAYNV2=elf_consts.EM_CRAYNV2, EM_RX=elf_consts.EM_RX, EM_METAG=elf_consts.EM_METAG, EM_MCST_ELBRUS=elf_consts.EM_MCST_ELBRUS, EM_ECOG16=elf_consts.EM_ECOG16, EM_CR16=elf_consts.EM_CR16, EM_ETPU=elf_consts.EM_ETPU, EM_SLE9X=elf_consts.EM_SLE9X, EM_L10M=elf_consts.EM_L10M, EM_K10M=elf_consts.EM_K10M, EM_AVR32=elf_consts.EM_AVR32, EM_STM8=elf_consts.EM_STM8, EM_TILE64=elf_consts.EM_TILE64, EM_TILEPRO=elf_consts.EM_TILEPRO, EM_MICROBLAZE=elf_consts.EM_MICROBLAZE, EM_CUDA=elf_consts.EM_CUDA, EM_TILEGX=elf_consts.EM_TILEGX, EM_CLOUDSHIELD=elf_consts.EM_CLOUDSHIELD, EM_COREA_1ST=elf_consts.EM_COREA_1ST, EM_COREA_2ND=elf_consts.EM_COREA_2ND, EM_ARC_COMPACT2=elf_consts.EM_ARC_COMPACT2, EM_OPEN8=elf_consts.EM_OPEN8, EM_RL78=elf_consts.EM_RL78, EM_VIDEOCORE5=elf_consts.EM_VIDEOCORE5, EM_78KOR=elf_consts.EM_78KOR, EM_56800EX=elf_consts.EM_56800EX, EM_BA1=elf_consts.EM_BA1, EM_BA2=elf_consts.EM_BA2, EM_XCORE=elf_consts.EM_XCORE, EM_MCHP_PIC=elf_consts.EM_MCHP_PIC, EM_INTEL205=elf_consts.EM_INTEL205, EM_INTEL206=elf_consts.EM_INTEL206, EM_INTEL207=elf_consts.EM_INTEL207, EM_INTEL208=elf_consts.EM_INTEL208, EM_INTEL209=elf_consts.EM_INTEL209, EM_KM32=elf_consts.EM_KM32, EM_KMX32=elf_consts.EM_KMX32, EM_KMX16=elf_consts.EM_KMX16, EM_KMX8=elf_consts.EM_KMX8, EM_KVARC=elf_consts.EM_KVARC, EM_CDP=elf_consts.EM_CDP, EM_COGE=elf_consts.EM_COGE, EM_COOL=elf_consts.EM_COOL, EM_NORC=elf_consts.EM_NORC, EM_CSR_KALIMBA=elf_consts.EM_CSR_KALIMBA, EM_Z80=elf_consts.EM_Z80, EM_VISIUM=elf_consts.EM_VISIUM, EM_FT32=elf_consts.EM_FT32, EM_MOXIE=elf_consts.EM_MOXIE, EM_AMDGPU=elf_consts.EM_AMDGPU, EM_RISCV=elf_consts.EM_RISCV, ) self.Elf_SegmentType = Enum( Hex(Int32u), PT_NULL=elf_consts.PT_NULL, PT_LOAD=elf_consts.PT_LOAD, PT_DYNAMIC=elf_consts.PT_DYNAMIC, PT_INTER=elf_consts.PT_INTER, PT_NOTE=elf_consts.PT_NOTE, PT_SHLIB=elf_consts.PT_SHLIB, PT_PHDR=elf_consts.PT_PHDR, PT_TLS=elf_consts.PT_TLS, PT_LOOS=elf_consts.PT_LOOS, PT_HIOS=elf_consts.PT_HIOS, PT_LOPROC=elf_consts.PT_LOPROC, PT_HIPROC=elf_consts.PT_HIPROC, PT_GNU_EH_FRAME=elf_consts.PT_GNU_EH_FRAME, ) self.Elf_Type = Enum( Hex(Int16u), ET_NONE=elf_consts.ET_NONE, ET_REL=elf_consts.ET_REL, ET_EXEC=elf_consts.ET_EXEC, ET_DYN=elf_consts.ET_DYN, ET_CORE=elf_consts.ET_CORE, ET_LOPROC=elf_consts.ET_LOPROC, ET_HIPROC=elf_consts.ET_HIPROC, ) self.Elf_Version = Enum( Hex(Int8u), EV_NONE=elf_consts.EV_NONE, EV_CURRENT=elf_consts.EV_CURRENT, EV_NUM=elf_consts.EV_NUM, ) self.Elf_Version2 = Enum( Hex(Int32u), EV_NONE=elf_consts.EV_NONE, EV_CURRENT=elf_consts.EV_CURRENT, EV_NUM=elf_consts.EV_NUM, ) self.Elf_OsAbi = Enum( Hex(Int8u), ELFOSABI_NONE=elf_consts.ELFOSABI_NONE, ELFOSABI_LINUX=elf_consts.ELFOSABI_LINUX, ) # special section indexes self.Elf_SectionIndex = Enum( Hex(Int32u), SHN_UNDEF=elf_consts.SHN_UNDEF, SHN_LORESERVE=elf_consts.SHN_LORESERVE, SHN_LOPROC=elf_consts.SHN_LOPROC, SHN_HIPROC=elf_consts.SHN_HIPROC, SHN_LIVEPATCH=elf_consts.SHN_LIVEPATCH, SHN_ABS=elf_consts.SHN_ABS, SHN_COMMON=elf_consts.SHN_COMMON, SHN_HIRESERVE=elf_consts.SHN_HIRESERVE, ) self.Elf_SectionType = Enum( Hex(Int32u), SHT_NULL=elf_consts.SHT_NULL, SHT_PROGBITS=elf_consts.SHT_PROGBITS, SHT_SYMTAB=elf_consts.SHT_SYMTAB, SHT_STRTAB=elf_consts.SHT_STRTAB, SHT_RELA=elf_consts.SHT_RELA, SHT_HASH=elf_consts.SHT_HASH, SHT_DYNAMIC=elf_consts.SHT_DYNAMIC, SHT_NOTE=elf_consts.SHT_NOTE, SHT_NOBITS=elf_consts.SHT_NOBITS, SHT_REL=elf_consts.SHT_REL, SHT_SHLIB=elf_consts.SHT_SHLIB, SHT_DYNSYM=elf_consts.SHT_DYNSYM, SHT_NUM=elf_consts.SHT_NUM, SHT_LOPROC=elf_consts.SHT_LOPROC, SHT_HIPROC=elf_consts.SHT_HIPROC, SHT_LOUSER=elf_consts.SHT_LOUSER, SHT_HIUSER=elf_consts.SHT_HIUSER, ) self.Elf32_Phdr = Struct( 'p_type' / self.Elf_SegmentType, 'p_offset' / Hex(Int32u), 'p_vaddr' / Hex(Int32u), 'p_paddr' / Hex(Int32u), 'p_filesz' / Hex(Int32u), 'p_memsz' / Hex(Int32u), 'p_flags' / Hex(Int32u), 'p_align' / Hex(Int32u), 'data' / If(this.p_type == self.Elf_SegmentType.PT_LOAD, Pointer(this.p_offset, Bytes(this.p_filesz)))) self.Elf32_Ehdr = Struct( 'e_ident' / Struct( 'magic' / Const(elf_consts.ELFMAG), 'class' / self.Elf_Class, 'data' / self.Elf_Data, 'version' / Default(self.Elf_Version, self.Elf_Version.EV_CURRENT), 'osabi' / self.Elf_OsAbi, 'pad' / Padding(8), ), 'e_type' / Default(self.Elf_Type, self.Elf_Type.ET_EXEC), 'e_machine' / Hex(self.Elf_Machine), 'e_version' / Default(self.Elf_Version2, self.Elf_Version2.EV_CURRENT), 'e_entry' / Hex(Int32u), 'e_phoff' / Hex(Int32u), 'e_shoff' / Hex(Int32u), 'e_flags' / Default(Hex(Int32u), 0), 'e_ehsize' / Hex(Int16u), 'e_phentsize' / Hex(Int16u), 'e_phnum' / Hex(Int16u), 'e_shentsize' / Hex(Int16u), 'e_shnum' / Hex(Int16u), 'e_shstrndx' / Hex(Int16u), ) self.Elf32_Shdr = Struct( 'sh_name' / self.Elf_SectionIndex, 'sh_type' / self.Elf_SectionType, 'sh_flags' / Hex(Int32u), 'sh_addr' / Hex(Int32u), 'sh_offset' / Hex(Int32u), 'sh_size' / Hex(Int32u), 'sh_link' / Hex(Int32u), 'sh_info' / Hex(Int32u), 'sh_addralign' / Hex(Int32u), 'sh_entsize' / Hex(Int32u), 'data' / If(this.sh_type != self.Elf_SectionType.SHT_NOBITS, Pointer(this.sh_offset, Bytes(this.sh_size)))) self.Elf32 = Struct( 'header' / self.Elf32_Ehdr, 'segments' / Pointer(this.header.e_phoff, Array(this.header.e_phnum, self.Elf32_Phdr)), 'sections' / Pointer(this.header.e_shoff, Array(this.header.e_shnum, self.Elf32_Shdr)), )