104
CRC_FIX_SUMMARY.md
Normal file
104
CRC_FIX_SUMMARY.md
Normal file
@@ -0,0 +1,104 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user