Mandatory fields (record/20)

Is there any documentation on what fields are mandatory for various kinds of messages? Especially so for record/20, since it seems to collect most kinds of data in one place.

Is the only mandatory field timestamp/253?

I'm (re-)writing a parsing library in Rust (not yet on crates.io) that started out specific to VIRB Ultra 30 when it comes to post-processing, since I needed to sync location with video for VIRBs for a tool we're using (fairly crude code in there right now, that's currently being cleaned up considerably + adding support for that other action camera brand). However I'm contemplating a full representation of at least record/20 as-per Profile.xlsx. My current record/20 struct only covers location data to generate KML from VIRBs or watches (for those that log location to record/20). This is mostly for deciding how to best represent optional fields since it seems record/20 have a lot of those.

This is basically a two-step parse, where the first step just gets the raw values for any FIT-file, with support for custom developer data, to be interpreted further in the second step (in my case location + time only).

  • The FIT SDK itself does not define any required messages or fields to be present in a file. A robust implementation of decoder should be able to handle a message with no fields, and on the flip side a robust implementation of an encoder should not write out a message with no fields.

    On this page it is mentioned as more of a best practice that: "Timestamp and at least one other value are required for each Record message." I'll add that, the timestamps should be in chronological ascending order.

    developer.garmin.com/.../

  • Ok, thanks! I think I've seen "timestamp and at least one other value" for GpsMetadata for one of Garmin's watches.

    Regarding timestamps and order: not record/20, but for VIRB Ultra 30 camera_event/161 some event types are not chronologically logged. Camera event type 2 seems to have a later timestamp + timestamp_ms than camera event type 6, but 2 is still logged before 6. Not really an issue since they're usually only 10-15ms apart (I look for 0, start of recording session, and 2, end of recording session).

    My decoder should work fine at the "first" parse regardless of contents - all that does is to parse values into whatever the corresponding definition message specifies. However, it seems a lot of data may or may not end up in record/20 which means a lot of optionals. I thought I'd try a more user friendly representation over the raw values for record/20 specifically, since right now an end user would have to first match on field definition number, then extract the value from an enum (may hold values in Rust).