blob: e3c3cbdb12f396242e6d27cfd079303664f6e0be [file] [log] [blame]
#!/usr/bin/env python
from construct import *
BLOCK_TYPE = Enum(Int8ul,
RESERVED = 0x00,
ARBITRARY_TIMESTAMP = 0x01,
CONSTANT_FREQUENCY = 0x02,
)
SAMPLE_TYPE = Enum(Int16ul,
RESERVED = 0x0000,
TEMPERATURE = 0x0001,
ACCELERATION = 0x0002,
ANGULAR_RATE = 0x0003,
VOLTAGE = 0x0004,
ECG = 0x0005,
HUMIDITY = 0x0006,
PRESSURE = 0x0007,
MAGNETIC_FLUX_DENSITY = 0x0008,
CUSTOM = 0xF000,
)
resd_header = Struct(
"magic" / Const(b"RESD"),
"version" / Int8ul,
"reserved" / Padding(3)
)
blob = Struct(
"size" / Rebuild(Int32ul, len_(this.data)),
"data" / Int8ul[this.size],
)
data_block_metadata_item = Struct(
"key" / NullTerminated(GreedyRange(Int8ub)),
"type" / Int8ul,
"value" / Switch(this.type,
{
0x00: Int8sl,
0x01: Int8ul,
0x02: Int16sl,
0x03: Int16ul,
0x04: Int32sl,
0x05: Int32ul,
0x06: Int64sl,
0x07: Int64ul,
0x08: Float32l,
0x09: Float64l,
0x0A: NullTerminated(GreedyRange(Int8ul)),
0x0B: blob,
}),
)
data_block_metadata = Struct(
"size" / Int64ul,
"items" / FixedSized(this.size, GreedyRange(data_block_metadata_item)),
)
data_block_sample = lambda sample_type: Switch(sample_type, {
"TEMPERATURE": Int32sl,
"ACCELERATION": Struct(
"x" / Int32sl,
"y" / Int32sl,
"z" / Int32sl,
),
"ANGULAR_RATE": Struct(
"x" / Int32sl,
"y" / Int32sl,
"z" / Int32sl,
),
"VOLTAGE": Int32ul,
"ECG": Int32sl,
"HUMIDITY": Int32ul,
"PRESSURE": Int64ul,
"MAGNETIC_FLUX_DENSITY": Struct(
"x" / Int32sl,
"y" / Int32sl,
"z" / Int32sl,
),
})
data_block_sample_arbitrary = lambda sample_type: Struct(
"timestamp" / Int64ul,
"sample" / data_block_sample(sample_type)
)
data_block_sample_arbitrary_subheader = Struct(
"start_time" / Int64ul,
)
data_block_sample_frequency = lambda sample_type: Struct(
"sample" / data_block_sample(sample_type)
)
data_block_sample_frequency_subheader = Struct(
"start_time" / Int64ul,
"period" / Int64ul,
)
data_block_sample_single = lambda type_, sample_type: Switch(type_, {
"ARBITRARY_TIMESTAMP": data_block_sample_arbitrary(sample_type),
"CONSTANT_FREQUENCY": data_block_sample_frequency(sample_type),
})
data_block_subheader = Switch(this.header.block_type, {
"ARBITRARY_TIMESTAMP": data_block_sample_arbitrary_subheader,
"CONSTANT_FREQUENCY": data_block_sample_frequency_subheader
})
data_block_header = Struct(
"block_type" / BLOCK_TYPE,
"sample_type" / SAMPLE_TYPE,
"channel_id" / Int16ul,
"data_size" / Int64ul,
)
data_block = Struct(
"header" / data_block_header,
"subheader" / data_block_subheader,
"metadata" / data_block_metadata,
"samples" / GreedyRange(data_block_sample_single(this.header.block_type, this._.header.sample_type))
)
resd = Struct(
"header" / resd_header,
"blocks" / GreedyRange(data_block)
)