Skip to content
This repository has been archived by the owner on Apr 1, 2022. It is now read-only.

Values of messages are completely wrong in Linux (endianness problem) #3

Open
smerchek opened this issue Feb 27, 2013 · 5 comments
Open
Assignees
Labels

Comments

@smerchek
Copy link
Owner

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 returns 702940946 which seems correct based on the csv value for the same record. However, on linux, the value is 319284777. 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.

@ghost ghost assigned smerchek Feb 27, 2013
@smerchek
Copy link
Owner Author

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.

@smerchek
Copy link
Owner Author

Field::Get Methods to fix

  • GetNumValue
  • GetBitsValue
  • GetBitsSignedValue
  • GetENUMValue
  • GetBYTEValue
  • GetSINT8Value
  • GetUINT8Value
  • GetUINT8ZValue
  • GetSINT16Value
  • GetUINT16Value
  • GetUINT16ZValue
  • GetSINT32Value
  • GetUINT32Value
  • GetUINT32ZValue
  • GetFLOAT32Value
  • GetFLOAT64Value
  • GetSTRINGValue

@smerchek
Copy link
Owner Author

smerchek commented Mar 1, 2013

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?

@smerchek
Copy link
Owner Author

smerchek commented Mar 1, 2013

I'm still not sure why there is a difference between linux and Windows; however I implemented a workaround in 35e15b2 by using a GetOS function.

@RusAlex
Copy link

RusAlex commented Jul 27, 2014

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:

Sat Sep 22 1990 20:28:46 GMT+0500 (MSK)
Fri Apr 05 1991 00:49:02 GMT+0500 (MSK)
Sat Nov 07 1992 12:49:50 GMT+0400 (MSK)
Sat Dec 24 1994 06:10:54 GMT+0400 (MSK)
Thu Jul 06 1995 11:31:10 GMT+0500 (MSK)
Fri Feb 07 1997 23:31:58 GMT+0400 (MSK)
Tue Mar 03 1998 08:12:30 GMT+0400 (MSK)
Fri Mar 26 1999 16:53:02 GMT+0400 (MSK)
Wed Oct 06 1999 22:13:18 GMT+0500 (MSK)
Tue Apr 18 2000 02:33:34 GMT+0500 (MSK)
Sun Oct 29 2000 05:53:50 GMT+0400 (MSK)
Wed Nov 21 2001 14:34:22 GMT+0400 (MSK)

Timestamps completely incorrect.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

2 participants