3.1 KiB
CRC Validation Fix Summary
Issue
The FIT parser was failing CRC validation on all real-world FIT files (168 test files from Wahoo ELEMNT devices), while passing validation on the SDK example files with 12-byte headers.
Root Cause
The CRC calculation was incorrect for FIT files with 14-byte headers. The implementation was only including the first 12 bytes of the header in the CRC calculation, excluding the header's CRC bytes (bytes 12-13).
Incorrect Implementation
// Only included bytes 0-11
d.crc = UpdateCRC(d.crc, headerData[:HeaderWithoutCRCSize]) // Wrong!
Correct Implementation
// Include all header bytes (0-11 for 12-byte header, 0-13 for 14-byte header)
d.crc = UpdateCRC(d.crc, headerData[:header.Size]) // Correct!
Technical Details
The FIT protocol specifies two header formats:
-
12-byte header (older format):
- Bytes 0-11: Header data
- No header CRC
- File CRC calculated from: bytes 0-11 + data records
-
14-byte header (current format):
- Bytes 0-11: Header data
- Bytes 12-13: Header CRC (CRC of bytes 0-11)
- File CRC calculated from: bytes 0-13 + data records
The key insight: The file CRC includes ALL bytes from the start of the file up to the file CRC position, including the header's CRC field if present.
Fix Location
File: fitparser/decoder.go
Function: Decode()
Line: ~65
Changed from:
d.crc = UpdateCRC(d.crc, headerData[:HeaderWithoutCRCSize])
Changed to:
d.crc = UpdateCRC(d.crc, headerData[:header.Size])
Validation Results
Before Fix
- ❌ SDK Activity.fit (14-byte header): CRC FAILED
- ✅ SDK Settings.fit (12-byte header): CRC OK
- ❌ User files (168 files, 14-byte headers): 0% success rate
After Fix
- ✅ SDK Activity.fit: CRC OK
- ✅ SDK Settings.fit: CRC OK
- ✅ User files: 100% success rate (168/168)
Test Coverage
The fix was validated against:
- 2 SDK example files (Activity.fit, Settings.fit)
- 168 real-world FIT files from Wahoo ELEMNT BOLT and ELEMNT ACE devices
- Files ranging from 8 KB to 2.4 MB
- Various activities: cycling, running, swimming
- Total data validated: ~44 MB of FIT files
Error Handling
CRC validation now properly fails fast:
- If CRC check is enabled (default) and fails, decoding stops immediately
- Error message format:
"file CRC mismatch: calculated 0xXXXX, expected 0xYYYY" - CRC checking can be disabled with
decoder.EnableCRCCheck(false)if needed
Files Modified
- fitparser/decoder.go - Fixed CRC calculation
- README.md - Updated to reflect 100% CRC validation
- QUICKSTART.md - Updated troubleshooting section
Verification Commands
# Run test suite
cd fitparser && go test -v
# Validate all user files
go run test_crc_validation.go
# Test with specific file
go run example/main.go data/in/YOUR_FILE.fit
Conclusion
The FIT parser now correctly implements CRC-16 validation according to the FIT protocol specification, with 100% success rate on all tested files.