Esempio n. 1
0
    def decode_field(self, field_definition: FieldDefinition) -> RecordField:
        raw_bytes = self.reader.read_bytes(
            field_definition.size)  # TODO endianness

        type_class = BASE_TYPE_NUMBER_TO_CLASS[field_definition.base_type]
        decoded_value = type_class.from_bytes(raw_bytes)

        if field_definition.number == Decoder.MESSAGE_INDEX_FIELD_NUMBER:
            if field_definition.base_type != UnsignedInt16.metadata(
            ).base_type_number:
                raise FITFileContentError(
                    'Message Index field number {} is expected to be of type {}, {} found',
                    Decoder.MESSAGE_INDEX_FIELD_NUMBER, UnsignedInt16.__name__,
                    type_class.__name__)

        if field_definition.number == Decoder.PART_INDEX_FIELD_NUMBER:
            if field_definition.base_type != UnsignedInt32.metadata(
            ).base_type_number:
                raise FITFileContentError(
                    'Part Index field number {} is expected to be of type {}, {} found',
                    Decoder.MESSAGE_INDEX_FIELD_NUMBER, UnsignedInt32.__name__,
                    type_class.__name__)

        if field_definition.number == Decoder.TIMESTAMP_FIELD_NUMBER:
            if field_definition.base_type != UnsignedInt32.metadata(
            ).base_type_number:
                raise FITFileContentError(
                    'Timestamp field number {} is expected to be of type {}, {} found',
                    Decoder.TIMESTAMP_FIELD_NUMBER, UnsignedInt32.__name__,
                    type_class.__name__)
            self.most_recent_timestamp = decoded_value

        return RecordField(decoded_value)
Esempio n. 2
0
    def decode_message_definition(
            self, header: NormalRecordHeader) -> MessageDefinition:
        reserved_byte = self.reader.read_byte()

        if reserved_byte:
            raise FITFileContentError(
                'Reserved byte after record header is not 0')

        architecture = Architecture(self.reader.read_byte())
        global_message_number = UnsignedInt16.from_bytes(
            self.reader.read_bytes(2))

        number_of_fields = self.reader.read_byte()
        field_definitions = tuple([
            self.decode_field_definition() for _ in range(0, number_of_fields)
        ])

        number_of_developer_fields = self.reader.read_byte(
        ) if header.has_developer_data else 0
        developer_field_definitions = tuple([
            self.decode_field_definition()
            for _ in range(0, number_of_developer_fields)
        ])

        definition = MessageDefinition(reserved_byte, architecture,
                                       global_message_number,
                                       field_definitions,
                                       developer_field_definitions)
        self.message_definitions[header.local_message_type] = definition
        return definition
Esempio n. 3
0
    def decode_crc(self, allow_zero) -> UnsignedInt16:
        computed_crc = self.reader.crc_calculator.current
        expected_crc = self.reader.read_double_byte()

        self.reader.crc_calculator.reset()

        if allow_zero and expected_crc == UnsignedInt16(0):
            return expected_crc

        if computed_crc != expected_crc:
            raise FITFileContentError(
                f'Invalid CRC. Expected: {expected_crc}, computed: {computed_crc}'
            )

        return expected_crc
Esempio n. 4
0
 def read_double_byte(self) -> UnsignedInt16:
     return UnsignedInt16(
         np.array([self.read_byte()
                   for _ in range(0, 2)]).view(UnsignedInt16)[0])
Esempio n. 5
0
 def reset(self) -> None:
     self.current = UnsignedInt16(0)
Esempio n. 6
0
 def __init__(self):
     self.current = UnsignedInt16(0)
Esempio n. 7
0
class CRCCalculator:
    CRC_TABLE = [
        UnsignedInt16(0x0000),
        UnsignedInt16(0xCC01),
        UnsignedInt16(0xD801),
        UnsignedInt16(0x1400),
        UnsignedInt16(0xF001),
        UnsignedInt16(0x3C00),
        UnsignedInt16(0x2800),
        UnsignedInt16(0xE401),
        UnsignedInt16(0xA001),
        UnsignedInt16(0x6C00),
        UnsignedInt16(0x7800),
        UnsignedInt16(0xB401),
        UnsignedInt16(0x5000),
        UnsignedInt16(0x9C01),
        UnsignedInt16(0x8801),
        UnsignedInt16(0x4400),
    ]

    x000F = UnsignedInt16(0x000F)
    x0FFF = UnsignedInt16(0x0FFF)

    def __init__(self):
        self.current = UnsignedInt16(0)

    def reset(self) -> None:
        self.current = UnsignedInt16(0)

    def new_byte(self, byte) -> None:
        crc = self.current

        tmp = CRCCalculator.CRC_TABLE[
            crc & CRCCalculator.x000F]  # tmp = crc_table[crc & 0xF];
        crc = (crc >> 4) & CRCCalculator.x0FFF  # crc = (crc >> 4) & 0x0FFF;
        crc = crc ^ tmp ^ CRCCalculator.CRC_TABLE[
            byte
            & CRCCalculator.x000F]  # crc = crc ^ tmp ^ crc_table[byte & 0xF];

        tmp = CRCCalculator.CRC_TABLE[
            crc & CRCCalculator.x000F]  # tmp = crc_table[crc & 0xF];
        crc = (crc >> 4) & CRCCalculator.x0FFF  # crc = (crc >> 4) & 0x0FFF;
        crc = crc ^ tmp ^ CRCCalculator.CRC_TABLE[
            (byte >> 4) & CRCCalculator.
            x000F]  # crc = crc ^ tmp ^ crc_table[(byte >> 4) & 0xF];

        self.current = crc