rubyfit 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/ext/rubyfit/extconf.rb +2 -0
- data/ext/rubyfit/fit.c +281 -0
- data/ext/rubyfit/fit.h +253 -0
- data/ext/rubyfit/fit_config.h +36 -0
- data/ext/rubyfit/fit_convert.c +439 -0
- data/ext/rubyfit/fit_convert.h +154 -0
- data/ext/rubyfit/fit_crc.c +43 -0
- data/ext/rubyfit/fit_crc.h +35 -0
- data/ext/rubyfit/fit_product.c +21 -0
- data/ext/rubyfit/fit_product.h +21 -0
- data/ext/rubyfit/fit_sdk.c +618 -0
- data/ext/rubyfit/fit_sdk.h +2083 -0
- data/ext/rubyfit/rubyfit.c +590 -0
- data/lib/rubyfit/version.rb +3 -0
- data/lib/rubyfit.rb +2 -0
- metadata +63 -0
data/ext/rubyfit/fit.c
ADDED
@@ -0,0 +1,281 @@
|
|
1
|
+
////////////////////////////////////////////////////////////////////////////////
|
2
|
+
// The following .FIT software provided may be used with .FIT devices only and
|
3
|
+
// remains the copyrighted property of Dynastream Innovations Inc.
|
4
|
+
// The software is being provided on an "as-is" basis and as an accommodation,
|
5
|
+
// and therefore all warranties, representations, or guarantees of any kind
|
6
|
+
// (whether express, implied or statutory) including, without limitation,
|
7
|
+
// warranties of merchantability, non-infringement, or fitness for a particular
|
8
|
+
// purpose, are specifically disclaimed.
|
9
|
+
//
|
10
|
+
// Copyright 2008 Dynastream Innovations Inc.
|
11
|
+
// All rights reserved. This software may not be reproduced by any means
|
12
|
+
// without express written approval of Dynastream Innovations Inc.
|
13
|
+
////////////////////////////////////////////////////////////////////////////////
|
14
|
+
|
15
|
+
#include "string.h"
|
16
|
+
#include "fit_product.h"
|
17
|
+
|
18
|
+
|
19
|
+
///////////////////////////////////////////////////////////////////////
|
20
|
+
// Public Constants
|
21
|
+
///////////////////////////////////////////////////////////////////////
|
22
|
+
|
23
|
+
const FIT_UINT8 fit_base_type_sizes[FIT_BASE_TYPES] =
|
24
|
+
{
|
25
|
+
sizeof(FIT_ENUM),
|
26
|
+
sizeof(FIT_SINT8),
|
27
|
+
sizeof(FIT_UINT8),
|
28
|
+
sizeof(FIT_SINT16),
|
29
|
+
sizeof(FIT_UINT16),
|
30
|
+
sizeof(FIT_SINT32),
|
31
|
+
sizeof(FIT_UINT32),
|
32
|
+
sizeof(FIT_STRING),
|
33
|
+
sizeof(FIT_FLOAT32),
|
34
|
+
sizeof(FIT_FLOAT64),
|
35
|
+
sizeof(FIT_UINT8Z),
|
36
|
+
sizeof(FIT_UINT16Z),
|
37
|
+
sizeof(FIT_UINT32Z),
|
38
|
+
sizeof(FIT_BYTE),
|
39
|
+
};
|
40
|
+
|
41
|
+
const FIT_ENUM fit_enum_invalid = FIT_ENUM_INVALID;
|
42
|
+
const FIT_SINT8 fit_sint8_invalid = FIT_SINT8_INVALID;
|
43
|
+
const FIT_UINT8 fit_uint8_invalid = FIT_UINT8_INVALID;
|
44
|
+
const FIT_SINT16 fit_sint16_invalid = FIT_SINT16_INVALID;
|
45
|
+
const FIT_UINT16 fit_uint16_invalid = FIT_UINT16_INVALID;
|
46
|
+
const FIT_SINT32 fit_sint32_invalid = FIT_SINT32_INVALID;
|
47
|
+
const FIT_UINT32 fit_uint32_invalid = FIT_UINT32_INVALID;
|
48
|
+
const FIT_STRING fit_string_invalid = FIT_STRING_INVALID;
|
49
|
+
const FIT_FLOAT32 fit_float32_invalid = FIT_FLOAT32_INVALID;
|
50
|
+
const FIT_FLOAT64 fit_float64_invalid = FIT_FLOAT64_INVALID;
|
51
|
+
const FIT_UINT8Z fit_uint8z_invalid = FIT_UINT8Z_INVALID;
|
52
|
+
const FIT_UINT16Z fit_uint16z_invalid = FIT_UINT16Z_INVALID;
|
53
|
+
const FIT_UINT32Z fit_uint32z_invalid = FIT_UINT32Z_INVALID;
|
54
|
+
const FIT_BYTE fit_byte_invalid = FIT_BYTE_INVALID;
|
55
|
+
|
56
|
+
const FIT_UINT8 *fit_base_type_invalids[FIT_BASE_TYPES] =
|
57
|
+
{
|
58
|
+
(FIT_UINT8 *)&fit_enum_invalid,
|
59
|
+
(FIT_UINT8 *)&fit_sint8_invalid,
|
60
|
+
(FIT_UINT8 *)&fit_uint8_invalid,
|
61
|
+
(FIT_UINT8 *)&fit_sint16_invalid,
|
62
|
+
(FIT_UINT8 *)&fit_uint16_invalid,
|
63
|
+
(FIT_UINT8 *)&fit_sint32_invalid,
|
64
|
+
(FIT_UINT8 *)&fit_uint32_invalid,
|
65
|
+
(FIT_UINT8 *)&fit_string_invalid,
|
66
|
+
(FIT_UINT8 *)&fit_float32_invalid,
|
67
|
+
(FIT_UINT8 *)&fit_float64_invalid,
|
68
|
+
(FIT_UINT8 *)&fit_uint8z_invalid,
|
69
|
+
(FIT_UINT8 *)&fit_uint16z_invalid,
|
70
|
+
(FIT_UINT8 *)&fit_uint32z_invalid,
|
71
|
+
(FIT_UINT8 *)&fit_byte_invalid,
|
72
|
+
};
|
73
|
+
|
74
|
+
|
75
|
+
///////////////////////////////////////////////////////////////////////
|
76
|
+
// Public Functions
|
77
|
+
///////////////////////////////////////////////////////////////////////
|
78
|
+
|
79
|
+
FIT_UINT8 Fit_GetArch(void)
|
80
|
+
{
|
81
|
+
const FIT_UINT16 arch = 0x0100;
|
82
|
+
return (*(FIT_UINT8 *)&arch);
|
83
|
+
}
|
84
|
+
|
85
|
+
const FIT_MESG_DEF *Fit_GetMesgDef(FIT_MESG_NUM global_mesg_num)
|
86
|
+
{
|
87
|
+
FIT_UINT8 index;
|
88
|
+
|
89
|
+
for (index = 0; index < FIT_MESGS; index++)
|
90
|
+
{
|
91
|
+
if (fit_mesg_defs[index]->global_mesg_num == global_mesg_num)
|
92
|
+
return (FIT_MESG_DEF *) fit_mesg_defs[index];
|
93
|
+
}
|
94
|
+
|
95
|
+
return (FIT_MESG_DEF *) FIT_NULL;
|
96
|
+
}
|
97
|
+
|
98
|
+
FIT_UINT16 Fit_GetMesgDefSize(const FIT_MESG_DEF *mesg_def)
|
99
|
+
{
|
100
|
+
if (mesg_def == FIT_NULL)
|
101
|
+
return 0;
|
102
|
+
|
103
|
+
return FIT_STRUCT_OFFSET(fields, FIT_MESG_DEF) + (FIT_UINT16)mesg_def->num_fields * FIT_FIELD_DEF_SIZE;
|
104
|
+
}
|
105
|
+
|
106
|
+
FIT_UINT8 Fit_GetMesgSize(FIT_MESG_NUM global_mesg_num)
|
107
|
+
{
|
108
|
+
const FIT_MESG_DEF *mesg_def;
|
109
|
+
FIT_UINT8 field;
|
110
|
+
FIT_UINT8 size = 0;
|
111
|
+
|
112
|
+
mesg_def = Fit_GetMesgDef(global_mesg_num);
|
113
|
+
|
114
|
+
if (mesg_def == FIT_NULL)
|
115
|
+
return 0;
|
116
|
+
|
117
|
+
for (field = 0; field < mesg_def->num_fields; field++)
|
118
|
+
{
|
119
|
+
size += mesg_def->fields[FIT_MESG_DEF_FIELD_OFFSET(size, field)];
|
120
|
+
}
|
121
|
+
|
122
|
+
return size;
|
123
|
+
}
|
124
|
+
|
125
|
+
FIT_BOOL Fit_InitMesg(const FIT_MESG_DEF *mesg_def, void *mesg)
|
126
|
+
{
|
127
|
+
FIT_UINT8 *mesg_buf = (FIT_UINT8 *) mesg;
|
128
|
+
FIT_UINT8 field;
|
129
|
+
|
130
|
+
if (mesg_def == FIT_NULL)
|
131
|
+
return FIT_FALSE;
|
132
|
+
|
133
|
+
for (field = 0; field < mesg_def->num_fields; field++)
|
134
|
+
{
|
135
|
+
FIT_UINT8 base_type_num = mesg_def->fields[FIT_MESG_DEF_FIELD_OFFSET(base_type, field)] & FIT_BASE_TYPE_NUM_MASK;
|
136
|
+
FIT_UINT8 base_type_size;
|
137
|
+
FIT_UINT8 field_size;
|
138
|
+
|
139
|
+
if (base_type_num >= FIT_BASE_TYPES)
|
140
|
+
return FIT_FALSE;
|
141
|
+
|
142
|
+
base_type_size = fit_base_type_sizes[base_type_num];
|
143
|
+
|
144
|
+
for (field_size = 0; field_size < mesg_def->fields[FIT_MESG_DEF_FIELD_OFFSET(size, field)]; field_size += base_type_size)
|
145
|
+
{
|
146
|
+
memcpy(mesg_buf, fit_base_type_invalids[base_type_num], base_type_size);
|
147
|
+
mesg_buf += base_type_size;
|
148
|
+
}
|
149
|
+
}
|
150
|
+
|
151
|
+
return FIT_TRUE;
|
152
|
+
}
|
153
|
+
|
154
|
+
FIT_UINT8 Fit_GetFieldOffset(const FIT_MESG_DEF *mesg_def, FIT_UINT8 field_def_num)
|
155
|
+
{
|
156
|
+
FIT_UINT8 offset = 0;
|
157
|
+
FIT_UINT8 field;
|
158
|
+
|
159
|
+
if (mesg_def == FIT_NULL)
|
160
|
+
return FIT_UINT8_INVALID;
|
161
|
+
|
162
|
+
for (field = 0; field < mesg_def->num_fields; field++)
|
163
|
+
{
|
164
|
+
if (mesg_def->fields[FIT_MESG_DEF_FIELD_OFFSET(field_def_num, field)] == field_def_num)
|
165
|
+
return offset;
|
166
|
+
|
167
|
+
offset += mesg_def->fields[FIT_MESG_DEF_FIELD_OFFSET(size, field)];
|
168
|
+
}
|
169
|
+
|
170
|
+
return FIT_UINT8_INVALID;
|
171
|
+
}
|
172
|
+
|
173
|
+
FIT_UINT8 Fit_LookupMessage(FIT_UINT16 global_mesg_num, FIT_UINT16 message_index, FIT_UINT32 *offset, FIT_READ_BYTES_FUNC read_bytes_func)
|
174
|
+
{
|
175
|
+
FIT_UINT16 global_mesg_nums[FIT_MAX_LOCAL_MESGS];
|
176
|
+
FIT_UINT8 sizes[FIT_MAX_LOCAL_MESGS];
|
177
|
+
FIT_UINT16 current_message_index = FIT_UINT16_INVALID;
|
178
|
+
#if defined(FIT_MESSAGE_INDEX)
|
179
|
+
FIT_UINT16 message_index_offset = FIT_UINT16_INVALID;
|
180
|
+
#endif
|
181
|
+
FIT_UINT8 i;
|
182
|
+
|
183
|
+
*offset = 0;
|
184
|
+
|
185
|
+
for (i = 0; i < FIT_MAX_LOCAL_MESGS; i++)
|
186
|
+
global_mesg_nums[i] = FIT_UINT16_INVALID;
|
187
|
+
|
188
|
+
while (1)
|
189
|
+
{
|
190
|
+
FIT_UINT8 header;
|
191
|
+
FIT_UINT8 local_mesg_num;
|
192
|
+
|
193
|
+
if (read_bytes_func(&header, *offset, sizeof(header)) != sizeof(header))
|
194
|
+
return FIT_UINT8_INVALID;
|
195
|
+
|
196
|
+
*offset += sizeof(header);
|
197
|
+
|
198
|
+
if ((header & (FIT_HDR_TIME_REC_BIT | FIT_HDR_TYPE_DEF_BIT)) == FIT_HDR_TYPE_DEF_BIT)
|
199
|
+
{
|
200
|
+
FIT_MESG_DEF mesg_def_header;
|
201
|
+
FIT_FIELD_DEF field_def;
|
202
|
+
#if defined(FIT_MESSAGE_INDEX)
|
203
|
+
FIT_UINT16 current_message_index_offset = FIT_UINT16_INVALID; // Initialize to invalid. If not found, it will remain invalid.
|
204
|
+
#endif
|
205
|
+
FIT_UINT8 current_size;
|
206
|
+
FIT_UINT8 current_field_def;
|
207
|
+
|
208
|
+
local_mesg_num = header & FIT_HDR_TYPE_MASK;
|
209
|
+
|
210
|
+
if (read_bytes_func(&mesg_def_header, *offset, FIT_MESG_DEF_HEADER_SIZE) != FIT_MESG_DEF_HEADER_SIZE)
|
211
|
+
return FIT_UINT8_INVALID;
|
212
|
+
|
213
|
+
*offset += FIT_MESG_DEF_HEADER_SIZE;
|
214
|
+
global_mesg_nums[local_mesg_num] = mesg_def_header.global_mesg_num;
|
215
|
+
current_size = 0;
|
216
|
+
|
217
|
+
for (current_field_def = 0; current_field_def < mesg_def_header.num_fields; current_field_def++)
|
218
|
+
{
|
219
|
+
if (read_bytes_func(&field_def, *offset, FIT_FIELD_DEF_SIZE) != FIT_FIELD_DEF_SIZE)
|
220
|
+
return FIT_UINT8_INVALID;
|
221
|
+
|
222
|
+
#if defined(FIT_MESSAGE_INDEX)
|
223
|
+
if (field_def.field_def_num == FIT_MESSAGE_INDEX_FIELD_NUM)
|
224
|
+
current_message_index_offset = current_size;
|
225
|
+
#endif
|
226
|
+
|
227
|
+
current_size += field_def.size;
|
228
|
+
*offset += FIT_FIELD_DEF_SIZE;
|
229
|
+
}
|
230
|
+
|
231
|
+
sizes[local_mesg_num] = current_size;
|
232
|
+
|
233
|
+
#if defined(FIT_MESSAGE_INDEX)
|
234
|
+
if (global_mesg_nums[local_mesg_num] == global_mesg_num)
|
235
|
+
message_index_offset = current_message_index_offset;
|
236
|
+
#endif
|
237
|
+
}
|
238
|
+
else
|
239
|
+
{
|
240
|
+
if (header & FIT_HDR_TIME_REC_BIT)
|
241
|
+
local_mesg_num = (header & FIT_HDR_TIME_TYPE_MASK) >> FIT_HDR_TIME_TYPE_SHIFT;
|
242
|
+
else
|
243
|
+
local_mesg_num = header & FIT_HDR_TYPE_MASK;
|
244
|
+
|
245
|
+
if (global_mesg_nums[local_mesg_num] == global_mesg_num)
|
246
|
+
{
|
247
|
+
// If the requested message index is invalid, we've found a match.
|
248
|
+
if (message_index == FIT_UINT16_INVALID)
|
249
|
+
return local_mesg_num;
|
250
|
+
|
251
|
+
#if defined(FIT_MESSAGE_INDEX)
|
252
|
+
if (message_index_offset != FIT_UINT16_INVALID)
|
253
|
+
{
|
254
|
+
// Read the message index.
|
255
|
+
if (read_bytes_func(¤t_message_index, *offset + message_index_offset, sizeof(current_message_index)) != sizeof(current_message_index))
|
256
|
+
return FIT_UINT8_INVALID;
|
257
|
+
}
|
258
|
+
else
|
259
|
+
#endif
|
260
|
+
{
|
261
|
+
current_message_index++;
|
262
|
+
}
|
263
|
+
|
264
|
+
#if defined(FIT_MESSAGE_INDEX)
|
265
|
+
if ((message_index & FIT_MESSAGE_INDEX_MASK) == (current_message_index & FIT_MESSAGE_INDEX_MASK))
|
266
|
+
#else
|
267
|
+
if (message_index == current_message_index)
|
268
|
+
#endif
|
269
|
+
{
|
270
|
+
return local_mesg_num;
|
271
|
+
}
|
272
|
+
}
|
273
|
+
else if (global_mesg_nums[local_mesg_num] == FIT_UINT16_INVALID)
|
274
|
+
{
|
275
|
+
return FIT_UINT8_INVALID;
|
276
|
+
}
|
277
|
+
|
278
|
+
*offset += sizes[local_mesg_num];
|
279
|
+
}
|
280
|
+
}
|
281
|
+
}
|
data/ext/rubyfit/fit.h
ADDED
@@ -0,0 +1,253 @@
|
|
1
|
+
////////////////////////////////////////////////////////////////////////////////
|
2
|
+
// The following .FIT software provided may be used with .FIT devices only and
|
3
|
+
// remains the copyrighted property of Dynastream Innovations Inc.
|
4
|
+
// The software is being provided on an "as-is" basis and as an accommodation,
|
5
|
+
// and therefore all warranties, representations, or guarantees of any kind
|
6
|
+
// (whether express, implied or statutory) including, without limitation,
|
7
|
+
// warranties of merchantability, non-infringement, or fitness for a particular
|
8
|
+
// purpose, are specifically disclaimed.
|
9
|
+
//
|
10
|
+
// Copyright 2008 Dynastream Innovations Inc.
|
11
|
+
// All rights reserved. This software may not be reproduced by any means
|
12
|
+
// without express written approval of Dynastream Innovations Inc.
|
13
|
+
////////////////////////////////////////////////////////////////////////////////
|
14
|
+
|
15
|
+
|
16
|
+
#if !defined(FIT_H)
|
17
|
+
#define FIT_H
|
18
|
+
|
19
|
+
#include "fit_config.h"
|
20
|
+
|
21
|
+
#if defined(__cplusplus)
|
22
|
+
extern "C" {
|
23
|
+
#endif
|
24
|
+
|
25
|
+
|
26
|
+
///////////////////////////////////////////////////////////////////////
|
27
|
+
// Version
|
28
|
+
///////////////////////////////////////////////////////////////////////
|
29
|
+
|
30
|
+
#define FIT_PROTOCOL_VERSION_MAJOR 1 // Non-backwards compatible changes. Decode compatible with this version and earlier.
|
31
|
+
#define FIT_PROTOCOL_VERSION_MINOR 0 // Backwards compatible changes.
|
32
|
+
#define FIT_PROTOCOL_VERSION_MAJOR_SHIFT 4
|
33
|
+
#define FIT_PROTOCOL_VERSION_MAJOR_MASK ((FIT_UINT8) (0x0F << FIT_PROTOCOL_VERSION_MAJOR_SHIFT))
|
34
|
+
#define FIT_PROTOCOL_VERSION_MINOR_MASK ((FIT_UINT8) 0x0F)
|
35
|
+
#define FIT_PROTOCOL_VERSION ((FIT_UINT8) (FIT_PROTOCOL_VERSION_MAJOR << FIT_PROTOCOL_VERSION_MAJOR_SHIFT) | FIT_PROTOCOL_VERSION_MINOR)
|
36
|
+
|
37
|
+
|
38
|
+
///////////////////////////////////////////////////////////////////////
|
39
|
+
// Type Definitions
|
40
|
+
///////////////////////////////////////////////////////////////////////
|
41
|
+
|
42
|
+
#define FIT_ANTFS_FILE_DATA_TYPE 128
|
43
|
+
|
44
|
+
#define FIT_BASE_TYPE_ENDIAN_FLAG ((FIT_UINT8)0x80)
|
45
|
+
#define FIT_BASE_TYPE_RESERVED ((FIT_UINT8)0x60)
|
46
|
+
#define FIT_BASE_TYPE_NUM_MASK ((FIT_UINT8)0x1F)
|
47
|
+
|
48
|
+
typedef unsigned char FIT_ENUM;
|
49
|
+
#define FIT_ENUM_INVALID ((FIT_ENUM)0xFF)
|
50
|
+
#define FIT_BASE_TYPE_ENUM ((FIT_UINT8)0x00)
|
51
|
+
|
52
|
+
typedef signed char FIT_SINT8;
|
53
|
+
#define FIT_SINT8_INVALID ((FIT_SINT8)0x7F)
|
54
|
+
#define FIT_BASE_TYPE_SINT8 ((FIT_UINT8)0x01)
|
55
|
+
|
56
|
+
typedef unsigned char FIT_UINT8;
|
57
|
+
#define FIT_UINT8_INVALID ((FIT_UINT8)0xFF)
|
58
|
+
#define FIT_BASE_TYPE_UINT8 ((FIT_UINT8)0x02)
|
59
|
+
|
60
|
+
typedef signed short FIT_SINT16;
|
61
|
+
#define FIT_SINT16_INVALID ((FIT_SINT16)0x7FFF)
|
62
|
+
#define FIT_BASE_TYPE_SINT16 ((FIT_UINT8)0x83)
|
63
|
+
|
64
|
+
typedef unsigned short FIT_UINT16;
|
65
|
+
#define FIT_UINT16_INVALID ((FIT_UINT16)0xFFFF)
|
66
|
+
#define FIT_BASE_TYPE_UINT16 ((FIT_UINT8)0x84)
|
67
|
+
|
68
|
+
typedef signed long FIT_SINT32;
|
69
|
+
#define FIT_SINT32_INVALID ((FIT_SINT32)0x7FFFFFFF)
|
70
|
+
#define FIT_BASE_TYPE_SINT32 ((FIT_UINT8)0x85)
|
71
|
+
|
72
|
+
typedef unsigned long FIT_UINT32;
|
73
|
+
#define FIT_UINT32_INVALID ((FIT_UINT32)0xFFFFFFFF)
|
74
|
+
#define FIT_BASE_TYPE_UINT32 ((FIT_UINT8)0x86)
|
75
|
+
|
76
|
+
typedef char FIT_STRING;
|
77
|
+
#define FIT_STRING_INVALID ((FIT_STRING)0x00)
|
78
|
+
#define FIT_BASE_TYPE_STRING ((FIT_UINT8)0x07)
|
79
|
+
|
80
|
+
typedef float FIT_FLOAT32;
|
81
|
+
#define FIT_FLOAT32_INVALID ((FIT_FLOAT32)0xFFFFFFFF)
|
82
|
+
#define FIT_BASE_TYPE_FLOAT32 ((FIT_UINT8)0x88)
|
83
|
+
|
84
|
+
typedef double FIT_FLOAT64;
|
85
|
+
#define FIT_FLOAT64_INVALID ((FIT_FLOAT64)0xFFFFFFFFFFFFFFFFull)
|
86
|
+
#define FIT_BASE_TYPE_FLOAT64 ((FIT_UINT8)0x89)
|
87
|
+
|
88
|
+
typedef unsigned char FIT_UINT8Z;
|
89
|
+
#define FIT_UINT8Z_INVALID ((FIT_UINT8Z)0x00)
|
90
|
+
#define FIT_BASE_TYPE_UINT8Z ((FIT_UINT8)0x0A)
|
91
|
+
|
92
|
+
typedef unsigned short FIT_UINT16Z;
|
93
|
+
#define FIT_UINT16Z_INVALID ((FIT_UINT16Z)0x0000)
|
94
|
+
#define FIT_BASE_TYPE_UINT16Z ((FIT_UINT8)0x8B)
|
95
|
+
|
96
|
+
typedef unsigned long FIT_UINT32Z;
|
97
|
+
#define FIT_UINT32Z_INVALID ((FIT_UINT32Z)0x00000000)
|
98
|
+
#define FIT_BASE_TYPE_UINT32Z ((FIT_UINT8)0x8C)
|
99
|
+
|
100
|
+
typedef unsigned char FIT_BYTE;
|
101
|
+
#define FIT_BYTE_INVALID ((FIT_BYTE)0xFF)
|
102
|
+
#define FIT_BASE_TYPE_BYTE ((FIT_UINT8)0x0D)
|
103
|
+
|
104
|
+
#define FIT_BASE_TYPES 14
|
105
|
+
|
106
|
+
typedef FIT_ENUM FIT_BOOL;
|
107
|
+
#define FIT_BOOL_INVALID FIT_ENUM_INVALID
|
108
|
+
#define FIT_BOOL_FALSE ((FIT_BOOL)0)
|
109
|
+
#define FIT_BOOL_TRUE ((FIT_BOOL)1)
|
110
|
+
#define FIT_FALSE FIT_BOOL_FALSE
|
111
|
+
#define FIT_TRUE FIT_BOOL_TRUE
|
112
|
+
#define FIT_NULL ((void *) 0)
|
113
|
+
|
114
|
+
typedef FIT_UINT32 (*FIT_READ_BYTES_FUNC)(void *, FIT_UINT32, FIT_UINT32);
|
115
|
+
#define FIT_MESG_DEF_HEADER_SIZE FIT_STRUCT_OFFSET(fields, FIT_MESG_DEF)
|
116
|
+
|
117
|
+
|
118
|
+
///////////////////////////////////////////////////////////////////////
|
119
|
+
// File Header
|
120
|
+
///////////////////////////////////////////////////////////////////////
|
121
|
+
|
122
|
+
typedef struct
|
123
|
+
{
|
124
|
+
FIT_UINT8 header_size; // FIT_FILE_HDR_SIZE (size of this structure)
|
125
|
+
FIT_UINT8 protocol_version; // FIT_PROTOCOL_VERSION
|
126
|
+
FIT_UINT8 profile_version_minor; // FIT_PROFILE_VERSION_MINOR
|
127
|
+
FIT_UINT8 profile_version_major; // FIT_PROFILE_VERSION_MAJOR
|
128
|
+
FIT_UINT32 data_size; // Does not include file header or crc. Little endian format.
|
129
|
+
FIT_UINT8 data_type[4]; // ".FIT"
|
130
|
+
} FIT_FILE_HDR;
|
131
|
+
|
132
|
+
#define FIT_FILE_HDR_SIZE 12
|
133
|
+
|
134
|
+
///////////////////////////////////////////////////////////////////////
|
135
|
+
// Record Definitions
|
136
|
+
///////////////////////////////////////////////////////////////////////
|
137
|
+
|
138
|
+
#define FIT_HDR_SIZE 1
|
139
|
+
#define FIT_HDR_TIME_REC_BIT ((FIT_UINT8) 0x80)
|
140
|
+
#define FIT_HDR_TIME_TYPE_MASK ((FIT_UINT8) 0x60)
|
141
|
+
#define FIT_HDR_TIME_TYPE_SHIFT 5
|
142
|
+
#define FIT_HDR_TIME_OFFSET_MASK ((FIT_UINT8) 0x1F)
|
143
|
+
#define FIT_HDR_TYPE_DEF_BIT ((FIT_UINT8) 0x40)
|
144
|
+
#define FIT_HDR_TYPE_MASK ((FIT_UINT8) 0x0F)
|
145
|
+
#define FIT_MAX_LOCAL_MESGS (FIT_HDR_TYPE_MASK + 1)
|
146
|
+
|
147
|
+
|
148
|
+
///////////////////////////////////////////////////////////////////////
|
149
|
+
// Message Definitions
|
150
|
+
///////////////////////////////////////////////////////////////////////
|
151
|
+
|
152
|
+
typedef struct
|
153
|
+
{
|
154
|
+
FIT_UINT8 field_def_num;
|
155
|
+
FIT_UINT8 size;
|
156
|
+
FIT_UINT8 base_type;
|
157
|
+
} FIT_FIELD_DEF;
|
158
|
+
|
159
|
+
#define FIT_FIELD_DEF_SIZE 3
|
160
|
+
|
161
|
+
typedef struct
|
162
|
+
{
|
163
|
+
FIT_UINT8 reserved_1;
|
164
|
+
FIT_UINT8 arch;
|
165
|
+
FIT_UINT16 global_mesg_num;
|
166
|
+
FIT_UINT8 num_fields;
|
167
|
+
FIT_UINT8 fields[1];
|
168
|
+
} FIT_MESG_DEF;
|
169
|
+
|
170
|
+
#define FIT_MAX_MESG_SIZE ((FIT_UINT8)255)
|
171
|
+
|
172
|
+
#define FIT_ARCH_ENDIAN_MASK ((FIT_UINT8)0x01)
|
173
|
+
#define FIT_ARCH_ENDIAN_LITTLE ((FIT_UINT8)0)
|
174
|
+
#define FIT_ARCH_ENDIAN_BIG ((FIT_UINT8)1)
|
175
|
+
|
176
|
+
|
177
|
+
///////////////////////////////////////////////////////////////////////
|
178
|
+
// Field Definitions
|
179
|
+
///////////////////////////////////////////////////////////////////////
|
180
|
+
|
181
|
+
#define FIT_MAX_FIELD_SIZE ((FIT_UINT8)255)
|
182
|
+
#define FIT_FIELD_NUM_INVALID ((FIT_UINT8)0xFF)
|
183
|
+
#define FIT_MESSAGE_INDEX_FIELD_NUM ((FIT_UINT8)254)
|
184
|
+
#define FIT_TIMESTAMP_FIELD_NUM ((FIT_UINT8)253)
|
185
|
+
|
186
|
+
|
187
|
+
///////////////////////////////////////////////////////////////////////
|
188
|
+
// Macros
|
189
|
+
///////////////////////////////////////////////////////////////////////
|
190
|
+
|
191
|
+
#define FIT_STRUCT_OFFSET(MEMBER, STRUCT_TYPE) ( ((FIT_UINT8 *) &(((STRUCT_TYPE *) FIT_NULL)->MEMBER)) - ((FIT_UINT8 *) (FIT_NULL)) ) // Computes the byte offset of a member in a file. Compiles to a constant.
|
192
|
+
#define FIT_MESG_OFFSET(MESG_MEMBER, MESG_TYPE, MESG_INDEX, MESG_SIZE, FILE) (FIT_STRUCT_OFFSET(MESG_MEMBER, FILE) + MESG_INDEX * (FIT_HDR_SIZE + MESG_SIZE) + FIT_HDR_SIZE) // Computes the byte offset of a message in a file structure. Compiles to a constant.
|
193
|
+
#define FIT_MESG_DEF_OFFSET(MESG_DEF_MEMBER, FILE) (FIT_STRUCT_OFFSET(MESG_DEF_MEMBER, FILE) + FIT_HDR_SIZE) // Computes the byte offset of a message definition in a file structure. Compiles to a constant.
|
194
|
+
#define FIT_MESG_DEF_FIELD_OFFSET(FIELD_MEMBER, FIELD_INDEX) (FIT_STRUCT_OFFSET(FIELD_MEMBER, FIT_FIELD_DEF) + FIT_FIELD_DEF_SIZE * FIELD_INDEX) // Computes the byte offset of a field definition member. Compiles to a constant.
|
195
|
+
|
196
|
+
|
197
|
+
///////////////////////////////////////////////////////////////////////
|
198
|
+
// Public Constants
|
199
|
+
///////////////////////////////////////////////////////////////////////
|
200
|
+
|
201
|
+
const extern FIT_UINT8 fit_base_type_sizes[FIT_BASE_TYPES];
|
202
|
+
const extern FIT_UINT8 *fit_base_type_invalids[FIT_BASE_TYPES];
|
203
|
+
|
204
|
+
|
205
|
+
///////////////////////////////////////////////////////////////////////
|
206
|
+
// Public Functions
|
207
|
+
///////////////////////////////////////////////////////////////////////
|
208
|
+
|
209
|
+
FIT_UINT8 Fit_GetArch(void);
|
210
|
+
///////////////////////////////////////////////////////////////////////
|
211
|
+
// Returns architecture type.
|
212
|
+
// Includes runtime check for little or big endian.
|
213
|
+
// See FIT_MESG_DEF->arch and FIT_ARCH_*.
|
214
|
+
///////////////////////////////////////////////////////////////////////
|
215
|
+
|
216
|
+
const FIT_MESG_DEF *Fit_GetMesgDef(FIT_UINT16 global_mesg_num);
|
217
|
+
///////////////////////////////////////////////////////////////////////
|
218
|
+
// Returns message definition corresponding to global message number.
|
219
|
+
///////////////////////////////////////////////////////////////////////
|
220
|
+
|
221
|
+
FIT_UINT16 Fit_GetMesgDefSize(const FIT_MESG_DEF *mesg_def);
|
222
|
+
///////////////////////////////////////////////////////////////////////
|
223
|
+
// Returns the size of message definition.
|
224
|
+
///////////////////////////////////////////////////////////////////////
|
225
|
+
|
226
|
+
FIT_UINT8 Fit_GetMesgSize(FIT_UINT16 global_mesg_num);
|
227
|
+
///////////////////////////////////////////////////////////////////////
|
228
|
+
// Returns the size of message corresponding to global message number.
|
229
|
+
///////////////////////////////////////////////////////////////////////
|
230
|
+
|
231
|
+
FIT_BOOL Fit_InitMesg(const FIT_MESG_DEF *mesg_def, void *mesg);
|
232
|
+
///////////////////////////////////////////////////////////////////////
|
233
|
+
// Initializes message with invalids.
|
234
|
+
// Returns 1 if successful, otherwise 0.
|
235
|
+
///////////////////////////////////////////////////////////////////////
|
236
|
+
|
237
|
+
FIT_UINT8 Fit_GetFieldOffset(const FIT_MESG_DEF *mesg_def, FIT_UINT8 field_def_num);
|
238
|
+
///////////////////////////////////////////////////////////////////////
|
239
|
+
// Returns the byte offset of a field in a message.
|
240
|
+
///////////////////////////////////////////////////////////////////////
|
241
|
+
|
242
|
+
FIT_UINT8 Fit_LookupMessage(FIT_UINT16 global_mesg_num, FIT_UINT16 message_index, FIT_UINT32 *offset, FIT_READ_BYTES_FUNC read_bytes_func);
|
243
|
+
///////////////////////////////////////////////////////////////////////
|
244
|
+
// Finds the byte offset of a message with the given message index in a .FIT file
|
245
|
+
// Requires a pointer to a function which can read a given number of bytes from a provided offset in a .FIT file.
|
246
|
+
// Returns the local message number if successful, or FIT_UINT8 if unsuccessful.
|
247
|
+
///////////////////////////////////////////////////////////////////////
|
248
|
+
|
249
|
+
#if defined(__cplusplus)
|
250
|
+
}
|
251
|
+
#endif
|
252
|
+
|
253
|
+
#endif // !defined(FIT_H)
|
@@ -0,0 +1,36 @@
|
|
1
|
+
////////////////////////////////////////////////////////////////////////////////
|
2
|
+
// The following .FIT software provided may be used with .FIT devices only and
|
3
|
+
// remains the copyrighted property of Dynastream Innovations Inc.
|
4
|
+
// The software is being provided on an "as-is" basis and as an accommodation,
|
5
|
+
// and therefore all warranties, representations, or guarantees of any kind
|
6
|
+
// (whether express, implied or statutory) including, without limitation,
|
7
|
+
// warranties of merchantability, non-infringement, or fitness for a particular
|
8
|
+
// purpose, are specifically disclaimed.
|
9
|
+
//
|
10
|
+
// Copyright 2008 Dynastream Innovations Inc.
|
11
|
+
// All rights reserved. This software may not be reproduced by any means
|
12
|
+
// without express written approval of Dynastream Innovations Inc.
|
13
|
+
////////////////////////////////////////////////////////////////////////////////
|
14
|
+
|
15
|
+
|
16
|
+
#if !defined(FIT_CONFIG_H)
|
17
|
+
#define FIT_CONFIG_H
|
18
|
+
|
19
|
+
|
20
|
+
#if defined(__cplusplus)
|
21
|
+
extern "C" {
|
22
|
+
#endif
|
23
|
+
|
24
|
+
#define FIT_LOCAL_MESGS 16 // Adjust to suit RAM requirements.
|
25
|
+
#define FIT_ARCH_ENDIAN FIT_ARCH_ENDIAN_LITTLE // Set to correct endian for build architecture.
|
26
|
+
|
27
|
+
#define FIT_CONVERT_CHECK_CRC // Define to check file crc.
|
28
|
+
#define FIT_CONVERT_TIME_RECORD // Define to support time records (compressed timestamp).
|
29
|
+
//#define FIT_CONVERT_MULTI_THREAD // Define to support multiple conversion threads.
|
30
|
+
//#define FIT_CONVERT_CHECK_FILE_HDR_DATA_TYPE // Define to check file header for .FIT data type. Verifies file is .FIT format before starting decode.
|
31
|
+
|
32
|
+
#if defined(__cplusplus)
|
33
|
+
}
|
34
|
+
#endif
|
35
|
+
|
36
|
+
#endif // !defined(FIT_CONFIG_H)
|