Welcome Guest,Register Now
Log In

ANT Forum

Welcome guest, please Login or Register

   

C++ Encode error

Avatar
Rank

Total Posts: 5

Joined 2014-05-16

PM

Hi all,
i'm developing in C++ with qt creator(QT 5.4) on a mac book(OSX 10.10.1 64 bit).
I have a problem when i try to use the encode function. I use the simple code in the example folder:
int EncodeSettingsFile()
{
   fit
::Encode encode;
   
std::fstream file;

   
file.open("/Users/utente/FIT_CPP/test.fit"std::ios::in std::ios::out std::ios::binary std::ios::trunc);

   if (!
file.is_open())
   
{
      printf
("Error opening file test.fit\n");
      return -
1;
   
}

   fit
::FileIdMesg fileIdMesg// Every FIT file requires a File ID message
   
fileIdMesg.SetType(FIT_FILE_SETTINGS);
   
fileIdMesg.SetManufacturer(FIT_MANUFACTURER_DYNASTREAM);
   
fileIdMesg.SetProduct(1000);
   
fileIdMesg.SetSerialNumber(12345);
   
fileIdMesg.SetNumber(87);

   
encode.Open(file);
   
encode.Write(fileIdMesg);

   if (!
encode.Close())
   
{
      printf
("Error closing encode.\n");
      return -
1;
   
}
   file
.close();

   
printf("Encoded FIT file test.fit.\n");
   return 
0;

The file is created well, but when i triyng to decode it i got the error:
"FIT decode error: File header signature mismatch. File is not FIT"

So i debugged line per line the decode class, and i found that in the header there is no information about data type. ( the string ".FIT" ) .
I use hexadump in the terminal and i'm 100% sure that this information is not written in the file.
So i checked again encode class, and i saw that in the WriteFileHeader() function the struct that represent the FIT File Header
typedef struct
{
   FIT_UINT8 header_size
// FIT_FILE_HDR_SIZE (size of this structure)
   
FIT_UINT8 protocol_version// FIT_PROTOCOL_VERSION
   
FIT_UINT16 profile_version// FIT_PROFILE_VERSION
   
FIT_UINT32 data_size// Does not include file header or crc.  Little endian format.
   
FIT_UINT8 data_type[4]// ".FIT"
   
FIT_UINT16 crc// CRC of this file header in little endian format.
} FIT_FILE_HDR

is written with the function
file->write((const char *)&file;_headerFIT_FILE_HDR_SIZE); 

That's probably is the problem, because the struct will have platform-dependent padding.
Indeed the size of the struct is 14 byte(FIT_FILE_HDR_SIZE define) but the size of the struct is 24 byte (sizeof(FIT_FILE_HDR file_header) ).

When i use the encode function of the java sdk everything works fine. (i'm able to decode the file from
the c++ decode function).

How can avoid this problem?
Thanks in advance


For more details, below i paste also the hexadump content of the two files(the first one is the wrong one created with C++ encode function, the second one is the one created with java encode function):

hexadump -c test.fit
0000000 016 020   x 005   ?   ?   ?   ?   !  \0  \0  \0  \0  \0   @  \0
0000010  \0  \0  \0 005  \0 001  \0 001 002 204 002 002 204 003 004 214 

hexadump -c test_java.fit
0000000 016 020 230 003 035  \0  \0  \0   .   F   I   T   0   w   @  \0
0000010 001  \0  \0 004 001 002 204 002 002 204 003 004 214 005 002 204 

For now i've solve the problem rewriting the encode WriteHeader() function, byte per byre like below:
file->put(file_header.header_size);
file->put(file_header.protocol_version);
file->write((const char *)&file;_header.profile_version2);
file->write((const char *)&file;_header.data_size4);
file->write((const char *)&file;_header.data_type4);
file->write((const char *)&file;_header.crc2); 

Instead of
file->write((const char *)&file;_headerFIT_FILE_HDR_SIZE); 

However in this way i will brake the FIT library...      
RankRankRank

Total Posts: 91

Joined 2012-10-12

PM

Hi Zanzarone,

I haven't tested the C++ SDK under that environment. It is quite likely the C++ SDK does not correctly support all structure alignments. I will flag this for further investigation and update this post when I have more information.      
Avatar
Rank

Total Posts: 5

Joined 2014-05-16

PM

Perfect, thanks!      
Avatar
RankRankRankRank

Total Posts: 123

Joined 2013-10-07

PM

I can confirm this.

I generate FIT file on windows with success, but the same function on OS X create an invalid file header.

Golden Cheetah parsing says : Error - bad header, expected ".FIT" but got ""
I check and the "void Encode::WriteFileHeader()" function seems to be in cause.

Thanks for your post, will try your fix, hopefully the next source code will have this fixed.      

Signature

——————————————————
Free Indoor Cycling Software - https://maximumtrainer.com

Avatar
RankRankRankRank

Total Posts: 123

Joined 2013-10-07

PM

Zanzarone - 22 February 2015 03:25 AM
Perfect, thanks!


You sir are my hero, I would have never found this error myself, lacking C++ skills.

I used your fix and now the FIT file can be generated on Mac and Windows without issues. ANT should hire you wink Using Qt 5.4.1

File I had to modify :

void Encode::WriteFileHeader()
{
   FIT_FILE_HDR file_header
;

   if (!
file)
      return;

   
file_header.header_size FIT_FILE_HDR_SIZE;
   
file_header.profile_version FIT_PROFILE_VERSION;
   
file_header.protocol_version FIT_PROTOCOL_VERSION;
   
memcpy((FIT_UINT8 *)&file;_header.data_type".FIT"4);
   
file_header.data_size dataSize;
   
file_header.crc CRC::Calc16(&file;_headerFIT_STRUCT_OFFSET(crcFIT_FILE_HDR));

   
file->seekp(0std::ios::beg);
//   file->write((const char *)&file;_header, FIT_FILE_HDR_SIZE);

   
file->put(file_header.header_size);
   
file->put(file_header.protocol_version);

   
file->write((const char *)&file;_header.profile_version2);
   
file->write((const char *)&file;_header.data_size4);
   
file->write((const char *)&file;_header.data_type4);
   
file->write((const char *)&file;_header.crc2);
     

Signature

——————————————————
Free Indoor Cycling Software - https://maximumtrainer.com

Avatar
Rank

Total Posts: 5

Joined 2014-05-16

PM

blaisminator - 30 April 2015 01:17 PM


You sir are my hero, I would have never found this error myself, lacking C++ skills.

I used your fix and now the FIT file can be generated on Mac and Windows without issues. ANT should hire you wink Using Qt 5.4.1



Thanks man! If someone is interested.. smile      
Rank

Total Posts: 1

Joined 2014-02-12

PM

Awesome! I was just running into the same problem and came across this solution. Much thanks!      
Rank

Total Posts: 20

Joined 2015-05-11

PM

Hi Zanzarone,

FIT_USE_STDINT_H is now defined by default on Apple computers as of the 16.00 release. This fixes some type define issues which were causing you to see the header size of 24 bytes, and should allow for proper encoding of FIT files from the C++ SDK.      
Avatar
RankRankRankRank

Total Posts: 123

Joined 2013-10-07

PM

MarioM - 12 August 2015 11:05 AM
Hi Zanzarone,

FIT_USE_STDINT_H is now defined by default on Apple computers as of the 16.00 release. This fixes some type define issues which were causing you to see the header size of 24 bytes, and should allow for proper encoding of FIT files from the C++ SDK.


Hi there, looking to upgrade to 16.20
Do I understand correctly that by using FIT SDK 16.00+, it should be fixed without modifying any .cpp code?
Thanks in advance!      

Signature

——————————————————
Free Indoor Cycling Software - https://maximumtrainer.com

Rank

Total Posts: 20

Joined 2015-05-11

PM

Yes, this should take no change in SDK code if you are compiling / running on an Apple computer.      
Rank

Total Posts: 7

Joined 2017-02-08

PM

I am stunned that this happens, memory alignment and handling of it shouldn't be too difficult...

Writing to a file should be done with a proper stream, the C++ way, compensating variables for Endianess.