Exemplo n.º 1
0
def generate_fitfile(data=None, endian='<'):
    fit_data = (
        generate_messages(
            # local mesg 0, global mesg 0 (file_id)
            mesg_num=0,
            local_mesg_num=0,
            endian=endian,
            field_defs=[
                # serial number, time_created, manufacturer
                (3, 'uint32z'),
                (4, 'uint32'),
                (1, 'uint16'),
                # product/garmin_product, number, type
                (2, 'uint16'),
                (5, 'uint16'),
                (0, 'enum'),
            ],
            # random serial number, random time, garmin, edge500, null, activity
            data=[[558069241, 723842606, 1, 1036, (2**16) - 1, 4]],
        ))

    if data:
        fit_data += data

    # Prototcol version 1.0, profile version 1.52
    header = pack('<2BHI4s', 14, 16, 152, len(fit_data), b'.FIT')
    file_data = header + pack('<' + Crc.FMT, Crc.calculate(header)) + fit_data
    return file_data + pack('<' + Crc.FMT, Crc.calculate(file_data))
Exemplo n.º 2
0
 def _read_and_assert_crc(self, allow_zero=False):
     # CRC Calculation is little endian from SDK
     crc_computed, crc_read = self._crc.value, self._read_struct(Crc.FMT)
     if not self.check_crc:
         return
     if crc_computed == crc_read or (allow_zero and crc_read == 0):
         return
     raise FitCRCError('CRC Mismatch [computed: %s, read: %s]' % (
         Crc.format(crc_computed), Crc.format(crc_read)))
Exemplo n.º 3
0
 def _read_and_assert_crc(self, allow_zero=False):
     # CRC Calculation is little endian from SDK
     crc_computed, crc_read = self._crc.value, self._read_struct(Crc.FMT)
     if not self.check_crc:
         return
     if crc_computed == crc_read or (allow_zero and crc_read == 0):
         return
     raise FitCRCError('CRC Mismatch [computed: %s, read: %s]' %
                       (Crc.format(crc_computed), Crc.format(crc_read)))
Exemplo n.º 4
0
 def _read_and_assert_crc(self, allow_zero=False):
     # CRC Calculation is little endian from SDK
     # TODO - How to handle the case of unterminated file? Error out and have user retry with check_crc=false?
     crc_computed, crc_read = self._crc.value, self._read_struct(Crc.FMT)
     if not self.check_crc:
         return
     if crc_computed == crc_read or (allow_zero and crc_read == 0):
         return
     raise FitCRCError('CRC Mismatch [computed: %s, read: %s]' % (
         Crc.format(crc_computed), Crc.format(crc_read)))
Exemplo n.º 5
0
def generate_fitfile(data=None, endian='<'):
    fit_data = (
        generate_messages(
            # local mesg 0, global mesg 0 (file_id)
            mesg_num=0, local_mesg_num=0, endian=endian, field_defs=[
                # serial number, time_created, manufacturer
                (3, 'uint32z'), (4, 'uint32'), (1, 'uint16'),
                # product/garmin_product, number, type
                (2, 'uint16'), (5, 'uint16'), (0, 'enum'),
            ],
            # random serial number, random time, garmin, edge500, null, activity
            data=[[558069241, 723842606, 1, 1036, (2 ** 16) - 1, 4]],
        )
    )

    if data:
        fit_data += data

    # Prototcol version 1.0, profile version 1.52
    header = pack('<2BHI4s', 14, 16, 152, len(fit_data), b'.FIT')
    file_data = header + pack('<' + Crc.FMT, Crc.calculate(header)) + fit_data
    return file_data + pack('<' + Crc.FMT, Crc.calculate(file_data))
Exemplo n.º 6
0
 def test_crc(self):
     crc = Crc()
     self.assertEqual(0, crc.value)
     crc.update(b'\x0e\x10\x98\x00(\x00\x00\x00.FIT')
     self.assertEqual(0xace7, crc.value)
     # 0 must not change the crc
     crc.update(0)
     self.assertEqual(0xace7, crc.value)
Exemplo n.º 7
0
    def _parse_file_header(self):

        # Initialize data
        self._accumulators = {}
        self._bytes_left = -1
        self._complete = False
        self._compressed_ts_accumulator = 0
        self._crc = Crc()
        self._local_mesgs = {}

        # Every FIT must have 'FIT' string in the 8th byte. So, it seems your FIT is wrong.
        header_data = self._read(12)
        if header_data[8:12] != b'.FIT':
            raise FitHeaderError("Invalid .FIT File Header")

        # Larger fields are explicitly little endian from SDK
        header_size, protocol_ver_enc, profile_ver_enc, data_size = self._read_struct(
            '2BHI4x', data=header_data)

        # Decode the same way the SDK does
        self.protocol_version = float(
            "%d.%d" % (protocol_ver_enc >> 4, protocol_ver_enc &
                       ((1 << 4) - 1)))
        self.profile_version = float(
            "%d.%d" % (profile_ver_enc / 100, profile_ver_enc % 100))

        # Consume extra header information
        extra_header_size = header_size - 12
        if extra_header_size > 0:
            # Make sure extra field in header is at least 2 bytes to calculate CRC
            if extra_header_size < 2:
                raise FitHeaderError('Irregular File Header Size')

            # Consume extra two bytes of header and check CRC
            self._read_and_assert_crc(allow_zero=True)

            # Consume any extra bytes, since header size "may be increased in
            # "future to add additional optional information" (from SDK)
            self._read(extra_header_size - 2)

        # After we've consumed the header, set the bytes left to be read
        self._bytes_left = data_size
Exemplo n.º 8
0
 def test_crc_format(self):
     self.assertEqual('0x0000', Crc.format(0))
     self.assertEqual('0x12AB', Crc.format(0x12AB))