Changing message definition length

Former Member
Former Member

Hi!
I am new to .fit file format and I have been working with FIT SDK for a few days. I am stuck when it comes to changing Definition Message and information what Data Messages are going to be send. After I sent Definition Message of type "record" I get the following results:

Definition,0,record,timestamp,1,,position_lat,1,,position_long,1,,distance,1,,time_from_course,1,,total_cycles,1,,accumulated_power,1,,enhanced_speed,1,,enhanced_altitude,1,,altitude,1,,speed,1,,power,1,,grade,1,,compressed_accumulated_power,1,,vertical_speed,1,,calories,1,,vertical_oscillation,1,,stance_time_percent,1,,stance_time,1,,ball_speed,1,,cadence256,1,,total_hemoglobin_conc,1,,total_hemoglobin_conc_min,1,,total_hemoglobin_conc_max,1,,saturated_hemoglobin_percent,1,,saturated_hemoglobin_percent_min,1,,saturated_hemoglobin_percent_max,1,,heart_rate,1,,cadence,1,,compressed_speed_distance,3,,resistance,1,,cycle_length,1,,temperature,1,,speed_1s,5,,cycles,1,,left_right_balance,1,,gps_accuracy,1,,activity_type,1,,left_torque_effectiveness,1,,right_torque_effectiveness,1,,left_pedal_smoothness,1,,right_pedal_smoothness,1,,combined_pedal_smoothness,1,,time128,1,,stroke_type,1,,zone,1,,fractional_cadence,1,,device_index,1,,

Problem is that I want to send Data Message that contains for example only distance, so Definition Message should look more like this:

Definition,0,record,distance,1,,,,,,,,,,,,,,,,

and Data Message:

Data,0,record,distance,"XXX",,,,,,,,,,,,,,,,

I've been analyzing .fit file exported from Strava and I see that it is possible - but is it possible with FIT SDK? I've been trying to change structures and enums related to this message type but with no success. 

Code I've been using:

       FIT_UINT8 local_mesg_number = 0;
       FIT_RECORD_MESG record_mesg;
       Fit_InitMesg(fit_mesg_defs[FIT_MESG_RECORD], &record_mesg);
       record_mesg.distance = 25;
       WriteMessageDefinition(local_mesg_number, fit_mesg_defs[FIT_MESG_RECORD], FIT_RECORD_MESG_DEF_SIZE, fp);
       WriteMessage(local_mesg_number, &record_mesg, FIT_RECORD_MESG_SIZE, fp);

  • Former Member
    0 Former Member

    Ok, so I guess there isn't really any implementation in SDK. Here is my example to change Definition Message on the fly.

    static const FIT_LENGTH_MESG_DEF_SELECTION record_mesg_def =
    {
       0, // reserved_1
       FIT_ARCH_ENDIAN, // arch
       FIT_MESG_NUM_RECORD, // global_mesg_num
    };
    
    // Write Record
    {
        FIT_UINT8 messages_to_send[mesg_cnt + mesg_to_send * field_def_size_bytes] =
        {
             5, //number of messages
             FIT_RECORD_FIELD_NUM_TIMESTAMP, (sizeof(FIT_DATE_TIME) * 1), FIT_BASE_TYPE_UINT32,
             FIT_RECORD_FIELD_NUM_POSITION_LAT, (sizeof(FIT_SINT32) * 1), FIT_BASE_TYPE_SINT32,
             FIT_RECORD_FIELD_NUM_DISTANCE, (sizeof(FIT_UINT32) * 1), FIT_BASE_TYPE_UINT32,
             FIT_RECORD_FIELD_NUM_TOTAL_CYCLES, (sizeof(FIT_UINT32) * 1), FIT_BASE_TYPE_UINT32,
             FIT_RECORD_FIELD_NUM_ENHANCED_SPEED, (sizeof(FIT_UINT32) * 1), FIT_BASE_TYPE_UINT32,
        };
        FIT_UINT8 local_mesg_number = 0;
        WriteMessageDefinitionSelection(local_mesg_number, fit_mesg_defs[FIT_MESG_RECORD], messages_to_send, sizeof(messages_to_send), fp);
        ...
        ...
        ...
    }
        
    void WriteMessageDefinitionSelection(FIT_UINT8 local_mesg_number, const void* mesg_def_pointer, FIT_UINT8 *mesg_def_selection, FIT_UINT16 size, FILE* fp)
    {
        /*Write header*/
        FIT_UINT8 header = local_mesg_number | FIT_HDR_TYPE_DEF_BIT;
        WriteData(&header, FIT_HDR_SIZE, fp);
        /*Write 4 bytes of record content*/
        WriteData(mesg_def_pointer, 4, fp);
    
        /*Write number of messages and Field Definitions */
        WriteData(mesg_def_selection, size, fp);
    
    }

  • The Java, C#, and C++ SDKs will generate the message definitions on the fly based on the valid data in the message. But the C SDK does not do that. 

    Something that can be done at compile time is to create alternative message definitions. You can remove fields that your app does not use, or you can create multiple versions of a message that support your most common use cases. This works well if you can define the requirements up front. 
     
    Look at the Alternate Message Configurations section on this page. I suggest reading the entire doc for context.
    developer.garmin.com/.../