Ejemplo n.º 1
0
    def read_messages(self):
        """Read messages."""
        from construct import Struct, PascalString, Int16ul, Tell, this, Bytes

        frmt = Struct(
            "instructions_length" / Int16ul,
            "instructions" / Bytes(this.instructions_length),
            "hints" / PascalString(Int16ul, "utf8"),
            "victory" / PascalString(Int16ul, "utf8"),
            "defeat" / PascalString(Int16ul, "utf8"),
            "history" / PascalString(Int16ul, "utf8"),
            "scouts" / PascalString(Int16ul, "utf8"),
            "offset" / Tell,
        )

        parsing = frmt.parse(self.header[self.position:])
        self.position += parsing.offset

        parsing.instructions = parsing.instructions.rstrip(b'\x00')
        parsing.hints = parsing.hints.rstrip('\x00')
        parsing.victory = parsing.victory.rstrip('\x00')
        parsing.defeat = parsing.defeat.rstrip('\x00')
        parsing.history = parsing.history.rstrip('\x00')
        parsing.scouts = parsing.scouts.rstrip('\x00')

        return dict(parsing)
Ejemplo n.º 2
0
    def _iter_gnrl_files(self) -> Generator[ArchiveFile, None, None]:
        """Iterates over the parsed data for GNRL fiels and yields instances of
            `ArchiveFile`.

        Raises:
            ValueError: If a filename cannot be determined for a specific file record

        Yields:
            :class:`.ArchiveFile`: A file contained within the archive
        """
        filename_offset = 0
        for file_container in self.container.files:
            filepath_content = self.content[(
                self.container.header.names_offset + filename_offset):]
            filepath = PascalString(VarInt, "utf8").parse(filepath_content)
            # filename offset increased by length of parsed string accounting for
            # prefix and suffix bytes
            filename_offset += len(filepath) + 2

            file_data = self.content[file_container.offset:(
                file_container.offset + file_container.unpacked_size)]
            if file_container.packed_size > 0:
                file_data = Compressed(GreedyBytes, "zlib").parse(file_data)

            yield ArchiveFile(filepath=PureWindowsPath(filepath[1:]),
                              data=file_data)
Ejemplo n.º 3
0
def String(name):
    """
    UTF-8 length-prefixed string.
    """

    return PascalString(name, length_field=UBInt16("length"),
        encoding="utf-8")
Ejemplo n.º 4
0
    def f(client: LedgerClient) -> DeviceResponse:
        response = client.apdu_exchange(INS, b"", P1, P2)

        response_template = Struct(
            p2pkh_prefix=Bytes(2),
            p2sh_prefix=Bytes(2),
            coin_family=Int8ub,
            coin_name=PascalString(Int8ub, "ascii"),
            coin_ticker=PascalString(Int8ub, "ascii"),
        )

        parsed_response = response_template.parse(response)
        return DeviceResponse(
            p2pkh_prefix=parsed_response.p2pkh_prefix,
            p2sh_prefix=parsed_response.p2sh_prefix,
            coin_family=parsed_response.coin_family,
            coin_name=parsed_response.coin_name,
            coin_ticker=parsed_response.coin_ticker,
        )
Ejemplo n.º 5
0
    def f(client: LedgerClient) -> DeviceResponse:
        response = client.apdu_exchange(INS, data, P1, P2)

        response_template = Struct(
            public_key=Prefixed(Int8ub, GreedyBytes),
            address=PascalString(Int8ub, "ascii"),
            chain_code=Bytes(32),
        )

        parsed_response = response_template.parse(response)
        return DeviceResponse(
            public_key=parsed_response.public_key,
            address=parsed_response.address,
            chain_code=parsed_response.chain_code,
        )
Ejemplo n.º 6
0
def Label(name):
    '''
    return a construct to parse/build a DNS label.

    Example:
    >> Label('qname').parse('\x05hello\x00')
    >> ['hello', '']

    :param name: the name of the field
    :type name: string
    :returns: a construct to parse/build a DNS label
    :rtype: construct.core.RepeatUntil
    '''
    return RepeatUntil(
        lambda obj, ctx: obj == '',
        PascalString(name),
    )
Ejemplo n.º 7
0
class InstantSoupData(object):

    # common
    server = Struct("server", CString("server_id"),
                    PrefixedArray(CString('channels'), UBInt8("num_channels")))

    # structures from rfc
    opt_client_nick = CString('nickname')

    opt_client_membership = PrefixedArray(server, UBInt8("num_servers"))

    opt_server = Struct("opt_server", UBInt16("port"))

    opt_server_channels = Struct(
        "opt_server_channels",
        PrefixedArray(CString("channels"), UBInt8("num_channels")))

    opt_server_invite = Struct(
        "opt_server_invite", CString("channel_id"),
        PrefixedArray(CString("client_id"), UBInt8("num_clients")))

    # option fields
    option = Struct(
        "option",
        Enum(UBInt8("option_id"),
             CLIENT_NICK_OPTION=0x01,
             CLIENT_MEMBERSHIP_OPTION=0x02,
             SERVER_OPTION=0x10,
             SERVER_CHANNELS_OPTION=0x11,
             SERVER_INVITE_OPTION=0x12),
        Switch(
            "option_data", lambda ctx: ctx["option_id"], {
                "CLIENT_NICK_OPTION": opt_client_nick,
                "CLIENT_MEMBERSHIP_OPTION": opt_client_membership,
                "SERVER_OPTION": opt_server,
                "SERVER_CHANNELS_OPTION": opt_server_channels,
                "SERVER_INVITE_OPTION": opt_server_invite
            }))

    # the peer pdu itself
    peer_pdu = Struct("peer_pdu", CString('id'), OptionalGreedyRange(option))

    command = PascalString("command",
                           length_field=UBInt32("length"),
                           encoding='utf8')
Ejemplo n.º 8
0
    def f(client: LedgerClient) -> DeviceResponse:
        response = client.apdu_exchange(INS, data, P1, P2)

        struct_kwargs = dict(
            public_key=Prefixed(Int8ub, GreedyBytes),
            address=PascalString(Int8ub, "ascii"),
        )
        if opts.return_chain_code:
            struct_kwargs["chain_code"] = Bytes(32)

        response_template = Struct(**struct_kwargs)

        parsed_response = response_template.parse(response)
        return DeviceResponse(
            public_key=parsed_response.public_key,
            address=parsed_response.address,
            chain_code=parsed_response.chain_code
            if opts.return_chain_code else None,
        )
Ejemplo n.º 9
0
    def _iter_dx10_files(self) -> Generator[ArchiveFile, None, None]:
        """Iterates over the parsed data for DX10 archives and yields instances of
            `ArchiveFile`.

        Raises:
            ValueError: If a filename cannot be determined for a specific file record

        Yields:
            :class:`.ArchiveFile`: A file contained within the archive
        """
        filename_offset = 0
        for file_container in self.container.files:

            filepath_content = self.content[(
                self.container.header.names_offset + filename_offset):]
            filepath = PascalString(Int16ul, "utf8").parse(filepath_content)
            filename_offset += len(filepath) + 2

            (dds_header, dx10_header) = self._build_dds_headers(file_container)
            if dds_header:
                dds_content = b"DDS "
                dds_content += dds_header

                if dx10_header:
                    dds_content += dx10_header

                for tex_chunk in file_container.chunks:
                    if tex_chunk.packed_size > 0:
                        dds_content += Compressed(GreedyBytes, "zlib").parse(
                            self.content[tex_chunk.offset:(
                                tex_chunk.offset + tex_chunk.packed_size)])
                    else:
                        dds_content += self.content[tex_chunk.offset:(
                            tex_chunk.offset + tex_chunk.unpacked_size)]

                yield ArchiveFile(filepath=PureWindowsPath(filepath),
                                  data=dds_content)
Ejemplo n.º 10
0
object_types[0x01] = Struct(
    "uno_" / Int8ul,
    "value" / Int8ul,
)

# float double
object_types[0x02] = Struct(
    "what_" / Int8ul,
    "value" / Float64l,
)

# string
object_types[0x03] = Struct(
    "red_" / Int8ul,
    "blue_" / Int8ul,
    "value" / PascalString(Int8ul, "latin-1"),
)

KeyValuePair = Struct(
    "bloom_" / Int8ul,
    "key" / PascalString(Int8ul, "latin-1"),
    "value" / SerializedObject,
)

# mapping
object_types[0x05] = Struct(
    "monkey_" / Int8ul,  # Usually 0
    "items" / PrefixedArray(Int32ul, KeyValuePair),
)

Version = Struct(
Ejemplo n.º 11
0
 def test_parse(self):
     s = PascalString("foo")
     self.assertEqual(s.parse(b"\x05hello"), b"hello")
Ejemplo n.º 12
0
class ByteArray(FixedObjectByteArray):
    classID = 11
    _construct = PascalString("value", length_field=UBInt32("length"))

    def __repr__(self):
        return '<%s(%i bytes)>' % (self.__class__.__name__, len(self.value))
Ejemplo n.º 13
0
class String(FixedObjectByteArray):
    classID = 9
    _construct = PascalString("value", length_field=UBInt32("length"))
Ejemplo n.º 14
0
    'event_code' / Enum(
        Int32ub,  # bytes 12-15
        VERSION=1,
        DATA_START=2,
        DATA_STOP=3,
        SENSOR_MAP=9,
        DATA_RATE=10),
    'sending_node' / Int32ub,  # bytes 16-19

    # Message data is optional
    # Previous implementation used If(this._.payload_length > 8, ...), but this
    # method does not seem to work in v2.8.

    # message_length: bytes 20-23, message: bytes 24+
    'message' / Optional(
        PascalString(lengthfield='message_length' / Int32ub,
                     encoding='ascii')))

EEG_data = Struct(
    'timestamp' / Float32b,  # bytes 12-15
    'data_counter' / Int8ub,  # byte 16; Unused, just 0 currently
    'ADC_status' / Bytes(6),  # bytes 17-22
    # bytes 23-26, 27-30, etc.
    'sensor_data' / Array((this._.payload_length - 11) // 4, Float32b))

null = Struct('none' / Array(111, Int8ub))

packet = Struct(
    Embedded(header), 'payload' / Embedded(
        Switch(this.type, {
            'NULL': null,
            'EVENT': event,
Ejemplo n.º 15
0
 Struct(
     "prechunk",
     SBInt32("x"),
     SBInt32("z"),
     UBInt8("enabled"),
 ),
 51:
 Struct(
     "chunk",
     SBInt32("x"),
     UBInt16("y"),
     SBInt32("z"),
     UBInt8("x_size"),
     UBInt8("y_size"),
     UBInt8("z_size"),
     PascalString("data", length_field=UBInt32("length"), encoding="zlib"),
 ),
 52:
 Struct(
     "batch",
     SBInt32("x"),
     SBInt32("z"),
     UBInt16("length"),
     MetaArray(lambda context: context["length"], UBInt16("coords")),
     MetaArray(lambda context: context["length"], UBInt8("types")),
     MetaArray(lambda context: context["length"], UBInt8("metadata")),
 ),
 53:
 Struct(
     "block",
     SBInt32("x"),
Ejemplo n.º 16
0
 def test_parse_custom_length_field(self):
     s = PascalString("foo", length_field=UBInt16("length"))
     self.assertEqual(s.parse("\x00\x05hello"), "hello")
Ejemplo n.º 17
0
 def test_build(self):
     s = PascalString("foo")
     self.assertEqual(s.build(b"hello world"), b"\x0bhello world")
Ejemplo n.º 18
0
 def test_build(self):
     s = PascalString("foo", encoding="utf8")
     self.assertEqual(s.build(six.u("hello world")), six.b("\x0bhello world"))
Ejemplo n.º 19
0
 def test_parse(self):
     s = PascalString("foo", encoding="utf8")
     self.assertEqual(s.parse(six.b("\x05hello")), six.u("hello"))
Ejemplo n.º 20
0
from __future__ import absolute_import, division, print_function, unicode_literals

from construct import this, If, Switch, OneOf
from construct import Struct
from construct import Byte, Int8ub
from construct import PascalString

AuthRequest = Struct("version" / OneOf(Int8ub, [1]),
                     "username" / PascalString(Byte),
                     "password" / PascalString(Byte))

AuthResponse = Struct("version" / OneOf(Int8ub, [1]), "status" / Byte)
Ejemplo n.º 21
0
 def test_build_custom_length_field(self):
     s = PascalString("foo", length_field=UBInt16("length"))
     self.assertEqual(s.build(b"hello"), b"\x00\x05hello")
Ejemplo n.º 22
0
 def test_build_custom_length_field(self):
     s = PascalString("foo", length_field=UBInt16("length"), encoding="utf8")
     self.assertEqual(s.build(six.u("hello")), six.b("\x00\x05hello"))
Ejemplo n.º 23
0
    "type" / DBFieldType,
    "value" / Switch(
        this.type,
        {
            "int8":
            Int8ub,
            "int16":
            Int16ub,
            "int32":
            Int32ub,
            "string":
            FocusedSeq(
                0,
                PascalString(ExprAdapter(Int32ub,
                                         encoder=lambda obj, ctx: obj // 2 + 1,
                                         decoder=lambda obj, ctx:
                                         (obj - 1) * 2),
                             encoding="utf-16-be"), Padding(2)),
            "binary":
            Prefixed(Int32ub, GreedyBytes)  # parses to byte string
        }))


class DBFieldFixedAdapter(Adapter):
    def __init__(self, subcon, ftype):
        self.ftype = ftype
        super().__init__(subcon)

    def _encode(self, obj, context):
        return {"type": self.ftype, "value": obj}
Ejemplo n.º 24
0
                            UnknownState=0x06,
                            Disconnected=0x07)  # not documented?
)

# Name doesn't fit to one element, so there's an index I assume..
# >>> x = bytes.fromhex("43 51 01 00 0d 5965656c696768742042656473")
# >>> x
# b'CQ\x01\x00\rYeelight Beds'
# >>> x = bytes.fromhex("43 51 01 01 08 696465204c616d700000000000")
# >>> x
# b'CQ\x01\x01\x08ide Lamp\x00\x00\x00\x00\x00'

Name = "name" / Struct(
    "id" / Byte,
    "index" / Byte,  # convert greeedystring to use this
    "text" / PascalString(Byte, "ascii"),
)

Version = "version" / Struct(
    "currentrunning" / Enum(Byte, App1=0x01, App2=0x02, Candela=0x31),
    "hw_version" / Int16ub,
    "sw_version_app1" / Int16ub,
    "sw_version_app2" / Int16ub,
    "beacon_version" / Int16ub,
)

SerialNumber = "serialno" / BytesInteger(12)

OnOff = "OnOff" / Struct("state" / Mapping(Byte, {True: 0x01, False: 0x02}))

# brightness max
Ejemplo n.º 25
0
 Struct(
     "update sign",
     SBInt32("x"),
     UBInt16("y"),
     SBInt32("z"),
     AlphaString("line1"),
     AlphaString("line2"),
     AlphaString("line3"),
     AlphaString("line4"),
 ),
 131:
 Struct(
     "item data",
     SBInt16("primary"),
     SBInt16("secondary"),
     PascalString("data", length_field=UBInt16("length")),
 ),
 132:
 Struct(
     "update tile entity",
     SBInt32("x"),
     UBInt16("y"),
     SBInt32("z"),
     SBInt8("action"),
     SBInt16("size"),
     If(lambda context: context["size"] > 0, NBTdata("nbt", "size")),
 ),
 200:
 Struct(
     "increment statistics",
     UBInt32("sid"),
Ejemplo n.º 26
0
)

minidump_directory_entry = Struct(
    "StreamType" / Int32ul,
    "Location" / minidump_location_descriptor,
#    "Data" / Switch(this.StreamType, {
#        SystemInfoStream: Computed(lambda this: get_string(Pointer(this.Location.RVA, minidump_system_info))),
#        Memory64ListStream: Computed(lambda this: get_string(Pointer(this.Location.RVA, minidump_memory64_list))),
#        MemoryInfoListStream: Computed(lambda this: get_string(Pointer(this.Location.RVA, minidump_memory_info_list))),
#        ModuleListStream: Computed(lambda this: get_string(Pointer(this.Location.RVA, minidump_module_list))),
#    })
)

# TODO: More meaningful defaults
MINIDUMP_HEADER = Struct(
    "Signature" / Const(MINIDUMP_SIGNATURE),
    "Version" / Const(MINIDUMP_VERSION),
    "VersionInternal" / Default(Int16ul, 0),
    "NumberOfStreams" / Int32ul,
    "StreamDirectoryRva" / Hex(Int32ul),
    "Checksum" / Default(Hex(Int32ul), 0),
    "TimeDateStamp" / Default(Int32ul, 0),
    "Flags" / Default(Hex(Int64ul), 0x421826),
#    "Directory" / Computed(lambda this: get_string(Pointer(this.StreamDirectoryRva, minidump_directory[this.NumberOfStreams])))
)

MINIDUMP_STRING = Struct(
    "String" / PascalString(Int32ul, "utf_16_le"),
    "ZeroTermination" / Const(b'\x00\x00')
)
Ejemplo n.º 27
0
        "vn" / Const(5, Byte),
        "method" / Byte
    )

    def __init__(self, method):
        self.method = method

    def build(self):
        return self.SOCK_5_AUTH_RESPONSE.build(dict(
            method=self.method
        ))


IP_4_Address = Int32ub
IP_6_Address = Array(16, Byte)
DOMAIN_NAME = PascalString(Byte, "ascii")


class Atyp(object):
    """The address types supported by Socks5
    """
    IP_V4 = 1
    DOMAIN_NAME = 3
    IP_V6 = 4


class Command(object):
    """The available commands of Socks5
    """
    CONNECT = 1
    BIND = 2
Ejemplo n.º 28
0

basemessage = Struct('base',
    snaptype,
    ULInt16('id'),
    ULInt16('refer'),
    Struct('sent', timestamp),
    Struct('recv', timestamp),
    ULInt32('payload_length'),
)


mapmessage = Struct('map',
    ULInt16('num'),
    Array(lambda ctx: ctx.num, Struct('map',
        PascalString('field', length_field=ULInt16('length')),
        PascalString('value', length_field=ULInt16('length'))
    ))
)


stringmessage = Struct('string',
    PascalString('string', length_field=ULInt16('string_length'))
)


request = Struct('request',
    Struct('request_type', Embed(snaptype))
)

Ejemplo n.º 29
0
CipherSuites = Struct(
    "cipher_suites",
    UBInt16("length"),  # TODO: Reject packets of length 0
    Array(lambda ctx: ctx.length // 2, UBInt16("cipher_suites")),
)

CompressionMethods = Struct(
    "compression_methods",
    UBInt8("length"),  # TODO: Reject packets of length 0
    Array(lambda ctx: ctx.length, UBInt8("compression_methods")),
)

ServerName = Struct(
    "",
    UBInt8("type"),
    PascalString("name", length_field=UBInt16("length")),
)

SNIExtension = Struct(
    "",
    TunnelAdapter(
        PascalString("server_names", length_field=UBInt16("length")),
        TunnelAdapter(PascalString("", length_field=UBInt16("length")),
                      GreedyRange(ServerName)),
    ),
)

ALPNExtension = Struct(
    "",
    TunnelAdapter(
        PascalString("alpn_protocols", length_field=UBInt16("length")),
Ejemplo n.º 30
0
    def _encode(self, obj, context, path):
        out = list()
        elements = obj.split("/")
        if elements[0] == "m":
            elements = elements[1:]
        for element in elements:
            if element.endswith("'"):
                out.append(0x80000000 | int(element[:-1]))
            else:
                out.append(int(element))
        return out


Bip32Path = Bip32PathAdapter(PrefixedArray(Byte, Int32ub))

PrefixedString = PascalString(Asn1Length, "utf8")

AppName = PrefixedString
Version = PrefixedString
Icon = Prefixed(Asn1Length, GreedyBytes)

CURVE_SEPCK256K1 = 1
CURVE_PRIME256R1 = 2
CURVE_ED25519 = 4

Curve = FlagsEnum(
    Byte, secp256k1=CURVE_SEPCK256K1, prime256r1=CURVE_PRIME256R1, ed25519=CURVE_ED25519
)

DerivationPath = Prefixed(
    Asn1Length, Struct(curve=Curve, paths=Optional(GreedyRange(Bip32Path)))
Ejemplo n.º 31
0
    LEAVE = 1
    ERROR = 2
    CHMOD = 3
    CREATE = 4
    GETATTR = 5
    OPEN = 6
    READ = 7
    READDIR = 8
    UNLINK = 9
    WRITE = 10
    TAKE = 11


MESSAGE = Struct(
    'opcode' / BytesInteger(OPCODE_LEN),
    'body' / PascalString(BytesInteger(LEN_FIELD_LEN), 'ascii')
)

def read_message(socket):
    header = socket.recv(3)
    body = socket.recv(BytesInteger(4).parse(header[1:]))
    message = MESSAGE.parse(header + body)
    message['body'] = json.loads(message['body'])
    return message

def write_message(socket, opcode, **kwargs):
    socket.send(MESSAGE.build(dict(opcode=opcode, body=json.dumps(kwargs))))

def message_addr(addr, opcode, **kwargs):
    sock = socket(AF_INET, SOCK_STREAM)
    sock.connect(addr)
Ejemplo n.º 32
0
    "next_uid" / Int32ul,
    "constant" / Bytes(4),
    Array(16, "names" / String(256)),
    Array(16, "player_ids" / Int32ul),
    Array(
        16,
        "player_data" / Struct(
            "active" / Int32ul,
            "human" / Int32ul,
            "civilization" / Int32ul,
            "constant" / Int32ul,  # 0x04 0x00 0x00 0x00
        )),
    Padding(5),
    "elapsed_time" / Float32l,
    "scenario_filename" /
    PascalString(lengthfield="scenario_filename_length" / Int16ul),
    If(lambda ctx: ctx._._.version == Version.DE, Padding(64)))

# Scenarios have intro text, a bitmap, and cinematics.
messages = "messages" / Struct(
    "instruction_id" / Int32ul,
    "hints_id" / Int32ul,
    "victory_id" / Int32ul,
    "defeat_id" / Int32ul,
    "history_id" / Int32ul,
    "scouts_id" / If(lambda ctx: ctx._._.version != Version.AOK, Int32ul),
    "instructions_length" / Int16ul,
    "instructions" / Bytes(lambda ctx: ctx.instructions_length),
    "hints" / PascalString(lengthfield="hints_length" / Int16ul),
    "victory" / PascalString(lengthfield="victory_length" / Int16ul),
    "defeat" / PascalString(lengthfield="defeat_length" / Int16ul),
Ejemplo n.º 33
0
    "session_id" / Bytes(lambda ctx: ctx.length),
)

CipherSuites = "cipher_suites" / Struct(
    "length" / Int16ub,  # TODO: Reject packets of length 0
    Array(lambda ctx: ctx.length // 2, "cipher_suites" / Int16ub),
)

CompressionMethods = "compression_methods" / Struct(
    "length" / Int8ub,  # TODO: Reject packets of length 0
    Array(lambda ctx: ctx.length, "compression_methods" / Int8ub),
)

ServerName = Struct(
    "type" / Int8ub,
    "name" / PascalString("length" / Int16ub),
)

SNIExtension = Prefixed(
    Int16ub,
    Struct(
        Int16ub, "server_names" / GreedyRange("server_name" / Struct(
            "name_type" / Int8ub,
            "host_name" / PascalString("length" / Int16ub),
        ))))

ALPNExtension = Prefixed(
    Int16ub,
    Struct(
        Int16ub,
        "alpn_protocols" / GreedyRange("name" / PascalString(Int8ub), ),
Ejemplo n.º 34
0
class Symbol(FixedObjectByteArray):
    classID = 10
    _construct = PascalString("value", length_field=UBInt32("length"))

    def __repr__(self):
        return "Symbol(%r)" % self.value
Ejemplo n.º 35
0
                     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, {
Ejemplo n.º 36
0
class UTF8(FixedObjectByteArray):
    classID = 14
    _construct = PascalString("value",
                              length_field=UBInt32("length"),
                              encoding="utf8")
Ejemplo n.º 37
0
    UBInt32('number'),  # bytes 8-11
)


_event = Struct('embedded',
    Enum(UBInt32('event_code'),  # bytes 12-15
         VERSION=1,
         DATA_START=2,
         DATA_STOP=3,
         SENSOR_MAP=9,
         DATA_RATE=10
    ),
    UBInt32('sending_node'),  # byes 16-19
    If(lambda ctx: ctx.payload_length > 8,  # Message data is optional
        # message_length: bytes 20-23, message: bytes 24+
        PascalString('message', length_field=UBInt32('message_length'), encoding='ascii')
    )
)


_EEG_data = Struct('embedded',
    BFloat32('timestamp'),  # bytes 12-15
    UBInt8('data_counter'),  # byte 16; Unused, just 0 currently
    Field('ADC_status', 6),  # bytes 17-22
    Array(lambda ctx: (ctx.payload_length - 11)/4, BFloat32('sensor_data'))  # bytes 23-26, 27-30, etc.
)


_null = Struct('embedded',
    Array(111, UBInt8('none'))
)