Values of messages are completely wrong in Linux (endianness problem) #3
Comments
I've found the source of the issue in the FIT SDK: FIT_UINT32 Field::GetUINT32Value(const FIT_UINT8 fieldArrayIndex, const FIT_UINT16 subFieldIndex) const
{
if ((fieldArrayIndex >= values.size()) || (values[fieldArrayIndex].size() < sizeof(FIT_UINT32)))
return FIT_UINT32_INVALID;
return ((FIT_UINT32) values[fieldArrayIndex][3] << 24) | ((FIT_UINT32) values[fieldArrayIndex][2] << 16) | ((FIT_UINT32) values[fieldArrayIndex][1] << 8) | values[fieldArrayIndex][0];
} This code always returns the unsigned integer in big endian format. If we detect the endianness, and adjust accordingly, then we can fix this problem. if (fit::GetArch()) {
//Big Endian
return ((FIT_UINT32) values[fieldArrayIndex][3] << 24) | ((FIT_UINT32) values[fieldArrayIndex][2] << 16) | ((FIT_UINT32) values[fieldArrayIndex][1] << 8) | values[fieldArrayIndex][0];
}
else {
return ((FIT_UINT32) values[fieldArrayIndex][0] << 24) | ((FIT_UINT32) values[fieldArrayIndex][1] << 16) | ((FIT_UINT32) values[fieldArrayIndex][2] << 8) | values[fieldArrayIndex][3];
} This problem exists for each data type. I'd prefer to fix the problem at this field retrieval level rather than have to deal with swapping the bytes every time I use the messages. |
Field::Get Methods to fix
|
As it turns out, both my windows machine and linux machine are big endian according to the fit::GetArch() function. While that may or may not be surprising, it is surprising that they behave as if they are different. Why are the bytes reversed on linux if it is the same endian format? Is something different about the file being read in? |
I'm still not sure why there is a difference between linux and Windows; however I implemented a workaround in 35e15b2 by using a |
I've just tried your software. And it does not work for me. Linux OS. This is the set of timestamps of records in decode callback:
Timestamps completely incorrect. |
The FIT SDK claims to handle the endianness of the various fields for each message. I do see that there is some logic for this; however, running decoding the example Activity.fit file yields different results on a Windows system and a Linux system.
For example, for the first record,
mesg.GetTimestamp()
, on Windows returns702940946
which seems correct based on the csv value for the same record. However, on linux, the value is319284777
. I get this same value on Windows if I swap the bytes before printing the result.I've asked for help on who's responsibility this is in the FIT SDK forum.
The solution may just be to detect the endianness of the the environment and adjust values accordingly. I feel like the SDK should handle this though. I could also just be doing something wrong.
The text was updated successfully, but these errors were encountered: