105 lines
3.1 KiB
Markdown
105 lines
3.1 KiB
Markdown
# 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
|
|
```go
|
|
// Only included bytes 0-11
|
|
d.crc = UpdateCRC(d.crc, headerData[:HeaderWithoutCRCSize]) // Wrong!
|
|
```
|
|
|
|
### Correct Implementation
|
|
```go
|
|
// 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:
|
|
|
|
1. **12-byte header** (older format):
|
|
- Bytes 0-11: Header data
|
|
- No header CRC
|
|
- File CRC calculated from: bytes 0-11 + data records
|
|
|
|
2. **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:**
|
|
```go
|
|
d.crc = UpdateCRC(d.crc, headerData[:HeaderWithoutCRCSize])
|
|
```
|
|
|
|
**Changed to:**
|
|
```go
|
|
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
|
|
|
|
1. **fitparser/decoder.go** - Fixed CRC calculation
|
|
2. **README.md** - Updated to reflect 100% CRC validation
|
|
3. **QUICKSTART.md** - Updated troubleshooting section
|
|
|
|
## Verification Commands
|
|
|
|
```bash
|
|
# 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.
|