tjwallace / fit

Ruby gem for reading Garmin FIT files
MIT License
44 stars 21 forks source link

Error when parsing FIT from Garmin 935? #26

Open emilkarl opened 7 years ago

emilkarl commented 7 years ago

I have a FIT file from Garmin 935. I dont really have more info as the file comes from a customer. When trying to parse the file it raises a runtime error. Any ideas on this?

fit_file = Fit.load_file(file)
*** RuntimeError Exception: Can't map base_type_number 28 to a data type
doc75 commented 7 years ago

Could you please provide a file which is failing as mentioned in your report ? It is quite hard to guess what could be wrong without a file showing the error.

emilkarl commented 7 years ago

Oh yeah, sorry! garmintest.zip

doc75 commented 7 years ago

I can reproduce the issue with your file. Unfortunately the base type 28 does not exist in FIT spec. I cannot understand so far what is the meaning of this.

emilkarl commented 7 years ago

Ok, thanks! I will take a look at it and see if I can sort it out.

emilkarl commented 7 years ago

According to the FIT file protocol, there seem to be 16 base types, not 13 (4.2.1.4.3 Base Type). And something they call Developer Data Field Description (4.2.1.5).

I will look into this and see if I can figure something out. I am not used to working with binaries tho.

D00001275 Flexible & Interoperable Data Transfer (FIT) Protocol Rev 2.3.pdf

emilkarl commented 7 years ago

More info on this...

This is the header, message and fields for a record av developer data. The global_message_number 33792 and its fields is something that would be nice to skip in the parsing, or if it would be possible to interpret these messages and build it in to the lib.

There are multiple fields with the same field_definition_number in this which also causes errors so the best way around this and make the library read at least build a useable object instead of raising the error would be awesome.

lib/fit/file/record.rb

def read(io)
  @header = RecordHeader.read(io)
  @content = case @header.message_type.snapshot
  when 1
    Definition.read(io).tap do |definition|
      puts "--------"
      puts "> header: #{@header.local_message_type.snapshot}"
      puts @header
      puts definition
      @@definitions[@header.local_message_type.snapshot] = Data.generate(definition)
    end
  when 0
    definition = @@definitions[@header.local_message_type.snapshot]
    raise "No definition for local message type: #{@header.local_message_type}" if definition.nil?
    definition.read(io)
  end

  self
end

Output

--------
> header: 4
{
  : header_type=>0,
  : message_type=>1,
  : local_message_type=>4
}

{
  : architecture=>0,
  : global_message_number=>33792,
  : field_count=>64,
  : fields=>[
    {
      : field_definition_number=>169,
      : field_size=>0,
      : endian_ability=>0,
      : base_type_number=>28
    },
    {
      : field_definition_number=>0,
      : field_size=>0,
      : endian_ability=>0,
      : base_type_number=>0
    },
    {
      : field_definition_number=>76,
      : field_size=>65,
      : endian_ability=>0,
      : base_type_number=>14
    },
    {
      : field_definition_number=>115,
      : field_size=>2,
      : endian_ability=>0,
      : base_type_number=>15
    },
    {
      : field_definition_number=>2,
      : field_size=>255,
      : endian_ability=>1,
      : base_type_number=>31
    },
    {
      : field_definition_number=>255,
      : field_size=>255,
      : endian_ability=>1,
      : base_type_number=>31
    },
    {
      : field_definition_number=>255,
      : field_size=>2,
      : endian_ability=>1,
      : base_type_number=>2
    },
    {
      : field_definition_number=>101,
      : field_size=>29,
      : endian_ability=>0,
      : base_type_number=>20
    },
    {
      : field_definition_number=>246,
      : field_size=>1,
      : endian_ability=>0,
      : base_type_number=>0
    },
    {
      : field_definition_number=>0,
      : field_size=>233,
      : endian_ability=>0,
      : base_type_number=>9
    },
    {
      : field_definition_number=>246,
      : field_size=>6,
      : endian_ability=>0,
      : base_type_number=>19
    },
    {
      : field_definition_number=>2,
      : field_size=>129,
      : endian_ability=>0,
      : base_type_number=>16
    },
    {
      : field_definition_number=>84,
      : field_size=>11,
      : endian_ability=>1,
      : base_type_number=>2
    },
    {
      : field_definition_number=>1,
      : field_size=>157,
      : endian_ability=>0,
      : base_type_number=>17
    },
    {
      : field_definition_number=>116,
      : field_size=>44,
      : endian_ability=>0,
      : base_type_number=>0
    },
    {
      : field_definition_number=>0,
      : field_size=>44,
      : endian_ability=>0,
      : base_type_number=>1
    },
    {
      : field_definition_number=>93,
      : field_size=>88,
      : endian_ability=>0,
      : base_type_number=>22
    },
    {
      : field_definition_number=>1,
      : field_size=>0,
      : endian_ability=>1,
      : base_type_number=>9
    },
    {
      : field_definition_number=>0,
      : field_size=>87,
      : endian_ability=>0,
      : base_type_number=>2
    },
    {
      : field_definition_number=>1,
      : field_size=>0,
      : endian_ability=>0,
      : base_type_number=>0
    },
    {
      : field_definition_number=>132,
      : field_size=>64,
      : endian_ability=>1,
      : base_type_number=>9
    },
    {
      : field_definition_number=>0,
      : field_size=>60,
      : endian_ability=>0,
      : base_type_number=>0
    },
    {
      : field_definition_number=>0,
      : field_size=>0,
      : endian_ability=>0,
      : base_type_number=>12
    },
    {
      : field_definition_number=>65,
      : field_size=>14,
      : endian_ability=>0,
      : base_type_number=>16
    },
    {
      : field_definition_number=>2,
      : field_size=>255,
      : endian_ability=>1,
      : base_type_number=>31
    },
    {
      : field_definition_number=>255,
      : field_size=>255,
      : endian_ability=>1,
      : base_type_number=>31
    },
    {
      : field_definition_number=>255,
      : field_size=>255,
      : endian_ability=>1,
      : base_type_number=>31
    },
    {
      : field_definition_number=>2,
      : field_size=>195,
      : endian_ability=>0,
      : base_type_number=>5
    },
    {
      : field_definition_number=>29,
      : field_size=>52,
      : endian_ability=>1,
      : base_type_number=>22
    },
    {
      : field_definition_number=>1,
      : field_size=>0,
      : endian_ability=>0,
      : base_type_number=>0
    },
    {
      : field_definition_number=>233,
      : field_size=>9,
      : endian_ability=>0,
      : base_type_number=>0
    },
    {
      : field_definition_number=>0,
      : field_size=>83,
      : endian_ability=>0,
      : base_type_number=>2
    },
    {
      : field_definition_number=>129,
      : field_size=>16,
      : endian_ability=>0,
      : base_type_number=>20
    },
    {
      : field_definition_number=>11,
      : field_size=>138,
      : endian_ability=>0,
      : base_type_number=>3
    },
    {
      : field_definition_number=>157,
      : field_size=>18,
      : endian_ability=>1,
      : base_type_number=>16
    },
    {
      : field_definition_number=>22,
      : field_size=>0,
      : endian_ability=>0,
      : base_type_number=>0
    },
    {
      : field_definition_number=>44,
      : field_size=>1,
      : endian_ability=>0,
      : base_type_number=>30
    },
    {
      : field_definition_number=>88,
      : field_size=>22,
      : endian_ability=>0,
      : base_type_number=>1
    },
    {
      : field_definition_number=>0,
      : field_size=>173,
      : endian_ability=>0,
      : base_type_number=>0
    },
    {
      : field_definition_number=>87,
      : field_size=>70,
      : endian_ability=>0,
      : base_type_number=>1
    },
    {
      : field_definition_number=>0,
      : field_size=>0,
      : endian_ability=>1,
      : base_type_number=>8
    },
    {
      : field_definition_number=>64,
      : field_size=>169,
      : endian_ability=>0,
      : base_type_number=>0
    },
    {
      : field_definition_number=>61,
      : field_size=>0,
      : endian_ability=>0,
      : base_type_number=>0
    },
    {
      : field_definition_number=>0,
      : field_size=>70,
      : endian_ability=>0,
      : base_type_number=>1
    },
    {
      : field_definition_number=>14,
      : field_size=>107,
      : endian_ability=>0,
      : base_type_number=>2
    },
    {
      : field_definition_number=>103,
      : field_size=>2,
      : endian_ability=>1,
      : base_type_number=>31
    },
    {
      : field_definition_number=>255,
      : field_size=>255,
      : endian_ability=>1,
      : base_type_number=>31
    },
    {
      : field_definition_number=>255,
      : field_size=>255,
      : endian_ability=>0,
      : base_type_number=>2
    },
    {
      : field_definition_number=>196,
      : field_size=>101,
      : endian_ability=>0,
      : base_type_number=>29
    },
    {
      : field_definition_number=>52,
      : field_size=>246,
      : endian_ability=>0,
      : base_type_number=>1
    },
    {
      : field_definition_number=>0,
      : field_size=>0,
      : endian_ability=>1,
      : base_type_number=>9
    },
    {
      : field_definition_number=>9,
      : field_size=>0,
      : endian_ability=>0,
      : base_type_number=>0
    },
    {
      : field_definition_number=>83,
      : field_size=>2,
      : endian_ability=>1,
      : base_type_number=>1
    },
    {
      : field_definition_number=>16,
      : field_size=>84,
      : endian_ability=>0,
      : base_type_number=>11
    },
    {
      : field_definition_number=>178,
      : field_size=>3,
      : endian_ability=>1,
      : base_type_number=>6
    },
    {
      : field_definition_number=>18,
      : field_size=>78,
      : endian_ability=>0,
      : base_type_number=>22
    },
    {
      : field_definition_number=>0,
      : field_size=>0,
      : endian_ability=>0,
      : base_type_number=>12
    },
    {
      : field_definition_number=>1,
      : field_size=>95,
      : endian_ability=>0,
      : base_type_number=>24
    },
    {
      : field_definition_number=>22,
      : field_size=>1,
      : endian_ability=>0,
      : base_type_number=>0
    },
    {
      : field_definition_number=>169,
      : field_size=>0,
      : endian_ability=>0,
      : base_type_number=>23
    },
    {
      : field_definition_number=>72,
      : field_size=>1,
      : endian_ability=>0,
      : base_type_number=>0
    },
    {
      : field_definition_number=>0,
      : field_size=>136,
      : endian_ability=>0,
      : base_type_number=>0
    },
    {
      : field_definition_number=>169,
      : field_size=>0,
      : endian_ability=>0,
      : base_type_number=>28
    },
    {
      : field_definition_number=>0,
      : field_size=>0,
      : endian_ability=>0,
      : base_type_number=>0
    }
  ]
}