rubyfit 0.0.11 → 0.0.16
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/rubyfit/fit.c +418 -412
- data/ext/rubyfit/fit.h +397 -380
- data/ext/rubyfit/fit_config.h +37 -36
- data/ext/rubyfit/fit_convert.c +619 -596
- data/ext/rubyfit/fit_convert.h +213 -203
- data/ext/rubyfit/fit_crc.c +67 -67
- data/ext/rubyfit/fit_crc.h +42 -42
- data/ext/rubyfit/fit_example.c +1512 -1431
- data/ext/rubyfit/fit_example.h +8000 -6147
- data/ext/rubyfit/fit_include.h +19 -19
- data/ext/rubyfit/fit_ram.c +211 -203
- data/ext/rubyfit/fit_ram.h +44 -39
- data/ext/rubyfit/rubyfit.c +560 -566
- data/lib/rubyfit/version.rb +1 -1
- metadata +3 -3
data/ext/rubyfit/fit_ram.h
CHANGED
@@ -1,39 +1,44 @@
|
|
1
|
-
////////////////////////////////////////////////////////////////////////////////
|
2
|
-
// The following FIT Protocol software provided may be used with FIT protocol
|
3
|
-
// devices only and remains the copyrighted property of
|
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
|
11
|
-
////////////////////////////////////////////////////////////////////////////////
|
12
|
-
// ****WARNING**** This file is auto-generated! Do NOT edit this file.
|
13
|
-
// Profile Version =
|
14
|
-
// Tag = production/akw/
|
15
|
-
// Product = EXAMPLE
|
16
|
-
// Alignment = 4 bytes, padding disabled.
|
17
|
-
////////////////////////////////////////////////////////////////////////////////
|
18
|
-
|
19
|
-
|
20
|
-
#if !defined(FIT_RAM_H)
|
21
|
-
#define FIT_RAM_H
|
22
|
-
|
23
|
-
#include "fit_example.h"
|
24
|
-
|
25
|
-
#if defined(FIT_RAM_INCLUDE)
|
26
|
-
|
27
|
-
///////////////////////////////////////////////////////////////////////////////
|
28
|
-
// Public Function Prototypes
|
29
|
-
///////////////////////////////////////////////////////////////////////////////
|
30
|
-
|
31
|
-
FIT_RAM_FILE FitRAM_LookupFile(FIT_FILE file);
|
32
|
-
FIT_UINT32 FitRAM_GetFileSize(FIT_RAM_FILE file);
|
33
|
-
void FitRAM_FileReadBytes(FIT_RAM_FILE file, FIT_UINT16 file_index, FIT_UINT32 file_offset, void *data, FIT_UINT32 data_size);
|
34
|
-
void FitRAM_FileWriteBytes(FIT_RAM_FILE file, FIT_UINT16 file_index, FIT_UINT32 file_offset, const void *data, FIT_UINT32 data_size);
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
1
|
+
////////////////////////////////////////////////////////////////////////////////
|
2
|
+
// The following FIT Protocol software provided may be used with FIT protocol
|
3
|
+
// devices only and remains the copyrighted property of Garmin Canada 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 2020 Garmin Canada Inc.
|
11
|
+
////////////////////////////////////////////////////////////////////////////////
|
12
|
+
// ****WARNING**** This file is auto-generated! Do NOT edit this file.
|
13
|
+
// Profile Version = 21.27Release
|
14
|
+
// Tag = production/akw/21.27.00-0-gef9575d
|
15
|
+
// Product = EXAMPLE
|
16
|
+
// Alignment = 4 bytes, padding disabled.
|
17
|
+
////////////////////////////////////////////////////////////////////////////////
|
18
|
+
|
19
|
+
|
20
|
+
#if !defined(FIT_RAM_H)
|
21
|
+
#define FIT_RAM_H
|
22
|
+
|
23
|
+
#include "fit_example.h"
|
24
|
+
|
25
|
+
#if defined(FIT_RAM_INCLUDE)
|
26
|
+
|
27
|
+
///////////////////////////////////////////////////////////////////////////////
|
28
|
+
// Public Function Prototypes
|
29
|
+
///////////////////////////////////////////////////////////////////////////////
|
30
|
+
|
31
|
+
FIT_RAM_FILE FitRAM_LookupFile(FIT_FILE file);
|
32
|
+
FIT_UINT32 FitRAM_GetFileSize(FIT_RAM_FILE file);
|
33
|
+
void FitRAM_FileReadBytes(FIT_RAM_FILE file, FIT_UINT16 file_index, FIT_UINT32 file_offset, void *data, FIT_UINT32 data_size);
|
34
|
+
void FitRAM_FileWriteBytes(FIT_RAM_FILE file, FIT_UINT16 file_index, FIT_UINT32 file_offset, const void *data, FIT_UINT32 data_size);
|
35
|
+
|
36
|
+
#if defined(FIT_CONVERT_MULTI_THREAD)
|
37
|
+
void FitRAM_FileWriteMesg(FIT_CONVERT_STATE *state, FIT_RAM_FILE file, FIT_UINT16 file_index, FIT_UINT16 mesg_num, const void *mesg_data, FIT_BOOL restore_fields);
|
38
|
+
#else
|
39
|
+
void FitRAM_FileWriteMesg(FIT_RAM_FILE file, FIT_UINT16 file_index, FIT_UINT16 mesg_num, const void *mesg_data, FIT_BOOL restore_fields);
|
40
|
+
#endif // defined(FIT_CONVERT_MULTI_THREAD)
|
41
|
+
|
42
|
+
#endif // defined(FIT_RAM_INCLUDE)
|
43
|
+
|
44
|
+
#endif // !defined(FIT_RAM_H)
|
data/ext/rubyfit/rubyfit.c
CHANGED
@@ -1,566 +1,560 @@
|
|
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 "stdio.h"
|
16
|
-
#include "string.h"
|
17
|
-
#include "ruby.h"
|
18
|
-
#include "math.h"
|
19
|
-
|
20
|
-
#include "fit_convert.h"
|
21
|
-
#include "fit_crc.h"
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
VALUE
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
if(mesg->
|
84
|
-
rb_hash_aset(rh, rb_str_new2("
|
85
|
-
if(mesg->
|
86
|
-
rb_hash_aset(rh, rb_str_new2("
|
87
|
-
if(mesg->
|
88
|
-
rb_hash_aset(rh, rb_str_new2("
|
89
|
-
if(mesg->
|
90
|
-
rb_hash_aset(rh, rb_str_new2("
|
91
|
-
if(mesg->
|
92
|
-
rb_hash_aset(rh, rb_str_new2("
|
93
|
-
if(mesg->
|
94
|
-
rb_hash_aset(rh, rb_str_new2("
|
95
|
-
if(mesg->
|
96
|
-
rb_hash_aset(rh, rb_str_new2("
|
97
|
-
if(mesg->
|
98
|
-
rb_hash_aset(rh, rb_str_new2("
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
if(mesg->
|
113
|
-
rb_hash_aset(rh, rb_str_new2("
|
114
|
-
if(mesg->
|
115
|
-
rb_hash_aset(rh, rb_str_new2("
|
116
|
-
if(mesg->
|
117
|
-
rb_hash_aset(rh, rb_str_new2("
|
118
|
-
if(mesg->
|
119
|
-
rb_hash_aset(rh, rb_str_new2("
|
120
|
-
if(mesg->
|
121
|
-
rb_hash_aset(rh, rb_str_new2("
|
122
|
-
if(mesg->
|
123
|
-
rb_hash_aset(rh, rb_str_new2("
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
if(mesg->
|
136
|
-
rb_hash_aset(rh, rb_str_new2("
|
137
|
-
if(mesg->
|
138
|
-
rb_hash_aset(rh, rb_str_new2("
|
139
|
-
if(mesg->
|
140
|
-
rb_hash_aset(rh, rb_str_new2("
|
141
|
-
if(mesg->
|
142
|
-
rb_hash_aset(rh, rb_str_new2("
|
143
|
-
if(mesg->
|
144
|
-
rb_hash_aset(rh, rb_str_new2("
|
145
|
-
if(mesg->
|
146
|
-
rb_hash_aset(rh, rb_str_new2("
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
}
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
rb_define_attr(cFitParser, "handler", 1, 1);
|
562
|
-
|
563
|
-
// CRC helper
|
564
|
-
VALUE mCRC = rb_define_module_under(mRubyFit, "CRC");
|
565
|
-
rb_define_singleton_method(mCRC, "update_crc", update_crc, 2);
|
566
|
-
}
|
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 "stdio.h"
|
16
|
+
#include "string.h"
|
17
|
+
#include "ruby.h"
|
18
|
+
#include "math.h"
|
19
|
+
|
20
|
+
#include "fit_convert.h"
|
21
|
+
#include "fit_crc.h"
|
22
|
+
|
23
|
+
/*
|
24
|
+
* garmin/dynastream, decided to pinch pennies on bits by tinkering with well
|
25
|
+
* established time offsets. This is the magic number of seconds needed to add
|
26
|
+
* to their number to get the true number of seconds since the epoch.
|
27
|
+
* This is 20 years of seconds.
|
28
|
+
*/
|
29
|
+
const long GARMIN_TIME_OFFSET = 631065600;
|
30
|
+
|
31
|
+
|
32
|
+
void pass_message(VALUE handler, char *msg) {
|
33
|
+
rb_funcall(handler, rb_intern("print_msg"), 1, rb_str_new2(msg));
|
34
|
+
}
|
35
|
+
|
36
|
+
void pass_err_message(VALUE handler, char *msg) {
|
37
|
+
rb_funcall(handler, rb_intern("print_error_msg"), 1, rb_str_new2(msg));
|
38
|
+
}
|
39
|
+
|
40
|
+
static VALUE fit_pos_to_rb(FIT_SINT32 pos) {
|
41
|
+
float tmp = pos * (180.0 / pow(2,31));
|
42
|
+
tmp -= (tmp > 180.0 ? 360.0 : 0.0);
|
43
|
+
return rb_float_new(tmp);
|
44
|
+
}
|
45
|
+
|
46
|
+
|
47
|
+
static VALUE init(VALUE self, VALUE handler) {
|
48
|
+
rb_ivar_set(self, rb_intern("@handler"), handler);
|
49
|
+
|
50
|
+
return Qnil;
|
51
|
+
}
|
52
|
+
|
53
|
+
static void pass_activity(VALUE handler, const FIT_ACTIVITY_MESG *mesg) {
|
54
|
+
VALUE rh = rb_hash_new();
|
55
|
+
|
56
|
+
if(mesg->timestamp != FIT_DATE_TIME_INVALID)
|
57
|
+
rb_hash_aset(rh, rb_str_new2("timestamp"), UINT2NUM(mesg->timestamp + GARMIN_TIME_OFFSET));
|
58
|
+
if(mesg->total_timer_time != FIT_UINT32_INVALID)
|
59
|
+
rb_hash_aset(rh, rb_str_new2("total_timer_time"), rb_float_new(mesg->total_timer_time / 1000.0));
|
60
|
+
if(mesg->local_timestamp != FIT_DATE_TIME_INVALID)
|
61
|
+
rb_hash_aset(rh, rb_str_new2("local_timestamp"), rb_float_new(mesg->local_timestamp + GARMIN_TIME_OFFSET));
|
62
|
+
if(mesg->num_sessions != FIT_UINT16_INVALID)
|
63
|
+
rb_hash_aset(rh, rb_str_new2("num_sessions"), UINT2NUM(mesg->num_sessions));
|
64
|
+
if(mesg->type != FIT_ENUM_INVALID)
|
65
|
+
rb_hash_aset(rh, rb_str_new2("type"), CHR2FIX(mesg->type));
|
66
|
+
if(mesg->event != FIT_ENUM_INVALID)
|
67
|
+
rb_hash_aset(rh, rb_str_new2("event"), CHR2FIX(mesg->event));
|
68
|
+
if(mesg->event_type != FIT_ENUM_INVALID)
|
69
|
+
rb_hash_aset(rh, rb_str_new2("event_type"), CHR2FIX(mesg->event_type));
|
70
|
+
if(mesg->event_group != FIT_UINT8_INVALID)
|
71
|
+
rb_hash_aset(rh, rb_str_new2("event_group"), UINT2NUM(mesg->event_group));
|
72
|
+
|
73
|
+
rb_funcall(handler, rb_intern("on_activity"), 1, rh);
|
74
|
+
}
|
75
|
+
|
76
|
+
static void pass_record(VALUE handler, const FIT_RECORD_MESG *mesg) {
|
77
|
+
VALUE rh = rb_hash_new();
|
78
|
+
|
79
|
+
if(mesg->timestamp != FIT_DATE_TIME_INVALID)
|
80
|
+
rb_hash_aset(rh, rb_str_new2("timestamp"), UINT2NUM(mesg->timestamp + GARMIN_TIME_OFFSET));
|
81
|
+
if(mesg->position_lat != FIT_SINT32_INVALID)
|
82
|
+
rb_hash_aset(rh, rb_str_new2("position_lat"), fit_pos_to_rb(mesg->position_lat));
|
83
|
+
if(mesg->position_long != FIT_SINT32_INVALID)
|
84
|
+
rb_hash_aset(rh, rb_str_new2("position_long"), fit_pos_to_rb(mesg->position_long));
|
85
|
+
if(mesg->distance != FIT_UINT32_INVALID)
|
86
|
+
rb_hash_aset(rh, rb_str_new2("distance"), rb_float_new(mesg->distance / 100.0));
|
87
|
+
if(mesg->time_from_course != FIT_SINT32_INVALID)
|
88
|
+
rb_hash_aset(rh, rb_str_new2("time_from_course"), rb_float_new(mesg->time_from_course / 1000.0));
|
89
|
+
if(mesg->heart_rate != FIT_UINT8_INVALID)
|
90
|
+
rb_hash_aset(rh, rb_str_new2("heart_rate"), UINT2NUM(mesg->heart_rate));
|
91
|
+
if(mesg->altitude != FIT_UINT16_INVALID)
|
92
|
+
rb_hash_aset(rh, rb_str_new2("altitude"), rb_float_new(mesg->altitude / 5.0 - 500));
|
93
|
+
if(mesg->enhanced_altitude != FIT_UINT32_INVALID)
|
94
|
+
rb_hash_aset(rh, rb_str_new2("enhanced_altitude"), rb_float_new(mesg->enhanced_altitude / 5.0 - 500));
|
95
|
+
if(mesg->speed != FIT_UINT16_INVALID)
|
96
|
+
rb_hash_aset(rh, rb_str_new2("speed"), rb_float_new(mesg->speed / 1000.0));
|
97
|
+
if(mesg->enhanced_speed != FIT_UINT32_INVALID)
|
98
|
+
rb_hash_aset(rh, rb_str_new2("enhanced_speed"), rb_float_new(mesg->enhanced_speed / 1000.0));
|
99
|
+
if(mesg->grade != FIT_SINT16_INVALID)
|
100
|
+
rb_hash_aset(rh, rb_str_new2("grade"), rb_float_new(mesg->grade / 100.0));
|
101
|
+
if(mesg->power != FIT_UINT16_INVALID)
|
102
|
+
rb_hash_aset(rh, rb_str_new2("power"), UINT2NUM(mesg->power));
|
103
|
+
if(mesg->cadence != FIT_UINT8_INVALID)
|
104
|
+
rb_hash_aset(rh, rb_str_new2("cadence"), UINT2NUM(mesg->cadence));
|
105
|
+
if(mesg->resistance != FIT_UINT8_INVALID)
|
106
|
+
rb_hash_aset(rh, rb_str_new2("resistance"), UINT2NUM(mesg->resistance));
|
107
|
+
if(mesg->cycle_length != FIT_UINT8_INVALID)
|
108
|
+
rb_hash_aset(rh, rb_str_new2("cycle_length"), UINT2NUM(mesg->cycle_length));
|
109
|
+
if(mesg->temperature != FIT_SINT8_INVALID)
|
110
|
+
rb_hash_aset(rh, rb_str_new2("temperature"), INT2FIX(mesg->temperature));
|
111
|
+
|
112
|
+
if(mesg->left_right_balance != FIT_UINT8_INVALID)
|
113
|
+
rb_hash_aset(rh, rb_str_new2("left_right_balance"), UINT2NUM(mesg->left_right_balance & FIT_LEFT_RIGHT_BALANCE_MASK));
|
114
|
+
if(mesg->left_torque_effectiveness != FIT_UINT8_INVALID)
|
115
|
+
rb_hash_aset(rh, rb_str_new2("left_torque_effectiveness"), UINT2NUM(mesg->left_torque_effectiveness));
|
116
|
+
if(mesg->right_torque_effectiveness != FIT_UINT8_INVALID)
|
117
|
+
rb_hash_aset(rh, rb_str_new2("right_torque_effectiveness"), UINT2NUM(mesg->right_torque_effectiveness));
|
118
|
+
if(mesg->left_pedal_smoothness != FIT_UINT8_INVALID)
|
119
|
+
rb_hash_aset(rh, rb_str_new2("left_pedal_smoothness"), UINT2NUM(mesg->left_pedal_smoothness));
|
120
|
+
if(mesg->right_pedal_smoothness != FIT_UINT8_INVALID)
|
121
|
+
rb_hash_aset(rh, rb_str_new2("right_pedal_smoothness"), UINT2NUM(mesg->right_pedal_smoothness));
|
122
|
+
if(mesg->combined_pedal_smoothness != FIT_UINT8_INVALID)
|
123
|
+
rb_hash_aset(rh, rb_str_new2("combined_pedal_smoothness"), UINT2NUM(mesg->combined_pedal_smoothness));
|
124
|
+
|
125
|
+
rb_funcall(handler, rb_intern("on_record"), 1, rh);
|
126
|
+
}
|
127
|
+
|
128
|
+
static void pass_lap(VALUE handler, const FIT_LAP_MESG *mesg) {
|
129
|
+
VALUE rh = rb_hash_new();
|
130
|
+
|
131
|
+
if(mesg->timestamp != FIT_DATE_TIME_INVALID)
|
132
|
+
rb_hash_aset(rh, rb_str_new2("timestamp"), UINT2NUM(mesg->timestamp + GARMIN_TIME_OFFSET));
|
133
|
+
if(mesg->start_time != FIT_DATE_TIME_INVALID)
|
134
|
+
rb_hash_aset(rh, rb_str_new2("start_time"), UINT2NUM(mesg->start_time + GARMIN_TIME_OFFSET));
|
135
|
+
if(mesg->start_position_lat != FIT_SINT32_INVALID)
|
136
|
+
rb_hash_aset(rh, rb_str_new2("start_position_lat"), fit_pos_to_rb(mesg->start_position_lat));
|
137
|
+
if(mesg->start_position_long != FIT_SINT32_INVALID)
|
138
|
+
rb_hash_aset(rh, rb_str_new2("start_position_long"), fit_pos_to_rb(mesg->start_position_long));
|
139
|
+
if(mesg->end_position_lat != FIT_SINT32_INVALID)
|
140
|
+
rb_hash_aset(rh, rb_str_new2("end_position_lat"), fit_pos_to_rb(mesg->end_position_lat));
|
141
|
+
if(mesg->end_position_long != FIT_SINT32_INVALID)
|
142
|
+
rb_hash_aset(rh, rb_str_new2("end_position_long"), fit_pos_to_rb(mesg->end_position_long));
|
143
|
+
if(mesg->total_elapsed_time != FIT_UINT32_INVALID)
|
144
|
+
rb_hash_aset(rh, rb_str_new2("total_elapsed_time"), UINT2NUM(mesg->total_elapsed_time));
|
145
|
+
if(mesg->total_timer_time != FIT_UINT32_INVALID)
|
146
|
+
rb_hash_aset(rh, rb_str_new2("total_timer_time"), rb_float_new(mesg->total_timer_time / 1000.0));
|
147
|
+
if(mesg->total_distance != FIT_UINT32_INVALID)
|
148
|
+
rb_hash_aset(rh, rb_str_new2("total_distance"), rb_float_new(mesg->total_distance / 100.0));
|
149
|
+
if(mesg->total_cycles != FIT_UINT32_INVALID)
|
150
|
+
rb_hash_aset(rh, rb_str_new2("total_cycles"), UINT2NUM(mesg->total_cycles));
|
151
|
+
if(mesg->message_index != FIT_UINT16_INVALID)
|
152
|
+
rb_hash_aset(rh, rb_str_new2("message_index"), UINT2NUM(mesg->message_index));
|
153
|
+
if(mesg->total_calories != FIT_UINT16_INVALID)
|
154
|
+
rb_hash_aset(rh, rb_str_new2("total_calories"), UINT2NUM(mesg->total_calories));
|
155
|
+
if(mesg->total_fat_calories != FIT_UINT16_INVALID)
|
156
|
+
rb_hash_aset(rh, rb_str_new2("total_fat_calories"), UINT2NUM(mesg->total_fat_calories));
|
157
|
+
if(mesg->avg_speed != FIT_UINT16_INVALID)
|
158
|
+
rb_hash_aset(rh, rb_str_new2("avg_speed"), rb_float_new(mesg->avg_speed / 1000.0));
|
159
|
+
if(mesg->max_speed != FIT_UINT16_INVALID)
|
160
|
+
rb_hash_aset(rh, rb_str_new2("max_speed"), rb_float_new(mesg->max_speed / 1000.0));
|
161
|
+
if(mesg->enhanced_avg_speed != FIT_UINT32_INVALID)
|
162
|
+
rb_hash_aset(rh, rb_str_new2("enhanced_avg_speed"), rb_float_new(mesg->enhanced_avg_speed / 1000.0));
|
163
|
+
if(mesg->enhanced_max_speed != FIT_UINT32_INVALID)
|
164
|
+
rb_hash_aset(rh, rb_str_new2("enhanced_max_speed"), rb_float_new(mesg->enhanced_max_speed / 1000.0));
|
165
|
+
if(mesg->avg_altitude != FIT_UINT16_INVALID)
|
166
|
+
rb_hash_aset(rh, rb_str_new2("avg_altitude"), rb_float_new(mesg->avg_altitude / 5.0 - 500));
|
167
|
+
if(mesg->max_altitude != FIT_UINT16_INVALID)
|
168
|
+
rb_hash_aset(rh, rb_str_new2("max_altitude"), rb_float_new(mesg->max_altitude / 5.0 - 500));
|
169
|
+
if(mesg->min_altitude != FIT_UINT16_INVALID)
|
170
|
+
rb_hash_aset(rh, rb_str_new2("min_altitude"), rb_float_new(mesg->min_altitude / 5.0 - 500));
|
171
|
+
if(mesg->enhanced_avg_altitude != FIT_UINT32_INVALID)
|
172
|
+
rb_hash_aset(rh, rb_str_new2("enhanced_avg_altitude"), rb_float_new(mesg->enhanced_avg_altitude / 5.0 - 500));
|
173
|
+
if(mesg->enhanced_max_altitude != FIT_UINT32_INVALID)
|
174
|
+
rb_hash_aset(rh, rb_str_new2("enhanced_max_altitude"), rb_float_new(mesg->enhanced_max_altitude / 5.0 - 500));
|
175
|
+
if(mesg->enhanced_min_altitude != FIT_UINT32_INVALID)
|
176
|
+
rb_hash_aset(rh, rb_str_new2("enhanced_min_altitude"), rb_float_new(mesg->enhanced_min_altitude / 5.0 - 500));
|
177
|
+
if(mesg->avg_power != FIT_UINT16_INVALID)
|
178
|
+
rb_hash_aset(rh, rb_str_new2("avg_power"), UINT2NUM(mesg->avg_power));
|
179
|
+
if(mesg->max_power != FIT_UINT16_INVALID)
|
180
|
+
rb_hash_aset(rh, rb_str_new2("max_power"), UINT2NUM(mesg->max_power));
|
181
|
+
if(mesg->total_ascent != FIT_UINT16_INVALID)
|
182
|
+
rb_hash_aset(rh, rb_str_new2("total_ascent"), UINT2NUM(mesg->total_ascent));
|
183
|
+
if(mesg->total_descent != FIT_UINT16_INVALID)
|
184
|
+
rb_hash_aset(rh, rb_str_new2("total_descent"), UINT2NUM(mesg->total_descent));
|
185
|
+
if(mesg->event != FIT_EVENT_INVALID)
|
186
|
+
rb_hash_aset(rh, rb_str_new2("event"), CHR2FIX(mesg->event));
|
187
|
+
if(mesg->event_type != FIT_EVENT_INVALID)
|
188
|
+
rb_hash_aset(rh, rb_str_new2("event_type"), CHR2FIX(mesg->event_type));
|
189
|
+
if(mesg->avg_heart_rate != FIT_UINT8_INVALID)
|
190
|
+
rb_hash_aset(rh, rb_str_new2("avg_heart_rate"), UINT2NUM(mesg->avg_heart_rate));
|
191
|
+
if(mesg->max_heart_rate != FIT_UINT8_INVALID)
|
192
|
+
rb_hash_aset(rh, rb_str_new2("max_heart_rate"), UINT2NUM(mesg->max_heart_rate));
|
193
|
+
if(mesg->avg_cadence != FIT_UINT8_INVALID)
|
194
|
+
rb_hash_aset(rh, rb_str_new2("avg_cadence"), UINT2NUM(mesg->avg_cadence));
|
195
|
+
if(mesg->max_cadence != FIT_UINT8_INVALID)
|
196
|
+
rb_hash_aset(rh, rb_str_new2("max_cadence"), UINT2NUM(mesg->max_cadence));
|
197
|
+
if(mesg->intensity != FIT_INTENSITY_INVALID)
|
198
|
+
rb_hash_aset(rh, rb_str_new2("intensity"), CHR2FIX(mesg->intensity));
|
199
|
+
if(mesg->lap_trigger != FIT_LAP_TRIGGER_INVALID)
|
200
|
+
rb_hash_aset(rh, rb_str_new2("lap_trigger"), CHR2FIX(mesg->lap_trigger));
|
201
|
+
if(mesg->sport != FIT_SPORT_INVALID)
|
202
|
+
rb_hash_aset(rh, rb_str_new2("sport"), CHR2FIX(mesg->sport));
|
203
|
+
if(mesg->event_group != FIT_UINT8_INVALID)
|
204
|
+
rb_hash_aset(rh, rb_str_new2("event_group"), UINT2NUM(mesg->event_group));
|
205
|
+
|
206
|
+
rb_funcall(handler, rb_intern("on_lap"), 1, rh);
|
207
|
+
}
|
208
|
+
|
209
|
+
static void pass_session(VALUE handler, const FIT_SESSION_MESG *mesg) {
|
210
|
+
VALUE rh = rb_hash_new();
|
211
|
+
|
212
|
+
if(mesg->timestamp != FIT_DATE_TIME_INVALID)
|
213
|
+
rb_hash_aset(rh, rb_str_new2("timestamp"), UINT2NUM(mesg->timestamp + GARMIN_TIME_OFFSET));
|
214
|
+
if(mesg->start_time != FIT_DATE_TIME_INVALID)
|
215
|
+
rb_hash_aset(rh, rb_str_new2("start_time"), UINT2NUM(mesg->start_time + GARMIN_TIME_OFFSET));
|
216
|
+
if(mesg->start_position_lat != FIT_SINT32_INVALID)
|
217
|
+
rb_hash_aset(rh, rb_str_new2("start_position_lat"), fit_pos_to_rb(mesg->start_position_lat));
|
218
|
+
if(mesg->start_position_long != FIT_SINT32_INVALID)
|
219
|
+
rb_hash_aset(rh, rb_str_new2("start_position_long"), fit_pos_to_rb(mesg->start_position_long));
|
220
|
+
if(mesg->total_elapsed_time != FIT_UINT32_INVALID)
|
221
|
+
rb_hash_aset(rh, rb_str_new2("total_elapsed_time"), rb_float_new(mesg->total_elapsed_time / 1000.0));
|
222
|
+
if(mesg->total_timer_time != FIT_UINT32_INVALID)
|
223
|
+
rb_hash_aset(rh, rb_str_new2("total_timer_time"), rb_float_new(mesg->total_timer_time / 1000.0));
|
224
|
+
if(mesg->total_distance != FIT_UINT32_INVALID)
|
225
|
+
rb_hash_aset(rh, rb_str_new2("total_distance"), rb_float_new(mesg->total_distance / 100.0));
|
226
|
+
if(mesg->total_cycles != FIT_UINT32_INVALID)
|
227
|
+
rb_hash_aset(rh, rb_str_new2("total_cycles"), UINT2NUM(mesg->total_cycles));
|
228
|
+
if(mesg->nec_lat != FIT_SINT32_INVALID)
|
229
|
+
rb_hash_aset(rh, rb_str_new2("nec_lat"), fit_pos_to_rb(mesg->nec_lat));
|
230
|
+
if(mesg->nec_long != FIT_SINT32_INVALID)
|
231
|
+
rb_hash_aset(rh, rb_str_new2("nec_long"), fit_pos_to_rb(mesg->nec_long));
|
232
|
+
if(mesg->swc_lat != FIT_SINT32_INVALID)
|
233
|
+
rb_hash_aset(rh, rb_str_new2("swc_lat"), fit_pos_to_rb(mesg->swc_lat));
|
234
|
+
if(mesg->swc_long != FIT_SINT32_INVALID)
|
235
|
+
rb_hash_aset(rh, rb_str_new2("swc_long"), fit_pos_to_rb(mesg->swc_long));
|
236
|
+
if(mesg->message_index != FIT_MESSAGE_INDEX_INVALID)
|
237
|
+
rb_hash_aset(rh, rb_str_new2("message_index"), UINT2NUM(mesg->message_index));
|
238
|
+
if(mesg->total_calories != FIT_UINT16_INVALID)
|
239
|
+
rb_hash_aset(rh, rb_str_new2("total_calories"), UINT2NUM(mesg->total_calories));
|
240
|
+
if(mesg->total_fat_calories != FIT_UINT16_INVALID)
|
241
|
+
rb_hash_aset(rh, rb_str_new2("total_fat_calories"), UINT2NUM(mesg->total_fat_calories));
|
242
|
+
if(mesg->avg_speed != FIT_UINT16_INVALID)
|
243
|
+
rb_hash_aset(rh, rb_str_new2("avg_speed"), rb_float_new(mesg->avg_speed / 1000.0));
|
244
|
+
if(mesg->max_speed != FIT_UINT16_INVALID)
|
245
|
+
rb_hash_aset(rh, rb_str_new2("max_speed"), rb_float_new(mesg->max_speed / 1000.0));
|
246
|
+
if(mesg->avg_power != FIT_UINT16_INVALID)
|
247
|
+
rb_hash_aset(rh, rb_str_new2("avg_power"), UINT2NUM(mesg->avg_power));
|
248
|
+
if(mesg->max_power != FIT_UINT16_INVALID)
|
249
|
+
rb_hash_aset(rh, rb_str_new2("max_power"), UINT2NUM(mesg->max_power));
|
250
|
+
if(mesg->total_ascent != FIT_UINT16_INVALID)
|
251
|
+
rb_hash_aset(rh, rb_str_new2("total_ascent"), UINT2NUM(mesg->total_ascent));
|
252
|
+
if(mesg->total_descent != FIT_UINT16_INVALID)
|
253
|
+
rb_hash_aset(rh, rb_str_new2("total_descent"), UINT2NUM(mesg->total_descent));
|
254
|
+
if(mesg->first_lap_index != FIT_UINT16_INVALID)
|
255
|
+
rb_hash_aset(rh, rb_str_new2("first_lap_index"), UINT2NUM(mesg->first_lap_index));
|
256
|
+
if(mesg->num_laps != FIT_UINT16_INVALID)
|
257
|
+
rb_hash_aset(rh, rb_str_new2("num_laps"), UINT2NUM(mesg->num_laps));
|
258
|
+
if(mesg->event != FIT_EVENT_INVALID)
|
259
|
+
rb_hash_aset(rh, rb_str_new2("event"), CHR2FIX(mesg->event));
|
260
|
+
if(mesg->event_type != FIT_EVENT_INVALID)
|
261
|
+
rb_hash_aset(rh, rb_str_new2("event_type"), CHR2FIX(mesg->event_type));
|
262
|
+
if(mesg->avg_heart_rate != FIT_UINT8_INVALID)
|
263
|
+
rb_hash_aset(rh, rb_str_new2("avg_heart_rate"), UINT2NUM(mesg->avg_heart_rate));
|
264
|
+
if(mesg->max_heart_rate != FIT_UINT8_INVALID)
|
265
|
+
rb_hash_aset(rh, rb_str_new2("max_heart_rate"), UINT2NUM(mesg->max_heart_rate));
|
266
|
+
if(mesg->avg_cadence != FIT_UINT8_INVALID)
|
267
|
+
rb_hash_aset(rh, rb_str_new2("avg_cadence"), UINT2NUM(mesg->avg_cadence));
|
268
|
+
if(mesg->max_cadence != FIT_UINT8_INVALID)
|
269
|
+
rb_hash_aset(rh, rb_str_new2("max_cadence"), UINT2NUM(mesg->max_cadence));
|
270
|
+
if(mesg->sport != FIT_SPORT_INVALID)
|
271
|
+
rb_hash_aset(rh, rb_str_new2("sport"), CHR2FIX(mesg->sport));
|
272
|
+
if(mesg->sub_sport != FIT_SUB_SPORT_INVALID)
|
273
|
+
rb_hash_aset(rh, rb_str_new2("sub_sport"), CHR2FIX(mesg->sub_sport));
|
274
|
+
if(mesg->event_group != FIT_UINT8_INVALID)
|
275
|
+
rb_hash_aset(rh, rb_str_new2("event_group"), UINT2NUM(mesg->event_group));
|
276
|
+
if(mesg->total_training_effect != FIT_UINT8_INVALID)
|
277
|
+
rb_hash_aset(rh, rb_str_new2("total_training_effect"), UINT2NUM(mesg->total_training_effect));
|
278
|
+
|
279
|
+
rb_funcall(handler, rb_intern("on_session"), 1, rh);
|
280
|
+
}
|
281
|
+
|
282
|
+
static void pass_user_profile(VALUE handler, const FIT_USER_PROFILE_MESG *mesg) {
|
283
|
+
VALUE rh = rb_hash_new();
|
284
|
+
|
285
|
+
if(*mesg->friendly_name != FIT_STRING_INVALID)
|
286
|
+
rb_hash_aset(rh, rb_str_new2("friendly_name"), rb_str_new2(mesg->friendly_name));
|
287
|
+
if(mesg->message_index != FIT_MESSAGE_INDEX_INVALID)
|
288
|
+
rb_hash_aset(rh, rb_str_new2("message_index"), UINT2NUM(mesg->message_index));
|
289
|
+
if(mesg->weight != FIT_UINT16_INVALID)
|
290
|
+
rb_hash_aset(rh, rb_str_new2("weight"), rb_float_new(mesg->weight / 10.0));
|
291
|
+
if(mesg->gender != FIT_GENDER_INVALID)
|
292
|
+
rb_hash_aset(rh, rb_str_new2("gender"), UINT2NUM(mesg->gender));
|
293
|
+
if(mesg->age != FIT_UINT8_INVALID)
|
294
|
+
rb_hash_aset(rh, rb_str_new2("age"), UINT2NUM(mesg->age));
|
295
|
+
if(mesg->height != FIT_UINT8_INVALID)
|
296
|
+
rb_hash_aset(rh, rb_str_new2("height"), rb_float_new(mesg->height / 100.0));
|
297
|
+
if(mesg->language != FIT_LANGUAGE_INVALID)
|
298
|
+
rb_hash_aset(rh, rb_str_new2("language"), UINT2NUM(mesg->language));
|
299
|
+
if(mesg->elev_setting != FIT_DISPLAY_MEASURE_INVALID)
|
300
|
+
rb_hash_aset(rh, rb_str_new2("elev_setting"), UINT2NUM(mesg->elev_setting));
|
301
|
+
if(mesg->weight_setting != FIT_DISPLAY_MEASURE_INVALID)
|
302
|
+
rb_hash_aset(rh, rb_str_new2("weight_setting"), UINT2NUM(mesg->weight_setting));
|
303
|
+
if(mesg->resting_heart_rate != FIT_UINT8_INVALID)
|
304
|
+
rb_hash_aset(rh, rb_str_new2("resting_heart_rate"), UINT2NUM(mesg->resting_heart_rate));
|
305
|
+
if(mesg->default_max_running_heart_rate != FIT_UINT8_INVALID)
|
306
|
+
rb_hash_aset(rh, rb_str_new2("default_max_running_heart_rate"), UINT2NUM(mesg->default_max_running_heart_rate));
|
307
|
+
if(mesg->default_max_biking_heart_rate != FIT_UINT8_INVALID)
|
308
|
+
rb_hash_aset(rh, rb_str_new2("default_max_biking_heart_rate"), UINT2NUM(mesg->default_max_biking_heart_rate));
|
309
|
+
if(mesg->default_max_heart_rate != FIT_UINT8_INVALID)
|
310
|
+
rb_hash_aset(rh, rb_str_new2("default_max_heart_rate"), UINT2NUM(mesg->default_max_heart_rate));
|
311
|
+
if(mesg->hr_setting != FIT_DISPLAY_HEART_INVALID)
|
312
|
+
rb_hash_aset(rh, rb_str_new2("hr_setting"), UINT2NUM(mesg->hr_setting));
|
313
|
+
if(mesg->speed_setting != FIT_DISPLAY_MEASURE_INVALID)
|
314
|
+
rb_hash_aset(rh, rb_str_new2("speed_setting"), UINT2NUM(mesg->speed_setting));
|
315
|
+
if(mesg->dist_setting != FIT_DISPLAY_MEASURE_INVALID)
|
316
|
+
rb_hash_aset(rh, rb_str_new2("dist_setting"), UINT2NUM(mesg->dist_setting));
|
317
|
+
if(mesg->power_setting != FIT_DISPLAY_POWER_INVALID)
|
318
|
+
rb_hash_aset(rh, rb_str_new2("power_setting"), UINT2NUM(mesg->power_setting));
|
319
|
+
if(mesg->activity_class != FIT_ACTIVITY_CLASS_INVALID)
|
320
|
+
rb_hash_aset(rh, rb_str_new2("activity_class"), UINT2NUM(mesg->activity_class));
|
321
|
+
if(mesg->position_setting != FIT_DISPLAY_POSITION_INVALID)
|
322
|
+
rb_hash_aset(rh, rb_str_new2("position_setting"), UINT2NUM(mesg->position_setting));
|
323
|
+
|
324
|
+
rb_funcall(handler, rb_intern("on_user_profile"), 1, rh);
|
325
|
+
}
|
326
|
+
|
327
|
+
static void pass_event(VALUE handler, const FIT_EVENT_MESG *mesg) {
|
328
|
+
VALUE rh = rb_hash_new();
|
329
|
+
|
330
|
+
if(mesg->timestamp != FIT_DATE_TIME_INVALID)
|
331
|
+
rb_hash_aset(rh, rb_str_new2("timestamp"), UINT2NUM(mesg->timestamp + GARMIN_TIME_OFFSET));
|
332
|
+
if(mesg->data != FIT_UINT32_INVALID)
|
333
|
+
rb_hash_aset(rh, rb_str_new2("data"), UINT2NUM(mesg->data));
|
334
|
+
if(mesg->data16 != FIT_UINT16_INVALID)
|
335
|
+
rb_hash_aset(rh, rb_str_new2("data16"), UINT2NUM(mesg->data16));
|
336
|
+
if(mesg->timestamp != FIT_EVENT_INVALID)
|
337
|
+
rb_hash_aset(rh, rb_str_new2("event"), CHR2FIX(mesg->event));
|
338
|
+
if(mesg->timestamp != FIT_EVENT_TYPE_INVALID)
|
339
|
+
rb_hash_aset(rh, rb_str_new2("event_type"), CHR2FIX(mesg->event_type));
|
340
|
+
if(mesg->event_group != FIT_UINT8_INVALID)
|
341
|
+
rb_hash_aset(rh, rb_str_new2("event_group"), UINT2NUM(mesg->event_group));
|
342
|
+
|
343
|
+
rb_funcall(handler, rb_intern("on_event"), 1, rh);
|
344
|
+
}
|
345
|
+
|
346
|
+
static void pass_device_info(VALUE handler, const FIT_DEVICE_INFO_MESG *mesg) {
|
347
|
+
VALUE rh = rb_hash_new();
|
348
|
+
|
349
|
+
if(mesg->timestamp != FIT_DATE_TIME_INVALID)
|
350
|
+
rb_hash_aset(rh, rb_str_new2("timestamp"), UINT2NUM(mesg->timestamp + GARMIN_TIME_OFFSET));
|
351
|
+
if(mesg->serial_number != FIT_UINT32Z_INVALID)
|
352
|
+
rb_hash_aset(rh, rb_str_new2("serial_number"), UINT2NUM(mesg->serial_number));
|
353
|
+
if(mesg->manufacturer != FIT_MANUFACTURER_INVALID)
|
354
|
+
rb_hash_aset(rh, rb_str_new2("manufacturer"), UINT2NUM(mesg->manufacturer));
|
355
|
+
if(mesg->product != FIT_UINT16_INVALID)
|
356
|
+
rb_hash_aset(rh, rb_str_new2("product"), UINT2NUM(mesg->product));
|
357
|
+
if(mesg->software_version != FIT_UINT16_INVALID)
|
358
|
+
rb_hash_aset(rh, rb_str_new2("software_version"), UINT2NUM(mesg->software_version));
|
359
|
+
if(mesg->battery_voltage != FIT_UINT16_INVALID)
|
360
|
+
rb_hash_aset(rh, rb_str_new2("battery_voltage"), UINT2NUM(mesg->battery_voltage));
|
361
|
+
if(mesg->device_index != FIT_DEVICE_INDEX_INVALID)
|
362
|
+
rb_hash_aset(rh, rb_str_new2("device_index"), UINT2NUM(mesg->device_index));
|
363
|
+
if(mesg->device_type != FIT_ANTPLUS_DEVICE_TYPE_INVALID)
|
364
|
+
rb_hash_aset(rh, rb_str_new2("device_type"), UINT2NUM(mesg->device_type));
|
365
|
+
if(mesg->hardware_version != FIT_UINT8_INVALID)
|
366
|
+
rb_hash_aset(rh, rb_str_new2("hardware_version"), UINT2NUM(mesg->hardware_version));
|
367
|
+
if(mesg->battery_status != FIT_BATTERY_STATUS_INVALID)
|
368
|
+
rb_hash_aset(rh, rb_str_new2("battery_status"), UINT2NUM(mesg->battery_status));
|
369
|
+
|
370
|
+
rb_funcall(handler, rb_intern("on_device_info"), 1, rh);
|
371
|
+
}
|
372
|
+
|
373
|
+
static void pass_weight_scale_info(VALUE handler, const FIT_WEIGHT_SCALE_MESG *mesg) {
|
374
|
+
VALUE rh = rb_hash_new();
|
375
|
+
|
376
|
+
if(mesg->timestamp != FIT_DATE_TIME_INVALID)
|
377
|
+
rb_hash_aset(rh, rb_str_new2("timestamp"), UINT2NUM(mesg->timestamp + GARMIN_TIME_OFFSET));
|
378
|
+
if(mesg->weight != FIT_WEIGHT_INVALID)
|
379
|
+
rb_hash_aset(rh, rb_str_new2("weight"), rb_float_new(mesg->weight / 100.0));
|
380
|
+
if(mesg->percent_fat != FIT_UINT16_INVALID)
|
381
|
+
rb_hash_aset(rh, rb_str_new2("percent_fat"), rb_float_new(mesg->percent_fat / 100.0));
|
382
|
+
if(mesg->percent_hydration != FIT_UINT16_INVALID)
|
383
|
+
rb_hash_aset(rh, rb_str_new2("percent_hydration"), rb_float_new(mesg->percent_hydration / 100.0));
|
384
|
+
if(mesg->visceral_fat_mass != FIT_UINT16_INVALID)
|
385
|
+
rb_hash_aset(rh, rb_str_new2("visceral_fat_mass"), rb_float_new(mesg->visceral_fat_mass / 100.0));
|
386
|
+
if(mesg->bone_mass != FIT_UINT16_INVALID)
|
387
|
+
rb_hash_aset(rh, rb_str_new2("bone_mass"), rb_float_new(mesg->bone_mass / 100.0));
|
388
|
+
if(mesg->muscle_mass != FIT_UINT16_INVALID)
|
389
|
+
rb_hash_aset(rh, rb_str_new2("muscle_mass"), rb_float_new(mesg->muscle_mass / 100.0));
|
390
|
+
if(mesg->basal_met != FIT_UINT16_INVALID)
|
391
|
+
rb_hash_aset(rh, rb_str_new2("basal_met"), rb_float_new(mesg->basal_met / 4.0));
|
392
|
+
if(mesg->active_met != FIT_UINT16_INVALID)
|
393
|
+
rb_hash_aset(rh, rb_str_new2("active_met"), rb_float_new(mesg->active_met / 4.0));
|
394
|
+
if(mesg->physique_rating != FIT_UINT8_INVALID)
|
395
|
+
rb_hash_aset(rh, rb_str_new2("physique_rating"), rb_float_new(mesg->physique_rating));
|
396
|
+
if(mesg->metabolic_age != FIT_UINT8_INVALID)
|
397
|
+
rb_hash_aset(rh, rb_str_new2("metabolic_age"), rb_float_new(mesg->metabolic_age));
|
398
|
+
if(mesg->visceral_fat_rating != FIT_UINT8_INVALID)
|
399
|
+
rb_hash_aset(rh, rb_str_new2("visceral_fat_rating"), rb_float_new(mesg->visceral_fat_rating));
|
400
|
+
|
401
|
+
rb_funcall(handler, rb_intern("on_weight_scale_info"), 1, rh);
|
402
|
+
}
|
403
|
+
|
404
|
+
static VALUE parse(VALUE self, VALUE original_str) {
|
405
|
+
int i = 0;
|
406
|
+
VALUE str = StringValue(original_str);
|
407
|
+
VALUE handler = rb_ivar_get(self, rb_intern("@handler"));
|
408
|
+
char *p = RSTRING_PTR(str);
|
409
|
+
char err_msg[128];
|
410
|
+
|
411
|
+
FIT_UINT8 buf[8];
|
412
|
+
FIT_CONVERT_RETURN convert_return = FIT_CONVERT_CONTINUE;
|
413
|
+
FIT_UINT32 buf_size;
|
414
|
+
FIT_CONVERT_STATE state;
|
415
|
+
FitConvert_Init(&state, FIT_TRUE);
|
416
|
+
|
417
|
+
if(RSTRING_LEN(str) == 0) {
|
418
|
+
//sprintf(err_msg, "Passed in string with length of 0!");
|
419
|
+
pass_err_message(handler, err_msg);
|
420
|
+
return Qnil;
|
421
|
+
}
|
422
|
+
|
423
|
+
while(i < RSTRING_LEN(str) && (convert_return == FIT_CONVERT_CONTINUE)) {
|
424
|
+
for(buf_size=0;(buf_size < sizeof(buf)) && (p != NULL); buf_size++) {
|
425
|
+
buf[buf_size] = *p;
|
426
|
+
p++;
|
427
|
+
i++;
|
428
|
+
}
|
429
|
+
|
430
|
+
do {
|
431
|
+
convert_return = FitConvert_Read(&state, buf, buf_size);
|
432
|
+
|
433
|
+
switch(convert_return) {
|
434
|
+
case FIT_CONVERT_MESSAGE_AVAILABLE: {
|
435
|
+
const FIT_UINT8 *mesg = FitConvert_GetMessageData(&state);
|
436
|
+
FIT_UINT16 mesg_num = FitConvert_GetMessageNumber(&state);
|
437
|
+
|
438
|
+
switch(mesg_num) {
|
439
|
+
case FIT_MESG_NUM_FILE_ID: {
|
440
|
+
break;
|
441
|
+
}
|
442
|
+
|
443
|
+
case FIT_MESG_NUM_USER_PROFILE: {
|
444
|
+
const FIT_USER_PROFILE_MESG *user_profile = (FIT_USER_PROFILE_MESG *) mesg;
|
445
|
+
pass_user_profile(handler, user_profile);
|
446
|
+
break;
|
447
|
+
}
|
448
|
+
|
449
|
+
case FIT_MESG_NUM_ACTIVITY: {
|
450
|
+
const FIT_ACTIVITY_MESG *activity = (FIT_ACTIVITY_MESG *) mesg;
|
451
|
+
pass_activity(handler, activity);
|
452
|
+
|
453
|
+
{
|
454
|
+
FIT_ACTIVITY_MESG old_mesg;
|
455
|
+
old_mesg.num_sessions = 1;
|
456
|
+
FitConvert_RestoreFields(&state, &old_mesg);
|
457
|
+
sprintf(err_msg, "Restored num_sessions=1 - Activity: timestamp=%u, type=%u, event=%u, event_type=%u, num_sessions=%u\n", activity->timestamp, activity->type, activity->event, activity->event_type, activity->num_sessions);
|
458
|
+
pass_message(handler, err_msg);
|
459
|
+
}
|
460
|
+
break;
|
461
|
+
}
|
462
|
+
|
463
|
+
case FIT_MESG_NUM_SESSION: {
|
464
|
+
const FIT_SESSION_MESG *session = (FIT_SESSION_MESG *) mesg;
|
465
|
+
pass_session(handler, session);
|
466
|
+
break;
|
467
|
+
}
|
468
|
+
|
469
|
+
case FIT_MESG_NUM_LAP: {
|
470
|
+
const FIT_LAP_MESG *lap = (FIT_LAP_MESG *) mesg;
|
471
|
+
pass_lap(handler, lap);
|
472
|
+
break;
|
473
|
+
}
|
474
|
+
|
475
|
+
case FIT_MESG_NUM_RECORD: {
|
476
|
+
const FIT_RECORD_MESG *record = (FIT_RECORD_MESG *) mesg;
|
477
|
+
pass_record(handler, record);
|
478
|
+
break;
|
479
|
+
}
|
480
|
+
|
481
|
+
case FIT_MESG_NUM_EVENT: {
|
482
|
+
const FIT_EVENT_MESG *event = (FIT_EVENT_MESG *) mesg;
|
483
|
+
pass_event(handler, event);
|
484
|
+
break;
|
485
|
+
}
|
486
|
+
|
487
|
+
case FIT_MESG_NUM_DEVICE_INFO: {
|
488
|
+
const FIT_DEVICE_INFO_MESG *device_info = (FIT_DEVICE_INFO_MESG *) mesg;
|
489
|
+
pass_device_info(handler, device_info);
|
490
|
+
break;
|
491
|
+
}
|
492
|
+
|
493
|
+
case FIT_MESG_NUM_WEIGHT_SCALE: {
|
494
|
+
const FIT_WEIGHT_SCALE_MESG *weight_scale_info = (FIT_WEIGHT_SCALE_MESG *) mesg;
|
495
|
+
pass_weight_scale_info(handler, weight_scale_info);
|
496
|
+
break;
|
497
|
+
}
|
498
|
+
|
499
|
+
default: {
|
500
|
+
sprintf(err_msg, "Unknown message\n");
|
501
|
+
pass_message(handler, err_msg);
|
502
|
+
break;
|
503
|
+
}
|
504
|
+
}
|
505
|
+
break;
|
506
|
+
}
|
507
|
+
default:
|
508
|
+
break;
|
509
|
+
}
|
510
|
+
} while (convert_return == FIT_CONVERT_MESSAGE_AVAILABLE);
|
511
|
+
}
|
512
|
+
|
513
|
+
if (convert_return == FIT_CONVERT_ERROR) {
|
514
|
+
sprintf(err_msg, "Error decoding file.\n");
|
515
|
+
pass_err_message(handler, err_msg);
|
516
|
+
return Qnil;
|
517
|
+
}
|
518
|
+
|
519
|
+
if (convert_return == FIT_CONVERT_CONTINUE) {
|
520
|
+
sprintf(err_msg, "Unexpected end of file.\n");
|
521
|
+
pass_err_message(handler, err_msg);
|
522
|
+
return Qnil;
|
523
|
+
}
|
524
|
+
|
525
|
+
if (convert_return == FIT_CONVERT_PROTOCOL_VERSION_NOT_SUPPORTED) {
|
526
|
+
sprintf(err_msg, "Protocol version not supported.\n");
|
527
|
+
pass_err_message(handler, err_msg);
|
528
|
+
return Qnil;
|
529
|
+
}
|
530
|
+
|
531
|
+
if (convert_return == FIT_CONVERT_END_OF_FILE) {
|
532
|
+
sprintf(err_msg, "File converted successfully.\n");
|
533
|
+
pass_message(handler, err_msg);
|
534
|
+
}
|
535
|
+
|
536
|
+
return Qnil;
|
537
|
+
}
|
538
|
+
|
539
|
+
static VALUE update_crc(VALUE self, VALUE r_crc, VALUE r_data) {
|
540
|
+
FIT_UINT16 crc = NUM2USHORT(r_crc);
|
541
|
+
const char* data = StringValuePtr(r_data);
|
542
|
+
const FIT_UINT16 byte_count = RSTRING_LEN(r_data);
|
543
|
+
return UINT2NUM(FitCRC_Update16(crc, data, byte_count));
|
544
|
+
}
|
545
|
+
|
546
|
+
void Init_rubyfit() {
|
547
|
+
VALUE mRubyFit = rb_define_module("RubyFit");
|
548
|
+
VALUE cFitParser = rb_define_class_under(mRubyFit, "FitParser", rb_cObject);
|
549
|
+
|
550
|
+
//instance methods
|
551
|
+
rb_define_method(cFitParser, "initialize", init, 1);
|
552
|
+
rb_define_method(cFitParser, "parse", parse, 1);
|
553
|
+
|
554
|
+
//attributes
|
555
|
+
rb_define_attr(cFitParser, "handler", 1, 1);
|
556
|
+
|
557
|
+
// CRC helper
|
558
|
+
VALUE mCRC = rb_define_module_under(mRubyFit, "CRC");
|
559
|
+
rb_define_singleton_method(mCRC, "update_crc", update_crc, 2);
|
560
|
+
}
|