Welcome Guest,Register Now
Log In

ANT Forum

Welcome guest, please Login or Register

   

[SOLVED] FIT SDK in Linux. Strange behavior in decode.c

Rank

Total Posts: 6

Joined 2016-03-21

PM

Hello,

I'm newbie workig with FIT format. I need to read FIT files (extract coordinates, heart rate, cadence, power, etc.) but I work in Linux. I've downloaded the FIT SDK. I need to work with pure C language, but and tried to create a library by compiling the files in the c/ and cpp/ folders.

For the C++ code, there is some errors compiling with g++, all of them related with memcpy and memcp functions, which are not declared. This is easy to fix, because the errors are due to a wrong (for GNU compilers) include in fit_buffer_encode.hpp and fit_field.hpp. The #include <string> lines must be modified to say #include <cstring>. Then, a Unix library can be created as (we are in the cpp/ folder):

for i in `ls *.cpp`; do g++ -c $idone
ar rcs libcppfit
.*.


Then, the examples/decode/decode.cpp program can be compiled as

g++ -Iexamples/decode/decode.cpp -o decode -lcppfit 


If I try to decode the file file.fit (which I attach in this message) as ./decode file.fit I obtain:

FIT Decode Example Application
File ID
:
   
Type4
   Manufacturer
1
   Product
1036
   Serial Number
3886102490
Device info
:
   
Timestamp815910596
   Battery status
Invalid
Device info
:
   
Timestamp815910596
   Battery status
Invalid
Device info
:
   
Timestamp815910596
   Battery status
Invalid
Device info
:
   
Timestamp815910596
   Battery status
Invalid
Device info
:
   
Timestamp815910596
   Battery status
Invalid
Device info
:
   
Timestamp815917265
   Battery status
Invalid
Device info
:
   
Timestamp815917265
   Battery status
Invalid
Device info
:
   
Timestamp815917265
   Battery status
Invalid
Device info
:
   
Timestamp815917265
   Battery status
Invalid
Device info
:
   
Timestamp815917265
   Battery status
Invalid
Decoded FIT file file
.fit


Now I've tried to do the same for the C code in the c/ folder:

for i in `ls *.c`; do gcc -c $idone
ar rcs libcfit
.*.o
gcc 
-Iexamples/decode/decode.-o decode -lcfit 


If I try to decode the file.fit file:

./decode file.fit
Testing file conversion using file
.fit file...
File is not FIT


I don't understand this behavior. The file is the same as the one in the C++ example (is a file generated by a Garmin Edge 500 and it was copied from the device without any preprocessing. It works when uploading to Strava for example). Why the C decode.c says that the file is not FIT? Which capabilities has the C interface of the FIT SDK? I need to extract coordinates, heart rate, power, etc.

Thanks      

File Attachments

  • file.fit (File Size: 156KB - Downloads: 1019)
Rank

Total Posts: 6

Joined 2016-03-21

PM

Well, I've been playing with the C interface and I've discovered some interesting things. First of all, I've added some lines to examples/decode/decode.c as

do
      
{
         
#if defined(FIT_CONVERT_MULTI_THREAD)
            
convert_return FitConvert_Read(&state;, bufbuf_size);
         
#else
            
convert_return FitConvert_Read(bufbuf_size);
         
#endif

            /////////////////////////////////////////////////
            //MY CODE
            
if(convert_return==FIT_CONVERT_CONTINUE)
                
printf("FIT_CONVERT_CONTINUE %d\n",convert_return);
            else if(
convert_return==FIT_CONVERT_MESSAGE_AVAILABLE)
                
printf("FIT_CONVERT_MESSAGE_AVAILABLE %d\n",convert_return);
            else if(
convert_return==FIT_CONVERT_ERROR)
                
printf("FIT_CONVERT_ERROR %d\n",convert_return);
            else if(
convert_return==FIT_CONVERT_END_OF_FILE)
                
printf("FIT_CONVERT_END_OF_FILE %d\n",convert_return);
            else if(
convert_return==FIT_CONVERT_PROTOCOL_VERSION_NOT_SUPPORTED)
                
printf("FIT_CONVERT_PROTOCOL_VERSION_NOT_SUPPORTED %d\n",convert_return);
            else if(
convert_return==FIT_CONVERT_DATA_TYPE_NOT_SUPPORTED)
                
printf("FIT_CONVERT_DATA_TYPE_NOT_SUPPORTED %d\n",convert_return);
            else if(
convert_return==FIT_CONVERT_MESSAGE_NUMBER_FOUND)
                
printf("FIT_CONVERT_MESSAGE_NUMBER_FOUND %d\n",convert_return);
            else
                
printf("Unknown convert_return\n");
            
//MY CODE
            /////////////////////////////////////////////////

         
switch (convert_return)
         
{
            
case FIT_CONVERT_MESSAGE_AVAILABLE:
            


With these lines I want to see the convert_return value after each buffer read. The output of ./decode file.fit (the file is the same as the one I uploaded in my original message):

./decode file.fit 
Testing file conversion using file
.fit file...
FIT_CONVERT_CONTINUE 0
FIT_CONVERT_DATA_TYPE_NOT_SUPPORTED 5
File is not FIT


So the problem is FIT_CONVERT_DATA_TYPE_NOT_SUPPORTED. But I don't understand why because the file was generated by a Garmin Edge 500 and the FIT SDK is the latest 16.60.0 version.

In order to inspect a little deeper I've modified the fit_convert.c file disabling the FIT_CONVERT_DATA_TYPE_NOT_SUPPORTED commentind some lines:

if (state->mesg_offset >= state->u.file_hdr.header_size)
            
{
               state
->file_bytes_left = *((FIT_UINT8 *) &state;->u.file_hdr.data_size);
               
state->file_bytes_left |= (FIT_UINT32)*((FIT_UINT8 *) &state;->u.file_hdr.data_size 1) << 8;
               
state->file_bytes_left |= (FIT_UINT32)*((FIT_UINT8 *) &state;->u.file_hdr.data_size 2) << 16;
               
state->file_bytes_left |= (FIT_UINT32)*((FIT_UINT8 *) &state;->u.file_hdr.data_size 3) << 24;
               
state->file_bytes_left += 2// CRC.

//                #if defined(FIT_CONVERT_CHECK_FILE_HDR_DATA_TYPE)
//                   if (memcmp(state->u.file_hdr.data_type, ".FIT", 4) != 0)
//                      return FIT_CONVERT_DATA_TYPE_NOT_SUPPORTED;
//                #endif

               
if ((state->u.file_hdr.protocol_version FIT_PROTOCOL_VERSION_MAJOR_MASK) > (FIT_PROTOCOL_VERSION_MAJOR << FIT_PROTOCOL_VERSION_MAJOR_SHIFT))
                  return 
FIT_CONVERT_PROTOCOL_VERSION_NOT_SUPPORTED;

               
state->decode_state FIT_CONVERT_DECODE_RECORD;
            
}
            
break; 


************************************************
EDIT:

Obviously, there is no need of code commenting in file_convert.c. Only is necessary comment the
#define FIT_CONVERT_CHECK_FILE_HDR_DATA_TYPE in fit_config.h
************************************************

Then, I've created again the library as

for i in `ls *.c`; do gcc -c $idone
ar rcs libcfit
.*.


I've compiled again the original (without my control lines) decode.c and executed with my file.fit:

gcc -Idecode.-o decode -lcfit
./decode file.fit result.fit 


I attach the result.fit file. Apparently it works, but I don't understand the last line which says:

Restored num_sessions=Activitytimestamp=815917700type=0event=26event_type=1num_sessions=1
Unexpected end of file


Why unexpected end of file?

Anybody knows the reason of the FIT_CONVERT_DATA_TYPE_NOT_SUPPORTED with this file and SDK version? If commenting the exception raising in the fit_convert.c and apparently works, why the "unexpected en of file"?

Thanks      

File Attachments

Rank

Total Posts: 6

Joined 2016-03-21

PM

Finally I've solved the "Unexpected end of file" issue. The error comes from the fact that by default the data types int32_t, uint32_t etc. are explicitly defined in fit.h unless the #define FIT_USE_STDINT_H is uncommented in the fit_config.h. In 64 bits systems this fix is needed